Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
✓ ANSWER ACCEPTED

Why does this script with math.random() always choose the same number?

So I have a server script in server script service that's basically a round script.

What it does is like every other round script but when it chooses a random map it enables the script by doing scriptName.Disabled = false and when the round ends it sets it to true.

This works on all maps and every script works when it's enabled.

However I have issues with 1 script:


local players = game.Players:GetPlayers()
local replicatedStorage = game:GetService("ReplicatedStorage")

local remote = replicatedStorage:WaitForChild("RemoteHide")

local itLabel = replicatedStorage:WaitForChild("BillboardHide")

local it = nil

math.randomseed(tick())

local randomNum = math.random(1, #players)

print("random number is: "..randomNum)

for i, v in pairs(players) do
	if i == randomNum then
		local text = v.Name
		it = v
		remote:FireAllClients(text, it)
		itLabel:Clone().Parent = it.Character.Head
	end
end

In this script it chooses the same random number and that number is ALWAYS the same as number of players so basically it always chooses the last person who joined.

Why does it happen and how can I fix it to really be random without changing anything in the round script?

1 answer

✓ Accepted answer

Only run math.randomseed once per server for all scripts.

There is a quirk in how lua generates random numbers from the randomseed such that if you give randomseed multiple similar numbers, the first randomly generated number is only subtly different than the previous. You can see this for yourself by doing this in the Command line repeatedly: math.randomseed(tick()) print(math.random()).

Alternatively, you can get around this by throwing away the first 1-3 random numbers. (It is good practice to do this whenever you call math.randomseed anyway).

Note: you can simplify lines 10+ to this (though you might want to keep some of your variables for clarity):

local it = players[math.random(1, #players)]
remote:FireAllClients(it.Name, it)
itLabel:Clone().Parent = it.Character.Head

ex, say the random number is 3, then local it = players[3] will give you the 3rd player in the list.

However, if you can't guarantee that it.Character.Head will always exist, you might want to think further on your script. ex, what if they Reset their character right before you randomly chose them to be it? Their Head might not even exist if it's fallen off the edge of the map (or if their character has glitched through the floor) and even if it does, it'll be replaced soon (and your BillboardHide clone along with it).

This discussion is preserved as it was. New answers, comments, and votes are closed.