Casual Developer

AI Agents Built a Browser MMO in One Day: Auditing All 115 Commits

Claude (Opus 5.5)

Written by Claude (Opus 5.5) and checked by Claude (Fable 5.2), from the game's repo, its notes, dested's journal and the session transcripts. Earlier Claude (Opus 5.5) sessions built the game; dested wrote the prompt, watched and played. The first person below is dested's voice.

On September 27 at 10:10 I opened a Claude session with this prompt: "super open ended task. i dont want to answer any questions, its all up to you lol." By 23:55 the repo had 115 commits and Duskbound, a co-op Diablo-style action RPG in the browser, was in production.

Four days later, describing it for a documentary, I called it "a scalable, battle tested, incredibly well balanced, automation tested piece of art." So I went back through git log and sorted every commit. 38 of the 115 were game code.

The 115 non-merge commits of September 27, sorted by what they changed: 38 touched the game, the rest were timed checkpoints, blog posts, video tooling and docs.
The 115 non-merge commits of September 27, sorted by what they changed: 38 touched the game, the rest were timed checkpoints, blog posts, video tooling and docs.

What ran at midnight

My journal says the day took 5 h 10 m. That's my time: ten-minute windows with at least one of my 61 prompts in them. The agents ran from 10:10 to 23:55, one orchestrating session and up to about 10 Opus 5.5 subagents at once. The first commit landed at 11:59 with 624 files.

Piece State at 23:55
Server Colyseus rooms, server-authoritative sim at 20 ticks a second, one Bun process
World Six acts, each with its own town and biome
Persistence Postgres and Prisma, migrations from 14:27
Endgame Nightmare and Hell difficulties, sockets, 16 runewords, rifts, a ladder
Multiplayer Parties, whispers, shared drops, AI companions
Mobile Touch stick, skill wheel, installable PWA
TypeScript 40,846 lines at 11:59, 99,447 at 23:55
Test files 12 at 11:59, 50 at 23:55

An agent QA pass at 14:17 found and fixed 11 multiplayer bugs, including a stash item duplicated by opening the same hero in two tabs. Level 1 to 4 bots passed the load test. Forty level-99 heroes casting area spells didn't, until a batching fix at 19:30.

The 40-hero showcase in the River of Flame that night: one rendered camera client and 39 headless bots, not 40 people.
The 40-hero showcase in the River of Flame that night: one rendered camera client and 39 headless bots, not 40 people.

A third of the day was game code

Kind Commits
Game features 23
Game fixes 15
Checkpoints (30 timed, 1 manual) 31
Blog: 21 posts and the /blog route 27
Devlog and video tooling 12
Docs and deploy config 7
Total 115

Every fix fixed something written that day, because the repo didn't exist that morning. Act 1 on Normal was lethal until 17:55. Beating the Act 3 boss opened Nightmare, three acts early, until 19:55. Five pet models shipped missing until 21:51.

Four of the 15 fixes weren't new work. Two were the same change committed twice, once to master and once to the release branch. Two kept the blog's files out of Tailwind's source scan, first the markdown, then public/ and trailer/ "too".

Commits per hour on September 27. The busiest two hours were mostly blog posts.
Commits per hour on September 27. The busiest two hours were mostly blog posts.

The commit messages describe work the diffs don't hold

The agents shared one tree, and an auto-checkpoint committed it every 20 minutes. The descriptive commits came after.

038aeee, "feat: endgame — Nightmare/Hell, sockets/gems/runes + 16 runewords…", inserts 732 lines. 615 of them are the trailer's bun.lock. The runewords had landed 45 minutes earlier in 14cd490, "wip: auto-checkpoint 15:17 (agents in flight)", a commit of 18,932 lines across 281 files.

After the first commit, 56,330 of the 71,118 lines inserted under server/, shared/ and src/ (79%) arrived in auto-checkpoints. For most of the day's code, the commit that added it is titled with a timestamp.

What the next three days found

Bug in day-one code Fixed Commit
Every deploy showed players "Logged in elsewhere" and left them out Sep 29 33abd0f
30,411 tiles you could walk through, houses included Sep 29 d822283
226 snap-backs in a lag test of click-to-move Sep 29 ec41ba9
Once a shop was open, buy, sell and stash worked from anywhere Sep 28 2eb972d
Travel markers piled up, about 50 glow cards leaked per zone change Sep 29 bda2d43

The deploy bug is the one to steal. The first commit ended sessions with close code 4001 for "logged in elsewhere" and 4003 for an admin kick. Colyseus owns 4000 to 4010: it sends 4001 on a graceful shutdown and 4003 when a reconnect fails. Every push to master deploys, so every deploy told every player they'd logged in elsewhere, and the client believed it. That ran from the first commit until 01:58 on Sep 29.

The walk-through tiles came from prop footprints typed by hand in the first commit, which never looked at the models. The snap-backs came from two path planners, one on the client and one on the server, that sometimes went around an obstacle different ways.

The fixes had follow-ups of their own. The snap-back fix added a catch-up step that made the touch stick read as standing still on WebKit, so on an iPhone the hero flipped to idle on most moves (c228e0c, Sep 30). Websocket compression, added on Sep 28 for bandwidth, killed Safari's sockets a second after every zone join (662f8cb, Sep 30).

What I'd put in the brief next time

Players reported the snap-backs, I walked through a house, and an agent hit the deploy bug while chasing a different error. Each was fixed within hours once something could measure it: a lag proxy that counts snap-backs, a collision audit against the rendered models, and a restart of the production build with players connected. Next time those three go in the first brief, ahead of the blog.

To audit your own agent day, count the checkpoints and see where the code went:

SINCE=2026-09-27T00:00-07:00; UNTIL=2026-09-28T00:00-07:00

git log --no-merges --since=$SINCE --until=$UNTIL --format=%s | grep -c auto-checkpoint

git log --no-merges --since=$SINCE --until=$UNTIL --format='>%s' --numstat |
  awk '/^>/ {ck = /auto-checkpoint/; next}
       NF == 3 && $1 != "-" && $3 ~ /^(server|shared|src)\// {if (ck) c += $1; else n += $1}
       END {print "checkpoint lines", c, "named lines", n}'

And if you use Colyseus, grep your server for leave(40. Anything from 4000 to 4010 is already taken.