Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions docs/todo.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,17 +72,17 @@ title: TODO / Backlog
<span class="logentry__tag">P2 ✓</span>
<span class="logentry__body"><b>Persistent game shell.</b> Done. The launcher now loads a game into a full-screen <b>iframe shell</b> instead of navigating away, so the page — and its live WebRTC controller links — <b>survive launch</b>. Controller intents are relayed into the running game over <code>postMessage</code> (<code>sc:intent</code>), injected through each game's shared <code>Input</code> layer with no per-game change; <b>Back</b> returns to the menu still connected. Verified with two clients on one machine. (Phone-over-LAN play depends on direct P2P succeeding — see <b>P5</b>.)</span>
</div>
<div class="logentry">
<span class="logentry__tag">P3</span>
<span class="logentry__body"><b>game-controller UX</b> — replace the placeholder pad with the real per-game control surface once a game actually consumes controller input (after P2).</span>
<div class="logentry logentry--done">
<span class="logentry__tag">P3</span>
<span class="logentry__body"><b>Per-game controller UX — Phase 1.</b> Done. A <b>control-profile system</b> lets each game declare the phone controls it wants: <code>Controls.define({profile, buttons:[{id,label,hold?}]})</code> 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 <code>hold</code> for held controls), bottom-anchored for thumbs. <b>9 games</b> got tailored controls: pinball (flippers), minesweeper (Flag), icy-tower &amp; bubble-trouble (movement), blackjack, slots, video-poker, flappy-bird, space-tower — most as pure <code>Controls.define</code> with no game-logic change. Also added <b>scan-to-join</b>: the launcher shows a QR (encoding the controller URL + room code) the phone scans to auto-join. <b>Remaining:</b> Phase 2 <code>pointer</code> profile (phone as trackpad) for fruit-ninja / candy-crush, and richer card-game buttons (poker Fold/Call/Raise, uno, ludo, bridge).</span>
</div>
<div class="logentry">
<span class="logentry__tag">P4</span>
<span class="logentry__body"><b>Game catalog source</b> — <code>games.js</code> is now wired to the real <a href="services/games/index.md">games</a> collection (30 games, sibling Pages paths) but is still a static module; decide if/when it moves to an API / CMS (could be served by <b>web-api</b>).</span>
</div>
<div class="logentry">
<span class="logentry__tag">P5</span>
<span class="logentry__body"><b>Signaling deploy</b> — <b>web-api</b> runs on a laptop (<code>ws://&lt;host&gt;:8080</code>) for dev. Host it for non-LAN play (add <code>wss://</code> + a public origin, and optional TURN for networks where direct P2P fails).</span>
<span class="logentry__body"><b>Public multiplayer deploy.</b> Connectivity is <b>solved for dev</b> and verified with a real iPhone as controller. Three fixes made it work: (1) signaling binds <b>IPv4 <code>0.0.0.0</code></b> (the default was IPv6-only, unreachable by LAN phones); (2) <code>web-api</code> can serve the app <b>and</b> the WebSocket <b>same-origin on one port</b> (<code>STATIC_DIR</code> → <code>npm run serve:app</code>) — 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 <b>public TURN</b> (free-tier) relays when direct P2P fails (iOS mDNS / cross-network). <b>Still needed for an always-on public URL</b> a friend can use off-LAN: host <code>web-api</code> on a public host with <b>wss://</b> (e.g. Render, or the college box) + our own <b>coturn</b>. 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 <a href="services/web-api/architecture.md">web-api / transport architecture</a>.</span>
</div>
</section>

Expand Down
Loading