← Back to Blog
β€’14 minβ€’Foad Kesheh

Replicating Fable with Opus: How a One-Line Prompt Built a 3D Game (and What It Taught Us About Prompting)

We asked Fable 5 to build a detailed 3D medieval survival RTS in one shot. Ninety minutes later we had an 11,826-line game β€” and a surprise: 94% of it was written by Sonnet, not Fable. Here is how the magic actually works, and how we replicated it with Opus.

AICoding AgentsMulti-AgentOrchestrationThree.jsClaude

The one-line prompt that built a game

It started as an experiment, not a project. On a personal Claude account, with maximum reasoning effort enabled, I typed a single sentence:

"Create a medieval survivor game, RTS format, lots of resources, farms, foods, everything very detailed, 3D."

That was the entire brief. No design doc, no file list, no architecture. I walked away.

Ninety minutes later I came back to a complete, playable, browser-based 3D medieval survival RTS. Not a demo. Not a gray box on an empty plane. A game with a rolling terrain, day/night cycle with visible stars, clustered forests, a working economy β€” gather wood and stone, farm wheat into flour into bread, hunt deer, raise an army β€” and ten escalating night raids you have to survive or lose your town hall.

The final tally: 38 TypeScript files, 11,826 lines of code (10,591 TS, 1,085 CSS, 150 HTML). One shot. No human-written game logic.

The original Fable 5 build, running on desktop β€” a complete 3D medieval survival RTS produced from a single sentence.

It is not just a video β€” the original build is playable right here in your browser:

My first reaction was the obvious one: "Fable 5 is incredible." But then I did something that changed the whole conclusion. I opened the repository and read how it had been built.

The surprise: 94% of it was Sonnet, not Fable

When you watch an autonomous agent produce a game in 90 minutes, the natural assumption is that the headline model did all the heavy lifting. It didn't.

Reading the git history and the orchestration artifacts, here's what Fable 5 actually wrote with its own tokens:

  • Three source files β€” a frozen type contract, a balance-data file, and a mesh-primitive helper library.
  • One workflow script β€” the orchestration that builds everything else.
  • A couple of planning documents.

That's roughly 754 lines of code for the three contract files β€” about 6% of the final codebase. The remaining 94% β€” every entity, every system, every building mesh, the UI, the game loop β€” was written by Sonnet 4.6 subagents that Fable spun up and coordinated.

It used no git worktrees. The entire concurrent build ran against one shared tree, kept safe not by isolation but by contract. And the implementation phase was over 90% Sonnet-powered.

That reframes the achievement entirely. The question stops being "how good is Fable at writing games?" and becomes the far more useful: "how good is Fable at prompting Sonnet to write games?" Because that skill is transferable. You can copy a prompt. You cannot copy a model's weights.

Plan by writing the contract, not a document

The most important design decision Fable made is one most teams get wrong. It did not produce a written plan, a /plan artifact, or a design doc for approval. The "plan" was code β€” three decisive files, committed before a single build agent ran, and then declared immutable.

FileLinesRole in the plan
src/types.ts366The entire type contract β€” IGameCtx, IUnit, IBuilding, IResourceNode, IEnemy, every service interface, and a single typed EventPayloads map keyed by an event-name union. A mistyped or invented event name simply fails to compile. Immutable.
src/config/gameData.ts266All balance: building/unit/enemy stats, the 10-wave schedule, upgrades, trades, world constants. Frozen during the build. Because all design lives in data rather than logic, balance can be retuned without touching a single code path.
src/meshes/common.ts122The shared low-poly vocabulary β€” box(), cyl(), cone(), sphere(), place(), a color PALETTE, a bakeGroup() draw-call merger, and a seeded rng(). So all the art would look like it came from one hand.

Those 754 lines governed all 11,826. The genius is in what they remove: design authority from the implementers. Eight agents writing code blindly and in parallel could only ever meet in one place β€” a contract they were forbidden to change. Interface drift, the classic failure mode of parallel work where eight workers invent eight incompatible versions of the same boundary, became structurally impossible.

Eight non-overlapping modules

The codebase was cut into eight file-groups, drawn so that no two agents would ever touch the same file. Every cross-module reference resolved through types.ts; concrete class imports were allowed only where the contract explicitly named them.

  • core β€” eventBus, input, cameraController, sound
  • world β€” noise, terrain, water, grid, dayNight, worldGen
  • meshes-buildings β€” props, buildings
  • meshes-units β€” units, fx
  • entities β€” entity, resourceNode, building, unit, enemy, animal
  • systems β€” pathfinding, combat, waves, production
  • ui β€” index.html, styles, hud, buildMenu, selectionPanel, minimap, messages, overlays
  • game β€” the integrator: game, selection, commands, placement, main

Each group went to one implementer agent. Every agent received the same two preambles β€” a RULES block and a full CONTRACT spec β€” and then its own module brief. Here is the RULES block, verbatim:

# Project rules (apply to every file you write)
- Repo root: /Users/fkesheh/medieval. All paths below are relative to it.
- TypeScript STRICT mode. Never use "any" (use precise types or "unknown" +
  narrowing). Named exports only. No default exports.
- Import three as: import * as THREE from 'three'. Relative imports between
  src files (e.g. import type { IGameCtx } from '../types').
- FIRST read these three contract files. They are FINAL β€” never modify them:
  src/types.ts, src/config/gameData.ts, src/meshes/common.ts.
- Implement interfaces from src/types.ts EXACTLY (names, signatures, semantics).
- Create ONLY your assigned files. Other modules are being written in parallel
  by other agents against the same contract β€” import from their documented
  paths and trust the documented exports.
- Do NOT run npm, tsc, vite or any dev server (node_modules may be mid-install;
  a later phase compiles). Write careful, complete, production-quality code with
  zero TODOs and zero placeholder stubs.
- Code comments: only where a constraint is non-obvious. No narration comments.
- This is a real, finished game, not a demo: handle edge cases (empty selection,
  depleted nodes, dead targets, no path found, unaffordable costs).

Notice what this does. Every agent trusts documented exports it cannot see yet, because the contract guarantees they exist. Every agent is told it is building a finished product, not a prototype β€” which is why you get edge-case handling instead of stubs.

The build workflow: six phases, one script

The plan didn't stop at "write the code." A single orchestration script encoded six phases β€” a fan-out to build, then an adversarial gauntlet to harden:

  1. Implement β€” eight module agents (Sonnet) build simultaneously against the frozen contract. Zero shared files.
  2. Compile β€” run tsc --noEmit; a cheap Haiku reporter groups errors by file; up to eight Sonnet fixers repair them in parallel. Loop ≀ 6 rounds until the typechecker is silent.
  3. Review β€” five reviewers (Sonnet), each with a distinct lens, hunt for integration and runtime bugs.
  4. Verify β€” each serious finding goes to an independent skeptic whose default verdict is "not a real bug." The burden of proof is on the finding; the verifier must quote the exact misbehaving code path to assert it's real. This kills false positives.
  5. Fix β€” confirmed bugs grouped by file, one fixer per file so edits never collide. 15 real bugs repaired.
  6. Gate β€” tsc --noEmit && vite build must both pass. It passed on the first attempt (~647 kB JS, ~168 kB gzip).

The five review lenses were deliberately diverse β€” lifecycle (game loop & entity lifecycle), economy (gather β†’ build β†’ farm β†’ food), combat (damage, towers, wave timing), ui-wiring (DOM ids & constructor args), and visual (meshes, shadows, hot-path allocations). Review and Verify were pipelined, not sequential: each lens's findings were verified the moment that lens finished, so the slowest reviewer never stalled the fastest one's verification.

One subtle but important detail: the whole pipeline ran on Sonnet, with a single Haiku reporter β€” six Sonnet roles plus one cheap Haiku step. Cost was tiered to the difficulty of the task, not flattened to the most expensive model.

Where the magic actually lives: the prompt, not the model

Here is the finding that matters most, and it only emerged when I re-ran the experiment with different seeds to compare.

I built two more versions of the same idea with the same orchestration approach but different contracts, and compared them against the original. All three were implemented by Sonnet agents β€” no human wrote a line of any of them; the only code Fable authored itself in each was the small scaffold. So any difference in visual quality is not a model-capability difference. It comes entirely from where the art direction was written.

The original's seed gave Sonnet a vocabulary β€” a palette, primitives, a bakeGroup(). But the seed contained none of the ~3,900 lines of visual code. Sonnet wrote all of it, guided by the CONTRACT prompt, which hand-specified the look of nearly every file. Read these excerpts verbatim and you'll see the difference:

"DETAILED and distinctive, 15-40 primitives each… townhall = grand two-story timber-framed hall, stone base, banners, torch posts; house = cottage w/ thatched roof + chimney…"

"warm dawn, golden dusk, deep blue night with visible stars… a Points starfield only visible at night… small glowing sun & moon sphere meshes orbiting the sky."

"VERTEX COLORS: sandy near water level, grass greens with noise-driven dirt patches, gray rock on steep slopes…"

And the module brief for the building-mesh agent literally framed the job as a craft:

"Focus: this is the art department. Every building must be instantly recognizable at RTS camera distance and charming up close β€” generous primitive counts, color variation via PALETTE, small storytelling details (barrels, sacks, fences, banners)."

Now contrast that with one of my re-run seeds, whose entire renderer art direction was a single sentence: "Implement the Three.js renderer… It must be visually nonblank and detailed without external binary assets." No palette, no "260 trees in clusters," no lighting mood, no per-building silhouettes, no "art department." The result? A competent, generic, single-file renderer with ad-hoc colors on a near-empty plane. The same pattern held when I tried to replicate the game with Opus and with GPT-5.5 as the architect: left to write their own contracts, both produced only shallow art direction β€” structurally sound, but nothing like Fable's per-building, per-mood prose. The games came out correct and flat.

Same model. Same competence. Wildly different output. The look was front-loaded into the implement prompts β€” and the review loop didn't add it later (the "visual" lens checks correctness, not aesthetics). Give Sonnet art-directed prose and it produces rich visuals; give it "render it, make it detailed" and it produces correct-but-boring ones.

Replicating it ourselves, with Sonnet

If the magic is in the prompt, then the prompt should be reproducible. So we preserved the exact orchestration script β€” every verbatim subagent prompt and the pinned model tier for each role β€” as a replayable workflow, and re-ran the build from the frozen 3-file scaffold.

It worked. The same contract-first seed, driven through the same six-phase Sonnet workflow, produced the same class of result: a detailed, playable 3D RTS, built almost entirely by Sonnet agents.

Our replication β€” Sonnet agents driven through the Fable-authored workflow. The visual richness survives because the art direction lives in the contract, not the model.

This is the part that should change how you work: the most valuable artifact from a successful agentic build is not the code. It's the workflow and the contract that produced it. Save those, and you can reproduce the result on demand.

Opus vs. Opus: more model is not more game

The obvious next question: if Sonnet did this well, what happens if we throw the most capable model at the whole thing?

I ran the same idea with Opus 4.8 at maximum effort, using Opus for the implementation work too. The build took 2 hours 52 minutes and produced ~12,500 lines of code β€” slightly more code, much more compute, much more wall-clock time.

It was worse as a game. No animations. Poorer gameplay β€” for example, choosing a peasant's job required selecting a function from a combo box instead of the fluid right-click-to-assign of the Sonnet build. The extra model capability did not translate into a better-playing, better-looking game.

The Opus-builds-everything run β€” nearly three hours and ~12,500 lines, yet flatter and less playable than the 90-minute Sonnet build. More model did not mean more game.

That sounds counterintuitive until you remember the previous section. The thing that made the original beautiful and fun was the art direction and interaction design encoded in the prompt β€” not the raw capability of whatever model executed it. Pointing a more expensive model at a thinner prompt buys you very little. The lever is the brief, not the brawn.

Replicating Fable with Opus, the right way

So here's the synthesis β€” and the actual point of the title. The way to "replicate Fable with Opus" is not to make Opus do everything. It's to put each model where it's strongest:

  • Opus as the architect. Use the most capable model to do what Fable did with its 6% β€” write the frozen contract, decompose the system into disjoint modules, and art-direct the workflow in prose. This is the high-leverage, low-volume work where capability compounds.
  • Sonnet as the implementer. Fan out the bulk of the code across parallel Sonnet agents bound by the contract. This is the high-volume work where a well-prompted Sonnet matches or beats Opus per dollar and per minute.

To test it, I took the findings above and built a deliberately art-directed Opus-plans / Sonnet-builds workflow β€” the "special prompt" β€” front-loading per-building silhouettes, a lighting mood, world density, animation hooks, and a dedicated art-department workstream, exactly as the original CONTRACT did. The visual and gameplay quality jumped accordingly. The exact prompt that drove this regeneration is open-sourced here: contract-first-game-build.md.

Opus-as-architect, Sonnet-as-implementer, with the art direction findings baked into the contract β€” proof that the right prompt, not the bigger model, is what lifts the result.

Want to see what one of these builds actually plays like? Here is a live, in-browser game β€” Hearthwatch β€” generated end-to-end by exactly this contract-first, art-directed workflow. No install, no assets to download; it runs entirely in your browser:

The conclusion my colleague drew when I shared this internally was the cleanest summary I've heard: "So Sonnet itself is good β€” we just didn't know how to use it?" Yes. That's exactly it.

Same prompt, different model β€” play them all

Here is the strongest evidence that the lever is the prompt, not the model: the art-directed contract is just plain text, so you can hand the whole build β€” architecture and implementation alike β€” to almost any capable model and still get a complete, animated, genuinely art-directed game. I ran the same open-sourced prompt end to end with several different models, each acting as its own architect and executor. Every one produced its own art style β€” but never the thin, flat, animation-less output a one-line brief gives. Play them and judge for yourself.

Opus β†’ Opus, with the art-directed prompt β€” Hearthhold

Remember the earlier all-Opus run that came out flat, with no animations? That was Opus pointed at a thin brief. Give the exact same Opus-builds-everything pairing the art-directed contract instead, and it ships this:

The same all-Opus pairing that looked flat earlier β€” now driven by the art-directed contract. The prompt, not the model, was the difference.

GLM-5.2 as architect and executor β€” Hamlet

GLM-5.2 running the same open-sourced prompt end to end β€” architect and executor both β€” for a different art style with the same completeness and polish.

GPT-5.5 as architect and executor

GPT-5.5 running the same prompt end to end β€” architect and executor both β€” another distinct look with the same art-directed richness.

Four models, one prompt, four complete games (five, counting the Opus β†’ Sonnet Hearthwatch above). That is the whole thesis in a single playable row: write the contract and the art direction well, and the choice of model becomes a matter of taste and budget β€” not the difference between a real game and a flat demo.

What this means for building real software with AI

Strip away the medieval theme and these are general, durable principles for any nontrivial agentic build:

  1. Plan by writing the contract, not a document. Freeze your interfaces, your data shapes, and your shared vocabulary in code before any implementation begins. A type that won't compile when violated is worth a thousand words of spec.
  2. Decompose into disjoint modules and fan out. Parallel agents are safe when β€” and only when β€” they cannot collide. Draw the boundaries so no two agents edit the same file, and route every cross-module reference through the frozen contract. You may not even need worktrees.
  3. Art-direct in the prompt. Whatever "quality" means for your domain β€” visual richness, UX polish, error-handling rigor, accessibility β€” it has to be written into the implement prompts. Models faithfully execute the direction they're given and rarely exceed it. A review pass checks correctness; it does not supply taste.
  4. Verify adversarially, then actually run it. Independent skeptics with a "guilty until proven" default kill false positives. But static review cannot see live behavior β€” budget for a real playtest or end-to-end run.
  5. Tier your models to the task. Capability where it compounds (architecture, contracts, the hardest verification); cheaper models where volume dominates (bulk implementation, mechanical error reporting). More expensive everywhere is not more correct β€” it's just more expensive.
  6. Save the workflow, not just the output. The reusable asset is the orchestration script and the contract. They let you reproduce β€” and improve on β€” the result deliberately, instead of hoping lightning strikes twice.

At FMKTech, this is precisely the kind of orchestration we build for clients: contract-first architectures, parallel agent fleets bound by typed boundaries, adversarial verification, and model tiering tuned for cost and quality. A one-line prompt produced a game in ninety minutes β€” but the repeatable version of that magic is an engineered workflow, and that's the part worth owning.

If you're exploring how to put multi-agent builds to work on your own products, let's talk. The lever, it turns out, was never the model. It was knowing how to ask.

Replicating Fable with Opus: How a One-Line Prompt Built a 3D Game (and What It Taught Us About Prompting) | FMKTech Blog