How could i make random numbers that can't be other random numbers

Hi, i am here to ask, how could i make something sort of like roblox ID, where when you make lets say a decal it gives it a id but your decal is the only one with that ID, so like if your id is 5023 when someone else makes a decal it makes a new random id but it can never be 5023 it will take something diffrent, how would i make something like this??

I guess keep a list of all existing IDs, then just reroll the random thing until it’s unique.

e.g.

local AlreadyRolled = {}

function GetRandomNumber()
	local Chosen = math.random(1, 10000)

	while table.find(AlreadyRolled, Chosen) do
		Chosen = math.random(1, 10000)
	end

	table.insert(AlreadyRolled, Chosen)
	return Chosen
end)

but this would restart everytime all players would leave

I guess.

What is the reason you need this system? There may be an alternative that’s superior

1 Like

If you’re considering unique IDs across all past and present servers, I’d immediately think of storing a “frontier” value (the smallest unused ID) and saving/incrementing it in your datastores using :UpdateAsync as it is safe from race conditions. Whenever you want to assign a unique ID, read from and increment the frontier value.

Adding on to what @SeargentAUS said above: If you give us more context, we might be able to reach a better solution that probably fits your situation better.

I just noticed that you wanted randomness! Read the message below by @12345koip. I think it’s a valid solution as well. :slight_smile:

1 Like

I would recomment using HttpService.GenerateGUID. The likelihood of generating two identical UUIDs is incredibly low, but you can keep a registry for them anyway if you want to do so, maybe in a memory store map or something similar.

The UUID is in a format with all hexadecimal digits, so you can split it at the dashes in between and convert it to denary, although adding them all together manually could exceed the Luau number limit. If you want to get around this, you can use a buffer and convert it to a string afterwards. For simplicity’s sake, I’ll give you an example which returns a string.

Note you cannot raw tonumber(hexString, 16) safely because it will ignore leading 0s, which we actually need, as well as containing dashes, and if you added all the results together you’d probably exceed the Luau number limit.

local dash = string.byte("-") --this is the ASCII code of the dash, which we want to ignore.

--we cannot raw tonumber(uuidString, 16) because tonumber ignores leading 0s.
local function uuidToDenary(uuidString: string): string
    local out = ""

    for character in string.gmatch(uuidString, ".") do --this iterates over every character in the string.
        if (string.byte(character) == dash) then continue end --ignore dash, we don't want it.
        out ..= tonumber(character, 16)
    end

    return out
end

local raw = uuidToDenary(HttpService:GenerateGUID(false))
2 Likes