Sommelier Arena
A real-time blind wine tasting quiz β Kahoot-style, β¬0/month to host, zero cold starts.
How it worksβ
A host creates a tasting with one or more wines. Each wine gets five questions (color, region, grape variety, vintage year, wine name). Participants join via a 4-digit code on their phone, answer live as the host controls the pace, and compete on a leaderboard.
Everything runs on Cloudflare: the frontend is a static Astro site on Cloudflare Pages; the game backend is a PartyKit Durable Object (Cloudflare Workers); session lists are stored in browser localStorage.
Core conceptsβ
- Session β a single game instance, identified by a randomly generated 4-digit numeric code (e.g.
4821). - Round β one wine. Each round has exactly 5 questions played back-to-back. The leaderboard is shown after all 5 questions, before the next wine begins.
- Question β one of the 5 fixed-category questions for a wine:
color,region,grape_variety,vintage_year,wine_name. The host pre-fills the correct answer and 3 distractors.
Key rulesβ
| Rule | Value |
|---|---|
| Max players | 10 (lobby rejects extra joins) |
| Questions per wine | 5 (fixed categories) |
| Timer per question | Configurable 15β120 s (default 60 s) |
| Scoring | 100 pts correct Β· 0 pts wrong/unanswered |
| Answer changing | Allowed until host reveals β no first-tap lock |
| Mid-session joins | Not allowed once first round starts |
| Persistence | DO storage (SQLite) in production; in-memory in local dev |
What's new in v2.0 (PartyKit)β
- Zero cost, zero cold starts β Durable Objects wake on demand
- Session persistence β create Monday, resume Wednesday
- Participant rejoin β page refresh or URL (
/play?code=X&id=PSEUDONYM) reconnects automatically, even from a different device - Host identity dashboard β see all your past and active sessions from one device
- Five questions per wine β added
wine_namecategory - Configurable timer β 15β120 s slider at session creation
- No-lock answers β participants can change their answer until the host reveals
- 2 Γ 2 option grid β cleaner layout on mobile
Who are you?β
| I am⦠| Start here |
|---|---|
| A developer setting up locally | Quick Start |
| A developer understanding the system | Architecture Β· Tech Stack |
| A product person / user | Features Β· Gameplay Workflow |
| An admin managing answer data | Quick Start β see /admin page |
| Deploying to Cloudflare | Deployment Guide |
| An automation agent / AI | For Automation |
Quick referenceβ
| Doc | What it covers |
|---|---|
| Quick Start | Run locally in under 2 minutes |
| Architecture | Repo layout, runtime communication, DO lifecycle |
| Tech Stack | Stack choices and design principles |
| Gameplay Workflow | Phase machine, event flow, answer/scoring rules |
| Event Reference | All WebSocket message types (client β server) |
| Host & Participant Identity | TANNIC-FALCON-style IDs, session dashboard, rejoin for host and participant |
| Data Persistence | DO storage keys, KV schema, what survives a restart |
| Deployment Guide | Cloudflare Pages + PartyKit + Wrangler deploy |
| Configuration & Environments | Env vars, local vs prod, nginx explanation, testing preview |