2.5 KiB
Task 4: Deterministic RNG
Depends on: Task 1
Context Files
.dev/2026-05-28-procgen-map-core/spec/design.md— §4.4 (RNG) and §7 (determinism contract).reikhelm-core/src/lib.rs— append the module declaration here.
Files
- Create:
reikhelm-core/src/rng.rs—Rng. - Modify:
reikhelm-core/src/lib.rs— appendpub mod rng;.
What to Build
A deterministic RNG wrapping rand_chacha::ChaCha8Rng (spec §4.4). Reproducible across machines — never thread_rng. The keystone feature is fork: deriving an independent child stream from a stable basis (the originating seed) plus a label, so that forks are independent of draw order and of each other. The Pipeline (Task 6) calls fork once per pass; this is what makes editing the pipeline non-destructive to existing seeds (spec §7).
Critical determinism detail: fork's label→seed mixing must be stable across runs and crate versions. Do not use std::collections::hash_map::DefaultHasher (unspecified, version-unstable). Use an explicit, fixed integer mix (e.g. a splitmix64 / FNV-style combine of the base seed and the label bytes). Document the chosen mixing.
Interface Dependencies
- Produces:
Rngwith:from_seed(seed: u64) -> Self(stores the seed as the fork basis)fork(&self, label: &str) -> Rng— returnsRng::from_seed(mix(self.basis_seed, label)); does not advanceself; order-independent.range(&mut self, lo: i32, hi: i32) -> i32(half-open or inclusive — document which)chance(&mut self, p: f64) -> boolchoose<'a, T>(&mut self, items: &'a [T]) -> Option<&'a T>shuffle<T>(&mut self, items: &mut [T])
Tests
- Same seed → identical sequence of
rangedraws (reproducibility). forkis order-independent:r.fork("a")produces the same stream regardless of how many values were drawn fromrbeforehand.- Distinct labels produce distinct (non-identical) streams:
fork("a") != fork("b"). fork("name#0")andfork("name#1")differ (the occurrence-keying scheme the pipeline relies on works).chooseon an empty slice returnsNone;shuffleis a permutation (same multiset).
Success Criteria
Rngwraps ChaCha8;forkderives from a stable basis with an explicit (non-DefaultHasher) mix.forkis order-independent and does not mutate the parent.pub mod rng;added tolib.rs.- All tests pass:
cargo test -p reikhelm-core rng
Commit
"feat(core): deterministic ChaCha8 RNG with order-independent fork"