I have a mod which really wants to change things beyond the currently loaded chunks, but instantly loading a huge number of chunks is expensive and unnecessary. What I would really like to do is to do all the changes when each chunk loads, however my mod also uses a lot of rng in the big change-the-world scripts.
My question is this:
If you use the global random number generator during an on_chunk_generated script, will this cause desyncs, and is this a bad practice.
I ask because I would guess that the chunk generation order isn't the same every time (as it depends on player actions, and maybe even load time) so the random numbers generated may be different. This may cause desyncs if the order is not guaranteed across different instances of the game (e.g. client and server).
Even if the order is guaranteed, it may be bad practice, as it makes the outcome of the game dependant on the order of chunk loading, so it may introduce future issues. It may also mean that a save which is loaded back doesn't result in the same events, as the random number generator is in a different state.
Using the global random number generator inside on_chunk_generated
-
- Fast Inserter
- Posts: 153
- Joined: Sun Jul 26, 2020 4:05 pm
- Contact:
Re: Using the global random number generator inside on_chunk_generated
You can combine the coordinates of the chunk with the map seed, to create your own tick-independent random number generator.
The x and y multipliers are random primes I found on the internet, the important part is that they are large and prime.
The x and y multipliers are random primes I found on the internet, the important part is that they are large and prime.
Code: Select all
local x = event.position.x
local y = event.position.y
local map_seed = event.surface.map_gen_settings.seed
local new_seed = (x * 374761393 + y * 668265263 + map_seed) % 4294967296
local rng = game.create_random_generator(new_seed)
local rand1 = rng(1, 100)
local rand2 = rng(1, 100)
...
Re: Using the global random number generator inside on_chunk_generated
Using `math.random()` is just fine.
Re: Using the global random number generator inside on_chunk_generated
This looks better then what RSO does now - it has something similar but not using prime numbers.DaveMcW wrote: ↑Sat Aug 21, 2021 6:17 pmYou can combine the coordinates of the chunk with the map seed, to create your own tick-independent random number generator.
The x and y multipliers are random primes I found on the internet, the important part is that they are large and prime.
Code: Select all
local x = event.position.x local y = event.position.y local map_seed = event.surface.map_gen_settings.seed local new_seed = (x * 374761393 + y * 668265263 + map_seed) % 4294967296 local rng = game.create_random_generator(new_seed) local rand1 = rng(1, 100) local rand2 = rng(1, 100) ...
I might upgrade it to get better overall randomness.
- eradicator
- Smart Inserter
- Posts: 5206
- Joined: Tue Jul 12, 2016 9:03 am
- Contact:
Re: Using the global random number generator inside on_chunk_generated
Just because nobody has explicitly answered @OPs questions: Most of your answers are in the doc.
https://lua-api.factorio.com/latest/Libraries.html
Not a mathematician myself, but if LuaRandomGenerator is a proper PRNG then isn't the randomness of the seed irrelevant as long as the seed function produces a unique seed above 341 for each (x,y)?[Edit: See post below.]
https://lua-api.factorio.com/latest/Libraries.html
No, math.random is safe. However math.randomseed is a no-op, see the doc above.
I'd personally say it's fine, however if you want a map-seed stable randomness that doesn't depend on exploration order then a chunk-seeded LuaRandomGenerator for each chunk is a good idea, as the posters above have already explained.
Not a mathematician myself, but if LuaRandomGenerator is a proper PRNG then isn't the randomness of the seed irrelevant as long as the seed function produces a unique seed above 341 for each (x,y)?
Last edited by eradicator on Mon Aug 23, 2021 3:43 pm, edited 1 time in total.
Author of: Belt Planner, Hand Crank Generator, Screenshot Maker, /sudo and more.
Mod support languages: 日本語, Deutsch, English
My code in the post above is dedicated to the public domain under CC0.
Mod support languages: 日本語, Deutsch, English
My code in the post above is dedicated to the public domain under CC0.
Re: Using the global random number generator inside on_chunk_generated
The documentation specifically says, "Seeds that are close together will produce similar results."
- eradicator
- Smart Inserter
- Posts: 5206
- Joined: Tue Jul 12, 2016 9:03 am
- Contact:
Re: Using the global random number generator inside on_chunk_generated
Ah, dang. I remembered the 341 thing, but not the sentence before that :P.
Author of: Belt Planner, Hand Crank Generator, Screenshot Maker, /sudo and more.
Mod support languages: 日本語, Deutsch, English
My code in the post above is dedicated to the public domain under CC0.
Mod support languages: 日本語, Deutsch, English
My code in the post above is dedicated to the public domain under CC0.
-
- Fast Inserter
- Posts: 153
- Joined: Sun Jul 26, 2020 4:05 pm
- Contact:
Re: Using the global random number generator inside on_chunk_generated
OK, thanks, that clears things up.eradicator wrote: ↑Sun Aug 22, 2021 9:36 pmNo, math.random is safe. However math.randomseed is a no-op, see the doc above.
The thing I was scared of was that the chunk loading could be done 'as and when', rather than in lock-step, meaning that client and server could differ in exact ordering, I kind of figured it wouldn't be a thing, but you never know.
I'll still use a chunk specific rng though, as it seems like a nice thing to do - that way you can't explore differently and change how the world works.