Skip to content

Verification

A mechanic is done when it works and moves the right stock in the right direction. Tuning its constants to real-tank numbers comes after the mechanics around it exist, because every new mechanic shifts the chemistry the old ones were tuned against.

Whole-tank behaviour is judged by running the preset tanks headless — nano, low-tech, high-tech, community, sword-gravel, low-flow and cold, and a guppy and a neon pair left to breed, whose head count is the reading — on a keeper’s schedule, sampled at fixed days and always on the last one. Each reading is graded against a plausibility band:

GradeMeaning
GreenInside what a real tank of that kind shows
AmberUnusual but possible — worth a look
RedNot something a real tank does

Per-action flags replay a tank under a different keeper: more food, no water changes, extra fish. A run saved as a baseline can be diffed against a later one, so a change shows as the few readings it moved. Amber and red are questions to reason about, not failures to fix — a constant is never moved during build-out just to turn a cell green.

The test suite pins what holds regardless of tuning:

KindExample
FormulaA function computes what it says
ScalingDoubling capacity doubles flow
ConservationCarbon, nitrogen and every mineral close across rot, the nitrogen chain, every body and the gases
SoundnessNo reading goes NaN or infinite
DeterminismThe same seed runs the same life

A test never pins a whole-tank outcome or a coefficient’s value; those move every time a mechanic lands.

The scenario runner and its bands live under src/cli/scenarios/, the invariant tests under src/simulation/tests/, and the constants under src/simulation/config/.