Playing a whole world in the terminal

A party plays in the terminal with no browser and no server, and a village year plays in under a second. Both run on the same primitives as the live simulation, so a rule that works headless works live.

A party
bun scripts/dry-run.ts syndicate
Reproducible
SEED=7 plays the same party every time
A village year
bun scripts/village-dry-run.ts, under a second
Three years
DAYS=36

Same primitives, not a second implementation

resolveTick, where everybody decides and one beat passes, is built on the same two primitives the live loop uses. That is what makes headless play trustworthy: there is no separate test engine to drift out of sync with the real one.

Seeded and on the house brain, a dry-run is deterministic, which is what lets the rules be tested as rules instead of as smoke.

What it makes possible

  • Tuning without paying. Iterate on a rig or a threshold for free, then spend three cents confirming it live.
  • Reading the ledger. The village run prints day by day, so you can change a rate, play a year, and look at deaths-by-cause before trusting it.
  • Adversarial play. BRAIN=chaos is only practical because a year takes a second. See the chaos brain.
  • A regression net. Any rule you would be annoyed to see break has a test, and the test is the simulation being played.

Why a second is the important number

A year that takes a second is something you run mid-thought. A year that takes a minute is something you run before committing, which means most of the tuning happens without it, which means the rate you changed on a hunch stays changed.

Speed of the feedback loop is a design constraint on the simulation itself, not a developer nicety.

Read next

More on the build