Skip to content

The cross-game compounding flywheel: how each game makes the next one cheaper, and the last one better

Everyone selling you on AI-assisted development tells you the same thing: reuse saves typing. You build one thing, you copy the pattern, the next thing is faster. It is true, it is boring, and it is not an argument for anything. Faster-to-type is a linear win you could get from a snippet library in 2005.

This post is about the claim underneath that one, which is not boring, because it is about quality and not just speed, and because it runs in a direction most people never mention. The catalog this project is building -- a multi-device board game platform with several games on it -- gets better in two directions at once. Forward, every shipped game makes the next one cheaper to build. Backward, every lesson learned building a new game gets folded back into the games that already shipped, so the oldest game in the catalog quietly inherits the newest game's hard-won fix. The forward direction is the linear, obvious one. The backward direction is the interesting one, because it is what makes the argument about compounding quality, not compounding line count.

That is the whole thesis, and it is the spine of everything below: one flywheel, two directions. Forward is cheaper and faster. Backward is better and more uniform. The rest of this post is evidence that the backward direction is a real, governed mechanism in this repo -- not a motivational metaphor -- and an honest accounting of where it costs you.

This is the capstone of a cluster about building an app with AI. The other posts describe the machine; this one argues the case the machine is built to make. It leans on three of them and re-explains none: Describe the screen, don't draw it (the UI-spec prompt playbook) for the forward half made concrete, The orchestration lifecycle: from phase to ticket to retro for the retro machinery the backward fold rides on, and Review surfaces and the AI-first guardrails for the gates that govern any change to an already-shipped game. If you want the internals, those are the posts. This one is the argument.

The forward half, in one paragraph

I am going to spend exactly one paragraph on the forward direction, because the UI-spec playbook post already spends a whole essay on it and I do not want to re-teach the machine here.

The forward direction is the cheap-and-fast one: a shipped game leaves behind frozen UI specs under the game docs, an engine that conforms to the engine base contract contract, shared stage code under the private source tree, and a trail of merged tickets and run records. The next game does not start cold. It primes the AI with an existing spec and inherits its conventions for free; it subclasses the same engine ABC; it reuses the same primitives. Werewolf, the third game through this loop, made that inheritance visible in code: its ticket explicitly named the relevant engine module as the hidden-information engine to mirror, and the relevant engine module now implements the same public_view, player_view, and full_view split while keeping private resolution bookkeeping under the SERVER_KEY convention from the relevant engine module. The client inherited the same pattern in React: the private source tree owns local selection state and the WebSocket ws_send callback, while the private source tree is the props-only deterministic surface the tests can render directly. The playbook post's seventh prompt -- paste a shipped spec, say "do the same for my game" -- is the canonical worked example, and its closing line is the whole forward thesis: a good prompt plus an ever-growing library of worked examples makes each new screen faster to spec than the last. Game three is cheaper than game two, which was cheaper than game one. Read that post for the how. For this post, that is the entire forward half: assume it, and move to the part nobody talks about.

The retro is the pump

A flywheel needs something to turn it. In this project that something is the retrospective, and the reason it moves lessons in both directions is the part worth understanding.

I will not re-explain the lifecycle -- the lifecycle deep-dive does that. The one fact this post needs is the shape of the loop: every ticket leaves a *.run.md run record sibling next to its ticket file, and that record captures what the code cannot -- the surprises, the dead ends, the judgment calls the agent had to make where the ticket was silent (the format is pinned in the run-record contract). Per-ticket, that is local memory. Then, after a phase or a feedback cluster finishes, a retro runs last (templates: the workflow docs and the workflow docs). Its job is not to write code. Its job is to read every sibling run record, find the cross-ticket patterns, and turn them into changes to the system itself.

Here is the pivot that makes the retro a two-way pump rather than a one-way archive. A lesson surfaced building a new game has two possible destinations:

  • It can become a global rule -- a new CLAUDE.md contract, a new lint, a template field -- which from that moment binds every game, including the ones that already shipped.
  • It can become a cross-game refactor ticket that reaches back and retrofits the earlier games to match what the new game taught.

Both destinations point backward. The forward direction happens passively -- the next game inherits the library just by existing. The backward direction has to be pumped: a lesson learned in game N does not retroactively improve game 1 unless something deliberately carries it there. The retro is that something. Without it, per-ticket lessons stay trapped in individual run records and silently drop between cycles, and the catalog stops being uniform -- game 1 keeps its old quirks forever while game 4 gets the good version. The pump is what keeps quality roughly monotonic across the library instead of stratified by build date.

The backward fold is a real mechanism -- two cases from this repo

A thesis like this collapses the instant the examples turn out to be aspirational. So here are two concrete folds that actually happened in this repository's history, plus one smaller Werewolf-era pass that shows the same machinery still firing. They are deliberately different in mechanism: one is a vocabulary fold that swept the catalog in a single governed pass; one is a shared-contract fold where a lesson from one game now binds every game through the code they all inherit; and one is a dedup scan that reached across old and new games together.

Case 1: a vocabulary decision that swept every game at once

The catalog used to call its no-auth, public-view-only role SPECTATOR. At some point that name lost to OBSERVER. In a hand-built codebase a rename like that is a multi-week, never-quite-finished chore -- you fix the obvious call sites and leave a long tail of stale references in docs and tickets that the next developer trips over for a year.

Here it was a single governed cluster of tickets. The code rename went through one ticket (the ticket archive, merged as PR #346); the server-protocol and landing docs through another; the per-game docs and the blog through a third; the overview docs and the agent-rule files through a fourth. The fold was uniform on purpose: every game's the game docs spec, the shared engine and server code, and even the in-flight tickets that had not merged yet (there is a literal the ticket archive, PR #344, whose entire job was to fold the rename into work that was still in the pipeline so it would not land already-stale). One decision, the whole catalog moved to it at once, including the games that shipped long before the decision existed.

And the fold did not just change a word -- it birthed two standing rules that now govern every future concept change. The incident left 160 stale SPECTATOR references scattered across the overview docs, the server docs, the client docs, the game docs, and the blog even after the first rename PR merged, and that mess is recorded in the overview docs as the origin story for the CLAUDE.md rule "Canonical doc edits propagate through every related doc in the same turn." A second rule -- "Wide-sweep doc tickets are BATCHES, not mega-tickets" -- was born from the same incident, after the first attempt to do the whole sweep as one ticket hit the org's token-rate cap and got terminated mid-run. So this case is a backward fold and a fold-mechanism that hardened into rules: the next catalog-wide rename will not leave a stale tail, because one game's rename taught the whole system how to sweep.

Case 2: one game's bug, now a contract every game inherits

The second case lives in the code every engine is built on: the engine base contract, the GameEngine ABC. It declares three abstract view methods that every engine must implement -- public_view, player_view, and full_view -- even for a perfect-information game that seems not to need the split. AGENT_RULES_HISTORY.md records why the uniformity is mandatory rather than per-game convenience: "Bluff, Hearts, Hold'em, Werewolf, Battleland, and D&D-style helpers all stress hidden information in different ways," and forcing the pattern onto every engine "prevents special cases where one game accidentally sends full state because it usually has no private data." A hidden-information lesson, generalized into a contract that the simplest game in the catalog is held to anyway.

The sharper half of this case is a specific bug. The CLAUDE.md rule "State flows one direction" -- server computes, role-filtered view out, client renders, never a round-trip of client-computed state -- carries a single named worked example in its history: the Memory Match quick-flip failure. Memory Match was this project's proof-of-rebuild game, the first one through the rebuilt stack. Its bug was about presentation timing being allowed to decide whether a legal next move existed. The fix was not "patch Memory Match." It was hardened into a one-directional-flow rule that now binds the stage layer of every game -- so Bluff, built later, inherited the corrected boundary without ever hitting the bug that produced it. That is the backward fold in its purest form: the newest game stands on a fix the oldest game paid for, because the lesson was lifted out of the one game and into the contract they share.

There is a smaller, concrete version of the same instinct in the client tree: the private source tree, where stage code that should not be re-implemented per game gets extracted so every game inherits one copy (today it holds UnimplementedRefereeView.jsx, the uniform "referee view not built yet" surface). The _shared/ directory is the forward-and-backward seam made physical -- the place a pattern proven in one stage becomes the version every stage gets. It is early and thin right now, and I will be honest about that in the edges below, but it is the right shape: the catalog's shared surface is a real directory, not a wish.

Werewolf also produced a smaller backward-fold beat without needing a new rule. The Phase 5 dedup pass (the ticket corpus) ran the whole-repo finder after Werewolf landed and found generated live-payload fixture clones spanning Werewolf, Bluff, and Memory Match. Nine of the top ten rows were already owned by existing remediation tickets, including refactor-werewolf-live-payload-fixtures-by-role; the one unowned Memory Match hidden-payload row became dedup-memory-match-hidden-payload-fixtures. That is the flywheel in miniature: a fresh game adds new surface area, the whole-repo pass sees the repeated shape across old and new games together, and the cleanup work folds back into the catalog instead of staying trapped in the game that exposed it.

Why this matters, and what it unlocks

It is worth being explicit about what the backward fold buys, because it is a capability claim and not just a tidy property -- the whole point of paying the retro tax is the thing it unlocks.

What it unlocks is a catalog whose quality is roughly monotonic across the library, decoupled from build date. In a normal codebase, quality is stratified by age: the first feature you shipped carries the mistakes you had not learned to avoid yet, the latest feature is the best you can currently do, and the gap between them only widens as you learn more. The backward fold inverts that. When a lesson learned on game four can be swept across all four games in one governed pass -- a rename, a hardened base contract, a new lint that every stage is now held to -- the oldest game's floor rises to meet the newest game's lessons. The marginal game gets cheaper to build (forward) and drags the rest of the catalog up with it (backward).

The compounding is the payoff. Forward-only reuse is linear: N games cost less than N times one game, and that is the end of it. Add the backward fold and the returns stop being linear, because each new game does two things at once -- it costs less than the last, and it contributes a lesson that upgrades all the games before it. Quality stops being something you have to go back and manually re-do on old code and becomes something the catalog accrues. That is the actual argument for running development this way: not "the robot types faster," but "the library gets better as a whole every time any one part of it learns something." A snippet library cannot do that. A governed retro loop over a shared contract can.

The second flywheel: game authoring trains game authoring

There is a second flywheel sitting next to the catalog-quality one, and it is worth naming separately: the game-authoring flywheel. Each verified game build emits training-shaped data -- tickets, run records, review corrections, lint-gate outcomes, preference pairs, reward signals, and eventually full game-run trajectories. That data can improve the next authoring attempt through retrieval, few-shot examples, and a private eval harness. Better authoring attempts lower the number of PRs per game, which ships more games, which emits more training-shaped data. That is a different loop from "lessons fold backward into old games." It is "the act of building games creates the corpus that teaches the next model how to build games here."

The honest near-term version is not a bespoke fine-tuned model. It is RAG and few-shot prompting over the existing catalog, plus an eval harness that can grade a candidate game build against the historical human-approved result. The AI training substrate post explains why this repo's tickets, run receipts, codemap, lint vectors, and audit trail are already shaped like eval/training material; the rulebook-PDF-to-engine experiment is the first narrow rung, asking whether a model can translate a specified rulebook and design doc into a GameEngine subclass safely enough to measure. A fine-tuned game-authoring model is the gated long-horizon rung after that, not a thing this project already has.

Why it compounds is the same reason the first flywheel compounds: the output of one cycle becomes the input quality of the next. What it unlocks, if the measurements eventually justify it, is the platform's hardest economic target -- a designer hands over a rulebook or one-paragraph concept, and the system drafts the engine, AI hookup, rules/design docs, and client stage with a human reviewing for faithfulness instead of hand-building every layer from scratch.

The honest edges

I would be selling you something if I stopped at "and the flywheel turns forever." It does not turn by itself, and it is not free. Here is where the thesis is load-bearing only if you keep paying for it.

Every backward fold is a change to already-shipped, working software. Retrofitting a lesson into game one is not a greenfield write; it is a ticket against code that currently works, which means review, regression risk, and the full weight of the guardrails the review-surfaces post describes. A rename that touches every game can re-break a screen that had been fine for months. The fold is governed precisely because it is dangerous -- the same lint wall and bug-fix gates that make a normal change safe are what make a catalog-wide retrofit survivable -- but "governed" means "costs review cycles," not "free."

Not every lesson generalizes, and forcing the ones that do not is its own failure mode. A fix that is genuinely specific to one game's mechanics does not belong in the shared base contract, and hoisting it there to feel uniform makes every other game carry a quirk it never needed. The Memory Match flow fix generalized because hidden-information boundaries are universal; a Memory Match card-matching rule would not. Part of the retro's skill is telling those apart, and it gets it wrong sometimes. A backward fold of the wrong lesson is worse than no fold -- it spreads one game's accident across the catalog under the banner of consistency.

The ratchet stalls the instant the retro discipline lapses. The forward direction is passive -- the library compounds whether or not anyone is paying attention, because the next game inherits it just by existing. The backward direction is entirely dependent on someone running the retro, reading the run records, and choosing to spend tickets retrofitting old games. Skip the retro and the lessons stay trapped in individual *.run.md files; the catalog keeps growing but stops getting more uniform, and within a few cycles you are back to quality stratified by build date with the newest game carrying all the good fixes and the oldest carrying none. The flywheel is a practice, not a property. It only compounds for as long as you keep turning it.


That is the case the whole cluster rests on. The UI-spec playbook shows the forward direction made concrete -- the example library that makes each new screen cheaper than the last. The lifecycle deep-dive shows the retro that pumps lessons both ways. The guardrails deep-dive shows the gates that make a backward fold into a working game survivable. The AI training substrate post names the adjacent authoring-data loop. This post is the argument those pieces are evidence for: build a catalog through a governed AI loop and it does not just get bigger over time, it gets better -- the newest game makes the next one cheaper, the last one better, and the library compounds in quality as long as you keep the retro turning.

That is the thing reuse-saves-typing never tells you, and it is the only reason any of this is worth doing.