diff --git a/docs/todo.md b/docs/todo.md index d0d0c2f..8b8ec0b 100644 --- a/docs/todo.md +++ b/docs/todo.md @@ -72,9 +72,9 @@ title: TODO / Backlog P2 ✓ Persistent game shell. Done. The launcher now loads a game into a full-screen iframe shell instead of navigating away, so the page — and its live WebRTC controller links — survive launch. Controller intents are relayed into the running game over postMessage (sc:intent), injected through each game's shared Input layer with no per-game change; Back returns to the menu still connected. Verified with two clients on one machine. (Phone-over-LAN play depends on direct P2P succeeding — see P5.) -
- P3 - game-controller UX — replace the placeholder pad with the real per-game control surface once a game actually consumes controller input (after P2). +
+ P3 ✓ + Per-game controller UX — Phase 1. Done. A control-profile system lets each game declare the phone controls it wants: Controls.define({profile, buttons:[{id,label,hold?}]}) posts to the launcher shell, which relays the layout to every phone over the DataChannel; the controller renders it dynamically (d-pad, or labeled buttons, with hold for held controls), bottom-anchored for thumbs. 9 games got tailored controls: pinball (flippers), minesweeper (Flag), icy-tower & bubble-trouble (movement), blackjack, slots, video-poker, flappy-bird, space-tower — most as pure Controls.define with no game-logic change. Also added scan-to-join: the launcher shows a QR (encoding the controller URL + room code) the phone scans to auto-join. Remaining: Phase 2 pointer profile (phone as trackpad) for fruit-ninja / candy-crush, and richer card-game buttons (poker Fold/Call/Raise, uno, ludo, bridge).
P4 @@ -82,7 +82,7 @@ title: TODO / Backlog
P5 - Signaling deployweb-api runs on a laptop (ws://<host>:8080) for dev. Host it for non-LAN play (add wss:// + a public origin, and optional TURN for networks where direct P2P fails). + Public multiplayer deploy. Connectivity is solved for dev and verified with a real iPhone as controller. Three fixes made it work: (1) signaling binds IPv4 0.0.0.0 (the default was IPv6-only, unreachable by LAN phones); (2) web-api can serve the app and the WebSocket same-origin on one port (STATIC_DIRnpm run serve:app) — needed because iOS Safari only lets a page reach its own origin host:port, so cross-port signaling and a local TURN are unreachable from a phone; clients now default signaling to the page origin; (3) a public TURN (free-tier) relays when direct P2P fails (iOS mDNS / cross-network). Still needed for an always-on public URL a friend can use off-LAN: host web-api on a public host with wss:// (e.g. Render, or the college box) + our own coturn. GitHub Pages serves the static app but has no signaling/TURN, so Pages alone isn't playable; a dev cloudflared tunnel works only when the host network allows it. See web-api / transport architecture.