Problem
Viv-runtime calls Math.random() directly in several places with no way to inject a seeded RNG:
src/interpreter/interpreter.ts — chance-gated expressions
src/role-caster/casting.ts — role assignment dice
src/utils/general-utils.ts — ID generation, shuffles, Gumbel noise, Box-Muller sampling
Because the host adapter can't override any of this, the same world setup + same inputs produce a different action trace on every run.
Why it matters
This blocks several downstream workflows:
- Snapshot / golden-file testing against visualizers and other UIs (exact action counts, memory salience, sifting-match tallies all drift between runs).
- Deterministic replay of a known-interesting run for debugging or demos.
- CI integration tests on host apps — forces every assertion down to loose ranges and substring matches, losing signal.
In practice it means anyone building tooling on top of Viv has to commit opaque binary fixtures and regenerate them by hand, instead of deriving them from a reproducible seed.
Suggested shape
Either (or both) of:
initializeVivRuntime({ contentBundle, adapter, seed: 42 }) — single entry point, runtime threads a seeded PRNG through its callsites.
- An optional
rng: () => number and/or provisionID: () => UID on HostApplicationAdapter — host retains full control, can wire in its own seeded generator.
Option 2 composes more cleanly with hosts that already have their own RNG (e.g. game engines).
Context
Versions: compiler 0.11.1, runtime 0.10.2.
Problem
Viv-runtime calls
Math.random()directly in several places with no way to inject a seeded RNG:src/interpreter/interpreter.ts— chance-gated expressionssrc/role-caster/casting.ts— role assignment dicesrc/utils/general-utils.ts— ID generation, shuffles, Gumbel noise, Box-Muller samplingBecause the host adapter can't override any of this, the same world setup + same inputs produce a different action trace on every run.
Why it matters
This blocks several downstream workflows:
In practice it means anyone building tooling on top of Viv has to commit opaque binary fixtures and regenerate them by hand, instead of deriving them from a reproducible seed.
Suggested shape
Either (or both) of:
initializeVivRuntime({ contentBundle, adapter, seed: 42 })— single entry point, runtime threads a seeded PRNG through its callsites.rng: () => numberand/orprovisionID: () => UIDonHostApplicationAdapter— host retains full control, can wire in its own seeded generator.Option 2 composes more cleanly with hosts that already have their own RNG (e.g. game engines).
Context
Versions: compiler 0.11.1, runtime 0.10.2.