guts/docs/LANES/ROUND2_INSTRUCTIONS.md
jing 29cca53675 [lane F] Mid-round-2 recovery: the glue that makes L2 a game
All round-2 lane sessions were cut off 15:08-15:16 before NOTES/commits; the three prior
commits preserve their work verbatim. This commit is the wiring B was cut off inside of,
plus the run-state boot owes per ruling #4:

- combat/index.js: fiction-id -> archetype resolve via C's getEnemy() (the round's declared
  ONE blocker), theta-array + spread fan-out for group spawns, hazards + pickups constructed
  and updated (order: enemies -> weapons -> hazards -> pickups, so a torpedo can neutralize
  a surge the frame it detonates), pickup score/samples onto the combat:state scoreboard,
  combat.reset(fromS) for respawn.
- flight/player.js: kill/shove/refill — the API B's new modules call; kill ignores iframes
  by design (boost-dodging through C's lethal acid wall is not a read). Deleted the
  crestSpeed fallback guard per its own comment — A's law landed.
- boot.js: run state. checkpoint crossed -> remembered; death -> 2s -> respawn at it +
  combat.reset() re-arms hazard timelines (pump deliberately does NOT rewind: no
  double-spawns, collected stays collected); gate -> level:complete {stats, par} for E's
  medal card. Exported step(dt) so the stepped-sim harness drives the REAL loop.
- ROUND2_INSTRUCTIONS: MID-ROUND STATUS box for the resuming lanes; f-progress entry.

Verified (deterministic stepped sim via boot.step, :8140): full L2 run fires all 47 events
with ZERO console warns (was: 11 spawn no-ops), all 5 hazard telegraphs, 2400 proximity
ticks, 14 pickups collected, finish 157s vs par 180 while surfing 94s of it. Death path:
throttle 0.7 into the finale -> killed by acid s=3386 -> respawn at Cardia Approach 2980 ->
surge re-arms -> second attempt escapes -> level:complete {deaths: 1}. Survivable AND
losable. Evidence: docs/shots/laneF/round2_L2_integrated_full_run.png. qa.sh GREEN.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-16 16:39:44 +10:00

203 lines
14 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# GUTS — Round 2 lane instructions (from Fable, integrator)
> ## ⚡ MID-ROUND STATUS (F, 2026-07-16 evening) — read this first if you are resuming
>
> All round-2 sessions were **cut off 15:0815:16** before NOTES or commits. F triaged,
> verified and committed the orphaned work per lane (`f0982e7` A · `4ed3433` B · `2e85ec0` C —
> read your commit message, it is the NOTES you never got to write), then landed the wiring
> B was cut off in the middle of. **The tree is GREEN and L2 now plays start-to-finish:
> every spawn resolves, all three hazards run, pickups collect, checkpoint→death→respawn
> works, gate emits `level:complete {stats, par}`.** Proof: f-progress + laneF shots.
>
> What F landed that touches your lane (F commit, post-`2e85ec0`):
> - **B**: your round-2 #1#5 are DONE in skeleton — resolve + theta-arrays/spread
> (combat/index.js), hazards+pickups wired, `player.kill/shove/refill` added,
> respawn/`level:complete` glue in boot. Your crestSpeed fallback guard is deleted (A
> landed the law). STILL YOURS: re-measure surf economy in-engine (#6), hazard feel +
> your proposed pickup values vs C's economy, arena 6DOF stretch, NOTES.
> - **A**: nothing of yours changed. STILL YOURS: stomach-arena shape read for C (#7),
> biome-tint re-eyeball vs D's textures (#4 second half), NOTES.
> - **C**: pump semantics settled: events fire ONCE per run, respawn does NOT rewind the
> pump, hazards re-arm via `combat.reset(fromS)`. `boot.step(dt)` now exists — your
> fly-through validation (#1) is unblocked and can run deterministically. STILL YOURS:
> fly it, pickup economy → B (B proposed placeholder values in balance.js §pickups),
> L1 design doc (#5), GDD boss folding (#4), NOTES.
> - **D/E**: no round-2 files reached the tree before the cut. Your lists below stand
> unchanged. E: the `level:complete` payload for your medal card is live and verified.
> - Ports: the cut sessions left sinks running — 8143 (→laneF shots) and 8144 (→laneA).
> Reuse them or pick a fresh port.
>
> Everything below is the original round-2 brief and still stands except where this box
> says F already did it.
Date: 2026-07-16 · Written after reviewing all four round-1 lanes (A/B/C/D — E did not run
and joins this round) and integrating their offered wiring. Every round-1 claim I checked
held up: A's hash `cefc4f83` and 8-draw sweep, B's `node --check` ESM no-op (reproduced on a
deliberately broken file), C's 3/3 selfcheck, D's manifest. Superb round, all of you.
## Repo state (F integrated, commit this round)
**The game is a game now.** Default boot = A's world on C's `L2_esophagus` with D's textures,
B's ENDO-1 + camera + combat, level-event pump live. Verified by stepped simulation (60 sim
seconds, deterministic dt): flow carried the player to s=777, checkpoints + pickups fired,
9 draws / 5261k tris, zero console errors, zero asset misses.
Evidence: `docs/shots/laneF/round1_integrated_s777.png`.
F landed since round 1: B/C/D snippets in `boot.js` (assets → world, player/combat wiring,
`?stub=1&lvl=` composing, event pump) · qa.sh **ESM gate fixed** (it had never checked
anything — thank you B) + A's spline selfcheck gate · TECH: world contract **frozen v1.1**,
bus events ratified, asset entry points ratified, colorspace + crest-speed laws · stub:
`crestSpeed()`, CREST factor, colorspace fix. Second dev server config `guts-f` on **8141**
(8140 was held by another session — lanes: if 8140 is busy, use your own port and say so).
## The ONE integration gap found (and it was predicted)
Stepped sim confirmed: **all 11 L2 spawn events no-op with `[combat] unknown enemy type
"bolus_chunk"/"eosinophil_swarm"/"candida_bloom"`.** C's fiction-id → archetype resolve
(LANE_C_NOTES → Lane B #1) is the single blocker between "it boots" and "it's a game with
enemies". B: it is your first task.
## Integrator rulings (settled — argue in NOTES for round 3 if you must)
1. **Surf: CREST_FACTOR = 1.6.** B proved crest speed == flow makes surfing strictly worse
than throttle (LANE_B_NOTES §surf). Ruling: `crestSpeed(s) = 1.6 × flow(s)` (beats
throttleMax 1.4), A implements `k(s) = OMEGA/(1.6·flow)`, B speed-locks to
`world.crestSpeed(s)` while riding, gameplay wave == visual wave stays law. Stub already
complies — B can build now. C re-runs pacing (pars will compress; the finale's escape
math changes deliberately — surfing becomes the stylish escape).
2. **Colorspace law** (TECH §Shader law): every custom shader ends `main()` with
`#include <colorspace_fragment>`. Stub done. A (wall), B (emissive) apply this round —
expect a visible shift; A re-eyeballs biome tints against D's textures after.
3. **Texture naming**: D renames keys to A's biome ids **early in the round** and pings in
NOTES; A deletes the slug map after pulling. That order, one round, done.
4. **`level:event` pump is boot's (F).** Landed. B: when you build respawn, tell F what
reset/replay API the pump needs (`### → Lane F`), don't work around it.
5. **`web/dev/` ratified** as the shared dev-harness dir, per-file lane ownership, never
shipped. D's texview stays. A: `world/dev.html` may move there or die, your call.
D's `pipeline/shot_sink.py` is the **house evidence tool** — all lanes:
`python3 pipeline/shot_sink.py --dir docs/shots/lane<x> --port 8143` (NOT 8140/8141),
then POST the canvas. `DBG.shot()`'s download silently no-ops in the pane (A was right).
6. **WebP shots ratified** (B's 25 KB vs 1.9 MB argument). PNG also fine. Name the round.
7. **C's GDD refinements + boss specs: signed off.** C folds the three boss one-pagers into
GDD.md proper. Per-level pars stand. A/D treat boss specs as stable input.
8. **A's uv simplification** (one uv attr + uTile uniform, no uv2): ratified, contract-level.
**C's arena semantics + A's per-segment `wave` override request: approved** — C specs
`segments[].wave: { amp }` into schema v2, A implements `waveMaxAt` preferring it.
## Round-2 goal
**L2 esophagus, playable start to finish, textured, scored, survivable and losable** — every
spawn live, all three hazards real, checkpoints/death/respawn, gate → `level:complete`,
HUD + audio on top. Tag `v0.2`. (Round-3 preview: arenas — L1 tutorial + L3 acid sea + the
Pyloric Guardian.)
---
## Lane A — contract v1.2 + the look, deepened
1. **`crestSpeed(s)` + CREST_FACTOR 1.6** (ruling #1) — small, unblocks B, do first.
2. **Answer C's biggest dependency** (LANE_C_NOTES → A #4): segment radius **blending**.
C assumes a smooth ~4060u taper at joins (12→9 at s 1100, 10→6.8 at 2600). Confirm or
implement; a hard step reads as a level seam and breaks the constrictions.
3. **Per-segment `wave` override** (ruling #8) — the hiatus should be tight AND calm.
4. Colorspace one-liner in the wall shader (ruling #2), then re-eyeball all six biome tints
with D's textures; adjust `biomes.js` freely (C's selfcheck re-checks live, as designed).
5. **TBN normal maps** — lift D's `perturb()` from `web/dev/laneD_texview.html` (their NOTES
has the exact GLSL and the trap: never add tangent-space normals to vertex normals). Wire
`_b` variants + matcap. This is the round's visual headline; D called it "the single
biggest visual win" and their shots agree.
6. `sample(s, out)` out-param variant (v1.2) — B adopts on landing.
7. Stomach-arena shape read for C (→ C #5): propose capsule/lobed/chained-spheres, one
paragraph + sketch, before C authors the acid sea in round 3. Triplanar arena shells if
time (the pole-pinch fix) — acid plane can wait for round 3 with the L3 work.
Defer: villi band (no L4 level yet).
## Lane B — make L2 a game (priority order is the order)
1. **C's three consumption fixes** (LANE_C_NOTES → B #13, exact snippets provided):
`getEnemy()` resolve, `theta` arrays, `spread`. Verify against the live L2: sim to s=800
and the console warns must be gone, bolus/eosinophil/candida all spawning.
2. **The three L2 hazards** (params in `levels/enemies.js` HAZARDS): `reflux_surge` (rear
chaser; emit `hazard:proximity {kind,distance}` — C's most important UI dependency),
`aortic_squeeze` (**directional** — one-sided by design, keep contact non-lethal or tell
C), `ring_gate` (timeable point gate). Emit `hazard:warn {kind,s,eta}` from each event's
`warn` field.
3. **Checkpoint / death / respawn** (≤30 s law). Define the pump reset API with F (ruling
#4). Respawn never inside a hazard zone (C placed checkpoints accordingly — keep it true).
4. **Pickups**: nutrient, mucin, B12, antacid ammo, biopsy samples (`pickup` events are in
L2 already; economy numbers from C via NOTES if you need more than `levels/enemies.js`).
5. **Gate → `level:complete {stats}`** with score/time/samples for E's medal card.
6. **Surf speed-lock** on `world.crestSpeed(s)` (stub has it now; A lands theirs early).
Re-measure: riding a crest must beat throttle-mashing by a margin worth learning.
7. Colorspace in `emissive.js` (your own finding) — then re-shoot `round1_combat`'s hostile
amber and confirm it reads amber.
8. Stretch only: arena 6DOF controller (round 3 needs it for L1/L3).
Your tuning.js header still cites the stale `wallRho` numbers (C flagged) — fix the comment.
## Lane C — validate with a real canal
1. **Fly L2 on the integrated build** once B's #1 lands (mid-round — watch B's NOTES). Use
F's stepped-sim technique (f-progress documents it) or the browser; replace sim numbers
with observed ones. **The hiatus (s 26003000) is the thing to validate**; your open
question #4 (`MIN_CLEARANCE 2.5`) gets its answer here, alongside John's playtest.
2. **Re-run pacing under CREST 1.6 surf** (ruling #1): pars, the finale escape math, and
whether antacid-stalling is still the smart play. Adjust `par` values with rationale.
3. **Schema v2**: `segments[].wave` override (approved) — spec it, re-author the hiatus calm
(amp ~0.6), selfcheck it.
4. Fold boss specs into GDD.md (signed off, ruling #7).
5. **L1 encounter design on paper** (molar crush-cycles, saliva tides, epiglottis exam) —
full authoring waits for B's arena controller in round 3, but the design doc and the
skeleton→full upgrade plan land now.
6. Give B the pickup economy (counts/values) as data or NOTES — B's #4 consumes it.
## Lane D — heroes and the full pack
1. **Slug rename first** (ruling #3): `wall_small_intestine_a` etc., manifest + batch JSONs,
ping A in NOTES same session.
2. **Hero meshes, the round-2 headline**: ENDO-1 ship, `bolus_chunk`, `eosinophil_swarm`
concepts via flux_local (ART_BIBLE stems + C's tints in `levels/enemies.js`) →
**concepts into `docs/shots/laneD/` + NOTES for F/C sign-off BEFORE any TRELLIS run**
sf3d draft → trellis_mac → normalize (port `normalize.py` + `glb_stat.py` from PROCITY —
the GLB law is unenforced until they exist) → thumbs → manifest. `candida_bloom` as a
decal/sprite sheet (your call, ratified — C agreed).
3. **Colon + mouth walls** (2 each) + acid/decal sprites — completes the biome texture set.
4. **Full audio pack**: E must hand you their key list by mid-round (E's #5); if it hasn't
arrived, propose the keys yourself in NOTES and E adapts. Beds for all six biomes, sfx
(torpedo, gate, alarm, checkpoint, death/respawn, UI ticks), 3 boss stingers, ≤10 MB law.
5. Tapeworm stays a **round-3** fal.ai candidate — do NOT spend on it yet; if concepts are
ready early, put it on `FAL_LIST.md` with the concept attached for John's go.
## Lane E — you have a full house waiting (round-1 charter + these specifics)
Read your charter + the `→ Lane E` sections in B/C/D/A NOTES — all four wrote APIs for you.
1. **HUD** from `player:state` + `combat:state` (emitted every frame, live now): coat/hull,
heat, throttle/speed/flow, boost cd, score/combo. Bus-only, no imports from B.
2. **Gut-map v1** (the signature): `listLevels()`/`getLevel()` in `levels/index.js` give you
names/lengths/pars; L2 has 7 named segments + 10 checkpoints authored for exactly this.
3. **Rear-proximity indicator** for `hazard:proximity` + telegraph pings for `hazard:warn`
C calls this the single most important UI request (the surge chases from behind).
4. Title (over `?fly=1`-style drift) · pause · **medal card** on `level:complete` (par data
in the level) · death/respawn feed-drop. Damage = feed corruption, never red vignette.
5. **Audio engine**: D's pack via `assets.audioUrl/audio` (keys + gain law in LANE_D_NOTES →
Lane E), procedural fallback beeps (`?localassets=0` must make noise), bed crossfade on
`biomeAt`, heartbeat tempo → danger scalar (define it from bus events, document mapping).
**Hand D your round-3 key wishlist by mid-round** (D's #4).
6. Respect `?shots=1`/`?mute=1`; every screen screenshotted into `docs/shots/laneE/`.
## Lane F (me) — done this round: the integration above. On-call for contract questions;
end of round: boot matrix, v0.2 tag, ROUND3.
---
## 🎮 John's playtest checklist (the things no agent can measure)
Open `http://localhost:8140/?dbg=1` (or 8141) in a real browser and just play:
1. **The fps number** in the bottom-left overlay (we can only prove draws/tris; rAF is
paused in our tooling — every lane flagged this honestly).
2. **Feel** — B set `bank.gain`, `cam.discFollow`, `aim.lag` by reasoning, not play. Say
"banking feels heavy/floaty/right" in any form; B will translate.
3. **The hiatus** (s 26003000, once B's hazards land): thrilling or miserable? This decides
C's clearance floor.
4. **Dart readability** when a turret volley passes the camera (B suspects too dominant).
5. **Audio ear-check** of D's pack (spectrograms pass; ears are yours).