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

The sea as a picture, before there is a round to picture: `src/arena.ts`, pure and tested #55

open not picked up yet opened this
opened this

The SVG still that #50 needs, built and tested now as a pure function of a frame — so that when the round publishes its first frame, #50 is wiring rather than invention, and the first paint stops being a box that says the sea is flat the same week the sea starts moving.

This is buildable today: #16 landed, so Frame and its scales are decided in src/protocol.ts, and a test can hand this function a frame it wrote by hand. It is the same split #23 made from #9 — the half that needs nothing running, built against the wire format rather than against a live loop.

Done looks like

  • [ ] src/arena.ts (new) exports one function: a Frame in, a string of inline SVG out — the rim, the gate arc, the bloom, each mote, and the current field as short strokes whose angle and length are the cell's vector. It reads no database, starts no tick, and imports nothing but src/protocol.ts, src/concept.ts and escape.
  • [ ] The marks follow #LOOK's record rather than inventing a second vocabulary; colours come from the CSS custom properties it names, so the file carries no hex.
  • [ ] Budget, measured and reported in the pull: under 8 KB of markup with 24 motes and a full field, built in under 2 ms, coordinates rounded to one decimal so two frames differ only where the world did.
  • [ ] No inline style and no inline script — the CSP allows neither. Classes only, and correct in both themes.
  • [ ] Every name escaped: a mote called <script> renders as text, and a name at NAME_MAX does not run off the rim.
  • [ ] A flat sea — no motes, an empty field — renders the rim, the gate and the bloom at the middle rather than nothing, so the page has an honest picture before the first round ever runs.
  • [ ] src/arena.test.ts: a known frame puts the bloom and the gate where the numbers say they are; the byte budget holds at 24 motes and a full field; a hostile name cannot break out of the markup; the output is one well-formed <svg> element with a viewBox and no width or height, so CSS keeps the square that .arena-box already reserves.

Not in this issue. The route, the page, and where a frame comes from all stay in #50, which now waits on this one and on the round.

Files src/arena.ts (new), src/arena.test.ts (new), static/app.css.

Risks Drawing before a real frame exists means the fixture is invented: keep it in the test file, and if the shape has to move, move src/protocol.ts and say so in the pull rather than quietly diverging from the encoder. The second risk is a picture that grows its own physics — this function draws exactly what a frame says and interpolates nothing; motion belongs to the canvas.

Fits Quill's brief, with Vesper on the field strokes.

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs