Commit Graph

2 Commits

Author SHA1 Message Date
type-two
9482b8a2bf [lane E+B] The pause card stops fighting the player, and a refused pointer lock stops
faking a crash

Audit item 8, plus two bugs the last commit introduced and one it exposed.

REQUESTPOINTERLOCK RETURNS A PROMISE. Both new call sites wrapped it in try/catch, which catches
nothing — the rejection went to window.onunhandledrejection, which the previous commit had just
taught to paint a full-screen FEED LOST. So a browser declining a lock for any of its ordinary
reasons (document not focused; Chrome's ~1s lockout after the player leaves a lock with Escape)
presented to the player as the game crashing. Caught by clicking: "the root document of this
element is not valid for pointer lock" in 15px type over a game running perfectly well
underneath. All three sites — title dismissal, resume, and input.js's canvas click — now swallow
the rejection. A refused lock costs one click, which is what input.js has always been for.

PAUSE ON BLUR HAD NO CARD AND TWO OWNERS. boot.js emitted ui:pause directly, so the loop halted
while cards.js's own `paused` stayed false: the game stopped with nothing on screen to say why,
and the next P press raised a card that then took a SECOND press to leave. Moved to cards.js,
which owns the pause state — setPaused raises the card and emits. It already refuses while the
title or debrief is up, so alt-tabbing away from a card correctly does nothing. Verified: blur
raises PAUSED, one P resumes, exactly one true and one false on the bus.

THE PAUSE CARD WAS NOT MODAL. #ui is pointer-events:none and it inherits, so a click anywhere
but the RESUME button fell through to the canvas — whose mousedown handler re-requests pointer
lock whenever it is not held. Clicking beside the button captured the pointer, hid the cursor,
and left the player paused with nothing to press RESUME with. The dimmer takes pointer-events
now (our own handlers are capture-phase on window, so they still see every click; only the
canvas stops seeing them). The title keeps no dimmer and stays click-through by design.

Pausing also now releases the lock and resuming takes it back. Pausing with P used to keep the
pointer captured — a RESUME button that could not be pointed at — while Escape looked fine only
because the browser drops the lock for you. Same key, two behaviours, no stated reason.

And losing the lock now drops the queued EDGES, not just held keys: the Space you pressed to
reach the RESUME button was still in the queue when the card went, so the run restarted by
spending a boost you did not ask for.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-26 22:11:29 +10:00
jing
0a038582a7 [lane B] Round 1: flight controller, cannon, enemy framework on the stub
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>
2026-07-16 08:56:32 +10:00