Simon Willison just published a detailed breakdown of using Claude Fable 5 to autonomously build a complete browser game from a single prompt. The post includes full transcripts, commit history, and candid assessment of where agents excel (implementation) versus fail (game design). It’s a rare public artifact showing agent decision-making, testing strategy, and failure modes in a contained creative project.
The experiment: dump two DALL-E screenshots and a text description into Claude Code for web, tell it to build a 3D browser game, then walk away. No further design input. The result is a working Three.js game with procedural audio, self-generated textures, and autonomous Playwright tests. The game itself is mediocre. The infrastructure choices are fascinating.
The GitHub Pages Preview Loop
Willison’s setup creates a continuous preview environment that changes how agents iterate. Here’s the flow:
- Create a GitHub repository (public or private).
- Start a Claude Code session and tell it to commit an
index.htmlas quickly as possible. - Navigate to Settings → Pages, select the Claude branch, hit Save.
- Within 30 seconds of each push, the latest content is live at
yourname.github.io/your-repo/.
This tight feedback loop means the agent can see its own work without waiting for human approval or manual deployment. Claude made 7 commits autonomously, each one visible in the browser within half a minute. The agent could visually verify changes, spot bugs, and iterate without blocking on external review.
Why this matters: Most agent workflows rely on local execution or sandboxed environments. GitHub Pages turns every commit into a live artifact. The agent can share URLs, test on real devices, and treat deployment as part of the build loop rather than a separate release step.
Self-Initiated Playwright Testing
Claude decided on its own to write Playwright tests. It wasn’t told to do this. The agent wrote smoke tests for desktop, portrait-phone, and landscape-phone viewports, then used them to catch two real bugs:
- 2× canvas sizing on mobile: A
cssTextassignment wiped Three.js’s inline sizing. Desktop DPR-1 tests masked the issue completely. - Full-screen CSS inheritance: The win screen’s star-rating div inherited the title screen’s
.starsCSS, silently swallowing every tap on the “next night” button.
Here’s a snippet from the dog-tracking test:
// walk near the dog
await page.evaluate(() => {
const d = window.__rh.dog;
window.__rh.teleport(d.x + 6, d.z);
});
await page.waitForTimeout(2000);
info = await page.evaluate(() => JSON.stringify({
dog: window.__rh.dog,
state: window.__rh.state,
player: window.__rh.debug().player
}));
console.log('after approach:', info);
await page.waitForTimeout(3000);
info = await page.evaluate(() => JSON.stringify({
dog: window.__rh.dog,
state: window.__rh.state
}));
console.log('after chase:', info);
await page.screenshot({ path: __dirname + '/shot-dog.png' });
The agent exposed internal game state via window.__rh hooks, then used those hooks to teleport the player, trigger chase logic, and verify state transitions. It took screenshots to visually confirm rendering.
What this exposes: Agents can choose their own verification strategies when given autonomy. Claude picked Playwright because it needed to test browser rendering, not just logic. It structured test hooks without being told the format. The failure mode is that desktop tests didn’t catch mobile bugs, which suggests agents don’t yet reason well about cross-device state space.
Cross-Vendor Tool Orchestration
Willison gave Claude an OpenAI API key and told it to use gpt-image-2 for texture generation. Claude wrote its own gen_textures.py script, generated images, and spot-checked them before applying them to 3D models.
Here’s the prompt Claude used for the title screen:
Video game key art, low-poly 3D render style, moody nighttime scene: a cute low-poly raccoon wearing a tiny black burglar mask sneaking on its hind legs carrying a glowing gold coin, next to a tipped-over metal trash can, suburban house with warm glowing windows in the background, deep blue night, full moon, fireflies, cinematic rim lighting, charming heist caper mood. No text, no words, no logos.
The agent called OpenAI’s image API, evaluated the result (“gorgeous”), and committed the asset. At runtime, the deployed game makes zero API calls. All textures and the title screen are pre-generated static assets.
Why this matters: Agents can orchestrate tools across vendor boundaries without explicit integration code. Claude used Anthropic’s reasoning to call OpenAI’s image model, then vendored the output. This pattern (call external API during build, ship static assets) avoids runtime dependencies and API rate limits in production.
Commit Cadence and Logging
Claude made 7 commits without being told how often to commit. It also maintained a notes.md file, appending to it with each commit. Here’s the entry when it added the guard dog:
New escalation: from night 3 the yards get a patrolling guard dog — a low-poly brown hound with a spiked red collar and a wagging tail. It wanders between random spots, and within 12 units it catches your scent and tracks you by smell (line of sight is irrelevant — it’s all nose, shown by a 👃 over its head and barking). It gives up if you open a 17-unit gap. Getting caught messages are now source-specific: guard / headlights / hound. Verified wander → track → caught with an automated test.
The agent documented its own design decisions, implementation details, and test coverage. It chose to log state transitions, distance thresholds, and emoji indicators without being told the format.
What this exposes: Agents can maintain their own audit trails when given a logging target. The notes.md pattern creates a human-readable changelog that tracks reasoning, not just code changes. The failure mode is that the log is optimistic (it says “verified” but mobile bugs slipped through).
Architecture Comparison
| Component | Choice | Rationale | Trade-off |
|---|---|---|---|
| 3D engine | Three.js (vendored) | No CDN dependency, full offline support | 600KB bundle size |
| Audio | Procedural WebAudio | Zero audio files, runtime synthesis | Limited musical complexity |
| Textures | Pre-generated via OpenAI | No runtime API calls, static assets | Build-time dependency on external service |
| Testing | Playwright (self-initiated) | Real browser rendering, screenshot verification | Missed mobile-specific bugs in desktop tests |
| Deployment | GitHub Pages | 30-second preview loop, no CI config | Public visibility for private repos (name-guessable) |
| State logging | notes.md append-only | Human-readable audit trail | No structured schema, optimistic reporting |
Failure Modes
Mobile rendering bugs: Desktop Playwright tests ran at DPR-1, which masked a 2× canvas sizing issue on real phones. The agent’s test suite didn’t cover device pixel ratio variance.
Game design quality: The agent built a working game but failed to make it fun. Willison’s assessment: “It’s an impressive starting point, but it’s not a good game.” The raccoon team mechanic from the original prompt was ignored (the two crew raccoons are static decoration). Levels have fixed duration, so you collect all items and then wait for dawn with nothing to do.
Test coverage gaps: The agent verified wander → track → caught flows for the dog, but didn’t catch the full-screen CSS inheritance bug that broke the “next night” button. Automated tests passed, manual testing found the issue.
Technical Verdict
Use this pattern when:
- You need a tight preview loop for agent-driven web projects (GitHub Pages + frequent commits).
- You want agents to choose their own testing strategies (give them Playwright and autonomy).
- You’re building static sites with pre-generated assets (call external APIs at build time, ship flat files).
- You need cross-vendor tool orchestration (one LLM calling another vendor’s API).
Avoid this pattern when:
- You need production-grade game design (agents excel at implementation, fail at fun).
- You require comprehensive cross-device testing (agents don’t yet reason well about mobile-specific state).
- You need structured audit logs (append-only markdown is readable but not queryable).
- You’re working with private repos and can’t tolerate name-guessable URLs (GitHub Pages exposes content to anyone who knows the repo name).
The real insight: agents can now manage their own build-test-deploy loops with minimal scaffolding. The GitHub Pages preview pattern and self-initiated Playwright tests show that agents can structure their own feedback cycles when given the right primitives. The gap between technical execution and product quality remains wide.