Partway through the week I noticed I had a lot of unused usage left on my personal Claude account. I wanted to test the new Projects feature in the Claude app, so I picked a small, fun target: a browser game built around my daughter, her dog and her boyfriend. The dog is Bronson, an 80 pound chocolate mix with a yellow collar and a blue harness. The game is free and runs in any browser, on a phone or a computer.

The test
I was not trying to ship a product. I wanted to see what happens when you hand a Project a loose idea and let it run: how far does it get, where does it stall, and what does it cost. I used the Claude app, not Claude Code, so there was no local setup, no terminal and no build pipeline on my side. The code landed in a GitHub repo as it went.
One week, 14 commits
The git history tells the story. Almost everything landed on the first day. The race mode came the next day. After that it was polish and the trailer.
The park
The Lake Haigler Dash course is based on a real park where we walk Bronson. I gave Claude the park's own website, an image of the park map and Google Maps of the park, and it shaped the race trail to follow the real layout, so it feels like somewhere we actually go. The rest of the world is made up. Nothing was imported from map data. The code builds the course from a hand tuned trail curve: the lake is an ellipse, 82 by 56 meters, and the trail has six hills. The dam, the bridges and the 12 race gates are computed from that one trail.
The stack
There is almost none. It is plain JavaScript and three.js (r128, from a CDN with a local fallback). No npm packages. A small build script inlines everything, bark sounds included, into a single 582 KB index.html. About 7,000 lines of source.
Everything you see is generated in code: the dog, the people, the trees, the textures and the terrain. There are no models or images from anywhere else. The music and sound effects are synthesized live in the browser with Web Audio. The only recording is a free (CC0) dog bark, cut into four short clips.



Design choices that mattered
Short chapters, each opening with a card that lists its goals, so a session takes minutes. A turning mini map and a goal arrow so nobody gets lost. Touch controls so it works on a phone. A wardrobe that unlocks by finding one hidden tennis ball per chapter. A photo mode that saves full resolution JPEGs. And Bronson gets bored if you leave him alone: a big stretch, a side scratch, or a long stare into your soul.

The leaderboard
Players type initials only. The scores live in a Cloudflare Worker with a D1 database. IP addresses are never stored, only a salted SHA-256 hash. To keep the board honest the server issues one use run ids, enforces minimum chapter times, rate limits requests, blocks a list of initials and checks the origin. Race runs are validated frame by frame against the course.
Racing ghosts
The Lake Haigler Dash is not live multiplayer yet. It is ghost racing. A best run is stored as 10 bytes every tenth of a second, so a 100 second run is about 10 KB. Other players race those ghosts. Dexter, Morgan and Cookie are starter ghosts the game synthesizes, with target times of 97.4, 111.8 and 87.6 seconds.
The trail has logs, mud, geese, hikers with dogs, a horse and rider, and a deer that spooks and bounds across the path.
Making the trailer
The trailer was a second project. The goal was real gameplay with nothing from the game's own HUD on top, so I captured the game frame by frame with a headless browser at 1080p and 60 frames per second, with the HUD hidden in a throwaway copy of the game. The graphics and edit are built in Remotion. The music came from a prompt, and the narration is a local voice clone of my wife, with her permission, running on my own machine.
It took far more tries than the game did. My first narration was a mess: stutters, clicks and stops mid sentence. The cause was generating the voice one sentence at a time. Generating each line in a single pass, and checking every take with speech to text, fixed most of it. The name "Bronson" took the longest of all, because the voice model kept bending the vowel.
Where it goes next: Deer Chase
The next mode is two player, and I'm calling it Deer Chase for now. Players are picked at random: one plays Bronson and the other plays a deer. Bronson has to chase down and catch the deer, and the deer tries to hide and get away, like hide and seek. The deer already exists in the game as a spooked animal on the race trail, so the character is not new. What is new is a real time connection between two browsers. The leaderboard already runs on Cloudflare, so I expect to stay there, but I have not built it yet.
The plan is Cloudflare Durable Objects, which can hold one match and pass moves between the two players. They used to require the Workers Paid plan ($5 a month). SQLite backed Durable Objects now run on the Workers Free plan with daily limits: 100,000 requests, 13,000 GB seconds, 5 million rows read and 100,000 rows written per day, reset at 00:00 UTC. If the free limits ever get tight, the $5 plan is the fallback, but a small game between friends should stay well under them. These numbers are from Cloudflare's pricing page this week and can change.
So, did it work?
Yes, with caveats. It was a fun little project. Setup was easy, and updating it after people started playing was even more fun. People have been having a blast trying to get to the top of the leaderboard, and the kids seem to enjoy how simple and short it is. That was the goal: an easy, fast game with no frills and no complicated setup.
The graphics could have been better. With more time spent on them I could probably have made them a lot nicer, and I may do that in the future. For now, it's a success.
The game is small enough that one Project could hold the whole thing in its head, and that is probably why it worked. I would not expect the same result on a large codebase.
