# Deterministic engine internals

This page is derived from the [canonical developer-reference](/learn/developer-reference); its content has one source of truth.

## Engine ownership and deterministic loop

Source: `src/game/world.ts`, `src/game/decisions.ts`, `src/game/runtime.ts`.

`createSimulation({seed, config, initialPopulation?, initialResources?})` clones and validates the rule graph. The default world is a 50×50 torus (2,500 cells), uses an unsigned 32-bit seed, has five byte-range traits per organism, energy capped at 255, and runs at most 180 generations. Initial resources and organisms can be injected for deterministic tests. `ENGINE_VERSION` is currently `lifepot-ca-8`; recorded ca7 runs select the explicit legacy engine.

The simulation's seeded PRNG drives resource initialization, placement, movement and reproduction choices, and mutation. Each generation calculates resource growth/hazards and organism actions from the previous state, then derives new aggregates/history and outcome. Organisms feed on basal resources only when their rule role allows it. Predation requires a directional graph relation (or an allowed cannibalistic self-relation); population counts do not create food-web edges. Reproduction transfers 38% of basal-parent energy (34% for hunter parents) to the child, rather than creating energy. In `lifepot-ca-8`, a selected mutation target chooses its corresponding heritable trait; without a target, selection remains seeded-random. Mutation is bounded, may fail at trait bounds, and may change variant identity; strategy and traits remain finite. Extinction-conditioned policies require a configured species that was actually populated and then disappeared; never-populated slots do not trigger them. New runs use `lifepot-ca-8`. Recorded `lifepot-ca-7` runs retain their original mechanics, mutation selection and activation semantics, including through replay restart and sharing. Applying old proposals under ca8 is a separately labeled counterfactual, not an exact replay.

The engine owns movement, feeding, resource growth, hazards, reproduction, mutation, death, scheduled rule activation, and outcome. These are deliberately toy-model mechanisms, not calibrated biological quantities. Basal feeders and consumers pay positive minimum upkeep after bounded social cost reductions; cooperation/mutualism reduces expenditure, never creates energy. Predation yields a fraction of the captured prey's available energy: efficient_kill 0.80, ordinary hunting 0.69, and pack_hunting 0.61, so strategy effects remain distinct while feeding-event energy equals the credited gain and cannot exceed prey energy. Competition remains non-feeding pressure. `fitness` influences mechanics; it does not specify a guaranteed result. The final `extinct` outcome is zero population; after the generation limit, a surviving world is `thriving` only when prey count is at least 50 and predators remain, otherwise `surviving`.

## Bounded decisions, frozen observations, and ledger

Decision schemas and allowed triggers/strategies live in `src/game/decisions.ts`. `src/game/runtime.ts` advances deterministically until a trigger, freezes and hashes the observation, and binds the accepted decision to that exact observation, generation, trigger and graph version. A decision must cover the declared probability choices, have valid probabilities and select a maximum-probability option. Species directives are checked against configured species. The model cannot send state mutations, arbitrary code, or undeclared enum values.

A trigger cannot occur before generation 12, within 12 generations of the previous accepted decision, or after eight ledger entries. Accepted entries remain ordered. Missing/invalid model output takes the labeled deterministic fallback path; no invalid proposal is treated as an accepted model decision. Cooldown, trigger, observation, generation, and graph-version checks are enforced in the runtime, not trusted from prose.
