Page 1 of 1
Deterministic random number
Posted: Tue Mar 19, 2019 7:52 am
by leadraven
Hello.
I need a random value determined by coordinates. Currently I'm using math.randomseed for each coordinates I need. Is it a correct way? Won't it break anything in other mods? Will it work properly in multiplayer?
Or, may be, I'd better to use local instance of RNG? If so, how to create it?
How can I upgrade it to be based not only on coordinates, but also on the map seed?
Re: Deterministic random number
Posted: Tue Mar 19, 2019 8:08 am
by darkfrei
Do you need nice noise on the map or every position can have any value?
Re: Deterministic random number
Posted: Tue Mar 19, 2019 8:24 am
by leadraven
darkfrei wrote: Tue Mar 19, 2019 8:08 am
Do you need nice noise on the map or every position can have any value?
Independent value for each position.
Re: Deterministic random number
Posted: Tue Mar 19, 2019 8:50 am
by orzelek
You can use LuaRandomGenerator for that but you still need to seed it.
You can find example in RSO in method rng_for_reg_pos.
It's still not perfect since you need to do some magic to create seed from coordinates to prevent bands and symetry. And lua is not exactly nice to play with when you want to overflow int's. Some internet research might net a better method of turning x, y pair into a seed.
Re: Deterministic random number
Posted: Tue Mar 19, 2019 9:01 am
by leadraven
orzelek wrote: Tue Mar 19, 2019 8:50 am
It's still not perfect since you need to do some magic to create seed from coordinates to prevent bands and symetry.
math.randomseed(x)
local seedx = math.random(math.mininteger, math.maxinteger)
math.randomseed(y)
local seedy = math.random(math.mininteger, math.maxinteger)
math.randomseed(seedx+seedy)
local rnd = math.random()
It works, but is it the "correct" way?
Re: Deterministic random number
Posted: Tue Mar 19, 2019 2:02 pm
by DaveMcW
Calling math.randomseed() more than once in a program is bad! Factorio already calls it once with the map seed, so mods should not call it at all.
Use
LuaRandomGenerator instead.
Code: Select all
function position_random(pos)
--[[ Generator only accepts even-numbered seeds from 172 to 4294967294. ]]
local seed = (math.floor(pos.x) % 46340 * 46340 + math.floor(pos.y) % 46340 + 86) * 2
local generator = game.create_random_generator(seed)
--[[ Throw away the first few numbers because they are not very random. ]]
for i = 1, 16 do
generator()
end
return generator()
end
--[[ Test ]]
local player = game.players[1]
for x = player.position.x - 20, player.position.x + 20 do
for y = player.position.y - 20, player.position.y + 20 do
local pos = {x=x, y=y}
player.surface.create_entity{
name = "flying-text",
text = math.floor(position_random(pos) * 100),
force = player.force,
position = pos,
}
end
end
Re: Deterministic random number
Posted: Tue Mar 19, 2019 5:11 pm
by Bilka
DaveMcW wrote: Tue Mar 19, 2019 2:02 pm
Calling math.randomseed() more than once in a program is bad!
In factorio it doesnt do anything so you can call it as often as you want :P