Light up top, dark below.the stage every rule plays out on.
§2 defines the world the §1 currencies move through — its shape, its light, how nutrients spread, and how time advances. It builds on the locked currency layer and inherits two hard constraints from the §1 pressure-test.
Two things the pressure-test already pinned for the world to honour.
O3 · LIGHT COMPETITION ✓ The asymmetry — autotrophs competing for nitrogen but getting light free — is resolved in §2.3 below: light self-shades, so it's a competed, depletable resource like the nutrients.
CONSERVATION · BOUNDARIES ✓ Total C and N must stay flat — which forces closed (no-flux) or periodic boundaries and a conservative diffusion stencil. Resolved in §2.2 below.
2.1
World substrate
● LOCKED
What space is, and how cells sit in it. Everything in §2.2–2.5 is built on this.
Space is a graph — realised as a lattice
The world's space is a graph — a fixed scaffold of parcels (nodes) at real 2D (x,y), joined by edges. Concretely we realise it as a regular lattice: each edge carries a conductance, each node a medium-type (water / solid / sediment / …) plus its C, N and light.
Uniform start = water everywhere, equal conductances → behaves exactly like a grid.
Structure enters through coefficients, not rewiring. Channels, solids, a sea floor are made by varying per-edge conductance and per-node medium on the fixed lattice — a solid is simply an edge with ~zero conductance. No rewrite; it's exactly how real finite-volume solvers represent obstacles and heterogeneous media; and it keeps the fast solver (§2.4). Structure is physics — where matter can be, what connects to what — never a rewarded niche. (Steering guardrail.)
Arbitrary irregular topology is held in reserve. Genuinely non-lattice wiring isn't needed for anything we've designed (every structure so far is a conductance field on the lattice) and would forfeit the fast solver — so we'd adopt it only if some future structure truly demands it. (External review: mainstream cell frameworks use regular grids, not general graphs — see the review section below.)
Cells float over it — two networks, one space
Cells are off-lattice — floating dots in the same continuous 2D space, each with its own position and size (per §1 reserve/structure). Cells are not nodes; they drift over the space-graph and sample the parcels near them.
So one X/Y space holds two distinct networks: the space-graph (static scaffold — only the values on nodes change) and the cells + their bonds (mobile dots, with a dynamic spring-bond network from §1). Cells aren't a graph; bonds are optional springs between dots.
A static water-scaffold underneath; mobile cells with their own bonds drifting over it.
Uniform now, structured later — same model
Same graph, just edited — a uniform field becomes a world with solids and a sediment floor, no rewrite.
Resolution is precision, not structure
Node density (the grid spacing) sets a length scale and some directional artifacts — a real physical parameter, not a neutral display choice. But it's precision, not ecological structure: a million identical water parcels is just precise emptiness, not a structured world. Every discretisation (graph or grid) has this; the only thing without a length scale is a pure formula, which can't remember edits. So resolution is a tuned constant (§6): set fine enough to sit below biological scales, use an isotropic diffusion stencil, and convergence-test (halve the spacing — if behaviour shifts, it was too coarse).
Implementation note (→§4): the lattice is stored grid-fast throughout — structure lives in per-edge conductances and per-node medium, not in the data layout — which is exactly what lets the implicit diffusion solver (§2.4) run.
2.2
Topology & boundaries
● LOCKED
The world's shape and how its edges behave — pinned as invariants so no implementation improvises.
A cylinder — wrap sideways, walls top & bottom
Finite world (forced: a fixed total of C and N can't live in an unbounded space), a 2D rectangle.
Vertical axis = no-flux walls. Light runs top→bottom, so the vertical is asymmetric — it can't wrap (surface would meet floor, bright meeting dark). A surface on top, a floor on the bottom; nothing crosses either. The photic gradient lives along this axis (§2.3).
Horizontal axis = periodic (wraps). Side-to-side is symmetric, so it wraps: a cell drifting off the right reappears on the left. This deletes the side edges entirely — no edge artifacts, every horizontal position equivalent. A faithful water column.
Two real boundaries kept (surface, floor); the two fake ones (sides) deleted by wrapping.
Boundary invariants — pinned
Past builds saw edges behave differently every time — the signature of edges hand-coded ad hoc. So the rules are fixed here as invariants, derived from one principle (nothing crosses; wrap = same place), not improvised per build:
Horizontal — periodic. Position x and x+W are one place. The wrap is applied to every operation — movement, neighbour search, diffusion, bond distances, rendering — so there is no seam to misbehave.
Vertical — no-flux walls. Zero matter crosses the surface or floor (a mirror boundary for diffusion; cells cannot pass). Surface is the light entry; the floor is where sediment will live if structure is added.
The canary. Total C and N stay flat every tick (§4). Any edge leak shows up instantly — so "edges drifted and I didn't notice" can't happen again.
The world's width and height (and so how much depth the photic gradient spans) are constants → §6; qualitatively, tall enough that light runs from saturating at the surface to darkness at the floor.
2.3
Photic gradient & light
● LOCKED
Light enters at the surface and descends the space graph, dimming as it goes. This resolves O3 — light becomes a competed, depletable resource.
Three things dim the light
As light descends from the surface, attenuation accumulates from three sources (Beer–Lambert — exponential, the physical law; linear would be unphysical):
Water — the baseline decay with depth (water's own coefficient).
Biomass — cells in the path absorb light, so upper cells shade those below (the canopy / self-shading).
Medium on the space graph — solids and sediment are opaque, so the light pass reads each node's medium-type as it goes.
Light descends the space graph from the surface, accumulating all three per node. Uniform start → a simple top-down sweep per column. Once structure exists, light follows the graph and respects opaque nodes — so a region tucked under a solid, or with no open path up, goes dark on its own: emergent shadow pockets / refugia, no special-casing.
Water dims it, cells shade beneath them, solids cast dark pockets — all from one top-down pass.
Day & night
Surface intensity is a periodic function of the tick clock — bright by day, ~dark at night. Nothing downstream changes: only the value at the top of the column rises and falls, then the same descend-the-graph attenuation runs.
It activates the §1 carbon reserve: every autotroph now banks carbon by day and respires it through the dark — real phytoplankton physiology, and a constant selective pressure on storage instead of a reserve that mostly sits idle.
It creates a temporal niche (photosynthesise by day / survive by night) and the pressure behind diel vertical migration — rise toward light, sink at night.
Pure environmental physics, so temporal niches emerge, not coded. Day-length is a §6 constant — and it pins part of §2.5 (it defines what "a day" is in ticks).
The surface brightens and darkens on a daily cycle; depth, biomass and medium still set what reaches each point.
Direction stays vertical. Underwater, almost all light is downwelling regardless of the sun's angle (refraction funnels it toward vertical), so straight-down light is the faithful choice. A moving / angled sun (sweeping shadows) is logged as an optional embellishment for when solid structure exists — not built now.
Light has no memory
Light stays a per-tick derived field: recomputed every tick from the current biomass and the (mostly static) medium — never stored across ticks. So self-shading adds no persistent state; it just lets the recompute read the current biomass. (This is the "computed, not remembered" field from the §2.1 discussion — unlike the nutrient ledger, which persists.)
The store was settled in §2.1 (the graph); this fixes how nutrients spread across it, and hands the numbers to §6.
What diffuses: inorganic C and N. Light doesn't (recomputed top-down each tick); detritus dynamics → §3.
Conservative graph diffusion: along each edge, flux = conductance × concentration difference, and what leaves one node enters its neighbour — so total C/N is conserved by construction (the flat-total canary watches it). No-flux at the surface/floor walls (§2.2); no currents/advection (§1 guardrail).
Isotropic stencil: on the uniform grid, diagonals are weighted in, so a plume spreads as a round blob, not a diamond — no grid-direction artifacts to steer outcomes.
Per-edge conductance ties matter to the medium: solids get ~zero conductance (matter can't diffuse through a wall — mirroring how solids block light), sediment gets low conductance (slow). Both light and matter respect the same graph.
Per-element rates: C and N diffuse at their own rates (cheap, marginally more faithful).
Implicit, operator-split solver: diffusion is solved implicitly, split from the cell exchange step, so it's unconditionally stable — no CFL sub-stepping to babysit. On the regular lattice this is a row/column (LOD / Thomas) solve; the periodic horizontal axis is a cyclic-tridiagonal solve, the walled vertical axis a plain one. (This is what BioFVM-class solvers do — see the review below.)
Cells exchange conservatively (off-lattice ↔ field): a floating cell reads and writes the field through the same spatial kernel, over the node(s) its footprint covers — removing exactly the mass it gains. The seam between mobile cells and the node field can't leak (the standard agent↔field bookkeeping). Node spacing vs max cell size → §6.
Round plumes, not diamonds; and matter diffuses around solids rather than through them.
Handed to §6: per-element diffusion rates, per-medium conductance, and the initial inventory (total C & N and how they're distributed at the start). The implicit solver removes the old sub-stepping/stability worry.
Extended by §3: the diffusing set grows to four matter species — inorganic C/N and dissolved-organic C/N (DOM) — all conservation-checked together, plus three massless signal channels (markers) that diffuse and decay but sit outside the matter canary. Same solver, more fields (a performance note for §4).
2.5
Time & ticks
● LOCKED
How time advances, and in what order things happen inside one step.
The tick
Time is discrete ticks — the atomic step. Every rate in the model is expressed per tick, and a day = N ticks (the constant pinned by 2.3).
Diffusion is solved implicitly each tick (operator-split, unconditionally stable, §2.4) — no sub-stepping needed.
Asynchronous, reshuffled, seeded
Each tick, cells act one at a time, each on the live state — so a draw can never take more than is currently present. Conservation is natural, no rationing needed.
The acting order is reshuffled every tick, which removes systematic first-mover bias (fair on average).
Seeded RNG → every run with the same seed and start replays bit-for-bit. Reproducible every time.
The shuffle uses a separate RNG stream from mutation, so changing biology logic doesn't desync the order — A/B comparisons stay clean.
The trade we accepted: update order is an extra (seeded) source of noise. We chose it over synchronous-with-arbitration because it's simpler, conserves for free, and stays fully reproducible — the arbitration logic sync needs wasn't worth its cost here.
Order within a tick
The types of process run in a fixed, conservation-safe sequence, identical every tick — only the per-cell order inside the "act" stage is shuffled. The exact loop is §4's job; 2.5 pins that it's fixed and ends on the canary.
A fixed per-tick sequence ending on the canary; only the order cells act in is shuffled.
Edge cases pinned
Newborns wait a tick: a cell created this tick doesn't act until the next, and a cell that dies mid-tick is pulled from the remaining order — so there are no order-dependent within-tick cascades.
The canary has teeth: it checks C/N totals against a tolerance (floating-point sums drift), with a no-negative-concentration guard on uptake and diffusion, and it monitors — never silently renormalises. Drift past tolerance is a bug to surface, not to paper over.
§2
Pressure-test & external review
● reviewed
Checked against the established coupled agent–field models, then the seams hardened.
Checked against real models
The architecture is the standard one. PhysiCell (off-lattice cell agents) coupled to BioFVM (a finite-volume reaction–diffusion field) is essentially what we designed — floating cells over a node field, each cell secreting/uptaking substrates and tracking the material it adds and removes. Off-lattice was their deliberate choice too, to avoid lattice artifacts.
The field is a regular grid, not a general graph. These frameworks use Cartesian voxel meshes. Our "graph" earns its keep only as a regular lattice + per-edge conductance + per-node medium — which is the finite-volume standard for obstacles and heterogeneous media. Arbitrary irregular topology is unused there and unneeded here, so it's held in reserve (§2.1).
Self-shading is textbook. Ocean and photobioreactor models build the attenuation coefficient as a sum of each constituent's concentration × its specific coefficient — exactly our water + biomass + medium. §2.3 is faithful.
The one upgrade — implicit diffusion. BioFVM solves diffusion by operator splitting + implicit (LOD/Thomas) steps for absolute stability; explicit schemes carry strict step limits. Adopted in §2.4/§2.5 (cyclic-tridiagonal on the periodic axis).
The rejected alternative — a cell as many lattice squares — is Cellular Potts (CompuCell3D/Morpheus), which doesn't scale to large cell counts. Good that we passed.
Fixes folded in
G1 — conservative cell↔field exchange: same kernel both ways; remove exactly the mass you gain. §2.4
G2 — footprint vs node spacing: act and shade over the nodes a cell covers; spacing ↔ max size → §6. §2.4
G4 — newborns wait a tick; the dead leave the order: no within-tick cascades. §2.5
G5 — canary with teeth: tolerance, no-negative guard, monitor not renormalise. §2.5
Logged & caveats
G6 · light on an irregular graph "Descends the graph" is unambiguous on the uniform lattice (top-down per column) but under-defined once structure makes propagation irregular. Fine now; needs a defined downward-propagation rule when structure arrives.
Calibration couplings (→§6): day-length vs reserve capacity vs maintenance must balance so autotrophs survive the night (the intended pressure, but miscalibration = nightly die-off); node spacing must sit below biological scales (convergence-test).
Reproducibility scope: "bit-for-bit" holds within a build / device; across platforms, floating-point and Math differences can diverge.
§2
All locked
2.1World substrategraph space + floating cells — settled aboveLOCKED
2.5Time & ticksdiscrete ticks (day = N ticks); async reshuffled+seeded updates; fixed order, ends on canaryLOCKED
Decision log
Space = a lattice with conductances (the "graph", realised)
nodes are parcels at real (x,y) holding nutrients, light and a medium-type; edges carry conductance. Uniform = a grid. Structure (channels, solids, sediment) enters by varying per-edge conductance and per-node medium on the fixed lattice — the finite-volume standard — never as a rewarded niche. Arbitrary irregular topology is held in reserve (unneeded so far, and it would forfeit the fast solver).
Cells are off-lattice; two networks, one space
cells float in continuous 2D with their own size (needed for §1 size + colony morphology); the space-graph is a static scaffold whose values change, while cells + spring-bonds form a separate mobile network. Cells are not nodes.
Resolution = precision, a tuned constant
node density sets a length scale and artifacts but isn't ecological structure; handled by an isotropic stencil + convergence testing (§6), not by changing representation.
Cylinder topology, edge invariants pinned
finite world; vertical no-flux walls (surface/floor — the photic axis, can't wrap); horizontal periodic (deletes the side edges). Edge behaviour is fixed as invariants — wrap applied everywhere, nothing crosses walls, flat-total canary — to end the "edges drift differently every build" problem.
Light self-shades (resolves O3)
light descends the space graph from the surface, dimmed by water + biomass + medium-type; recomputed each tick (no memory). Makes light a competed resource like nutrients, switches on vertical ecology, and yields emergent dark pockets behind structure for free.
Day/night cycle; light stays vertical
surface intensity is periodic over the tick clock (bright day, dark night) — activates the §1 reserve daily (store by day, burn by night), drives diel vertical migration, and pins day-length as a §2.5/§6 constant. Light stays straight-down (downwelling is faithful underwater); a moving/angled sun is logged for later, with structure.
inorganic C and N spread by edge-flux (conductance × difference) that conserves totals by construction; an isotropic stencil avoids diamond artifacts; per-edge conductance makes solids block matter (like light) and sediment slow it. Per-element rates; rates/conductance/initial inventory → §6.
Async, reshuffled, seeded updates
discrete ticks (day = N ticks); cells act one at a time on live state in a per-tick reshuffled order — conserves naturally, fair on average, fully reproducible under a seeded RNG, with a separate shuffle stream so logic changes stay diagnosable. Fixed per-tick process order ending on the conservation canary; exact loop → §4.
Pressure-tested & reviewed against real models
matches the PhysiCell + BioFVM architecture (off-lattice agents over a finite-volume field; conservative agent↔field exchange); self-shading matches ocean/PBR practice. Folded in five seam fixes (G1 conservative coupling, G2 footprint, G3 implicit operator-split solver, G4 newborn/death ordering, G5 canary tolerance + no-negative + monitor). Logged G6 (light on irregular graphs, with structure) and the cross-platform reproducibility caveat.