imneme / pcg-cpp

PCG — C++ Implementation
Apache License 2.0
745 stars 99 forks source link

Rebase seed #72

Open TaaTT4 opened 3 years ago

TaaTT4 commented 3 years ago

I'm working on an algorithm (procedural racetrack generator) whose outcome, in the general case, is solely based on the RNG outputs. But in some specific scenarios, I need to provide to user the ability to bypass some generation steps (e.g. terrain conformation) without affecting the rest of the generation process.

Let me make a simple practical example:

## Procedural racetrack ##
                                                         *
           | Track shape generation | Terrain generation | Surfaces generation | Assets picking |
RNG stream | 1 2 3                  | 4 5 6 7            | 8 9                 | 0              |
## User-overridden racetrack ##
                                                         *
           | Track shape generation | Terrain generation | Surfaces generation | Assets picking |
RNG stream | 1 2 3                  | provided by user   | 4 5                 | 6              |

As you can see, in the User-overridden racetrack case, the fact that the Terrain generation step is bypassed (and so no RNG output is consumed) alters all the subsequent generation steps.

What I'm looking for is some sort of RNG synchronization operation (probably not the most corrected term to use...) to put in between the Terrain generation step and the Surfaces generation step to have the same RNG stream from the * onwards, regardless if the terrain is provided by user or not. I thought about something like:

uint64_t seed = // initialized with racetrack ID
pcg32 rng(seed);

// Do Track shape generation step
// Do Terrain generation generation step

seed = seed + k; // where k is some constant
rng.seed(seed);

// Do Surfaces generation step
// Do Assets picking step

But I don't know if seed = seed + k; is a valid reseeding approach (or there's something better) and if some value is better than others for k.

[EDIT] Forgot to state it, but the number of RNG outputs required for every generation step in not constant among different racetracks generation (and it isn't even predeterminable in advance).