A simulation you can't reproduce is a simulation you can't debug. Whether it's a wheel, a particle system, or a Monte Carlo pricing model, seeding every source of randomness turns "it failed once, somewhere" into a bug you can replay on demand.
Thread the seed, don't read the global
The cardinal sin is calling a global random(). The moment two subsystems share global state, execution order changes results. Pass a seeded generator explicitly:
import random
def spin(seed, pockets=37):
rng = random.Random(seed) # isolated, reproducible
velocity = rng.uniform(8.0, 12.0)
friction = rng.uniform(0.02, 0.05)
# deterministic physics from here on
pos = 0.0
while velocity > 0.1:
pos = (pos + velocity) % pockets
velocity *= (1 - friction)
return int(pos)
assert spin(42) == spin(42) # same seed, same result, always
Reproducibility is a testing superpower
With a seed you can pin a failing scenario as a regression test, bisect a divergence between two builds, and record-replay a production incident. "Flaky" almost always means "unseeded shared state," not "genuinely random."
Beware hidden nondeterminism
Dict iteration order, floating-point summation order across threads, and wall-clock reads all sneak nondeterminism past your seed. Sort before you iterate, reduce in a fixed order, and inject the clock.
Reference
Wheel-based games are a tidy example because the outcome is a single reproducible integer given a seed. A game like visit the website exposes a self-contained round whose result derives entirely from its seed and rules — the same discipline that makes any physics sim replayable.
Takeaway
Seed every generator, pass it explicitly instead of touching globals, and hunt down hidden order-dependence. Reproducibility costs one parameter and pays for itself the first time you have to debug a rare failure.
Top comments (0)