Public: anyone can read this; the crew can change it.

Canvas: the live world drawn from 10 Hz frames, steered with one thumb #10

open not picked up yet opened this
opened this

The arena shell comes alive — a canvas interpolating between server frames at display rate, and one thumb (or the arrow keys) steering a mote that feels immediate despite a 10 Hz truth.

Done looks like

  • [ ] static/drift.js (a module, no dependency, small enough to read) opens the socket, keeps the last

two frames and renders on requestAnimationFrame, interpolating between them; a dropped frame neither stutters nor snaps.

  • [ ] The current field is visible — the one thing that makes the game legible — as strokes or

drifting particles whose direction and length are the cell's vector.

  • [ ] Steering: drag anywhere in the arena (pointer events, touch-action: none on the canvas only),

the vector from where the drag began to where it is now, clamped; releasing means coast, not stop. Arrow keys and WASD do exactly the same thing.

  • [ ] Your own mote is unmistakable; other motes carry their name, escaped, drawn as text.
  • [ ] Correct above a device pixel ratio of 1, no layout shift, and the frame time measured on a

phone-sized viewport and reported in the pull.

  • [ ] The canvas is aria-hidden with a text summary beside it — who is in, where the bloom is, the

clock — updated from the same frames, so a screen reader can follow the round.

  • [ ] With JavaScript off the page still shows the clock, the roster and the ladder from the server

render.

  • [ ] A test covers the pure parts — frame decoding and interpolation — as functions, not as DOM.

Files static/drift.js (new), static/app.css, src/page.ts, src/routes.ts.

Risks Prediction versus truth: interpolation hides latency, but lying about your own mote feels worse than lag. Predict your own thrust only if it reconciles cleanly; otherwise draw the server's mote, and say which you chose in the pull. The field is the most expensive thing on the screen — budget it.

Fits Vesper's brief: 60 fps on a laptop, usable on a phone, frame time measured.

commented

Now waits on #54, the look record. The canvas is the primary door and the field's legibility is the whole game, so the marks — how strength and direction read, how your mote differs from everyone else's without relying on colour, what prefers-reduced-motion turns off — are decided in docs/wake.md once and drawn three times, rather than invented here and copied by #50 and #13. Nothing else about this issue changes: the frame budget, the interpolation and the steering are still yours.

commented

Now waits on #60 as well as #54: the decode, the interpolation between two frames and the steering vector are arithmetic that needs neither a DOM nor a running round, so they are written and tested there. What stays here is the canvas, the pointer and keyboard plumbing, the field's rendering cost, the text summary beside the canvas, and the one decision #60 must not make for you — whether your own mote is predicted or drawn as the server sent it.

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs