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
37 changes: 29 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,20 +1,41 @@
# game-controller

Phone/controller client for **Space Console** — turns a phone into a game
controller that joins a launcher (the TV) via a short room code, AirConsole-style.
Pairs with the `game-launcher-web` repo (the TV/screen side).
The **phone/controller** app for **Space Console** — turns a phone into a game
controller that joins the launcher (the TV) by a short **room code** or a scanned
QR, AirConsole-style. Pairs with the `game-launcher-web` repo (the TV/screen side).

It opens a **WebRTC DataChannel straight to the TV** and sends input peer-to-peer;
the `web-api` service only brokers the handshake (room code + SDP/ICE) and vends
STUN/TURN. The controller renders whatever pad the running game asks for over that
channel:

- a **d-pad** + action buttons for menus and classic games;
- a **landscape analog driving pad** (steering joystick + gas / brake / drift,
with optional tilt steering) for racing games, streamed as continuous frames;
- **name entry** on join (shown in the TV's player roster), and **auto-rejoin**
if the tab is backgrounded or the network blips.

Zero-build, zero-backend static site — plain ES modules, no bundler, no
framework. Open `index.html` and it runs.

```sh
npm install # dev server only
npm run dev # http://localhost:5174 (auto-reload)
npm install # dev tooling only
npm run dev # http://localhost:5174 (auto-reload)
```

This is an early **placeholder**: a join screen + a stubbed control pad whose
transport (`assets/js/session.js connect()/send()`) is a seam to fill in with a
real WebSocket / WebRTC / AirConsole client.
## Transport

The client lives in `assets/js/session.js`:

- `send(intent)` — a discrete button press (`up/down/left/right/enter/back`, plus
game-declared aux buttons like `reset` / `powerup`).
- `sendAnalog(steer, throttle, brake, handbrake)` — a continuous driving frame.

Both go over the DataChannel; the TV relays them into the running game. Signaling
defaults to the page's own origin, and ICE/TURN is fetched from the server at
`/api/ice` (a `?signal=` / `?turn=` query param can override per device). For real
phones, the controller, the launcher and the signaling socket must share **one
origin** — the `web-api` repo serves them together (see its README).

## Documentation

Expand Down
Loading