How I Built Numerator Using Claude
A non-developer builds a full-stack web game from concept to deployment in four sessions
Ingredients
- Claude.ai — AI pair programmer and game designer ($200/yr)
- Supabase — PostgreSQL database for storing every guess globally (free)
- Vercel — hosting platform and auto-deploy pipeline (free)
- GitHub — code repository, Vercel auto-deploys from it (free)
- Next.js — the React framework running the site and API routes (free)
- VS Code — code editor for making changes locally (free)
- Node.js / npm — runs the dev server and manages packages (free)
- Terminal — where you type commands to navigate, install, and deploy (free)
- HTML Canvas — renders the shareable result card as a downloadable PNG (free)
The Idea: A Game Nobody Could Google
There’s a classic game theory puzzle that goes like this: a large group of people each pick a number between 0 and 100. The winner is whoever guesses closest to 50% of the group’s average. The catch: if everyone thinks the answer is 50, the optimal guess is 25. If everyone thinks it’s 25, the optimal guess is 12. The right answer is always moving — it depends on what you think everyone else is thinking.
I’d read about this puzzle and wanted to play it for real, with real players, where the correct answer shifts every time someone new guesses. No app existed for this. It was a logic exercise that lived in economics textbooks but never became a game you could share with a link.
So I built it.
Session 1: Game Design and Prototype
Pace: Deliberate. Lots of back-and-forth on game logic, then fast execution.
Before writing any code, Claude asked seven clarifying questions to lock down exactly how the game should work — rules, edge cases, how streaks are counted, what happens when the cycle resets. Ten minutes of conversation caught a critical typo in the spec and saved hours of rework later.
🔧 Developer section: Spec clarifications
- Caught a typo in the spec — I'd written "30% correct answer" instead of 50%, which would have broken the entire game
- Clarified that "in a row" means consecutive perfect matches checked against the new average (which shifts with every guess)
- Confirmed guesses persist across all visitors as a shared global pool, not per session
- Asked whether the "within 5" retry path could lead into the streak win — answer: no, only a first-round perfect match starts the legendary path
With the rules confirmed, Claude generated a fully playable game from the description alone — animations, five distinct outcomes depending on how close your guess is, and a shareable result card. Everything ran in the browser immediately, no database connected yet.
🔧 Developer section: Prototype features
- Intro screen with participant count and cycle progress indicator
- Number input with a 2.5-second flywheel calculating animation
- Five outcome paths — perfect match, within 5 (3 retries), within 10, far away, and not enough data
- Arcade-style GAME OVER screen with "INSERT COIN" blink effect
- Legendary CHAMPION win screen with falling sparkle particles for 3 perfect matches in a row
- Canvas-rendered share card (Wordle-style blocks, stats, downloadable PNG via HTML Canvas)
Then came the tuning. Over five rounds of feedback I adjusted colors (swapped orange to the site's signature #F3D104 in Claude), rewrote outcome messages, improved text readability against the dark background, and fixed a bug where the correct answer wasn't recalculating between rounds.
Spend the time getting the spec right before any code gets written. Claude asked seven clarifying questions — one caught a typo (30% vs 50%) that would have broken the entire game. A 10-minute conversation saved hours of rework.
Session 2: Database and Deployment
Pace: Moderate. Database setup was new territory, but deployment was one click.
The prototype was single-session — close the tab and the data reset. Making guesses persist across all visitors required a real database. Claude recommended Supabase (a free, hosted database service) and generated the entire setup as a single block of code to paste and run in Supabase’s web dashboard.
🔧 Developer section: Supabase database setup
- Created a free Supabase project named
numerator— chose a region and set a database password - Pasted Claude's SQL into the Supabase SQL Editor — created two tables (
guessesfor every guess ever made,cycle_statefor tracking the 300-guess rotation) - The same SQL block created Row Level Security policies (anyone can read and insert, nobody can tamper) and two server-side functions (
submit_guessandget_game_state) - Copied the Project URL and anon public key from Supabase Settings → API
With the database ready, Claude generated the files that connect the game to it and packaged everything for deployment. Three steps in the terminal later — install dependencies, push to GitHub, click deploy on Vercel — the game was live at its own URL in under a minute.
🔧 Developer section: Next.js integration and Vercel deployment
- Ran
npm installin Terminal to install dependencies, thennpm run devto test locally atlocalhost:3000 - Pushed to GitHub with
git init,git add .,git commit, andgit pushin Terminal - Imported the repo on Vercel, added the two Supabase environment variables, clicked Deploy — live at
numerator-three.vercel.appin under a minute
One push to GitHub → Vercel auto-deployed → game live in under a minute.
Supabase's SQL Editor is your best friend. Claude generated the entire schema, security policies, and server functions as one SQL block. Paste, run, done — no database configuration UI to learn.
Session 3: Integrating into JoseAndGoose.com
Pace: Bumpy. A hidden Git issue turned a simple copy into a debugging puzzle.
Moving the game into joseandgoose.com should have been a simple file copy — same framework, same hosting platform. What looked straightforward hit a hidden issue where Git (the version control system) was tracking the game folder as a reference to another project rather than actual files, making the page invisible to Vercel after deployment.
🔧 Developer section: Integration steps
- Ran
npm install @supabase/supabase-jsin Terminal to add the Supabase package to the existing site - Created
lib/supabase.ts,app/api/guess/route.ts, andapp/api/state/route.tsusingcatcommands in Terminal - Downloaded the game component
page.tsxfrom Claude and moved it intoapp/numerator/using Finder - Created
.env.localwith the Supabase credentials in Terminal - Tested locally with
npm run dev— game loaded atlocalhost:3000/numerator
Pushed to GitHub, Vercel deployed — and the page returned a 404. The build log showed every route except /numerator, plus a warning: "Failed to fetch git submodules."
- Ran
git ls-files app/numerator/in Terminal — it returnedapp/numerator(a directory reference) instead ofapp/numerator/page.tsx(the actual file) - Root cause: when the standalone numerator project (which had its own
.gitfolder) was dragged into the site, Git tracked it as a submodule — invisible to Vercel - Fixed with
git rm --cached app/numeratorthengit add app/numerator/page.tsxin Terminal to track it as a proper file - Pushed again — Vercel rebuilt,
joseandgoose.com/numeratorloaded
Removed the submodule ghost, re-added the actual file, pushed — Vercel built /numerator this time.
If Vercel says "Failed to fetch git submodules" and your page 404s even though the files are in VS Code — run git ls-files on the folder in Terminal. If it returns a directory name instead of file paths, you have a submodule ghost. Fix it with git rm --cached then git add the actual files.
Session 4: Navigation and Mobile
Pace: Fast design iteration, then a surprise dev environment bug at the finish line.
Once the game was live at its URL, the next problem was discoverability — no link to it existed anywhere on the site. Adding a nav button also revealed that the site navigation was duplicated across seven separate page files, which meant a quick button addition would become a maintenance problem without a bigger fix.
🔧 Developer section: Navigation button and mockup iteration
- Previewed the button mockup in the browser — a yellow
#F3D104pill-shaped button next to Contact - Three rounds of feedback in Claude — centered the text, tightened the padding, reduced the font 25% until the button felt right
- Discovered the nav was hardcoded in every single page file — seven
.tsxfiles with the same HTML block in VS Code - Used VS Code's Find and Replace across files (
Cmd + Shift + H) to add the button to one page, but only 1 of 7 files committed
Rather than duplicate the button across all seven page files, Claude converted the navigation into a shared component — one file that renders on every page automatically, and which also added a mobile hamburger menu the site had never had before.
🔧 Developer section: Shared Nav component
- Created
app/Nav.tsxas a shared "use client" component with desktop nav links, the yellow button, and a hamburger toggle - Updated
app/layout.tsxin VS Code to import and render<Nav />before the page content - Added hamburger animation CSS (three spans that rotate into an X) and mobile dropdown styles to
globals.css - Deleted the old
<header>blocks from all seven page files in VS Code
The last surprise was a dev environment bug. Running npm run dev in Terminal flooded the screen with infinite "Can't resolve tailwindcss" errors:
- The Next.js startup warning said "multiple lockfiles detected" — it found a stale
package-lock.jsonin the home directory from an earlier project - Next.js inferred the wrong workspace root and looked for Tailwind in the Desktop folder instead of the project folder
- Fixed by running
rm -rf node_modules .nextthennpm installin Terminal for a clean reinstall - Dev server started cleanly — nav with hamburger confirmed at
localhost:3000in the browser
Clean install fixed the tailwind lockfile conflict — no more infinite error loops.
If your Next.js dev server floods errors about missing packages, check the startup warning for "multiple lockfiles detected." A stale package-lock.json in a parent directory can hijack your entire workspace in Terminal. Delete it and run a clean npm install.
Final Output
A live multiplayer game theory puzzle at joseandgoose.com/numerator with a PostgreSQL database storing every guess across all visitors, a 300-guess cycle that resets the running average, five distinct outcome paths, a legendary win screen for 3 perfect matches in a row, a canvas-rendered shareable result card, responsive mobile navigation with a hamburger menu, and auto-deployment from GitHub — built in about 8–10 hours by someone with no prior backend development experience, guided entirely by Claude.
What went fast
- Game prototyping in Claude.ai (full playable loop generated from a text description in minutes)
- Supabase database setup (one SQL block pasted into the dashboard — tables, security, and functions created instantly)
- Vercel deployment (one
git pushin Terminal → live URL in under a minute, every time) - Design iteration (Claude generated HTML mockups for the nav button — preview in browser, adjust, approve, then build)
What needed patience
- Git submodule ghost (dragging a project folder with its own
.gitinto another repo created an invisible tracking error — a 45-minute debugging detour in Terminal) - Tailwind lockfile conflict (a stale
package-lock.jsonin a parent directory caused infinite error loops — solved by deleting the file and a cleannpm install) - Hardcoded nav across 7 files (a maintenance problem discovered in VS Code that forced the creation of a shared
Nav.tsxcomponent — the right fix, but more work upfront) - Game logic tuning (five rounds of feedback in Claude on outcome messages, colors, text readability, and a recalculation bug)
The biggest lesson? Building a game isn't one skill — it's a dozen small ones stacked vertically. Game design. Database architecture. API routes. Git debugging. CSS responsive design. Claude handled the code. I handled the decisions. And the correct answer is still 50% of whatever everyone else is thinking.