# Hoard
The gold pile, the nest scrape beside it, and the clutch in the scrape.
The pile is a **thermal battery**: `Sim.hoardStep` integrates its temperature
against the air (sheltered when `Game.inCave` says so), the sun, and any
dragon lying on it. A cold pile steals body heat; a charged one pays it back
and its thermal mass rides out the night. Its rendered size comes from
`dragon.fauna`'s `hoard(mass)`, whose hemisphere radius is the same one
`Sim.hoardSurfaceArea` integrates — the geometry you see IS the geometry the
physics reads.
The clutch: `Sim.nestStep` + `Sim.incubationRate`. A dragon standing within
~6 m of the scrape broods it (its core temperature drives the brood patch);
an unguarded clutch drifts toward the pile/air and progress decays.
Incubation progress is clamped to [0, 1]; at 1.0 the clutch fledges —
`Game.milestones.clutch` is set and the roster lays a fresh clutch after a
quiet interval. Raptors and wolves remove eggs through `stealEgg()`.
Publishes the flight-controller contract `Game.nearestHoard(x, z)`
(contact-gated: returns the pile only when (x, z) is actually on it) and
`Game.hoards` for the egg thieves.
Multiplayer/persistence: the lowest peer id integrates; state mirrors through
`runtime_data.world` under `dragon/hoard/main`, so every peer converges on
one ledger and the hoard survives restarts.
# DragonHUD
Every screen the game has, in one component: the flight HUD, the menus, and
the Codex. Put it on a scene entity — one instance owns all of them.
## What it draws
The component reads `dragon.game` and renders whichever screen `Game.screen`
names. It simulates nothing and caches no dragon: each frame the active screen
is rebuilt from whatever the singleton currently holds, so the HUD cannot drift
from the animal.
| `Game.screen` | Screen |
|---|---|
| `playing` | the flight HUD |
| `main` | title, New Lineage / Continue / Settings / Codex / Gallery, controls |
| `lineage` | name the lineage, and what generation 1 starts as |
| `settings` | volumes, subtitles, flight assist, colourblind mode |
| `codex` | one entry per system: the real equation and your dragon's live value |
| `gallery` | the roster — where it lives, what it does, what beats it |
| `pause` | resume / settings / codex / gallery / main menu, plus the controls |
| `death` | cause, what the generation built, respawn as your own hatchling |
Each screen is registered separately and only the one `Game.screen` names is
visible. The HUD rebuilds every frame because it is live data; a menu rebuilds
only when something on it changed.
## The Codex
Thirteen entries: Kleiber's BMR, lift, wing loading, stall speed, the
Pennycuick power curve, the square-cube law, insulation and vasomotor tone,
evaporative cooling, the methanogen bioreactor, catalytic ignition, jet-flame
length, the hoard as a heat sink, and the clock.
Every constant printed there is read out of `dragon.sim` at build time and
every live value is computed with the function the simulation itself calls, so
the Codex cannot say one thing while the animal does another. Entry 13 states
what is real (the equations) and what is not (the clock: metabolic and thermal
processes run at `Sim.TIME_SCALE` real time so a session is playable).
## Accessibility
No instrument depends on hue alone. Every bar prints its number and a status
word, every band is bracketed and named, and the reserve pulses as well as
reddens. `Game.settings.colorblind` picks which colour axis carries the
redundant channel — `off`, `deuteranopia` / `protanopia` (good→bad runs
blue→orange), `tritanopia` (green→red). `Game.settings.flightAssist` and
`subtitles` are on the same screen and labelled.
Everything is sized against `ui.screenSize()` scaled by
`Game.settings.uiScale`, so the layout holds at any canvas size.
## Public fields
- `hudLayer` (number, default 40) — draw order against other UI in the scene.
## Callbacks
Every `onClick` id is handled in the component's top-level `onCallback`. Ids are
namespaced `drg:` — `drg:nav:<screen>`, `drg:begin`, `drg:continue`,
`drg:respawn`, `drg:back`, `drg:name:edit`, `drg:vol:<bus>`, `drg:set:<flag>`,
`drg:cb:<mode>`, `drg:grow:<channel>`, `drg:codex:<n>`.
`drg:grow:<channel>` spends 25% of `growthPoints` through
`State.spendGrowth(Game.dragon, channel, amount)`.
# DragonFlight
A component script.
# Fauna
Herd, raptors and wolves — one component, role picked by `kind`.
- `kind = "manager"` — one instance on a scene entity. Keeps ~8 aurochs, 2
raptors and 2 wolves alive, spawn-guarded to the lowest peer id so N peers
never spawn N herds. Replacements spawn one per tick so simultaneous
managers converge.
- `kind = "aurochs"` — grazes around a herd anchor at true scale (~700 kg,
420 kg usable meat via a sibling `Prey` component). A dragon within ~40 m
and overhead reads as a stoop: the WHOLE herd bolts together (the panic
record lives on the `dragon.game` singleton — component module locals are
per-instance, so shared state crosses instances through the require-cached
module). A grounded, slow dragon
inside 6 m gets **gored**: the gore check runs on every peer against that
peer's own dragon, costing kcal and stamina through `Game.say`. When the
sibling `Prey` flips `isCarrion`, the body swaps to the carcass mesh and
rots away over ~2 game days.
- `kind = "raptor"` / `"wolf"` — egg thieves denned near the nest caves.
They watch the nest (`Game.hoards`) and commit only after it has been
unguarded — no dragon within 30 m — for a sustained window, then take an
egg via the Hoard's `stealEgg()` method.
Animal entities are synced (`setSynced(true)`); AI runs only on the owning
peer (`entity.isLocal()`), other peers render the replicated transforms.
Meshes come from `dragon.fauna` (`aurochs` / `wolf` / `raptor` / `carcass`).
# DragonHide
Matte grey-green scaled hide: the player dragon's body, applied to the procedural mesh DragonFlight rebuilds from live morphology.
## Look
A desaturated grey-green, rough (0.72) and fully dielectric -- reptilian hide that reads as living tissue.
## Shader
Built on the engine's standard PBR surface shader, driven entirely by the constants in `mat.yaml` -- no textures, so it streams for free and scales to any mesh.
## Where it is used
Matte grey-green scaled hide: the player dragon's body, applied to the procedural mesh DragonFlight rebuilds from live morphology.
# Territory
Scent marks on the ground and the display rule between rival dragons.
**Marking.** While its dragon is grounded, each peer periodically rakes a
scent mark at the dragon's position. A claim — center, radius, score, up to
8 marks — persists in `runtime_data.world` under `dragon/territory/<ownerId>`,
so territory survives restarts and every peer renders every claim (dark
stain + tinted scent wisp per mark, owner-colored). Marks decay after
~10 minutes; each peer prunes only its own claim.
**Rival resolution — the core MMO rule.** When two dragons come within
~35 m, dominance resolves by DISPLAY, not combat. The local peer computes its
own `Sim.displayScore(mass, traits, sacMoles, bodyK)` and reads the rival's
visible fitness from its replicated DragonFlight fields (`dispDisplayScore`
when it has roared, else an honest estimate from `dispMass` / `dispWingArea`
/ `dispArmor`):
- Higher score **wins without a blow** — the loser's marks near the encounter
are overwritten and its claim shrinks; the winner's claim grows.
- Scores within ~5% **escalate to combat**: kcal-expensive, staminal, and it
spikes core heat — both sides pay, each applied by its own peer so every
wound lands exactly once.
Everything is surfaced through `Game.say` so the player reads the politics as
it happens.
# DragonWorld
The world driver. One instance on a scene entity builds the deterministic
landscape every peer sees — a rolling grassland plain, a ~120 m escarpment
with a plateau (adults cannot flap-launch; the cliff is how they get airborne),
and three cave grottos carved into the cliff base (cold refuge + nest sites) —
and publishes the world contract on the `dragon.game` singleton:
- `Game.groundHeight(x, z)` — interpolates the same height grid the terrain
mesh is triangulated from, with the same triangle split, so the sampler and
the rendered surface agree exactly.
- `Game.inCave(x, y, z)` — the grottos' sheltered volumes.
- `Game.caves` — grotto centers/floors for nest and fauna placement.
- `Game.thermals` — sun-driven updraft columns, visible only by their dust
motes and circling birds.
- `Game.storms` — drifting storm fronts with visible cloud mass and rain
curtains; drifted by `Game.advanceWeather`.
It also drives the scene's ProceduralSky `timeOfDay` and the sun/ambient light
intensity from `Game.hourOfDay()`, ticks `Game.clock` on the compressed
`Sim.TIME_SCALE` whenever the flight controller isn't (any screen but
"playing"), and persists the world clock in `runtime_data.world` under
`dragon/clock/t`.
All spawned dressing is `temporary` under one `drg_worldroot` entity — nothing
it builds is saved into the scene.