How Controller+ connects
Controller+ moves a phone's input into a game with as few hops as possible. This page explains who talks to whom, what is encrypted, what runs where, and what we are building next.
The pieces
The phone controller. It runs in the phone's browser, with nothing to install, or in the Controller+ app for iPhone (Android is coming). Both speak the same protocol.
The host. This is what the phone connects to, and it is one of three things:
- The Controller+ desktop app on your computer. It turns phones into gamepads or game keys for any game on that computer.
- Your game's own server, built with the SDK's
ControllerHostor an engine plugin. - The Controller+ relay at controller.plus, for browser games that have no server.
The QR code. It holds everything the phone needs: the host's address, a room code and a join token. The desktop app's QR also holds its encrypted port and the exact fingerprint of its certificate.
The three routes in use today
| Route | Used by | Path | What the phone shows |
|---|---|---|---|
| Local network | The desktop app | Phone to your computer over Wi-Fi. Browser controllers use port 4320; the app uses the encrypted port 4321. Nothing goes over the internet. | LAN and a ping of a few milliseconds |
| Game server | Games with their own server | Phone straight to the game's server. Our service is not involved. | SERVER |
| Relay | Browser games without a server: the homepage demo, the example games, a ten-line web game | The game tab and the phones both connect out to wss://controller.plus/relay/ws, and the relay passes messages within the room. |
RELAY and a ping that includes two internet legs |
Why the homepage demo uses the relay
A web page cannot accept incoming connections; a browser can only connect out. A game running in a browser tab, with no server and no desktop app, therefore has no address a phone can reach. Both sides meet at the relay, which is why the demo shows VIA RELAY. The routes below remove that limitation.
What travels, and how fast
Phones and hosts exchange small JSON messages over a WebSocket:
helloandwelcomepair the phone with the host and give it a player seat.inputcarries the sticks and sixteen buttons with a sequence number. It is sent when something changes and refreshed about 30 times a second, so a lost moment heals quickly.viewgives a phone its own private screen: a secret role, a vote, a drawing pad.feedbackplays sounds and rumble on the phone.pingandpongmeasure the round trip. The phone shows the smoothed value on its screen; it is the time to the host and back, not the whole touch-to-screen delay.
Security
- Join tokens. The QR carries a join token. The desktop app can issue a new QR at any time, and relay rooms close after 30 idle minutes.
- Pinned encryption for the app. The app connects to the desktop app over TLS and accepts only the certificate whose fingerprint was in the QR, so only the computer you scanned can answer. No certificate authority is involved.
- Remembered computers. When the app pairs with a desktop app, each side keeps a pairing key: the phone in its Keychain, the computer only as a hash. The phone reconnects without scanning until either side forgets the other.
- Mouse and keyboard. Control of the computer itself needs the encrypted app connection and the owner's approval on the computer. Browser controllers can play, but cannot move your mouse or type.
- No accounts, no stored input. Relay rooms live in memory; we keep counts for operations, not what players pressed.
What runs where
| Part | Built with |
|---|---|
| Browser controller | HTML and JavaScript, served by controller.plus or by the desktop app |
| iPhone app | Swift and UIKit |
| Android app | Kotlin (in progress) |
| Desktop app | A Node.js runtime in a single executable, plus a small native helper per system: Swift with CoreHID on macOS, C with the ViGEmBus driver (an Xbox 360 controller) on Windows, uinput on Linux |
| Relay and website | A Node.js service at controller.plus |
| SDK | JavaScript, with Godot, Unity, Unreal and C/C++ packages |
Next: the connection ladder
Planned; not built yet. The goal is that every session takes the shortest path that works, and the relay becomes the last resort instead of the default for browser games:
- Local first. When the desktop app is running, a browser game on the same computer will reach it on
localhost, and phones reach it over Wi-Fi. Web games then stay entirely on your network, at local-network latency. - The Controller+ port. The desktop app listens on fixed ports: 4320, and 4321 for encrypted connections. If you forward 4321 on your router, or let the app map it automatically (an opt-in setting), phones outside your home can connect to your computer directly. Pinned encryption and pairing keys protect it.
- Peer to peer. When no direct path exists, the relay only introduces the two sides. Input then flows directly between phone and game over a WebRTC data channel, which crosses most home routers.
- Relay. It always works, at the cost of an extra internet leg, so it is used only when nothing else connects.
Developers stay in control: a game's connection manifest lists the routes it allows and in what order, and it can rule out our relay entirely. See Connection information for what the phone displays and Protocol for the message formats.