All projects

Yes & No

Your phone is the controller, the laptop is the console, and nobody installs anything

2026 Tools
Yes & No
WebRTCPeerJSDevice sensorsCanvasVanilla JS

Open a page on a laptop. Two QR codes appear. Each player scans their own with a phone, taps enable sensors, and the phone becomes a motion controller. The laptop screen splits and mirrors both phones live.

No app store, no pairing screen, no accounts — a URL with a room code in it.

Why QR, and why one each

Local multiplayer on the web usually dies at the join step: type this code, or share this link, or install this. A QR per player removes the entire negotiation. Both codes sit on screen at once, labelled P1 and P2 with their own colours, so two people in a room join simultaneously rather than one waiting for the other to finish.

The instructions are three numbered lines under the codes. If a two-player setup flow needs more than three lines, it’s the wrong flow.

WebRTC peer-to-peer, with a relay that catches the rest

Phone-to-laptop runs over WebRTC data channels via PeerJS, so control input goes direct between the two devices instead of via a server — which is the only way tilt input feels attached to the thing on screen. When peer-to-peer can’t be established, a WebSocket relay picks it up. The footer states which mode you got, because a game that feels laggy for a network reason should say so rather than feel broken.

The localhost warning

If you open the page on localhost, a warning appears saying your phone can’t reach that URL and to use a LAN IP or an HTTPS tunnel.

That’s the whole class of problem with this kind of toy: it works perfectly for the person who built it and fails silently for everyone else, because their phone resolves localhost to itself. Detecting it and saying so costs four lines and saves the entire first-run experience.

The games

Air hockey, bowling, snake, and a word search — each a self-contained HTML file sharing the same controller transport. Tilt-based games first, since the phone’s gyroscope is the input that a keyboard can’t imitate and therefore the reason for the whole thing to exist.