Procedural Content Generation – Random Number Generation

Random Number Generation in Procedural Content Generation (PCG)

  • Purpose
    • Acts as the primary “information source” used to define parameters for models/algorithms that create game content (terrain, texture, quests, path networks, etc.).
    • In classic computer‐science contexts, the goal is to approximate true randomness (values that cannot be reproduced).
    • In PCG, the goal is controlled, repeatable randomness: we want the same input seed to yield the exact same output sequence so that generated content can be recreated any time (e.g., re-loading a save file, sharing a level code).
  • True vs. Pseudo
    • True random sources: hardware noise, atmospheric static, radioactive decay, camera Brownian motion, etc., usually post-processed through a whitening/randomization algorithm.
    • Pseudorandom sources: algorithmic functions that appear random but are 100 % deterministic from the same seed.

Desired Statistical Distribution

  • Uniform Distribution
    • Every value in the range has equal probability.
    • Works for both discrete (integer) and continuous (floating-point) domains.
    • Common default because it gives maximal entropy per bit and predictable statistics.
  • Other Distributions
    • Gaussian/Normal, Poisson, Exponential, etc., can be built on top of the uniform generator.
    • Computational cost varies (Box-Muller for Gaussian, alias tables for discrete custom distributions, rejection sampling, Ziggurat, etc.).
    • Choice depends on artistic need: e.g., Gaussian for clustered placement, Poisson for natural spacing.

Numeric Mixing & Seeds

  • A pseudorandom number generator (PRNG) is fundamentally a mixing function.
    • The seed’s bits are iteratively permuted and combined so that each output bit is influenced by many (ideally all) seed bits.
  • Determinism property
    • Same Seed    Same Full Sequence\text{Same Seed} \; \Rightarrow \; \text{Same Full Sequence}
    • Enables reproducible PCG; different seeds produce wholly different worlds.
  • Update formulation
    • Let S0S_0 be the initial state (equal to or derived from the seed).
    • A step of the PRNG can be written S<em>0S</em>1,rS<em>0 \to S</em>{1,r} where S1S_{1} is the new internal state and rr the output random value.
    • Repeated calls chain the state: S<em>nS</em>n+1,rn+1S<em>{n} \to S</em>{n+1,r_{n+1}}.

Challenges for Perfect Repeatability

  • Call Count Consistency
    • Even when the same seed is used, the sequence index must match. Any extra or missing call shifts the remainder of the sequence.
  • Multiple Subsystems
    • Physics, AI, animation, loot rolls, VFX, networking, analytics—all might tap the same RNG.
    • An innocent change (new particle spawn) can break level generation determinism.
  • Nondeterministic Triggers
    • Frame-rate dependent loops (variable update counts).
    • External events: human input, network packets, sensor data.
  • Guideline: keep strict accounting of every RNG request or use separate generators for isolated systems (see “Isolate RNG”).

Unity Engine Facilities (Example)

  • Random.InitState(int initialSeed)
    • Sets the global Unity PRNG state from an integer seed.
  • Random.Range(int/float a, int/float b)
    • Discrete or continuous uniform range sampling.
  • Random.state (get & set)
    • Struct holding the full internal state; serializable for save games.
    • Limitation: you cannot derive the original seed from an arbitrary state snapshot.
  • Best practice in Unity: save/restore Random.state when you enter/exit PCG functions to avoid global contamination.

Isolating RNG per Subsystem

  • Provide a root/master seed via a game manager.
  • Each subsystem constructs its own local PRNG instance (or keeps its own copy of Unity’s Random.State).
  • Benefits
    • Changes in one subsystem do not affect the sequence consumed by another.
    • Easier debugging—log or serialize each subsystem’s seed/state.
    • Facilitates deterministic re-runs of only a subset (e.g., regenerate terrain without re-simulating AI).

Platform & Implementation Variations

  • Different operating systems, compilers, CPU architectures, or library versions may embed distinct PRNG algorithms (e.g., Microsoft rand() vs. glibc rand()).
  • Small, seemingly harmless updates (SDK, driver, console firmware) can silently change RNG results.
  • Mitigation: ship your own PRNG implementation inside the codebase.
    • Guarantees bit-identical output across Windows, macOS, Linux, PS5, Xbox, Switch, mobile, etc.
    • Allows forward compatibility; if you upgrade the algorithm you can still keep legacy generators around for old saves.
  • Popular Choice: Mersenne Twister (MT19937)
    • Period of 21993712^{19937}-1, excellent statistical quality, fast.
    • But not cryptographically secure (fine for games/fairness, unsafe for security tokens).

Quality of RNG & Post-Processing

  • Raw RNG output is high-frequency noise—usually unsuitable as‐is for content.
    • Example: If you directly map height values to a terrain mesh, you get unplayable spiky landscapes.
  • Typical pipeline
    • RNG ➔ Noise function (Perlin, Simplex) ➔ Filtering/Smoothing ➔ Domain-specific model.
  • Visual Example (Millington Fig 8.7)
    • Pure elevation noise displayed as a gray-scale height map: looks like TV static; needs filtering to become rolling hills.

Practical / Ethical / Philosophical Implications

  • Fairness & Transparency
    • Deterministic seeds allow players to share world codes—bolstering community and e-sports fairness.
    • Conversely, hidden seed usage can hide drop-rate manipulation; transparency matters.
  • Creative Control vs. Surprise
    • Designers oscillate between wanting handcrafted predictability and emergent unpredictability. Seeded PRNG offers a middle ground: controlled chaos.
  • Preservation & Archiving
    • Repeatable RNG lets future researchers, speed-runners, or historians regenerate worlds and study them long after original servers shut down.