Multiplayer: play Prisma Duel with friends in a browser
Room codes, matchmaking, and why the match keeps going if the server does not
Prisma Duel is a free multiplayer browser game for up to four players. There is nothing to install and no account to make: one of you opens the game, sends the others a four-letter room code, and everyone is in the same arena within a few seconds. Leave the code blank and you are matched with whoever else is waiting.
Open the game and start a room
How to play with friends
- Open prismaduel.com. Type a callsign.
- Type any 2–8 letter room code —
KITE,ROOM1, whatever — and press JOIN ROOM. If the room does not exist it is created. - Send the code to your friends. They type the same code and join.
- When everyone is in, the first pilot to have joined gets a START MATCH button.
Rooms take up to four pilots. A room with an empty code puts you into the oldest room with space, so
strangers clump together rather than each waiting alone. Room codes use no I or
O, so one read out over voice cannot be misheard as a digit.
What a multiplayer turn looks like
The game is turn-based with simultaneous resolution: everyone plans at once, against a 25-second clock, and the turn plays out for everyone the moment the last pilot commits. A pilot who runs out the clock holds their previous course. Nobody waits for anybody in sequence, so four players is exactly as fast as two.
After a match, REMATCH asks the room rather than sending everybody back through the lobby: the others get a card, and a fresh arena starts with the same pilots as soon as everyone still in the room has joined.
Peer-to-peer, with a net underneath
The server does matchmaking and hands peers each other's connection details; after that, any pair of
players that can reach each other directly plays peer-to-peer over WebRTC. You can kill the server
in the middle of a match and that pair plays on. Any pair that cannot connect directly — symmetric
NAT, a corporate firewall, UDP blocked — is relayed through the server over the same WebSocket the
page loaded from, which works anywhere the page itself does. The HUD says via server relay
for such peers.
Nothing waits for the connection to be negotiated. The relay is live from the moment you join, and each pair upgrades to a direct link the instant its channel opens. A TURN server can sit in between as a lower-latency relay if the operator configures one; the deployment at prismaduel.com does.
Why it stays in sync without an authority
There is no server that owns the truth. Every client runs the same simulation, so the simulation has
to be bit-identical on every machine: the rules are a pure module with no DOM, no wall clock and no
Math.random, and each turn's trajectories are precomputed into a fixed 96-substep path that
every peer walks in the same order. Only one peer — the arbiter, always the lowest-numbered
connected seat — declares a turn, and every client, arbiter included, starts the turn from the same
message. That single code path is what stops a client who commits last from resolving a different set of
moves than the one the arbiter filled in on timeout.
It is checked, not assumed: two live browsers were driven through an ordinary turn and a turn where a player timed out, and both ended with identical state hashes on both peers. The headless test suite forms a real six-link mesh between six browsers, plus a relay-only pair, and does the same.
If someone drops
A socket that dies keeps its seat for fifteen seconds. Refresh the page inside that window and you get the same seat back with no churn for anybody else — the peer-to-peer mesh survives a blip in the signalling connection. After that the seat is released and the match carries on without you.
Running your own
The whole server is one file with one dependency. cd server && npm install && node
server.js and open the printed URL; or docker compose up. It serves the game as well
as the signalling, runs read-only as an unprivileged user, and a small instance is plenty: direct pairs
never touch it after the handshake, and relayed pairs send it a couple of small JSON messages a second.
The source has the details,
including how to point it at a TURN server.