Case study · Gaming · A JQiT product
Paulie Paulie.
A 3D open-world MMO with flying racing that runs in an ordinary browser tab, at 60 frames per second on a phone.
The game began at home: the family's real Blue-crowned Conure, a Warcraft childhood and a Minecraft imagination. It is now a live product on its own domain, and this page is our engineering record of it. What we built, the architecture underneath it, and the security work that shipped with it rather than after it.
The game itself lives at pauliepaulie.com. Play it there; read on for how it works.
What we built
An open 3D world with WoW-style progression, real-time multiplayer, player-versus-player duels, boss fights, a cosmetics store and aerial racing. It loads from a URL. There is no install, no launcher and no app store between a player and the game, which is also what makes the engineering interesting: everything below had to be achieved inside a browser's limits.
| Runs on | Any modern browser, phone first. The performance floor is 60 frames per second on mid-range mobiles, held by per-device budgets and an adaptive quality scaler. |
|---|---|
| Rendering | WebGL through Three.js, written in plain JavaScript. No TypeScript, no bundler, no build step: the files that ship are the files we write. |
| Multiplayer | A realtime backend on InstantDB: presence, rooms, topics and transactional writes, with a thin sync layer over them. |
| Performance discipline | Object pools for anything created more than once a frame, module-scope scratch buffers instead of per-frame allocation, and a physics step budgeted at under 1.5 milliseconds at the 99th percentile. |
| Platforms | One codebase, built to ship to web, Android, iOS and Steam in that order. Platform behaviour sits behind a thin adapter layer, never in forks of the game logic. |
How it is built
The unusual choice is the absence of machinery. The client is hand-written JavaScript served as-is, which keeps the loop between an idea and a running game very short, and makes every shipped byte one a person wrote and can read. Discipline replaces tooling: one system per file, balance numbers kept in data files rather than code, and a documentation wiki where each design document is the single source of truth for its own scope.
Architecture decisions are recorded as ADRs and treated as immutable once accepted. A decision that turns out wrong is superseded by a new record, never quietly edited, so the reasoning trail behind the game stays honest. The same delivery framework runs the project day to day: a task board with explicit gates, continuous integration that lints and validates on every change, and a dashboard regenerated by tooling so it cannot drift from the truth.
Where the browser fights back, the game adapts rather than degrades. Boot probes measure the device before committing to a quality tier, a watchdog heals lost WebGL contexts after a phone sleeps, and collision geometry is pre-baked so the client never pays to compute it.
Security, built in from the start
JQiT is a security consultancy, and the game is held to the same standard as our client work. The principle throughout is that the client is never trusted with a decision that matters.
| Purchases | The browser sends product identifiers, never prices. A Cloudflare Worker builds every checkout server-side with Stripe as the merchant of record, and entitlements are granted only by signed webhooks. Refunds revoke automatically. |
|---|---|
| Identity | Every server decision reads the caller's own token. There is no client-supplied account id anywhere in the API surface. |
| Age gating | A neutral date-of-birth screen, with the applicable minimum age decided at the edge from the connecting country. The date of birth itself is never stored, only the outcome of the check. |
| Abuse | Cloudflare Turnstile proves a human before an account can be created, server-set stamps are field-locked so a client cannot forge them, and write rates are limited per user and per address. |
| Process | Every change to the payment surface must pass a recorded security review bound to the exact code being merged, and continuous integration blocks any shipped dependency with a known vulnerability. |
From a real bird to a playable one
The player character is the family's actual bird, carried through four stages of art direction until he could fly in a browser.



