Random.new() not that random

Hello, recently ive tried to make a bacon generator that spawns bacons, it works! everything works but theres one weird thing i was using math.random for the random spot selecting and math.random for a random bacon select the problem is that math.random wasnt that random so i decided to change to Random.new() after trying it out it fixed a little bit the problem but still it’s not really that random. Any way to fix it?

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ServerStorage = game:GetService("ServerStorage")
local RunService = game:GetService("RunService")

local Bacons = ServerStorage.Bacons

local Spawns = workspace.Bacons.Spawns
local SFX = workspace.SFX

local RandomGenerator = Random.new()

local function FindUnoccupiedSpot(): boolean | Part
	local UnoccupiedSpots = {}

	for _, SpawnSpot in Spawns:GetChildren() do
		if SpawnSpot:GetAttribute("Occupied") == false and SpawnSpot:FindFirstChild("NPC_who_occupies").Value == nil then
			table.insert(UnoccupiedSpots, SpawnSpot)
		end
	end

	if #UnoccupiedSpots > 0 then
		return UnoccupiedSpots[RandomGenerator:NextInteger(1, #UnoccupiedSpots)]
	else
		return false
	end
end

while task.wait(1) do
	for _, SpawnSpot in Spawns:GetChildren() do
		if SpawnSpot and not SpawnSpot:FindFirstChildOfClass("ObjectValue") then
			local ObjectValue = Instance.new("ObjectValue")
			ObjectValue.Name = "NPC_who_occupies"
			ObjectValue.Parent = SpawnSpot
		end
	end
	
	local RandomBacon = Bacons:GetChildren()[RandomGenerator:NextInteger(1, #Bacons:GetChildren())]

	for _, SpawnSpot in Spawns:GetChildren() do
		if SpawnSpot and RandomBacon and SpawnSpot:GetAttribute("Occupied") == false and SpawnSpot:FindFirstChild("NPC_who_occupies").Value == nil then
			local ClonedBacon = RandomBacon:Clone()
			local RandomSpawnSpot = FindUnoccupiedSpot()

			if RandomSpawnSpot then
				print(RandomBacon)
				ClonedBacon:PivotTo(RandomSpawnSpot.CFrame)
				RandomSpawnSpot:SetAttribute("Occupied", true)
				RandomSpawnSpot:FindFirstChild("NPC_who_occupies").Value = ClonedBacon

				ClonedBacon.Parent = workspace.Bacons.NPCs
				SFX.Spawn:Play()
			end
		end
	end
end

One way is you can change the output of the RNG object by setting the seed through random, i usually do this: local RandomGenerator = Random.new(DateTime.now().UnixTimestampMillis)

Its not guaranteed to have better results as its pseudo-random but its done the trick for me before

Event with that, it’s not that random sometimes.
image

RandomGenerator is set because it is outside of a loop so it will stay consistent, put it inside the loop

I was thinking of that but if i put it inside the loop i will need to generate a new random generator for the FindUnoccupiedSpot, is that fine if i generate a new one?

Yes, if you have it outside the loop it becomes a constant. So you want it inside the loop to constantly generate a new random number. It really shouldn’t affect it that much performance wise

Or, i could use math.random() for the UnoccupiedSpots function and the Random.new for selecting?

Make it so the function needs a number to require the random

local function FindUnoccupiedSpot(number): boolean | Part
local UnoccupiedSpots = {}

	for _, SpawnSpot in Spawns:GetChildren() do
		if SpawnSpot:GetAttribute("Occupied") == false and SpawnSpot:FindFirstChild("NPC_who_occupies").Value == nil then
			table.insert(UnoccupiedSpots, SpawnSpot)
		end
	end

	if #UnoccupiedSpots > 0 then
		return UnoccupiedSpots[number:NextInteger(1, #UnoccupiedSpots)]
	else
		return false
	end
end

while task.wait(1) do
	local RandomGenerator = Random.new()
	for _, SpawnSpot in Spawns:GetChildren() do
		if SpawnSpot and not SpawnSpot:FindFirstChildOfClass("ObjectValue") then
			local ObjectValue = Instance.new("ObjectValue")
			ObjectValue.Name = "NPC_who_occupies"
			ObjectValue.Parent = SpawnSpot
		end
	end
	
	local RandomBacon = Bacons:GetChildren()[RandomGenerator:NextInteger(1, #Bacons:GetChildren())]

	for _, SpawnSpot in Spawns:GetChildren() do
		if SpawnSpot and RandomBacon and SpawnSpot:GetAttribute("Occupied") == false and SpawnSpot:FindFirstChild("NPC_who_occupies").Value == nil then
			local ClonedBacon = RandomBacon:Clone()
			local RandomSpawnSpot = FindUnoccupiedSpot(RandomGenerator)

			if RandomSpawnSpot then
				print(RandomBacon)
				ClonedBacon:PivotTo(RandomSpawnSpot.CFrame)
				RandomSpawnSpot:SetAttribute("Occupied", true)
				RandomSpawnSpot:FindFirstChild("NPC_who_occupies").Value = ClonedBacon

				ClonedBacon.Parent = workspace.Bacons.NPCs
				SFX.Spawn:Play()
			end
		end
	end
end
1 Like

That works, i forgot about parameters lol. Thanks.

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