guts/docs/LANES/ROUND2_INSTRUCTIONS.md
jing 111ade7d12 [lane A] The swept room + the acid sea, built — and it corrected me four times
The shape read in LANE_A_NOTES was written from reading code, so I built it to
find out if it was true. Flyable: web/dev/laneA_world.html?dbg=1&assets=1&lvl=swept
Nothing here is imposed on anyone: every addition is additive and a level that
opts out behaves exactly as today. C can bin the whole proposal and lose nothing.

WHAT THE PROTOTYPE DISPROVED (my own cost estimates, all four):
- "radial resolution must scale with radius" — wrong. 64 segments is a 0.05u
  circle error at r=70. The arena needs it because it fbm-displaces; the tube's
  wave is smooth in theta. No change made.
- "cap geometry at the span ends" — a thinko. The canal is continuous; a room is
  a fat part of it. Only the fundus dome caps, and it stays an icosphere.
- cost — cheaper than feared: 9 draws / 98k tris worst-frame for a radius-70
  cathedral vs 8 / 74k for the L2 corridor. No leak over a full sweep.
- "one schema flag" — held. `segments[].mode: "open"` is the entire ask.

THE TWO REAL COSTS, NEITHER PREDICTED:
1. D's `tile[0]` is a COUNT, not a density — only a texel size if radius never
   changes. Measured 6.1:1 smear at r=70. The wall now derives the count from
   each ring's own arc length (aRadius attr + uThetaSpan); D's authored numbers
   keep their exact meaning at their reference radius, no re-authoring. That fix
   then laid a seam down the canal (a fractional count can't wrap) -> rounded to
   an integer, seam gone. Not a no-op on corridors: L2's hiatus takes 3 repeats
   where it took 4, which is the texel size correctly holding still as the pipe
   narrows. Eyeballed.
2. MY OWN PINCH GUARD WAS WRONG and would have blocked C. The fixture scored
   1.30 and "failed" the >1.5 law; it was never bent. stats() divided the
   tightest turn ANYWHERE by the widest radius ANYWHERE — 996 units apart, a
   bend in the radius-13 pylorus against the radius of the sea. Locally its
   worst point is 6.4. pinchRatio is now min over s of turnRadius(s)/radius(s).
   Provably one-directional (global <= local by construction) so nothing that
   passed can fail; real levels GAINED headroom: L2 3.32->4.16, L3 1.91->6.99,
   L1 2.11->6.06. This mattered — the guard is what backs the round-1 promise
   that C never has to think about curvature.

THE ACID SEA (world/acid.js, `level.acid {from,to,height,biome}`):
Flat emissive #c8ff3a, level and NOT tube-following — that's the mechanic. The
best find of the session: `height` is ONE NUMBER that tunes the level. Measured:
-18 -> 0% of the sea floor is dry shallow, -55 -> 14%, -62 -> 48%. So C's "position
IS the resource" falls out of the radius wobble they already author — the mucus
shallows are just "where the wall rises above the waterline", nothing to place —
and rising acid literally drowns them: free escalation, same scalar their event
pump drives. Also disproved my own claim: the centreline stays level (+/-1u over
700u), so shallows come from radius wobble, NOT the canal's bends. C must author
vertical bends deliberately if they want depth by anatomy.

Stated plainly, not papered over: the waterline is prototype quality (the plane
meets faceted rings and the shoreline steps). Acid does not drain the coat —
depthAt(pos) is the hook and the cost is Lane B's call. Nothing drives height but
DBG until C's events do.

qa GREEN incl. the new provenance gate; spline selfcheck green; L2 corridor
re-eyeballed for regression. Rulings requested from F in NOTES §-> Lane F.

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

15 KiB
Raw Blame History

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. [A, later 2026-07-16: all three done — lane A's round-2 list is closed. Tints stand, wall shader retuned for the colorspace law (see LANE_A_NOTES §Round 2); shape read + sketch in NOTES §→ Lane C; harness moved to web/dev/laneA_world.html per ruling #5. Only round-3 items remain for A.] **[A, later still — went past the list; read LANE_A_NOTES §Round 2 part 3 before resuming: C — the swept room + acid sea are FLYABLE (?lvl=swept), and acid.height turns out to be a one-number dial for how much of the sea is survivable. Your shape decision is now a look-at, not a read. D — all six biomes are textured (A generated oral+colon on MODELBEAST, $0, your pipeline, yours to ratify or bin), and 4 of 6 walls had provenance recording a prompt that never shipped — fixed + gated, please check the call. B — nothing of yours moved; world.acid.depthAt() is a hook awaiting your coat rules. F — four rulings requested (§→ Lane F), incl. qa.sh gate 5b and a pinch-metric change that moves quoted numbers (L2 3.32→4.16, L3 1.91→6.99, same geometry, measured correctly).]
  • 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).