Procedural Generation · Reference
RandomNumberGenerator cheat sheet
The class you should reach for whenever a procgen algorithm needs randomness. See official docs .
Why not the global randi() / randf()
Godot exposes global random functions (randi(), randf(), randi_range()) that use a single shared, engine-wide PRNG state. That’s fine for one-off effects (particle jitter), but for procgen you want an isolated, seedable stream so one system’s randomness doesn’t perturb another’s, and so you can save/restore exact state. Use an instance of RandomNumberGenerator instead.
Basic usage
var rng := RandomNumberGenerator.new()
rng.seed = 12345 # any int — same seed, same sequence
# rng.randomize() # use instead of a fixed seed for true randomness
var x := rng.randi_range(0, 9) # int in [0, 9]
var f := rng.randf() # float in [0.0, 1.0)
var f2 := rng.randf_range(-1.0, 1.0)
var coin := rng.randi() % 2 == 0 # avoid — use randi_range instead
Reproducing a run
var rng := RandomNumberGenerator.new()
rng.seed = 12345
generate_dungeon(rng) # pass the SAME rng instance through the whole generator
# Later, to reproduce exactly:
var rng2 := RandomNumberGenerator.new()
rng2.seed = 12345 # same seed →same dungeon, if generation order is unchanged
Gotcha Determinism only holds if you call the RNG in the same order every time. Branching generation order on, say, dictionary iteration (unordered) or
Array.shuffle() called from a different RNG can silently break reproducibility.Common calls
| Call | Returns |
|---|---|
randi() |
random 32-bit unsigned int, full range |
randi_range(from, to) |
random int, inclusive both ends |
randf() |
random float in [0.0, 1.0) |
randf_range(from, to) |
random float in [from, to) |
randomize() |
reseeds from OS entropy — use for non-reproducible runs |