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>
203 lines
14 KiB
Markdown
203 lines
14 KiB
Markdown
# 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:08–15: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 / 52–61k 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 ~40–60u 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 #1–3, 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 2600–3000) 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 2600–3000, 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).
|