Campaign `aetheria-fauna`, target content r4 (r1 was admitted from the r0 draft at `f9705d32`, r2 by Self; r3 and
r4 are admitted by Imagination). Repo `GameCult/Aetheria`, working branch `master`, cut branches
`eureka/aetheria-fauna-<cut>`; the DAG's node primitives land in `GameCult/CultLib` (CultMath). Written by
Imagination (agents imagination-aeth-fauna, imagination-aeth-fauna-r2, imagination-aeth-fauna-r3 and
imagination-aeth-trophic-dag, sessions self-2026-10-13-ag2 and self-2026-10-14-ag); r4 is against `origin/master`
`7633408f` and CultLib `6c902fd4`. Trophic DAG prior art: `docs/research/2026-10-14-trophic-dag-filaments-prior-art.md`
(`TD:<line>`); its probe: `docs/research/2026-10-14-trophic-dag-probe/`. Body facts and probes are in `docs/aetheria-fauna-map.md` (cited below as `B<n>`); prior art is
6.**Deterministic.** A fauna's state is a function of the zone's seed, its world laws, its bodies' orbits, zone
time and sim events on fixed steps (`SimClock`, B9). Nothing about where fauna are is saved. It uses no `UnityEngine.Random`, no wall clock and no frame time. Any dice
Where fauna of a species are is decided by a **trophic DAG**: layers of fields, each a deterministic function of the
layers below it and of world facts, evaluated at a point at zone time when a query, presenter or sensor asks
(`habitat-trophic-dag`). Pointwise fields of slope and flow alone draw bands and blobs (B25); filaments need an
input that is not local, and the DAG takes it from the zone's bodies, which every point can read (map r4).
| Layer | Fields (the first web, from the lore's Open Water; the bestiary stays open) | Reads |
|---|---|---|
| 0 Environment | Slope and the operator's `Deposition(slope)` band, the steep-core mask (`Zone.GetNormal`); the flow (`Zone.Flow`); the zone's bodies: positions from the per-tick orbit cache, gravity radius, kind; energy kernels round them: starlight inside a sun's light radius, heat-light on warm well floors. Later sources join here: gravity-wave rings (whales), mind-light round crews and stations (moths), wormhole mouths (upwelling), wrecks (succession). | World facts only |
| 1 Structure | **The Skein**: strands between neighbouring bodies (a site graph with a soft gate, each edge a Gaussian strand, bent by a Zel'dovich warp of the flow, TD:39 [V]) and a weighted lattice Voronoi web hanging off them (`voronoi-primitive`). **Slack**: the borders of the bodies' weighted Voronoi, where pulls cancel. Which construction is the Skein is the question `skein-filament-construction`. | Layer 0 |
| 2 Producers | Glim: energy times the Skein's feeding. | 0, 1 |
| 3 Grazers | Krill: the Skein times a saturating response to glim (Holling II, TD:55 [S]). Minnows: krill over a hunting ring. | 0-2 |
| 4 Predators and ambushers | Sharks: minnows over a wider ring, on the band. Lanterns and void spiders: slack times krill over a ring. | 0-3 |
1.**Operators.** A sim-visible layer uses only: pointwise arithmetic, remap curves, smoothstep, min, max and smooth
| Krill | Thousands of members at hosted candidates on the well shoulders; each advects along the flow for one cycle, fades and re-seeds | Faint reflection per member; a patch is bright in aggregate | Drifts with the global flow (advected cycles) | Hide in a cloud; later, a dense cloud thins sight lines as a vapour cloud does (`Zone.Obscuration`) |
| Minnow | Schools of hundreds that ride the flow | Faint reflection, a bright school | Flow plus fast milling inside the school | Clutter of small returns; a ship moving through a school is noticed (later: scatter) |
| Shark | One to three members, each about the size of a ship | Reflection and moderate thermal | Crosses the flow; patrols with sprints | A ship-sized return a hunter must think about; the best disguise target for a fighter |
| Whale | One member, many times a ship's size | Strong thermal; heard song (later) | Slow long arcs | A bright anchor; a ship near it is hard to separate (later: shadowing) |
| **Field kind** (existing, extended) | `FieldKindData` catalog record (`ZoneData.cs:122`), by key. A fauna kind is a field kind with a non-zero member sway and zero belt `GenerationWeight`, so a rock belt never draws it (`FieldKinds.Assign`, "Zero never picks it"). | Authored in AetherDb, append-only MessagePack keys. | The catalog. Forbidden: runtime writes. |
| **Fauna field** (one per fauna kind a zone hosts) | The fauna kind's catalog key within the zone: a zone hosts every fauna kind its world laws admit, so the field is derived, not generated. | Derived when the zone is built, from its world laws and the catalog; never saved. Only its members' wear is saved (`ZonePack.ChunkWear`). | `Zone`. Forbidden: `ZoneGenerator` writing fauna into the pack; presenters; entities. |
| **Member** (a chunk of a fauna field) | `ChunkId(field, index)` (`Zone.cs:825`; the type was named `Field` so other field kinds could join, per its own comment); the index is a lattice cell. | Present while its candidate is hosted (placement law) and it is not broken (`Zone.ChunkExists`). Wear and respawn are lazy comparisons against zone time (`Zone.Wear`), as for rocks. Its pose is a pure function of zone time: its seed point advected along the flow for its cycle. | The habitat law decides hosting; the class law alone computes the pose; `Zone.Wear` is the only writer of damage. Forbidden: any stored pose or hosting bit, any per-tick member loop. |
| **Fauna provider** (existing, widened) | `BeltTargets`, one per field (`Zone.cs:175`). | Built with the zone, never saved. | Its region bounds must hold for every member. Sway widens the slack by the kind's amplitude. Forbidden: a second index or a fauna scan. |
| **Fauna detection** (derived) | `(observer, member)`, never stored. | Derived per query: `ChunkInfo` → `PassiveInfo` → `Sensor.Gain`. | `Entity`. Forbidden: any fauna-specific threshold or gain. |
| **Swarm anchor** (later, sharks and whales) | Per field: a law that moves the field's frame across the flow. | Pure function of zone time plus sparse event records (fork `fauna-motion-model`). | `Zone`. Forbidden: per-member stepping. |
| **Disturbance** (later) | `(member, time, push)`, sparse, as `ChunkWear` is. | Written when a hull passes through or a shot lands, then decays lazily against zone time. | `Zone`. It is read only by `Pose`. |
| **Flow field** (new owner) | One law: `FlowField`, evaluated per zone by `Zone.Flow(position)` from the zone's world-law settings (`PlanetSettings.Flow`). | Settings authored in `Settings.asset`; time is zone time. Never stored per position. | `Zone`. Derived: every shader flow uniform (`_FlowScroll` and the rest). Forbidden: `VolumeSampling._flowScroll`, `ZoneEnvironment.Flow`, any frame-time accumulator. |
| **Habitat** (new owner, a law: the trophic DAG) | `Habitat` in `ServerShared`: one composition per species over CultMath nodes, a species' settings record, a candidate's hashed seed point and threshold. | Never stored: evaluated at zone time per candidate when asked. | `Habitat` decides density and hosting; `Zone` supplies world facts (`GetNormal`, `Flow`, body positions from the per-tick orbit cache); CultMath owns every node and its HLSL twin. Forbidden: a generation pass, a saved or cached habitat map, a per-tick sweep, a math twin in Aetheria, a grid operator in a sim-visible layer. |
| **Skein site graph** (derived) | Per zone: the soft gate of each pair of bodies (map r4). | Recomputed per tick from orbit positions; never saved. | `Habitat`, through a CultMath gate function. Forbidden: a hard (0/1) gate; a cached graph across ticks. |
| **Attack** (later, per class) | `(member or swarm, ship, time)`, an event. | Raised by a class law when its trigger holds; applied through the ordinary damage path. | `Zone`. Forbidden: a fauna-only damage rule. |
| **Harvest yield** (later) | Item kinds in the catalog, per fauna kind. | A member broken or netted by harvesting gear yields items through the economy's yield table; the field refills by respawn. | The catalog and the yield table. Forbidden: fauna-only loot code. |
| **Fauna background kind** (aetheria-ew) | Entries of aetheria-ew's `BackgroundKind` for fauna classes (that target's row says "more by ruling"). | Static data. | `GameplaySettings`, per aetheria-ew. Its envelope gains a motion term per class (fork `fauna-disguise-path`). |
## Invariants
-`fauna-sim-owned`: no fauna state is written outside `Zone`, `ZoneGenerator` and the catalog. A test spies the
renderer's inputs, and a grep finds no Unity writer.
-`fauna-pose-pure`: a member's pose at time t does not depend on the steps taken to reach t. Stepping a zone to t
by 1/60 and by 1/7 gives equal poses.
-`fauna-cost-per-swarm`: zone update cost does not grow with member count. This is pinned with the index's
`Examined` counter and by `Zone.Update` touching no member, not by timing.
-`fauna-one-gain`: a fauna member is visible exactly when `ChunkVisible` says so.