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

A phone held upright plays a shooter through a 4:3 letterbox, and nothing suggests turning it sideways #221

open told opened this
opened this

Make the phone say turn me sideways once, and take the landscape the game needs when it can.

The direction asks for a game that is usable on a phone, and the phone half is nearly there: #touch appears on a coarse pointer (main.ts:385-395), fullscreen goes on #wrapper so the pad comes along (game.ts:139-145), and quality.ts adapts the render scale. Orientation is the hole: grep -rn "orientation|portrait|landscape" src finds nothing at all, and game.ts:242 pins the stage to aspect-ratio:4/3 under 640 px. Held upright, a phone gets a squat box with the pad crowded under it, a 90 degree field of view crammed into the narrow axis, and no hint that the game is meant to be played the other way round. Most players will simply decide it does not work on a phone.

Done looks like

  • [ ] On a coarse pointer in portrait, one calm line over the stage - turn your phone sideways - that disappears the moment the device is landscape. CSS-driven off @media (orientation: portrait) and (pointer: coarse), not a script polling the size, and it is never shown on a desktop window that happens to be tall.
  • [ ] It does not block the game: a player who ignores it can still play. It is a hint, not a gate. Say in the pull which you chose and why if you disagree - but do not silently take the match away.
  • [ ] Entering fullscreen attempts screen.orientation.lock("landscape") and ignores a rejection completely: Safari has no such method, a desktop rejects it, and a rejected promise must not reach the console or the player. Guard on the API's existence, catch the promise, carry on.
  • [ ] Landscape on a phone gets the room it is owed: whatever aspect-ratio the stage takes under 640 px, it does not letterbox a landscape phone into 4:3. Name the rule and say what a 360x800 device and an 800x360 device each get.
  • [ ] No layout shift when the hint appears or goes, and no motion for its own sake (#77 is landing prefers-reduced-motion - do not add something it then has to chase).
  • [ ] Tests: src/pages/game.test.ts asserts the hint's markup and the media query are in the served page; the fullscreen lock attempt is guarded such that a missing screen.orientation cannot throw - a unit test around the guard, or a sentence saying why it cannot.
  • [ ] One line in README's phone section describing what a portrait visitor sees.
  • [ ] bun run check green.

Files I expect to change

  • src/pages/game.ts, src/pages/game.test.ts, src/client/main.ts (the fullscreen handler only), README.md.

Risks

  • screen.orientation.lock only works in fullscreen and only on some browsers; treating its rejection as an error is how a phone gets an unhandled promise on every fullscreen click.
  • The hint must not sit over the touch pad's buttons or steal their taps: #touch is touch-action:none for the look drag, and an overlay that swallows a pointer is worse than no hint.
  • Do not change the desktop layout: the 640 px query is the phone's, and a narrow desktop window is not a phone.

Crew

vesper - the phone's feel, the page's CSS and the fullscreen path.

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs