Convert decal ID to image ID, with your free private proxy

Roblox has now provided an official implementation! We no longer have to rely on proxies or hacky workarounds :tada:


:warning: This tutorial is now obsolete - continue if you’re curious, but you shouldn’t use this method in new work.

Yesterday, Roblox announced that they were planning to make their asset ID generation non-sequential. If Roblox moves forward with this, many developers relying on the “subtract ID until image ID” method will find that their conversion will no longer work. And, in PeZsmistic words, that method is hideous at this scale.

But still, there’s no good alternative workaround without relying on public proxies…

…well, at least until now.

Within now and 10 minutes, you’ll have your own free private proxy, even if you’ve never touched anything web before. We’ll get through this!


Step 1. Click the magic button :sparkles:

Deploy to Cloudflare Workers

Step 2. Deploy

  1. Click on the Deploy button:
    image

If you already have a CloudFlare account, log in and skip to Step 3.

  1. Create a CloudFlare account:

  2. Verify your email address:
    CloudFlare sent you a verification message, click the link in the email to continue.

Step 3. Actually Deploy

  1. Give your worker a name and press Deploy

  2. Congratulations! You just launched the proxy! :tada:
    Make sure to note down the address, you’ll need this later on.
    image

Step 4. Using your proxy in Roblox

  1. Create a ModuleScript called DecalToImage under ServerStorage.
  2. Copy-paste the following code:
--!strict
--@author Chris van Chip (xChris_vC)

local API_ENDPOINT = "https://decal-to-image.temp-rblx.workers.dev"

local HttpService = game:GetService("HttpService")

local function Convert(decalId: number): (boolean, string)
	assert(decalId, "Decal ID must be defined")
	
	local success, body = pcall(function(): {error: string?, id: string?}
		local response = HttpService:GetAsync(`{API_ENDPOINT}/{decalId}`)
		local body: {error: string?, id: string?} = HttpService:JSONDecode(response)
		return body
	end)
	
	if not success then
		return false, "Request failed"
	end
	
	if body.error or not body.id then
		return false, body.error or ""
	end
	
	return true, body.id
end

return Convert
  1. Replace the URL in API_ENDPOINT with your new worker URL from Step 3:
    image

  2. You can now call the Convert(decalId) function from a ServerScript! For example:

local ServerStorage = game:GetService("ServerStorage")
local Convert = require(ServerStorage.DecalToImage)
local Success, Body = Convert(17819356961)
print(Success, Body) --> Body is image id on success, or error message if failed

Step 5. Give yourself a pat on the back! :tada:

you deserved it


Questions you may ask

Q: Are there any limits?
A: CloudFlare Workers accepts up to 100k requests per day, and 1k requests per minute. The IP address is rotated for every request, so you won’t hit ratelimits with Roblox’s AssetDelivery. You can send 500 requests per minute using HttpService in a single Roblox server. If you have reasonable usage, you should never hit any limits.

Q: Can I repurpose this into an overall Roblox proxy?
A: You sure can! CloudFlare Workers are perfect for proxying, as long as you stay under the 10ms limit. If there’s interest for this, lmk!

S: i am roblox engineer and i will now triage an official conversion method as “backlog Y2030”
A: please don’t i beg u
(EDIT: you listened and delivered, thank you very much)


Anyway, let me know if this is helpful to you - if you got any feedback, don’t be shy; hit the reply!

15 Likes