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

forked from trevato/cs

The HUD makes room for thumbs: health and ammo stop sitting under the touch buttons #404

Closed opened this
Closed without merging

On a phone, health, armour, ammo, the weapon name and the "reloading"/"switching" line now sit on top of the touch pads instead of under them. With a mouse and keyboard nothing moves, and a test pins that.

stopped closed without shipping deploy 941ee62

opened this

On a phone, health, armour, ammo, the weapon name and the "reloading"/"switching" line now sit on top of the touch pads instead of under them. With a mouse and keyboard nothing moves, and a test pins that.

The pads had to change first. I measured them in headless Chromium. The old flex wrap turned each pad into four rows at 360×640: 275px tall on a 246px stage, covering the whole picture, radar and clock included. At 390×844 it was 222px of 269. There was no room to put the HUD above that. In src/pages/shell.ts each pad is now a grid three buttons wide, with smaller button padding and text. Six buttons make two rows of 44px, so the panel is 106 CSS px tall at every width, from 360 up to 1280. Every button is still at least 44×44.

How the HUD finds the pads. In src/client/main.ts, one function, showTouch, shows or hides the pads everywhere they're toggled. It reads the panel's offsetHeight right then, which is 0 while hidden, and again on a window resize, never in a frame. drawHud takes that height as a new last parameter, thumbs, converted to canvas pixels. footOf(height, pad, thumbs) in src/client/hud.ts puts the bottom row at height - max(pad, thumbs), and the spectator's "Watching …" panel moves up with it.

One trade-off. Lifting the bottom row put the armour line on top of "defuse kit" under the radar at 360×640. So while the pads are up, the radar shrinks just enough for the money column to end above the armour line. That's about 9 CSS px of map at 360×640 and nothing at 390×844. With no pads the radar is exactly as it was.

What the pads cover at 360×640 and 390×844, upright:

  • Radar, round clock, score, players left, kill feed, round message: clear. The pads start at 139/162 CSS px; the radar ends by 86/93 and the clock bar by 31.
  • Plant/defuse bar: still under the pads. It's drawn at 62% of the height (152 and 167 CSS px), below the pad line, and lifting it would put it on the crosshair.
  • Spectator panel: it now lands on the money line under the radar instead of being hidden under the pads.
  • #fps readout (page text in the stage's bottom-right corner): under the right pad.

Those three are issue #403, which waits on #204. In landscape or full screen there's room for all of them.

Tests. src/client/hud.test.ts draws frames with pads and without:

  • With no pads, the bottom row sits at pinned coordinates. Leaving thumbs out gives exactly the same calls as thumbs = 0 at 1280×720, 1920×1080, 2560×1440 at 2×, and 360×640.
  • With pads, at both phone sizes and at 2× and 3× pixel density, every bottom-row line is above the pad line and keeps its x. The same things are drawn in the same order, and the clock, score and players-left counts don't move.
  • The money column ends above the armour line.
  • The spectator panel moves up by the same amount as the row under it.

Density matters here: the engine caps the HUD's pixel ratio at 2, so the text/radar overlap only appears at 2×. I checked the new tests fail with the radar cap removed, and with a HUD that always moves up. src/client/main.test.ts checks that a phone's health number sits on the 106px panel, a mouse's sits on the usual margin, and that 30 frames read the height zero times while a resize reads it once. bun run test passes: typecheck, 1658 tests including src/frames.test.ts, and the bundle is under its size ceiling.

To try it: open the preview in device emulation at 360×640 or 390×844 with a touch pointer and press Play. Health and ammo sit just above the button grid. On a desktop the HUD looks as it did.

🤖 Generated with Claude Code

Closes #204

commented

Closed in the owner's sweep of 2026-10-12: a week old and in conflict with main now; the branch stays if anyone wants it back.

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs