The 5-minute map of how the whole product is built. Written for a human, not a compiler β every technical word is explained where it first appears. Start here, then open the deep-dive pages above.
A group of friends plays simple party games together. Every game is
learnable in under a minute β depth over breadth. The line-up itself lives in the code
(apps/app/src/games/catalog.ts, and the site's /games page), not
here. What matters for the architecture is that each game declares where it can be
played, and the pickers and the referees enforce it:
| A game that⦠| Same device | Online | LAN (paused) | Example |
|---|---|---|---|---|
| is a board or a turn you can take on one shared phone | β | β | β | Tic-Tac-Toe, Ludo |
| needs every player on their own screen (a secret ticket, a secret answer) | β | β | β | Tambola, Trivia Clash |
| only works in some languages (a grid of AβZ letters) | offered only to players reading those languages | Word Search | ||
Leaving a game out of a mode is deliberate, not missing work: pass-the-phone cannot hide a secret from the person holding the phone next.
Two are offered to players today. The third is complete in the codebase and switched off for launch β why, and how to bring it back.
The whole game runs on that one phone. No account, no setup β pick a game, type names, hand the phone over. Each game decides for itself whether it needs the internet.
A referee in the cloud (a service called Convex) keeps one shared game that everyone watches live. The host signs in with Google or Apple; friends just type a 4-letter room code β no account needed.
The host's phone becomes the server. Friends on the same wifi or the host's hotspot scan a QR code and play from their phone's browser β nothing to install. Not offered at launch: an all-iPhone group can't reach a hotspot that has no internet. The come-back note β
Game rules are written once, as plain calculations with no side-effects (developers call this "pure functions" β think of it as a rulebook that only answers questions). Each play mode is just a different place that same rulebook runs:
packages/engine + each game's game.ts β no clock,
no dice, no network. Time and randomness are handed in from outside.
Seven pieces, each living in its own folder. Together they are the whole system:
One codebase (built with Expo) that becomes three things: the iPhone app, the Android app, and the play website. Screens, games, and all three play modes live here.
apps/app Β· Frontend page β
The home, one page per game, contact, privacy and terms are routes of the App, static-rendered on the web with their own titles and descriptions β what search engines and AI assistants read. No second site.
apps/app/src/site Β· Frontend page β
The cloud referee: rooms, players, live game state, and content a host supplies for the room. Fully generic β adding a game adds zero backend code.
convex/ Β· Backend page β
Shared pure game logic: the contract every game implements, plus reusable mechanics (turns, timers, scoring, seeded diceβ¦).
packages/engine
The same "run the match" job Convex does online, packaged as a tiny library the host's phone runs during LAN games.
packages/match-host Β· LAN page β
A small native module that turns the phone into a web server, so friends' browsers can load the game straight from the host's phone.
apps/app/modules/expo-lan-server
Passes short-lived messages between the phones in an online room, like a drawer's line while it is still being drawn. Stores nothing. See the live channel.
live/
Some things other players should see the moment they happen, but nobody needs kept: a line growing under the drawer's finger, later a pointer. So an online room also has a live channel: a small Cloudflare relay with one room object per room. The backend signs a short pass that the relay checks when a phone connects, a phone holds the channel only while a feature needs it, and the relay passes messages between the room's phones and stores no messages. The game's real moves still go through the backend, so if the relay is down, nobody sees an error. Same device and LAN have no channel.
The tracks go live independently β knowing which one you're touching
is half the job. Full step-by-step commands: docs/releasing.html.
| Thing | Where people see it | How it ships |
|---|---|---|
| The site β content pages + web play | gamesforgroup.com | Manual β bun run deploy builds, checks and uploads to Cloudflare. A push deploys nothing |
| Online backend | (invisible β powers online mode) | Manual β and before any site change that needs it |
| iPhone app | TestFlight β App Store | Local build on the Mac (free) β or an EAS cloud build when credits allow |
| Android app | Play internal testing | Local build on the Mac (free) β or an EAS cloud build when credits allow |
| The live relay | (invisible β the growing line in online drawing) | Manual β bun run deploy:live, with the shared secret set on the relay and on the backend |
| These docs | docs.gamesforgroup.com | Manual β bun run deploy:docs uploads the docs/ folder as it is, no build |
The site and the docs are served by Cloudflare (each a "Worker" that
hands out static files; www is a third, tiny one that redirects to the bare domain).
Online play is counted on the backend; website visits are counted by Cloudflare's cookie-free
analytics.
Where everything lives, what a game folder looks like, and the few hard rules that keep the codebase safe to change.
π± FrontendThe one app, how screens are organized, the Board-vs-shell split that makes one game work in all three modes, the shared kits, and where the words live.
βοΈ Online backendWhat Convex is, the life of an online room, the database tables, and the one deploy rule that must never be broken.
π‘ LAN modeHow a phone becomes a game server, what travels over the wifi, and the fragile part every release must double-check.
π©Ή LearningsBugs that fooled us β what broke, why it really broke, and why our testing didn't catch it. So we stop re-learning the same lesson.
π§ DecisionsThe calls we made and why β with the alternatives we rejected and what would make us change our minds.
Big calls that shaped the whole system, newest first. (Each deep-dive page keeps its own log for decisions in its area.)
bun run deploy is the one way the site
goes live (why).docs/decisions.html.docs/decisions.html.docs/decisions.html.gamesforgroup.com/room/CODE and sign-in state is shared across the whole
site.docs/decisions.html for the board/rules calls (classic Ludo cross board,
first-finisher ends the race, humans-only).docs/releasing.html.CLAUDE.md) that they get updated in the same session
as any architecture change.CLAUDE.md rule "Architecture docs β keep them in
sync". If the code changed and this page didn't, that's a bug β fix the page.
See also learnings.html and
decisions.html.