Split The code is public; the app answers only to the crew.

A whole match on a phone: fire while aiming, weapon switch, scoreboard and a way to leave #20

shipped merged opened this has it
opened this

Make the touch build a client that can play a whole match: fire without lifting your aiming thumb, switch weapons, see the scoreboard, and leave a match without reloading the page.

On a phone today: controls.onPause is only ever called from pointerlockchange (src/client/input.ts), which a touch screen never fires, so there is no pause and no way out of a match; the touch pad has duck, jump, use, reload, buy and fire and no weapon switch or scoreboard; and the fire button sits in the same half of the canvas the look touch lives in, so firing means stopping aiming.

Done looks like

  • [ ] Firing and aiming happen at once: a look touch that is already down keeps steering while fire is held. Say which way you did it — a second touch on the right half firing, or the fire button not stealing the canvas touch — and why.
  • [ ] The pad gains weapon switch (1/2/3), a scoreboard control (held), and a menu button that opens the same #pause overlay Escape opens, from which Leave match works. The slot buttons need no change to input.ts: press.isDown("slot1") is what slotWanted already reads, and attachButtons already wires any [data-action].
  • [ ] controls.onPause is reachable without pointer lock.
  • [ ] Buy works with a thumb in freeze time: the overlay opens from the pad, its buttons are 44px on a side, and the grid does not overflow at 360px.
  • [ ] At 360×640 there is no horizontal scroll, every touch control is at least 44px on a side, and nothing covers the radar, the health readout or the ammo readout.
  • [ ] A test that would fail without the change — the action table, or press.ts behaviour for a fire held across a frame that also steers.
  • [ ] Say what you checked it at: viewport size, and what the fps counter read with the pad up.
  • [ ] bun test passes; the README's controls section documents the touch controls next to the keys.

Files I expect to change

src/pages/game.ts (the touch pad markup and its CSS), src/client/input.ts, src/client/press.test.ts or a new src/client/input.test.ts, src/client/main.ts, README.md.

Risks

  • The canvas touch handlers are { passive: false } and call preventDefault; a control placed over the canvas can swallow the look touch or be handled twice (once as a pointer on the button, once as a touch on the canvas). lookX/lookY must keep accumulating in exactly one place.
  • press.clear() on blur and on unlock must not strand a held fire — a stuck trigger on a phone is unrecoverable without a reload.
  • The CSP forbids inline script (src/server.ts): every handler stays in the bundle, and [data-action] stays the way markup asks for behaviour.
  • The pad is position: absolute inside #stage; a taller pad eats the bottom of the view. Keep the playfield the same size it is now.

Crew

scout — this is page markup, CSS and button wiring done small and finished, with the thing it left out named. If the two-finger aiming turns out to need real work inside the canvas touch handlers, vesper is the better fit.

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs