Using the global random number generator inside on_chunk_generated

Place to get help with not working mods / modding interface.
Post Reply
BicycleEater
Fast Inserter
Fast Inserter
Posts: 153
Joined: Sun Jul 26, 2020 4:05 pm
Contact:

Using the global random number generator inside on_chunk_generated

Post by BicycleEater »

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.

User avatar
DaveMcW
Smart Inserter
Smart Inserter
Posts: 3700
Joined: Tue May 13, 2014 11:06 am
Contact:

Re: Using the global random number generator inside on_chunk_generated

Post by DaveMcW »

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.

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)
...

PFQNiet
Filter Inserter
Filter Inserter
Posts: 289
Joined: Sat Sep 05, 2020 7:48 pm
Contact:

Re: Using the global random number generator inside on_chunk_generated

Post by PFQNiet »

Using `math.random()` is just fine.

orzelek
Smart Inserter
Smart Inserter
Posts: 3911
Joined: Fri Apr 03, 2015 10:20 am
Contact:

Re: Using the global random number generator inside on_chunk_generated

Post by orzelek »

DaveMcW wrote:
Sat Aug 21, 2021 6:17 pm
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.

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)
...
This looks better then what RSO does now - it has something similar but not using prime numbers.
I might upgrade it to get better overall randomness.

User avatar
eradicator
Smart Inserter
Smart Inserter
Posts: 5206
Joined: Tue Jul 12, 2016 9:03 am
Contact:

Re: Using the global random number generator inside on_chunk_generated

Post by eradicator »

Just because nobody has explicitly answered @OPs questions: Most of your answers are in the doc.
https://lua-api.factorio.com/latest/Libraries.html
BicycleEater wrote:
Sat Aug 21, 2021 5:33 pm
will this cause desyncs
No, math.random is safe. However math.randomseed is a no-op, see the doc above.
BicycleEater wrote:
Sat Aug 21, 2021 5:33 pm
and is this a bad practice.
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.
DaveMcW wrote:
Sat Aug 21, 2021 6:17 pm
the important part is that they are large and prime.

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.]
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.

User avatar
DaveMcW
Smart Inserter
Smart Inserter
Posts: 3700
Joined: Tue May 13, 2014 11:06 am
Contact:

Re: Using the global random number generator inside on_chunk_generated

Post by DaveMcW »

eradicator wrote:
Sun Aug 22, 2021 9:36 pm
if LuaRandomGenerator is a proper PRNG
:lol: :lol: :lol: :lol:

The documentation specifically says, "Seeds that are close together will produce similar results."

User avatar
eradicator
Smart Inserter
Smart Inserter
Posts: 5206
Joined: Tue Jul 12, 2016 9:03 am
Contact:

Re: Using the global random number generator inside on_chunk_generated

Post by eradicator »

DaveMcW wrote:
Sun Aug 22, 2021 9:43 pm
The documentation specifically says, "Seeds that are close together will produce similar results."
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.

BicycleEater
Fast Inserter
Fast Inserter
Posts: 153
Joined: Sun Jul 26, 2020 4:05 pm
Contact:

Re: Using the global random number generator inside on_chunk_generated

Post by BicycleEater »

eradicator wrote:
Sun Aug 22, 2021 9:36 pm
No, math.random is safe. However math.randomseed is a no-op, see the doc above.
OK, thanks, that clears things up.
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.

Post Reply

Return to “Modding help”