Very weird issue with math.random

I really need some help. I’m not sure if this is a bug or not, but math.random is repeating numbers, even if the scope of the number is 1-1000.

This script here sometimes repeats the math.random at the top.

while task.wait(0.1) do
		print(math.random(1,1000))

		if #self.Alive_Enemies < self.Max_Alive_Enemies then
			local PossibleEnemy = self:GetNewPossibleEnemy()

			if PossibleEnemy then
				local SurfacePosition = Vector3.new(math.random(-7500,7500) / 100, 150, math.random(-7500,7500) / 100)
				if not SurfacePosition then continue end

				local DungeonEnemy = EnemyModule.NewEnemy(PossibleEnemy, CFrame.new(SurfacePosition + Vector3.new(0,5,0)))
				
				self.Spawned_Enemies += 1
				table.insert(self.Alive_Enemies, DungeonEnemy)
				
				DungeonEnemy.Humanoid.Died:Once(function()
					table.remove(self.Alive_Enemies, table.find(self.Alive_Enemies, DungeonEnemy))
					self:CheckForNextDungeon()
				end)
			else
				warn("NO ENEMY")
			end
		end

		task.wait(0.1)
		
		if self.Spawned_Enemies == self.Max_Enemies then
			break
		end
	end

However, The math.random works normally when I change the code to this:

	while task.wait(0.1) do
		print(math.random(1,1000))

		if #self.Alive_Enemies < self.Max_Alive_Enemies then
			local PossibleEnemy = self:GetNewPossibleEnemy()

			if PossibleEnemy then
				local SurfacePosition = Vector3.new(math.random(-7500,7500) / 100, 150, math.random(-7500,7500) / 100)
				if not SurfacePosition then continue end
                    --nothing
				end)
			else
				warn("NO ENEMY")
			end
		end

		task.wait(0.1)
		
		if self.Spawned_Enemies == self.Max_Enemies then
			break
		end
	end

Something with creating a new enemy is repeating the number multiple times. Any help will be appreciated!

try using Random.new instead

local new_random = Random.new()

while task.wait(.1) do
print(new_random:NextInteger(0,1000))
end
1 Like

ok for some odd reason, changing the task.wait() time stops the number from repeating.

pseudo random number generators likely use time for their seed which would cause repeating if generating 2 numbers quickly. I think Random.new doesnt have this problem or it isnt as severe

1 Like

alright that makes sense. Thank you

Using task.wait()

vs using task.wait(1)

small note;
you’d probably want to generate a different position if it’s in a certain radius to the player

all really it does is generate a random position on the map

@Hzodx
Pretty sure math.random and the Random object both use the same pseudorandom generator internally, but obviously people should get into the habit of using the Random object as it has more functionality.

@LazerPigeon0429
If you want, you can throw in this line:

math.randomseed(DateTime.now().UnixTimestampMillis)

at the start of each loop to set the seed of the generator to a different seed each loop, essentially guaranteeing that you won’t see the same numbers each loop. This way you don’t have to worry about changing the value that you pass into task.wait.

DateTime.now().UnixTimestampMillis gives you the number of milliseconds that have passed since January 1st, 1970 at midnight. This will be different every single call, even if you use task.wait(), which just pauses the script until the end of the current frame.

2 Likes

also, you could swap the while loop for a for loop as such:

for _ = 1, self.Max_Enemies do
–rest of logic here
end

you probably dont want wait’s in your enemy spawning code


	while true do
		math.randomseed(DateTime.now().UnixTimestampMillis)

		if #self.Alive_Enemies < self.Max_Alive_Enemies then
			local PossibleEnemy = self:GetNewPossibleEnemy()

			if PossibleEnemy then

image

I used your randomseed code, and now the zombies appear like this, did i place it in the wrong spot?

NOTE: im using a task.wait(0.1)

i want to waits to be around 0.1. and before this i used a repeat until loop, but i switched to while loop because i thought that was throwing the random numbers off.

Honestly that’s odd, you should be getting random numbers each time.

1 Like

heres my “random position code”

function Main:GetRandomSpawnPosition()
	local EnemiesFolder = workspace.Enemies
			
	if self.Surface_Folder == nil then return end
	
	math.randomseed(DateTime.now().UnixTimestampMillis)
	local HitboxPosition = self.Hitbox.CFrame * CFrame.new(0,self.Hitbox.Size.Y/2,0)
	local DivX = self.Hitbox.Size.X/2
	local DivZ = self.Hitbox.Size.Z/2
	
	local X = math.random(-DivX, DivX)
	local Z = math.random(-DivZ, DivZ)

	local RandomCF = HitboxPosition * CFrame.new(X,0,Z)
		
	local LowerCast = workspace:Raycast(RandomCF.Position, Vector3.new(0,-100,0), SpawnRaycastParams)
				
	if LowerCast and LowerCast.Instance and LowerCast.Instance.Parent == self.Surface_Folder then
		return LowerCast.Position
	end
end

But for some really weird reason, it only does this when im spawning an enemy. If i remove this code right here, the random position generator works as intended. Also note this is also effected by task.wait times

if PossibleEnemy then
	local SurfacePosition = self:GetRandomSpawnPosition()
	if not SurfacePosition then continue end

		local DungeonEnemy = EnemyModule.NewEnemy(PossibleEnemy, CFrame.new(SurfacePosition + Vector3.new(0,5,0)))
				
		self.Spawned_Enemies += 1
		table.insert(self.Alive_Enemies, DungeonEnemy)
				
		DungeonEnemy.Humanoid.Died:Once(function()
		table.remove(self.Alive_Enemies, table.find(self.Alive_Enemies, DungeonEnemy))
		self:CheckForNextDungeon()
	end)
else
	warn("NO ENEMY")
end

I’m not sure, but I believe this is because everything is happening at almost the same time, and UnixTimestampMillis is staying the same. You can try creating an offset variable, then add that to DateTime.now().UnixTimestampMillis and increment it every iteration.

Edit: I just tested this, and I can confirm that the execution is too fast for UnixTimestampMillis try using tick()

1 Like

UnixTimestampMillis will almost certainly return a different number each loop, but the problem is I’m an idiot and providing a very similar number to randomseed each time will produce very similar results. So @LazerPigeon0429 don’t listen to me I’m dumb lol.

alright I did

math.randomseed(self.Spawned_Enemies + os.time())

And it works! thanks

2 Likes

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.