The last level. 6 segments, 3200 units, 51 events, and the end of the game: `next: null`.
THE GAS. GDD: "flammable gas pockets: shooting inside one detonates it (hurts everyone —
risk/reward)". Built literally, as an entity whose kill() throws a blast:
- one cannon pellet sets it off (hp 10) — the hazard has to be hair-trigger or "don't shoot
near it" is not a constraint;
- the blast reaches 16 units, FALLS OFF with distance, wipes foes, hurts YOU, and chains
through other pockets, so a corridor of them is a fuse;
- foe:false, so the pocket itself scores nothing — you are paid for what the blast KILLS,
which makes the reward self-balancing.
Measured: one pellet into a line of four detonated all four; a blast took 4 virions and paid
240; the player takes 30.3 coat point-blank, 15.4 at mid range and 0 at 20 units. "Detonate
from max range" — which C's Blockage spec calls optimal play — is a real, measurable skill.
And the cruelty that makes the level: fog 0.075 is the densest in the game and there are no
real-time lights in GUTS, so THE POCKETS ARE THE LIGHTING. Clearing a room safely also clears
the lights. No new rendering path was added for the dark; the biome's fog and the emissives
already did it.
THE BLOCKAGE (LANE_C_NOTES §Boss specs 3) — 5 armoured plates -> 4 tumbling chunks -> the core
under a 30s doom timer, with gas pockets seeded into every phase, so the boss's own room is its
worst weakness. First cut ran 25.7s, shorter than the mid-game Guardian, which is the wrong
shape for a finale — its windows are continuous by spec, so hp went 120/130/150 -> 220/230/280.
Now: 49.7s brute-forcing the plates, 30.2s using the gas. The room is the weapon, and the
difference is 40%.
The reputation loop lands here as designed: two biofilm gates, the second sixty units from the
final boss. Five levels of deciding whether to shoot the cyan resolve into three phage escorts
and a full coat, or nothing at all, in the dark, at the door.
Registering L5 also closes two dangling threads — L4's ileocecal valve and LS_appendix's exit
both pointed at it and now resolve.
C's tooling: 6/6 levels valid, sim par 540 vs par-pace 505 (reachable, with room for the boss),
pressure 1.33/4.09/3.21/5.75/4.12, min clearance 8.30 vs the 2.5 law. par.score corrected
7000 -> 4000 and a missing checkpoint added at 3060 (the 30s law caught a 34.8s gap I had left
between the boss and the gate).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
L1 has been a 2-event skeleton since round 1, waiting (in its own status field) on "Lane B's
arena-mode controller". That exists now, so C's round2_plan is built as written: molar
crush-cycles, the saliva tide, amylase droplets, the three samples exactly where C put them
(behind the molars / under the tongue / a tonsillar crypt), and the epiglottis exam. 24 events.
The teaching order is the level: move (orbs, no current) -> LOOK (the arena opens and you can
stop, which no other level allows) -> shoot (one droplet, then two) -> coat (the molar ring
grazes you, mucin is right there) -> RESTRAINT -> flow returns (the tide, the funnel) -> the
exam. Every verb alone, in the calmest room in the game, before anything is asked of it. Two
hazards are deliberately re-used rather than invented: the molar crush IS a ring_gate and the
saliva tide IS a non-lethal surge, so L2's gates and its reflux finale become callbacks instead
of new ideas.
THE MAST CELL (LANE_C_NOTES §Boss specs 5) sits at the exact midpoint. A sentinel immune cell:
cyan, no attack, no chase, inert aura (auraDps 0 — it shares the floater's drift branch and its
aura does literally nothing). Fly past and the encounter just ends. Shoot it and it degranulates
— droplets close in from the walls (which is how "the cavity swells shut" is expressed, because
a runtime tube radius is not in Lane A's contract), the coat bleeds, and past half health the
airway closes on a 25s timer. You always get through. The only question is what you get through.
It needed a new boss `kind: 'sentinel'` with its own update path, because forcing a thing with
no rings and no windows through the phase machine would have been worse than a branch. Damage is
the failure state, so every number describes a consequence rather than a fight.
Verified, all three player choices: SPARE -> "spared", coat untouched at 100, karma +25, score 0.
SHOOT -> "degranulated", coat 100->56. KILL -> "anaphylaxis-survived", coat 100->6. Score is 0 in
every case: shooting it buys literally nothing, so no medal can ever reward the mistake.
Two bugs the testing paid for: `def.phases[0]` crashed on a boss that has no phases, and the
first degranulation drain (5/s) was UNDER the player's 8/s coat regen — measured coat going
80 -> 100 during a histamine cascade, i.e. the punishment was healing you. Now 14 and 22, which
are net -6/s and -14/s against regen.
L1 is no longer a skeleton: its checkpoint-gap and zero-samples warnings are gone, and the
campaign now opens on a real tutorial instead of an empty mouth with a gate at the end.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
GUTS has had three bosses designed and none implemented. This is the first, and the framework
the other two should reuse. Built to LANE_C_NOTES §Boss specs, phase table and all.
WHY IT IS SMALL. A boss here is not a parallel entity system, it is a SCHEDULE over the enemy
pool. The nodes and vents are ordinary enemies, so weapons hit them, the InstancedMesh draws
them and enemy:die reports them for free; the fight's identity lives entirely in WHEN they can
be hurt, which is two flags (`invuln`, `armor`) honoured by enemies.hurt(). boss.js is a state
machine and nothing else.
Faithful to C's table:
P1 4 rim nodes, iris opens 2.5s every 8s
P2 4 nodes, opens 1.8s every 5s, TWO armoured — and only the antacid torpedo strips them
P3 the core alone, 60hp = C's "x5 hits", plus the 25s doom timer that kills you if you stall
Telegraphs are C's too: a "deep gulp" 2s before each window (boss:telegraph + audio), and nodes
go amber -> white-hot exactly when they become shootable — one uniform driven off `invuln`, so
the thing that glows IS the thing you can hurt, always.
Vents are turrets at fixed arcs: a turret already fires a telegraphed homing projectile on a
cooldown, which is what an acid vent is.
hp is B's call (C: "numbers need B's framework to tune against"). 150 per rim node means a ring
outlives its first window, so you must come back for it — which is what lets the stomach's
coat-drain be the real clock. C's pillar, verified: parked in the lair for 20s without fighting
back, coat goes 100 -> 0. "A race against your coat, not its hp."
Verified end-to-end: a paced pilot (11 shots/s, ~70% uptime) wins in 38.8s across 9 windows at
0.38 open-duty (spec: 31-36%); phases report 4/0 armoured, 4/2 armoured, 1 core; damage is
refused while the iris is shut; the two armoured nodes consumed exactly 2 torpedo strips.
Not included: C's arena churn (a force on the player, the one part of the spec that is a feel
change rather than a schedule) — noted for the round that tunes it.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Roster round-2, batch 2 — three new archetypes, mostly reusing existing behaviour branches:
- virion (norovirus): a tiny fast swarmer, its own pool of 40 so a cloud reads as a swarm.
Shares the seeker branch (chase + dissolve on contact). The arithmetic threat. -> L5.
- driller (H. pylori): a TANKY corkscrewer (hp 50). Seeker chase + a rotating perpendicular
drift (the helix), and it does NOT dissolve on contact — it grinds you and keeps drilling,
so you must out-damage it. A new behaviour branch. -> L3 stomach; previewed in L2 at s2240.
- beacon (Faecalibacterium): the reward-state commensal. Shares the commensal branch, heals
AND gives the biggest standing (25) with no coat cost. A bright cyan octahedral gem, the
special one of the family. -> L5; previewed in the L2 breather at s1580.
Verified in-engine: driller corkscrews + survives contact; virion is tiny + dissolves; beacon
heals coat and spikes standing to 50% in two tends. Three clean distinct silhouettes (gem /
cone / dot-swarm).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The first foe with an ATTACH state machine, and the first that gives boost a defensive job.
Giardia chases like a seeker, CLAMPS its ventral suction disc onto your hull, and drains coat
while it rides — until a boost's i-frames throw it (or it lets go after attachMax, then can't
re-grab for reattachCd). The counterplay is timing a boost, not out-running it.
- enemies.js: `latcher` archetype — a two-state (chase / attached) branch. Attached, it rides
player.pos + a spin offset and drains `drain`/tick; ps.iframeT > 0 (boost) detaches and flings
it clear. Amber tetrahedron (the trophozoite), so a clinging one reads on the hull.
- levels/enemies.js: ARCHETYPES += latcher; catalogue `giardia_latch` (biome small_intestine).
- L2: one Giardia previewed on the open thoracic run (s1940) — it belongs to L4's villi maze,
but the grab works in a flow tube, so it teaches the boost-dodge verb now.
Verified: it chased + clamped, drained coat 100->84 while attached, and a simulated boost
(iframeT) shook it off.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
A foe whose corpse keeps hurting — the definitive colon enemy. C. diff drifts with a corrosive
aura like any floater, but on death it leaves a SPORE_CLOUD: a static acid-green zone that
damages anything in it for ~5s, then disperses. Killing it costs you the ground it died on
(shoot the cloud to clear it, or fly around).
- enemies.js: two archetypes. `cdiff` (amber octahedron, shares the floater drift+aura branch)
drops a `spore_cloud` in kill(), placed at the death spot. `spore_cloud` (acid-green per the
readability law, foe:false so the phage ignores it and clearing it never scores) is static,
damages on contact, and counts down a `life`. Entities gained a `life` field (only the cloud
uses it).
- levels/enemies.js: ARCHETYPES += cdiff; catalogue `cdiff_bloom` (biome large_intestine —
registered for L5's encounter pass, not shoehorned into the esophagus).
Verified: killing a cdiff dropped a cloud at its death spot; sitting in it dropped coat 100->89;
the cloud expired after its life. Amber octahedron vs acid-green blob — clean read.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The cleverest node in the reputation loop — a commensal that eats your mucus. Brushing it
COSTS coat but fills BIOME STANDING fast (gain 12 vs flora's 5): the "spend coat for a quicker
phage ally" trade against flora's safe heal-and-slow.
- enemies.js: flora's branch generalised to a shared COMMENSAL branch, sign-flipped by data
(cfg.coat gifts, cfg.coatCost nibbles); flora:tended now carries `gain`. New `mucus_grazer`
archetype — cyan (still flora, readability law), but a dodecahedron amoeba-blob so the coat
cost reads as a different bug, not a betrayal by the healing rod.
- combat/index.js: standing gain comes from the event's `gain`.
- levels: ARCHETYPES += mucus_grazer; catalogue `akkermansia`; L2 teaches it at s210, right
after the flora reef so the same-colour / opposite-trade contrast lands.
Verified: brushing it dropped coat 100->88 while standing hit 36% in 3 tends (4x flora's rate);
distinct blob vs the flora capsule.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The first ALLY, and the reputation loop that earns it — "don't shoot the biome, it helps you"
(V2_IDEAS) made mechanical.
- combat/enemies.js + balance.js: the `phage` archetype. A friendly seeker that hunts the
nearest FOE (not the player) and rams it — a bacteriophage bursts its host after `bursts`
hits. Fast (26 > every foe) so it catches things, fragile (hp 8) so it is spent, not a wall.
Entities now carry a `foe` flag (foes true; flora + phage false); kill() generalised so ANY
ally scores nothing and never combos. Fallback silhouette is a bare icosahedron = the phage's
real icosahedral capsid. Teal (EMISSIVE.ally), distinct from cyan "don't shoot" flora.
- combat/index.js: BIOME STANDING — one run-scoped float. flora:tended raises it, flora:harmed
drops it 25; at the symbiotic threshold the biome BUDS a phage near you (capped 3, 3s cooldown),
spending standing. Emits `standing {value}` for a future Lane E meter.
- levels/enemies.js: ARCHETYPES += phage; catalogue `phage`.
Verified deterministically in-engine: tending flora budded a phage, which hunted a spore_pod foe
(30hp) and rammed it dead; three-colour readability holds (amber foe / teal ally / cyan friend).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The round-2 microbe pass, vertical slice. Cross-lane (integrator call): the point was one
thread proven end to end — art pipeline in, friend and foe out.
- core/assets.js (D): the GLB loader, finally wired. GLTFLoader was vendored but never
imported and the manifest had 0 models, so enemies.js's `glb?.geometry` hook was dead code.
Now every manifest model preloads (AWAITED — pools set geometry at construction, a late load
can't retrofit an InstancedMesh) into ONE BufferGeometry normalized to a unit bounding
sphere; get('models',n).geometry lights up the hook. Optional-asset law intact: any failure
-> no geometry -> procedural fallback.
- combat/enemies.js + balance.js (B): two new archetypes.
flora — the FIRST FRIEND. Cyan (ART_BIBLE: flora reads friendly). Drifts like a
floater but its aura HEALS (sheds coat), never harms. Shootable — and shooting
it is the reputation trap: kill() gives no score, no combo, emits flora:harmed.
Verified: the aura fires player.refill({coat}); a shot flora scores 0.
spore_pod — a foe yeast cluster: the floater's drift+aura, but its OWN pool so its blobby
GLB will not reskin the food-debris floater.
Pool geometry now scales a GLB by the archetype radius (GLBs ship unit-normalized).
- levels/enemies.js (C): ARCHETYPES += flora, spore_pod; catalogue entries lacto_drifter
(Lactobacillus) + yeast_pod (Candida). L2 gets a light teach beat in the calm opening — a
friendly reef at s180, one yeast at s300, both off the racing line.
Ships playable as glowing primitives (a capsule + an icosahedron), exactly like the rest of
the round-1 roster; the Trellis/Hunyuan meshes drop in via the manifest with no code change.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Landed before the cut: surf as a speed-lock onto world.crestSpeed(s) with surf.authority
(ruling #1) — riding beats throttle and holding a crest is throttle discipline; tuning.js
header corrected to the real wallRho frame (C's flag); enemies.js reads rho as a FRACTION
of safe radius (C's placement law); balance.js hazard + pickup constants; NEW hazards.js
(reflux_surge / aortic_squeeze / ring_gate, self-scheduling telegraphs, reset(fromS) built
for respawn) and NEW pickups.js (all five kinds, shape-coded).
Cut off before: wiring — nothing imports hazards/pickups yet; the fiction-id -> archetype
resolve (round-2 task #1) does NOT exist despite the enemies.js comment saying index.js
does it; player.kill/shove/refill are called but were never added; checkpoint/respawn and
gate -> level:complete not started; NOTES unwritten. F lands the glue next commit.
Committed by F to protect the shared tree.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Flight (js/flight/): tube-mode controller in spline space (s,x,y) — flow-locked
forward motion, throttle as a spring-back lean, boost + i-frames, banking chase
cam on the parallel-transport frame, arcade wall response (shove + graze damage,
never a hard stop). Twin-stick input: WASD/left-stick moves the ship in the disc,
mouse/right-stick aims, Shift/Ctrl is throttle. Gamepad supported.
Combat (js/combat/): lysozyme cannon (pooled, instanced, heat-limited with
hysteresis lockout) + antacid torpedo emitting level:neutralize. Enemy framework
with floater/seeker/turret and turn-rate-limited homing darts, spawned from C's
level:event. Coat/hull model and the full bus surface E builds against.
Measured (deterministic stepper): flow-lock exact (3s at flow 14 -> s=44.0);
boost peak 30.8 u/s; heat 4s fire -> 2s lockout; wall slam 13.3 coat at 11.3 u/s
with forward speed untouched; 10 combat draws at 55 live enemies (budget <=80);
0.10 ms/frame CPU; 0 leaks over 20 create/dispose cycles. fps NOT claimed — rAF
does not run in the automated pane. Evidence: docs/shots/laneB/.
Three findings escalated in LANE_B_NOTES:
- qa.sh gate #1 is a no-op: node --check silently exits 0 on ESM, so the syntax
gate has never checked anything. I shipped a real SyntaxError past a GREEN qa.
Fix + verification handed to F.
- Surf is structurally broken: the peristalsis wave (13.64 u/s) is slower than
the player (19.6 u/s), so level 2's signature mechanic loses to mashing
throttle. Not tunable from this lane; escalated to A/F with options.
- Custom ShaderMaterials need #include <colorspace_fragment>, else ART_BIBLE's
hostile amber reaches the display as rgb(255,26,6). Fixed here; stub/walls
inherit it.
js/flight/dev.html is a dev harness (boot.js has no player wiring yet); it
retires once F pastes the snippet in LANE_B_NOTES.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>