I am trying to make a world generate based on a seed how ever i am struggling to keep it the same based on the seed yet still random.
I am trying to make every chunk have its own random number based on the seed.
e.g. Vector3.new(-5,0,5) will always have a random number between -180 and 180 on seed 1
for now i am just testing with these chunks with the following code how ever its not very random as i can spot some very obvious patterns.
local s = seed
for _,chunk in game.Workspace.Chunks:GetChildren() do
local x = chunk.Position.X
local z = chunk.Position.Z
math.randomseed(s) s = math.random(-180,180)
chunk.Orientation = Vector3.new(0,math.random(-360,360),0)
end
Im sure the solution is really simple and im just stupid or maybe its been solved before but i did some searching and couldnt find any help.
local RNG = require(script.RNG)
local Seed = Random.new():NextInteger(-180, 180)
for ID , chunk in game.Workspace.Chunks:GetChildren() do
local x = chunk.Position.X
local z = chunk.Position.Z
local Y = RNG.new(Seed .. ID .. "ChunkOrientationRNG"):NextNumber(-360, 360)
chunk.Orientation = Vector3.new(0,Y,0)
end
RNG module:
--[VARIABLES]
local Min = -2147483648
local Max = 2147483647
local Range = Max - Min
--[MODULE]
local RNG = {}
RNG.WrapNumber = function (Number)
local Result = (Number - Min) % Range + Min
if Result > Max then
Result = Result - Range
end
return Result
end
RNG.HashString = function (String : string)
local Hash = 2166136261
for Index = 1, #String do
Hash = bit32.bxor(Hash, string.byte(String, Index)) * 16777619
Hash = RNG.WrapNumber(Hash)
end
return Hash
end
RNG.new = function (Seeds : Seeds)
return Random.new(RNG.HashString(Seeds))
end
return RNG
kinda get what you want, random will be consistent on same seed as long as you generate your objects in consistent order, the problem is :GetChildren() returns blocks in random order
and btw use Random object if you want seeded random
its not really the parameters that im worried about, its the fact that some of these numbers are fairly similar like how 4 numbers in the middle are close to 80 or 90 and the other 4 in the middle seem to be close to -150
Each chunk’s seed is derived from the previous chunk’s result instead of its own position, making the output order-dependent and pattern-prone. You have just hit maths little secret, there is no truly real random..
local s = seed
for _, chunk in game.Workspace.Chunks:GetChildren() do
local x = chunk.Position.X
local z = chunk.Position.Z
math.randomseed(s + x * 73856093 + z * 19349663)
chunk.Orientation = Vector3.new(0, math.random(-180, 180), 0)
end
that would explain a lot with this method and i kind of realised that .
is there any other way around this such as using a different formula or some kind of randomness map based on a seed?
Depending on how deep you want to go, you may want to look into Perlin Noise. But that is a different topic entirely. You should be fine with that last post. The prime multiplier spatial hash gives every chunk a unique deterministic seed based solely on its position and the world seed.
he is right and even though the prime multiplier spatial hash seems a good alternative in the end all i can do with a pseudorandom algorithm is make the patterns less obvious. i ended up settling with this code i made my self.
local seed = 23987561
local s = seed
local grid_szie = 16
local step = 2
for x = -grid_szie / 2,grid_szie / 2,step do
for z = -grid_szie / 2,grid_szie / 2,step do
local chunk for _,c in game.Workspace:GetPartBoundsInBox(CFrame.new(Vector3.new(x,0,z)),Vector3.one) do
if c.Parent == game.Workspace.Chunks then chunk = c break end
end if not chunk then warn("no chunk found at",x,z) continue end
s = Random.new(s):NextNumber(-180,180) print(s)
chunk.Orientation = Vector3.new(0,math.floor(s),0)
end
end
im not completely happy with it but works just fine for what im doing. players arent to notice anyway. thank you all for your help this question was a little silly.