Math.random() never picks random number

Here is my problem, not much more to say…

Here is the output:

Here is the code (server script)

NOTICE: THE CODE IS A LOOP SO IT RUNS MULTPLE TIMES. THE CODE ABOVE IS ALL INSIDE A FOR LOOP

Could you show us the code with the loop? My best guess is you’re setting num to a random number between 1 and 3, 3 gets picked and you never set it again in the loop so it’s only checking for 3.

1 Like

This is very weird. I just recreated a version of this script of my own and I got a different number every time

Here is the entire script…I think your onto something…

--Terrain Generation v1.0
local demensions = {
	x =  200, 
	z = 200,
}


local grass = workspace.voxel_Grass
local stone = workspace.voxel_Stone
local sand = workspace.voxel_Dirt

local resolution = 100
local amplitude = 10
local frequency = 2

local blockHeights = {
	["stone"] = 1000,
	["grass"] = 2,
}

local position

local function spawnTrees(position)
	local trees = workspace.Trees:GetChildren()
	local tree = trees[math.random(#trees)]:Clone()
	tree:SetPrimaryPartCFrame(CFrame.new(position+Vector3.new(0, tree.main.Size.Y, 0)))
	tree.Parent = workspace.Trees
	return true
end

local function getPosition(x, z)
	local height = math.noise(x/resolution * frequency, z/resolution * frequency, math.randomseed(1000000000))
	height = math.clamp(height, -0.5, 0.5) + 0.5
	return Vector3.new(x, height*amplitude, z)
end

for x = demensions.x, 0, -1 do
	wait()
	for z = demensions.z, 0, -1 do
		--calculate position 
		position = getPosition(x, z)
		
		
		if position.Y >= blockHeights.stone then
			--stone 
			if position.Y > frequency + 7  then
				local new_Block = workspace.voxel_Snow:Clone()

				new_Block.Anchored = true
				new_Block.Position = position
				new_Block.Parent = workspace.Ground
			else
				local new_Block = stone:Clone()

				new_Block.Anchored = true
				new_Block.Position = position
				new_Block.Parent = workspace.Ground
			end
		elseif position.Y >= blockHeights.grass then
			--grass
			local new_Block = grass:Clone()

			new_Block.Anchored = true
			new_Block.Position = position
			new_Block.Parent = workspace.Ground
		else
			--sand
			local new_Block = sand:Clone()

			new_Block.Anchored = true
			new_Block.Position = position
			new_Block.Parent = workspace.Ground
		end
		
		local num = math.random(3) 
		warn(num)
		if num == 1 then
			spawnTrees(position)
		end
	end
end

I re-created it with a for loop instead just so I could limit how many times it checked, but I got varying results.

Code I ran:

local function spawnTrees(position)
	-- your code here
end

for i = 1, 100 do
	local num = math.random(3)
	print("Num:",num)
	if num == 1 then
		spawnTrees(position)
	end
	task.wait()
end

Output:

Easy.

You aren’t updating the variable, num, therefore it only picks a random number once.

To fix this, you need to pick a new random number, or update the variable: num every time you want a new number.

I do not understand. I have formatted this (code) like I have done so in the past. I frequently encounter these sorts of “glitches.”

All the code provided was in the loop, this is why these results are unexpected!

Could you elaborate please? I’m not sure I understand.

If you try, just for the sake of testing, to make the range of the math.random bigger, do you still get only one number. Try 20 for example.

1 Like

I thought the same, but dimensions.x and dimensions.z are both 200. It is extremely unlikely that you’d get the same number 200 times, let alone 29,000 times.

Not sure if this will help, but try using the new random library:

local num = Random.new():NextInteger(1, 10)

Roblox has deprecated the old random function due to behavior like this.

2 Likes

Well I have a very similar game that spawns trees, but they are not random, it’s based on a probability check, here’s the code:

local trees = {
	{script.Basic, 500/1000}, -- 50%
	{script.Intermediate, 250/1000}, -- 25%
	{script.Advanced, 125/1000}, -- 12.5%
	{script.Neon, 60/1000}, -- 6%
	{script.Godly, 10/1000} -- 1%
}

function getRandomTree()
	local p = math.random()
	local cumulativeProbability = 0
	for name, item in pairs(trees) do
		cumulativeProbability += item[2]
		if p <= cumulativeProbability then
			return item[1]
		end
	end
end
1 Like

This is actually very very weird I ran your exact code and got the exact same thing!
But while using the Random library it picked a different number everytime!

Right here is mostly likely your problem. Try adding wait(1) instead of just wait.

Alright I was able to reproduce the issue using the code snippet below:

for i = 1, 25 do 
	math.randomseed(1000000000)
	local num = math.random(3)
	warn(num)
end

you keep manually changing the math.random() seed before using the function causing the same result to be shown every time.

3 Likes

I figured out the issue:

image

This bit of code in your getPosition function is setting the randomseed to a constant value. Because of this, all “random” numbers generated on that same seed will produce the same results. Try changing it to math.randomseed(tick()) instead.

3 Likes

Just realized this too, nice catch :wink:

3 Likes

This is solved the issue when I ran his exact code, except this part! This is in fact the solution. All though this is still very weird!

1 Like