Everyone has a game idea; few can build one. The Game Factory turns a sketch or a sentence into a game you can play in your browser. You refine it by chatting, then race or team up with a friend, even inside iMessage.
Inspiration
The games that last, like Minecraft, Roblox and Geometry Dash, last because players make the content. Making that content is still gated by skill. Roblox needs Lua, Mario Maker needs a console, and a serious level editor takes hours to learn. So most people only ever play.
Every one of us has drawn a level in the margin of a notebook. We wanted that drawing to be the game, with no translation step, no engine and no tutorial. Once a game exists, the natural next move is to show a friend. For most people that happens in a group chat, not on a game platform, so we wanted the game to be playable right there.
That gave us three goals:
| Goal | What it means in practice |
|---|---|
| No skill barrier | If you can sketch or describe it, you can play it. |
| Conversation, not configuration | You change the game by saying what you want ("make the hero a dragon"). |
| Play where your friends already are | An invite is a link or a card in iMessage, not an app download. |
What it does
The Game Factory has two ways to make a game, and both end in the same place: a game you can share.
sketch on canvas ─┐ ┌─> AI-generated game ─────┐
photo of paper ───┼──> The Game Factory ─┤ (any genre) ├──> play, refine, share
a sentence ───────┘ └─> verified platformer ───┘ (browser + iMessage)
(bot-tested levels)
1. Create with AI. Combine a sketch, a theme and a short gameplay brief. Claude designs the game, draws its art and writes the whole thing as a self-contained browser game. Then you keep talking to it. Every follow-up message ("add lava", "two players, versus", "make it night") produces a new revision that keeps everything you liked. Tick Better graphics for a dedicated SVG art pass, and Multiplayer for a two-player versus or co-op version.
2. Build a faithful platformer. Draw with colored ink and every color means something:
| Ink | Becomes |
|---|---|
| Black | Ground and platforms |
| Red | Hazards and enemies |
| Green | The goal |
| Blue | Collectibles |
Draw on screen, or print one of our template sheets, draw with markers and scan it with your phone. Before you ever press play, a bot plays your level to confirm it can be beaten. You get four versions of your level, Faithful, Polished, Challenging and Hard, so you can choose how much the designer changes your drawing.
3. Play together. Publish your game, remix someone else's level, race a friend's ghost, or invite a friend to a live two-player match. With Photon Spectrum, the invite arrives as a game card inside iMessage, and both players join without leaving the conversation.
How we built it
Architecture
┌──────────────────────────────────────────────┐
Phone / laptop ────> │ Vultr Cloud Compute (Docker Compose) │
(browser or │ │
iMessage card) │ Caddy ── automatic HTTPS, static web app │
│ │ │ │
│ Auth0 login │ ├── /api, /uploads, WebSockets │
└─────────────> │ ▼ │
│ FastAPI (Python) ── SQLite + uploads volume │
│ │ │ │
│ │ └── Node 24 workers: TypeScript │
│ │ simulation core, bot, replays │
│ ▼ │
│ Claude (design, art, game code) │
│ │
│ Messaging service (spectrum-ts) <── Photon │
└──────────────────────────────────────────────┘
| Layer | Stack |
|---|---|
| Frontend | TypeScript, Vite, Phaser 3, a paper-and-ink drawing editor |
| Game core | A deterministic TypeScript simulation that runs in the browser and in Node workers, so the bot, the replays and the player all use the same physics |
| Backend | Python, FastAPI, OpenCV for paper scans, SQLite |
| AI | Claude via structured outputs: Opus 5.5 writes generated games, Sonnet 5.5 paints the optional SVG art pack |
| Accounts | Auth0 |
| Hosting | Vultr Cloud Compute, Docker Compose, Caddy |
| Messaging | Photon Spectrum for iMessage game cards |
An agentic build pipeline, with a referee
We never let the model's output reach the player unchecked. For platformers, the model proposes and deterministic code decides:
PLAN ──> LAY OUT ──> BOT PLAYTEST ──> FIX (up to 3 steps) ──> still stuck?
▲ │
└────────── retry once, with the bot's findings in plain words ───┘
A critic reads where players actually die and suggests at most three fairness fixes, such as a checkpoint or a coin trail. Each suggestion is validated by the core before it is shown.
The staged build streams results as soon as they exist, so you are never staring at a spinner. These are the stage targets the orchestrator is built around:
t (seconds) 0 5 10 15 20 25
|--------|--------|--------|--------|--------|
Ink █ playable in ≤ 0.6 s
Understood ███████████████████████ ≈ 11 s
Designed ██████████████████████████ ≈ 13 s
Hard deadline ██████████████████████████████████████████████ 25 s: best result ships
Paper scanning
Each printed sheet carries four ArUco markers and a row of color swatches. We warp the photo back to the template with a homography and classify ink against the swatches, which removes most lighting problems. A grid cell becomes solid when ink covers enough of it:
$$ \text{solid}(c) \iff \frac{\text{ink pixels in } c}{\text{pixels in } c} \ge \tau, \qquad \tau \approx 0.3 $$
Hand-drawn slopes become charming staircases, physics stays stable, and remixes merge cleanly.
Photon Spectrum: games inside iMessage
This is the part we are most excited about. A separate Node 24 service built on spectrum-ts talks to Photon's iMessage line.
Host taps "Start in iMessage"
│ prefilled text: play d_1a2b3c4d (or: race lvl_world_l1)
▼
Photon bot ──> creates a fresh two-seat room ──> replies with a game card
│
▼
Host forwards the card ──> friend taps it ──> both tap Ready ──> 3, 2, 1, go
│
▼
Results posted back into the chat: "Maya wins! Maya: 41.27s (verified)"
- Commands. The bot understands
play <draft>,race <level> [version],invite <room> <token>andhelp. It only answers recognized commands and never starts a conversation on its own. - Cards that work as launchers. The card is a tappable launcher that opens the game in a compact Messages layout matched to the game's proportions, instead of squeezing a live game into a chat bubble.
- Verified races. For platformer races the server replays each player's inputs through the same simulation core, so a posted time is a verified time.
- Seat transfer. Some players want to start in Messages and continue in Safari. We built a single-use link that is valid for two minutes, lives in the URL fragment so it never reaches server logs, and revokes the old session when it is used.
- Graceful fallback. If a Photon project cannot send app cards, one setting switches the bot to ordinary links that open the same game in the browser.
- Service security. The messaging service authenticates to our API with a separate random secret of at least 32 bytes. Bot requests are idempotent, so a retried message never creates two rooms.
Multiplayer for AI-generated games follows a small contract. Every generated multiplayer game exposes start, input, snapshot, restore, pause and result. Our trusted page owns networking, tickets, controls, readiness and rematches. Player 1 simulates and publishes snapshots, and Player 2 renders them:
$$ \text{bandwidth per room} \;\le\; 48\ \text{KB} \times 10\ \text{snapshots/s} \;=\; 480\ \text{KB/s} $$
Snapshots are checkpointed, so a dropped connection pauses the round and reopening the invite resumes it.
Auth0: accounts without tokens in the browser
We used Auth0 as an ordinary Regular Web Application login with server-side sessions:
- The Auth0 exchange happens on the server through Authlib. Auth0 tokens never reach JavaScript. The browser only holds an opaque,
HttpOnlysession cookie that lasts seven days. We store only a hash of it, so sessions can be revoked. - Playing stays open and creating requires an account. Anyone with a link can play and post race runs. Creating or changing games, drafts, levels and scans requires a signed-in creator.
- CSRF protection. Every state-changing request must come from our own origin or carry a custom header that a hostile site cannot send through our CORS policy.
- Profile linking. Players who started anonymously can link their old device profile to their account, but only after proving they hold that device's token and completing an Auth0 login.
- No Auth0 value is ever shipped in the frontend bundle.
Vultr: one server, everything on HTTPS
The whole product runs on a single Vultr Cloud Compute instance with Docker Compose:
| Service | Role | Public? |
|---|---|---|
web |
Caddy: automatic HTTPS certificates, serves the app, proxies /api, /uploads and WebSockets |
Ports 80 and 443 only |
api |
FastAPI plus two Node 24 simulation workers, with a health check that boots a real level | No |
messaging |
Photon Spectrum service, enabled with a Compose profile | No |
The game database, uploaded art, message queues and certificates live in persistent Docker volumes, and every service restarts after a reboot. The Vultr firewall allows only 80/443 and SSH. Because the website, API and live multiplayer share one HTTPS origin, an iMessage card, a browser invite and a WebSocket all point at the same place. In the app's build-crew view, Vultr is shown storing each piece of art and the finished game as they are produced.
Challenges we ran into
- iMessage is a tiny, unusual browser. A web page cannot resize Spectrum's native container. We designed a compact Messages layout matched to each game's aspect ratio, added an Enlarge mode that fills whatever space the webview allows, and moved from live bubbles to tap-to-launch cards.
- The same player in two apps. Moving from Safari into Messages could occupy the host's seat twice. Fresh bot cards now always leave both seats open, and a seat moves between apps only through the single-use transfer link.
- "It works on my Mac." A
localhostinvite cannot open on a friend's phone. We added authenticated online publishing that uploads the exact room build, including its artwork, to the Vultr server (capped at 12 MiB) and returns a public invitation. - Trusting generated code. AI-written games run in a sandboxed iframe with a strict content security policy: scripts, but no network, storage, navigation or same-origin access. They never see player tickets or invite secrets.
- Schemas the model could not compile. Our first perception schema used a 10-variant union, which the API rejected as too large to compile, every time. We flattened it into one shape and validate each variant on our side.
- Kids draw impossible levels. Gaps that are too wide and goals that cannot be reached are common. The bot playtest and the fixer turn "this doesn't work" into "this gap is too wide", followed by a fix that keeps the drawing's intent.
- Deployment details. A stray AAAA DNS record can break automatic HTTPS, and a small server can run out of memory building the frontend. Both are now documented in our Vultr launch guide.
Accomplishments that we're proud of
- A drawing becomes playable almost instantly. The build is staged so a first version arrives in under a second, and a designed, bot-verified version follows within the 25-second deadline.
- Real multiplayer inside iMessage for both verified platformer races and AI-generated games, with rematches, reconnects and results posted back into the chat.
- Every platformer level is checked by a bot before anyone plays it, and race times are verified by replay.
- It degrades gracefully. Without an API key, starter levels and the deterministic builder still work. Without app cards, the bot sends links. If the model is late, the greedy result ships at the deadline.
- Cost-aware AI. A typical generated game costs about \$0.25, and daily and per-draft budgets keep a public demo from running up a bill.
- Production-grade plumbing in a hackathon: Auth0 sessions, CSRF protection, a sandboxed game runtime, and a one-command Vultr deploy.
What we learned
- Let the model propose and let code decide. Pairing Claude with a deterministic simulator and a bot playtester gave us creativity without broken levels.
- Streaming beats waiting. Showing the first playable version immediately and improving it in place felt far faster than a single slow, perfect result.
- Distribution is a feature. Where a game shows up matters as much as how good it is. Putting the invite inside the group chat removed the last step between making a game and playing it with someone.
- Security choices are cheapest on day one. Keeping tokens off the client and secrets out of URLs was easy at the start and would have been painful to retrofit.
What's next for The Game Factory
- Paper remixing. Print any level in light gray, draw on top of it, scan it, and publish it as a remix that credits the original, with a visible remix tree.
- Handwritten rules. Writing "this platform moves" with an arrow next to it should just work.
- Host-verified multiplayer for generated games, so competitive results are protected the way platformer races already are.
- Group play beyond two players, and tournaments that run entirely in a group chat.
- Classrooms. A teacher prints a sheet, every student draws a level, and the class plays through all of them together.
Sketch it. Build it. Play it.
Built With
- anthropic
- auth0
- gemini
- opencv
- phaser.js
- photon
- python
- typescript
- vultr

Log in or sign up for Devpost to join the conversation.