CascadeRng
Seed-reproducible: the same seed, the same parameters and the same player actions replay the same run.
CascadeRng — deterministic pseudo-random numbers
Seed-reproducible: the same seed, the same parameters and the same player actions replay the same run.
local Rng = require("CascadeRng")
local r = Rng.new(20250922)
r.next() -- a float in [0, 1)
r.int(1, 6) -- an integer in [1, 6]
r.chance(0.3) -- true 30% of the time
r.getState() -- snapshot the stream position
Why it is arithmetic only
The obvious choice — a xorshift over bit32 — costs about half a microsecond
per draw in this VM, because every bit32 call crosses the native boundary. A
tick makes roughly one draw per cell, so that alone was three times the cost
of the entire simulation.
The Lehmer (Park–Miller) generator here is one multiply and a remainder, both exact in a double because the product stays inside 2^53:
s = (s * 48271 + 11) % 2147483647
Measured at roughly ten nanoseconds per draw — fifty times cheaper than the xorshift, with the same statistical job to do.
Period
2^31 − 2 draws, which is about twenty-five minutes of continuous simulation at full rate on a 256×256 board. Past that the stream repeats; the run is still fully deterministic, and a cellular automaton this chaotic has long since lost any resemblance to the earlier pass.
hash2
The same trade, for the procedural fields: a few multiplies and a remainder with every intermediate inside 2^53, so the growth field and the terrain generate identically on every machine and cost nothing.
Scoped to this part · feeds back into the world's score.