Home/Guides/How to make a multiplayer browser game

guide · beginner

How to make a multiplayer browser game

You have a game that runs in a browser. This guide makes it online in five steps — and explains why each step exists, so you can make the right calls for your own genre.

Free sandbox · $19.99/mo to go live · cancel anytime

overview

The five problems of any online game

  1. Identity — who is this player, and is it the same one as yesterday?
  2. Matchmaking — which players share a session?
  3. Transport — how does data get from one browser to another quickly?
  4. Authority — who decides the score, and how do you stop a modified client?
  5. Persistence — what survives the match: stats, items, leaderboards?

Traditionally each of those is a server you write. Below, each one is a single call.

steps

Step 1 — Get keys

curl -X POST https://multiplayerapi.com/v1/games \
  -H 'Content-Type: application/json' \
  -d '{"name":"My Game","preset":"realtime_arena"}'

Keep mp_pk_… for the client. Store mp_sk_… somewhere safe: it is shown once and must never ship in a client.

Step 2 — Identity: guest login

const mp = new Multiplayer({ key: 'mp_pk_...', displayName: 'Alice' });
await mp.login();   // resumes a stored session, or creates an instant guest account

Requiring a sign-up form before the first match loses most players. Guests get stats, inventory and a leaderboard place immediately and can upgrade() to a username and password later without losing anything.

Step 3 — Matchmaking

const room = await mp.quickmatch({ mode: 'ffa', max_players: 8 });
// or private games with friends:
const priv = await mp.create({ max_players: 4 });  // share priv.code
await mp.join('B2K2D3');

quickmatch joins the best matching room or creates one. Filter with free-form meta such as { map: 'desert' }.

Step 4 — Transport: pick the right channel

ChannelCallDeliveryUse it for
Directroom.send(data)peer-to-peer, best effort, zero server costpositions, aim, animation
Stateroom.set(path, value)server-validated, kept for the match, reaches late joinershealth, score, whose turn
Eventsroom.emitEvent(topic, data)ordered, guaranteed, not persistedchat, rematch, one-shots
room.on('peer', (p, from) => others[from] = p);
setInterval(() => room.send({ x: me.x, y: me.y }), 50);
room.mine('hp', 100);                       // writes players.<me>.hp
room.state.watch('players.*.hp', drawHp);
room.emitEvent('chat', { text: 'gg' });

Step 5 — Authority and persistence

Declare rules once; the server enforces them on every sync:

{
  "state": {
    "players.$self.hp":    { "write": "self", "type": "int", "min": 0, "max": 100 },
    "players.$self.score": { "write": "host", "type": "int", "monotonic": "up" }
  }
}

Then submit scores with mp.submitScore('arena', score) and read mp.leaderboard('arena', { period: 'weekly' }). Results that grant rewards can require peer attestation so a lone host cannot award itself anything.

ship it

Hosting the game

Your game is now a static site. Put it on GitHub Pages, Netlify, Vercel, Cloudflare Pages or itch.io. In production, list those domains in the game's origins so other sites cannot use your public key from a browser.

Engine-specific versions of this guide: Phaser, Three.js, PixiJS, vanilla JavaScript.

Questions
Do I need a server to make a multiplayer browser game?

You need server infrastructure — signaling, relay, accounts, validation — but you do not need to run it yourself. A hosted multiplayer API provides it while your game stays static.

Should I use WebSockets or WebRTC for a browser game?

WebRTC data channels connect players directly, which is faster and costs no server bandwidth. WebSockets go through a server. The best setup uses WebRTC with a server relay fallback — which the SDK handles automatically.

Make your game online today

Free sandbox keys in one call, no account and no card. $19.99/month when you ship, for every game you make.

Free sandbox · $19.99/mo to go live · cancel anytime