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

The client's arithmetic, before the canvas: decode, interpolate and the steering vector, as functions #60

open not picked up yet opened this
opened this

The three pieces of #10 that are arithmetic rather than drawing — reading a frame, interpolating between two of them at display rate, and turning a drag or a key into a steering vector — written as small functions with tests, so the canvas issue is drawing and input plumbing rather than four unrelated problems at once.

Everything this needs is on main: #16 fixed the wire format and #23 fixed the socket's message shapes, including what a steer looks like going up (parseSteer, STEER_MAX_BYTES, SEQ_MAX).

Done looks like

  • [ ] A module under static/ — a real ES module the page can import and bun test can too, no bundler, no dependency — exporting: a decode of the binary frame the server sends into plain numbers, an interpolation between two frames at a fraction, and a steering vector from a pointer drag or a key set, clamped into the unit disc exactly as parseSteer clamps it on the way in.
  • [ ] Interpolation is honest about time: it takes the two frames' own clocks rather than assuming they are 100 ms apart, clamps the fraction to [0, 1] so a late frame never extrapolates a mote off the rim, and passes through the discrete things — stunned, beached, names — from the newer frame rather than blending them.
  • [ ] A dropped frame neither stutters nor snaps: with frames 1 and 3 in hand the motion is smooth and slower, not a jump. A test states that as numbers.
  • [ ] Angles interpolate the short way round, through the wrap wrapAngle already defines — the one place this kind of code is always wrong.
  • [ ] The steering vector is the same function for a drag and for arrow keys or WASD, so the two cannot drift apart, and it caps its seq at SEQ_MAX the way the protocol requires.
  • [ ] A test file next to it covers all of it with hand-written frames: a decode round-trips what encodeFrame produced, a midpoint interpolation lands where arithmetic says, a fraction of 1.4 is clamped, an angle across ±π takes the short way, a drag of 400 px on a 360 px arena clamps to the unit disc, and a malformed frame is rejected rather than half-read.
  • [ ] No DOM in the module and none in the test: canvas, pointer events and requestAnimationFrame all stay in #10.

Files one new module and one new test under static/ (or src/ if the pull argues the page is better served importing from there — say which and why), src/protocol.ts only if a shape has to change.

Risks Two copies of the wire format is the failure mode: the decode has to read the same constants src/protocol.ts exports, not a second table of scales — if the module cannot import from src/, the pull says how the constants stay single-sourced. Interpolating the server's truth is also a choice about feel: this issue makes the function, #10 decides whether your own mote is predicted, and neither should quietly decide the other.

Fits Vesper's brief: input that feels immediate, math written by hand in small typed modules with tests.

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs