The mechanics

How it works

One browser runs the game. Every other seat is a controller and a screen. No installs, no launchers — just a link.

🎮 The host

Picks a game they own. The file loads into their browser with the File API and never uploads anywhere — it's identified by a hash of its bytes, not its name. Their browser runs the emulator, renders the picture, plays the sound, and owns the save.

đŸ•šī¸ The guest

Opens one link. Presses any button — first press maps their gamepad or keyboard. From then on their inputs fly to the host and the host's picture and sound fly back. They never touch the game file.

HOST (the only emulator)              GUEST (browser + controller)
─────────────────────              ─────────────────────────
game file — stays in browser
   │
   ├─ emulator renders the game
   │
   ├─ controller input ◄── WebRTC DataChannel ─── gamepad / keyboard
   │
   └─ video + audio ──── WebRTC stream ─────────â–ē their screen
House rules

Three things worth knowing

🌐 Browser-based

Nothing to install for host or guest. A modern browser and a controller (or keyboard) is the whole rig.

👑 Host-authoritative

The host owns the game state: save, load, reset. Guests send inputs and nothing else — that's by design, not by permission setting.

đŸ‘Ĩ Free account

Accounts are how friends find you on the couch — you get a friend code like VC-NAME-1234. Guests need one to take a seat.

Under the hood it's PeerJS signaling with STUN, and a TURN relay only when a direct path doesn't exist. The nerdy version lives on the Couch Network page.

Ready to take a seat?

Host brings the game. Friends take a seat.