d39c0b9358
3 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
4ee6ae49a1 |
[lane B+E+F] Arena mode: in a room, you own the forward axis
The 6DOF unlock the player header has promised since round 1 ("Arena/6DOF mode is round 2;
modeAt() is guarded below"). It unblocks L1 and L3, which are both arena levels in the GDD and
have been skeletons waiting on this.
The insight that made it small: spline space ALREADY spans a room — s is the axial coordinate,
x/y are the cross-section — and world.collide() already resolves against arena spheres
(arenaSpatial, Lane A round 2). So this is not a new controller. The only real difference
between a tube and a room is WHO OWNS s: in a tube the flow carries you and you may only trim
it +/-40%; in a room `intent.throttle` becomes signed thrust with its own damping, so you can
stop dead and you can reverse. That is the whole feature, and it is what "slower, spatial,
exploratory" actually means in play.
- tuning.js: arena{thrust 44, maxSpeed 11, damping 2.2}. maxSpeed sits UNDER the esophagus's
12-20 flow on purpose — the GDD asks for slower.
- player.js: st.vs (axial velocity), the mode branch, surf disabled in rooms (no travelling
wave to ride, and a hanging surfBlend would speed-lock you to a crest that isn't there),
respawn() clears vs so a death in a room can't leak momentum into a tube.
- player:state gains `mode`; `flow` reads 0 in a room and `speed` goes signed.
- hud.js prints "6dof · free" instead of "flow 0 · thr 100%" — two lies on one instrument.
Safe by construction: both arena triggers are opt-in (level.arenas, or a segment marked
mode:"open"). L1/L2/L4 declare neither and are byte-for-byte unaffected.
Verified in L3's stomach: tube hands-off carries you at 4.53 u/s, acid-sea hands-off coasts to
a dead stop (0.0), and a room lets you travel BACKWARDS (-3.8u). Bus reports
{mode:arena,flow:0,speed:0} vs {mode:tube,flow:3,speed:3}.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
||
|
|
4bcb942312 |
[lane E] The biome meter: the reputation you're building, made visible
A teal BIOME STANDING bar joins coat/hull in the HUD (matches the thin-cyan line-work; scale- only per the 60fps law). Hidden until the first `standing` event, so a flora-less level never shows a bar you can't fill. Brightens near full to telegraph an incoming phage ally. combat/index.js: rescaled standing to a clean 0..100 (tend +5, harm -35) — a FULL bar buds an ally and drops to a 50 recharge floor, so the meter reads as "charge it to summon help." First- pass numbers; tune to taste. Verified in-engine: tending flora reveals the bar and fills it proportionally (0.20 -> 0.45), teal, below coat/hull. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
83c30bf344 |
[lane E] The instrument exists: a HUD, and a surgical team who talk to you
#ui had been an empty div since round 0 — E never ran. It has an owner now. HUD (charter #1): coat/hull, heat, torpedo pips, speed/flow/throttle, boost, score, combo, biome + segment name, and a progress rail with C's 10 checkpoints ticked. Bus-only — zero imports from B, exactly as the charter asks. player:state and combat:state arrive every frame and ARE the clock, so the HUD cannot tick while the game isn't running. 60fps law: DOM is built once; the hot path is transform + textContent-on-change only. Bars scale (scaleX), they never resize — a width:% write per bar per frame is a layout pass. Torpedo pips rebuild only when ammoMax changes, not when ammo does. COMMS — on nobody's list. Argued for, then built. The GDD says "Star Fox arcade flow" and there was nobody in the game but the player. Three-hander: voss (attending, terse), park (resident, over-excited), adeyemi (immunology, apologetic — and amber, the colour of the cells attacking you; his fault). Deterministic round-robin per trigger key, no RNG. Priority ladder + per-key cooldowns so the crew shuts up during a firefight. It turned out to be more than flavour: it is the tutorialisation channel the GDD asks for and L1 has no other vehicle for. The hazard lines teach what C's HAZARDS registry note says the hazard IS ("ring gate. it opens on a beat — match the beat, do not ram it"). Keys are the real HAZARDS ids, checked against levels/enemies.js rather than guessed — all three L2 kinds get bespoke lines, zero generic fallbacks. A level's worth of dialogue is now a data edit in LINES. Three defects, all mine, all found by the stepped sim, none visible to the eye: - The progress rail was dead. I read `level.length` — a field that does not exist. The level carries segments, not a total. It now uses the runtime world.length that B already divides into p.progress. - My clock was fiction. Comms counted `+= 0.1` per timer tick and called it seconds; a backgrounded tab throttles setTimeout to ~1s, so lines held ~10x too long. It now reads performance.now(). - Every hazard warning had the LOWEST priority in the game. PRI has a key `warn`, but say() is called with `warn_reflux_surge`, so PRI[key] was undefined and fell through to the default of 1 — the surge screaming "GO. GO." could be talked over by park admiring a specimen. Keys now resolve exact-then-family. The evidence shot IS the fix: same seed, same frame, the warning now sits where the checkpoint line used to be. ### -> Lane B — player:state stops emitting the moment you die player.js:103 early-returns before the emit when !st.alive. So `alive` is unobservable (E can only ever read true — the field is currently decorative), and E cannot use player:state as a clock, because it stops exactly when the death UI needs to run and through boot's whole 2.0s respawn window. Comms works around it with its own wall-clock. The death/respawn feed-drop (charter #4) will not be able to. Ask is in NOTES; not patching your file. ### -> Lane F — two contract items I edited boot.js (~10 lines mirroring your own dynamic-import/try-catch/ console.info fallback) because #ui needed an owner and two modules nothing constructs aren't worth much. Ratify or move it. Second: shot_sink.py cannot photograph Lane E — it POSTs renderer.domElement.toDataURL(), and the HUD is a DOM overlay, so the house evidence tool renders it invisible. This shot is a composite (canvas -> 2D canvas, then #ui via an SVG foreignObject). Offer to lift it into pipeline/ as DBG.shotUI() stands. qa GREEN. Evidence: docs/shots/laneE/round2_hud_aortic.webp (s=1111, seed 7, live hazard warn + x6 chain). Dev server guts-e on 8146. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |