The party game that gets wild. Every round a new daring task lands on your phone — complete it, earn points, outlast your friends. No accounts, no installs. Share the link or scan the QR.
Do your best catwalk across the room.
Wildround is for groups of friends who want to do something more than stare at their phones. It puts everyone's phone to work — each player gets a unique daring task every round and has a countdown to complete it. Points for doing it, a penalty for skipping. The player with the most points when the timer runs out wins.
There are no complicated rules to explain. The host creates a game, everyone scans the QR code or types the six-letter code, and the game begins. It works at a bar, at a party, at a dinner table, at a festival — anywhere a group of people wants to be challenged.
Wildround's source code is kept private. The game is free to play — no account, no ads.
When the game starts, each player receives a unique task on their screen with a countdown timer. Read it, do it, tap Done! for +100 points. If you can't or won't do it, tap Skip for −30 points. The task expires automatically when the timer hits zero — that also counts as a skip.
After completing a task you get a brief moment to rate it (fun / boring). Then you wait for the next round. The scoreboard at the bottom updates live as everyone resolves their tasks.
The player with the most points when the game ends wins. Results show a podium, full standings, and a highlights reel of submitted notes from completed tasks.
Every group has those games — the ones that require a deck of cards, a printed sheet, or at least someone who remembers the rules. Wildround was built to remove all of that. A phone in everyone's pocket is already a personal game device. The only missing piece was software that treated it that way: a real task on your screen, a real timer, real stakes in the form of points your friends can see.
The core challenge was game state synchronisation. With 6+ players each completing different tasks at different times, the server needs to maintain a consistent view of who has which task, what round each player is on, and what the scoreboard looks like at any given moment. Claude Code built the full Socket.IO event model — game:join, game:start, task:assigned, task:complete, task:reject, score:updated, game:ended — with the corresponding DB writes handled inside each event.
The task assignment system was designed to avoid repetition: each player tracks which task IDs they've already seen in a given game and only receives tasks from the remaining pool. With 101 tasks in the seed database, most games never exhaust the pool even in long sessions.
Game recovery was one of the harder problems. If the server restarts while a normal-mode game is running, the in-process timers are gone. The recovery function, added during the production hardening pass, queries active games on startup, calculates how many rounds have elapsed based on wall-clock time, expires stale assignments, issues fresh tasks for the current round, and resumes timers from the correct offset.
"The per-task countdown is the heartbeat of the game. Getting it to sync correctly between the client (which runs its own local timer) and the server (which tracks assignment timestamps) was the most detail-intensive part of the build."
The task pool is managed through a password-protected admin panel at /tasks. Anyone can suggest a task through the public suggestion form — it lands in a pending queue. The admin reviews, adjusts difficulty, and approves or rejects. Tasks that rate poorly in post-game feedback get surfaced for re-evaluation. It's a lightweight content pipeline that doesn't require a CMS.
The full stack — React client, Express server, and SQLite database — runs in a single Docker container on Fly.io. A persistent volume stores the database across deploys. The free tier covers everything: the machine is always-on (no cold starts, important for WebSocket connections), and the volume is encrypted and snapshot-backed.
Monorepo with three packages: client (React SPA), server (Express + Socket.IO), and shared (TypeScript types). In production, the server builds and serves the client bundle as static files — one container, one origin, no CORS.
All game state is stored in SQLite via Drizzle ORM. The schema is straightforward: games, players, tasks, and game_task_assignments. The assignments table tracks which task each player received in each round, their outcome (completed / rejected / expired), any submission note, and a post-game rating. This makes it easy to compute aggregate task quality metrics over time.
Socket.IO rooms map 1:1 to games (game:{id}). Score updates are broadcast to the whole room; task assignments are sent directly to the individual player's socket. In-process Maps track active game timers and per-player round counters — these are rebuilt on startup by recoverActiveGames().
SQLite + Fly.io persistent volume. The database file lives at /app/server/data/wildround.db, which is mounted from an encrypted Fly.io volume. Tasks are seeded automatically on first startup. Redeploys don't touch the volume — all game history, task ratings, and suggestions persist across container swaps.
The source code for this project is kept private. The game itself is completely free to play — no account, no ads, no cost.
Got thoughts?
Played a game? Have a task idea or feedback? Drop it here — no account needed.