This page contains notes for the page Roblox (Engine)/Revisional Differences/Official Places.
Place files archives#
Downloading uncopylocked place files#
After some time I got Gemini to spit out this code, which allows you to download all place files that exist for a game using Python. To get the max. place number check out the next paragraph.
import requests
import os
import time
def download_roblox_place_versions(place_id, start_version, end_version, output_directory="."):
"""
Downloads a range of versions of a Roblox place and adds the .rbxl extension.
Args:
place_id: The ID of the Roblox place (an integer).
start_version: The first version number to download (an integer).
end_version: The last version number to download (an integer).
output_directory: The directory where downloaded files will be saved. Defaults to the current directory.
"""
os.makedirs(output_directory, exist_ok=True) # Create output directory
for version_number in range(start_version, end_version + 1): # +1 so that end_version is included
url = f"https://assetdelivery.roblox.com/v1/asset/?id={place_id}&version={version_number}"
try:
response = requests.get(url, stream=True)
response.raise_for_status()
file_name = f"{place_id}_v{version_number}.rbxl"
file_path = os.path.join(output_directory, file_name)
with open(file_path, "wb") as f:
for chunk in response.iter_content(chunk_size=8192):
f.write(chunk)
print(f"Downloaded place version {version_number} to {file_path}")
except requests.exceptions.RequestException as e:
print(f"Error downloading version {version_number}: {e}")
except OSError as e:
print(f"OS Error with version {version_number}: {e}")
time.sleep(2) # Wait for 2 seconds before the next request
# Example usage:
place_id = 1437 # Replace with the actual place ID
start_version = 0 # Replace with the desired starting version
end_version = 112 # Replace with the desired ending version
download_roblox_place_versions(place_id, start_version, end_version)
Get max. place version#
To get the currently published place version which tends to be the newest place version you can use this python code. (To use this you need an API key from here with read access to the asset API.)
import requests
api_key = "REPLACETHISWITHYOURAPIKEY" #Replace with your api key
def get_asset_revision_id(asset_id, api_key, read_mask="revisionId"):
url = f"https://apis.roblox.com/assets/v1/assets/{asset_id}?readMask={read_mask}"
headers = {
"x-api-key": api_key
}
try:
response = requests.get(url, headers=headers)
response.raise_for_status() # Raise HTTPError for bad responses (4xx or 5xx)
data = response.json()
return data.get("revisionId") # Safely get the revisionId from the response
except requests.exceptions.RequestException as e:
print(f"An error occurred: {e}")
return None
except ValueError: #if the json cannot be decoded.
print("Invalid JSON response")
return None
except KeyError: #if the revisionId is not in the json
print("revisionId not found in response")
return None
asset_id = input("Asset ID (example: 1437): ")
revision_id = get_asset_revision_id(asset_id, api_key)
if revision_id is not None:
print(f"Revision ID: {revision_id}")
Making an asset tree#
I made the asset tree using the following script, the script needs to be put into the ServerScriptService as a normal script.
local function printTree(prefix, name, classname)
if not classname then
script.Value.Value = script.Value.Value .. prefix .. name .. "\n"
else
script.Value.Value = script.Value.Value .. prefix .. name .. " (" .. classname .. ")\n"
end
end
local function traverse(parent, prefix)
for _, child in ipairs(parent:GetChildren()) do
printTree(prefix, child.Name, child.ClassName)
traverse(child, prefix .. " ")
end
end
local services = {
game:GetService("Workspace"),
game:GetService("ReplicatedStorage"),
game:GetService("ReplicatedFirst"),
game:GetService("ServerStorage"),
game:GetService("ServerScriptService"),
game:GetService("StarterPack"),
game:GetService("StarterGui"),
game:GetService("StarterPlayer"),
}
for _, service in ipairs(services) do
printTree("", service.Name)
traverse(service, " ")
end
For this code to work you need to run it and you need to put a child StringValue inside of the script. It should look like the example tree below.
ServerScriptService
└── Script (Script)
└── Value (StringValue)
After running the code, make sure you're looking at the game on the serverside. Copy the value found in the StringValue and paste it into [https://tree.nathanfriend.io/?s=(%27options!(%27fancy!true~fullPath*~trailingSlash*~rootDot*)~-(%27-%27%27)~version!%271%27)*!false-source!%01-* this website.] Now copy the tree using the Copy button found at the top of the screen and put the tree into the page surrounded by the following code.
Code#
<pre style='white-space: pre-wrap; overflow: auto; width: 700px'; height: 300px'>
</pre>
Getting the time an asset was updated for the last time#
Well just put this code into a script located inside of ServerScriptService. (This is for the specific versions of experiences.)
local asset = game:GetService("MarketplaceService"):GetProductInfo(PutYourAssetIdHere, Enum.InfoType.Asset, VersionValue)
local update_stamp = tostring(asset.Updated)
function ConvertTimeStamp(time_stamp)
local date_pattern = "%d%d%d%d%-%d%d%-%d%d"
local stamp_date = string.sub(time_stamp, string.find(time_stamp, date_pattern))
local split_date = string.split(stamp_date, "-")
local year = split_date[1]
local month = split_date[2]
local day = split_date[3]
local elapsed_years = (year - 1970)
local elapsed_months = month - 1
local elapsed_days = day - 1
return year, month, day
end
print(ConvertTimeStamp(update_stamp))
Use this if you want the overall last update time:
local asset = game:GetService(“MarketplaceService”):GetProductInfo(PutYourAssetIdHere)
local update_stamp = tostring(asset.Updated)
function ConvertTimeStamp(time_stamp)
local date_pattern = “%d%d%d%d%A%d%d%A%d%d”
local stamp_date = string.sub(time_stamp, string.find(time_stamp, date_pattern))
local split_date = string.split(stamp_date, “-”)
local year = split_date[1]
local month = split_date[2]
local day = split_date[3]
local elapsed_years = (year - 1970)
local elapsed_months = month - 1
local elapsed_days = day - 1
return year, month, day
end
print(ConvertTimeStamp(update_stamp))