// TECH //
From click to live match in seconds
What the browser fetches, how identity crosses the iframe boundary, and what the servers do while you play. Every number here was measured against the live site.
What a click on Play actually fetches
A tile on the home page takes you to /play.html?game=<slug>. That page is small on purpose: eleven files, about 82 KB of HTML, CSS and JavaScript, roughly 31 KB compressed, parsed and running 100 to 150 milliseconds after the request leaves.
None of it is the game. The page reads the slug from the query string, fetches the catalog from games.blitzbrawl.com/catalog.json and looks it up. If that fetch fails, a copy bundled into the page is used, so a bad minute on the network still shows a game.
The entry supplies the one thing that matters: a play URL shaped like games.blitzbrawl.com/<game id>/<version id>/index.html. The page creates an iframe, points it there, and is done.
Why there is no install step
That version id does real work: every build lands on a new immutable path, so browsers and the CDN cache it hard and a release invalidates nothing. Nothing is installed because there is nothing to install: the games are HTML, JavaScript and a canvas.
What a first visit with an empty cache costs, from the browser's own resource timing:
- Blob Volley: 20 files, 145 KB on the wire (524 KB unpacked). The game is one 345 KB HTML document that arrives compressed at 86 KB.
- Clash of Stars: 41 files, about 620 KB, mostly nebula artwork and one music track.
- Zone Command: far heavier. Its sprite atlases run to several megabytes across roughly two hundred images, still arriving after the menu is usable.
All three menus were on screen and clickable inside one second on a desktop connection. A phone on a weak signal takes longer, and the heavier the art the more that shows.
The game runs in a sandbox, on its own domain
The game does not run on blitzbrawl.com. It runs on games.blitzbrawl.com, in an iframe declared sandbox="allow-scripts allow-same-origin allow-pointer-lock" with allow="autoplay; fullscreen".
A different origin means the game cannot read the page around it, its DOM or its storage, and that page cannot read the game's. Fullscreen and pointer lock are granted deliberately, so the Fullscreen button uses the real browser API where one exists and hands over the viewport by hand where none does, as on iPhone Safari.
How the game learns who you are, without a password
There are no passwords in this stack. The first time an identity is needed, the accounts service mints an anonymous device account: an opaque token and a player id, no email. To carry it between your phone and your laptop you add an email address and confirm a 6-digit code. That is the whole sign-in. The routine that checks an existing session never registers, so a flaky network cannot swap a real account for a fresh anonymous one.
The token lives in a bb_dt cookie scoped to .blitzbrawl.com, with a copy in local storage. That leading dot is what makes the split origin work: a game on games.blitzbrawl.com sits under the same domain and already sees the token.
The cleaner path is a handshake across the iframe boundary. The game's SDK posts a hello carrying its protocol version; the page answers ready with the game id and the current player. Both sides stay suspicious: the page ignores anything not from the exact games origin and the exact iframe it mounted, and the game locks onto the parent origin at ready. No player data moves before that lock, and a failed handshake falls back to the cookie. Sign in or out mid-game and a playerChange event rides the same channel, so multiplayer lights up with no reload.
How you end up in a match with a real person
Two of the three games share one server-side matchmaker, and it tries the dull option first: if a public lobby is waiting with a free seat and a live host, you are dropped into it already readied. Rating is ignored there: landing in a live game beats a fair pairing when nobody is queued.
With no lobby to join you enter a queue that widens as you wait. The acceptable rating gap starts at 150 points and grows by 100 per five seconds waited, and both players' windows have to span the gap before they pair, so a long waiter is never fed a mismatched newcomer. There are no server-side timers: your client re-sends its request every five seconds, and two compatible searchers pair immediately. The match begins 800 milliseconds later, on a clock both clients agree on.
Blob Volley runs a coarser version of the same idea, stepping the gap through 200, 500 and 1000 rating points and then to anyone, five seconds per step.
Matchmaking is seconds when somebody else is looking too. When nobody is, it is a wait, and no engineering fixes that, which is why all three games also hand out a four-character lobby code to send a friend.
What keeps the match running
Every online match runs over a WebSocket to a regional endpoint. Clash of Stars guesses the region from your time zone (Frankfurt, Virginia or Singapore) and lets you override it in Options. Blob Volley opens all three and keeps whichever answers first. Zone Command runs one region today, Frankfurt.
That socket is a relay, and the relay is the floor rather than the ceiling. Each game also negotiates a direct WebRTC data channel, unordered and without retransmissions, because a late input is worth nothing. While both routes exist, packets go out on both, so the direct one can only lower latency and can never take a match down. Blob Volley inverts the order: it prefers the direct channel and falls back to the relay after 15 seconds.
What crosses the wire is not game state. All three send inputs and orders and compute the consequences locally, which is why the traffic is tiny:
- Clash of Stars runs a deterministic simulation at 20 ticks per second. Commands are stamped five ticks (250 ms) ahead so they land in time everywhere, and each client hashes its state every 40 ticks to catch a divergence.
- Zone Command uses the same engine family with a tighter two-tick (100 ms) command delay and a hash every 30 ticks.
- Blob Volley is a rollback game at 60 frames per second. An input packet is 8 bytes: a 24-bit frame number plus four input bytes, the current frame and the three before it, so a lost packet repairs itself. A late input rolls back and replays up to 20 frames.
Where the seconds actually go
Totted up for a cold first visit on a desktop connection: about 150 milliseconds for the page around the game, under a second for the lightest game to reach a clickable menu, two taps to reach quick match, and then the one ingredient no engineering can supply, another human.
▶ Play the games