← back to work

The pipeline behind ChampChase

I wanted a game. I had no coding background. So I built a way to build it.

7 Ed · coordinator · the ledger

“… Wave 3 slot allocation T1=965, T2=966 …, T3=967, T4=968, T5=969, T6=970”

  1. 968 T4
  2. 971 T3
  3. 965 T1
  4. 970 T6
  5. 969 T5
  6. 966 T2
Output ChampChase
One real round, 8 May 2026: an audit of the build's own tools (pass 963) split into six file sets, one per session. Each pane quotes that session's record in the build ledger, trimmed but not reworded; open one to read more. The landing order is the ledger's.
  • Role architecture, orchestration & verification
  • Scope custom build pipeline, built and run over 15 weeks
  • Output ChampChase, shipped solo to beta on iOS + Android
  • Self-initiated
  • the public build record

I wanted ChampChase to exist. I had no development, computer-science or coding background, so the first question was how to make it happen. The six-terminal pipeline grew out of that question: six AI sessions running in parallel over non-overlapping file sets, a lock protocol keeping them out of each other's way, and one human in the middle deciding what was allowed to survive. It has run 2,031 recorded passes (count as of 6 August 2026) and took a full game to public beta. With the names changed, the same architecture fits a business's own repetitive work.

The real six-session setup — parallel agent terminals across two monitors at sunset, each pinned to its own slice of the codebase
The actual setup, not a diagram. Each pane owns a different slice of the codebase; none of them may touch another's files.

// the problem

One person, a full game, no team

A full game is not a big website. It is a fight engine, a campaign, an economy, an inventory, a shop, a save system, a dialogue system, an audio director and a hundred screens that all have to agree with each other. I had one person and no prior game-development experience.

The naive version of "use AI for it" fails immediately and predictably: one session, one conversation, and a codebase that drifts out from under you until nothing compiles and nobody — human or otherwise — can say which change broke it. Throughput was never the hard part. Knowing what was true after each change was the hard part. So I built for that instead.

// the architecture

Six sessions, one coordinator, no shared files

A launcher script opens six sessions in a grid across two monitors. Each is assigned a non-overlapping set of files — the fight engine here, the campaign manager there, UI, audio, saves, content validation — so two of them can never be editing the same thing at the same time. Ownership is enforced by a lock protocol: a folder of lock files, claimed before work starts and released after. Deliberately the dumbest mechanism that could work, because a coordination system nobody can debug at 2am is worse than no coordination system.

I sat in a seventh window as the coordinator. That role is not supervision, it is the actual job: assigning work so the slices stay disjoint, holding the architectural picture none of the six can see, and reconciling documentation when parallel sessions inevitably contradict each other. When six things move at once, the scarce resource is not code — it is a single consistent account of what the system now is.

It is not tidy. After one six-way run I spent an hour reconciling thirty-five missing history entries, and nine passes were never recovered — I still don't know what they did. I'm including that because a method described only by its good days is a sales pitch, not a method.

The same desk in March 2026: four sessions on the left screen, two more and the coordinator's chat on the right, pine trees outside.
The same pipeline as posted to the game's dev log on 18 March 2026: four sessions on the left screen, two more and the coordinator's chat on the right.

// one round, in order

Seven windows, 8 May 2026

The round from the top of this page, step by step, as its six records tell it. Not every round is glamorous: this one hardened the build's own tools before a release build.

  1. 01 Input

    Pass 963 audits the build's own tools: 22 of them, every finding with its file and line. The coordinator cuts the fixes into six file sets that cannot overlap.

    Coordinator. Slices are assigned so no two sessions own the same file.

  2. 02 Locks

    Before touching anything, each session claims its lock: t1_standing_rule_965.lock through t6_medium_cluster_970.lock.

    The lock folder. Claimed before work, released after the record. Nothing smarter than that.

  3. 03 Work

    Six changes at once: the build-number tools, the problem lists, the golden-path test, the history checker, the auto-wiring filter, four medium findings.

    One owner per file. Each session edits its slice and nothing else.

  4. 04 Verify

    Five compiles come back 0 errors, 0 warnings; T1 and T6 run theirs after every file. T2 changed no code, so it checks its citations instead.

    The gate. No record is written until the checks pass.

  5. 05 Collide

    T6 reads the end of the ledger; T3 lands before T6 can write. T6 reads the end again and appends. T1 hits the same once.

    Append-only records. A write that loses the race reads again. Nothing is overwritten.

  6. 06 Land

    The records land in the order they finish: 968, 971, 965, 970, 969, 966. T3 planned as 967 and lands as 971.

    The seventh window. The coordinator merges six accounts into one state, nesting the out-of-order ones instead of renumbering history.

  7. 07 The rig

    Six windows and a seventh, on two screens, at one desk.

    Then the next round. Wave 4 started the same day.

Assembled from the records of passes 963–972, dated 8 May 2026. The windows quote their record lines, trimmed but not reworded; nothing was re-run for this page.

// the unit of work

Every pass ends in a verdict

Nothing here is a conversation. The unit of work is a pass, and a pass has a fixed shape:

StageWhat happensRule
Input the requirement, plus the current true state of the system — not the state I assumed it was in state, not memory
Execute the change, made against one owned slice of the codebase and nothing else one owner
Verify compile check plus an audit against the requirement — did it do the thing, and did it break something else gate
Record what changed and why, written down so the next pass starts from fact no silent edits

2,031 passes, each shaped as input → execute → verify → record. The verify stage is the whole point: it is the only reason those changes compose into a working product instead of 2,031 opportunities for silent breakage.

// the record

All 2,031 passes, day by day

Every pass number in the build's ledger up to the count of 6 August 2026, placed on the day its record is dated: 17 March to 6 August. Each is coloured by the class its record gives itself. The ledger has no lane or verdict field, so neither is drawn.

  • build 732
  • fix 289
  • polish 451
  • audits, records 158
  • no class recorded 392
  • never recovered 9
A calendar of 2,014 dated passes, 17 March to 6 August 2026, one small square per pass. The busiest day, 18 March, holds 122; most weeks after that hold between fifty and three hundred.

From the build ledger, read 2 October 2026. Seventeen of the 2,031 records carry no date and are not placed.
  1. 18 March 122 passes dated that one day, six sessions at once. Nine never got a record back: 51, 52, 56–59, 106, 109 and 114. The dev log that day counted eight; the ledger marks nine.
  2. 19 March Pass 163 rebuilds the worst screen from code instead of repairing it: 1,713 lines to 913.
  3. 8 May The round at the top of this page: six sessions, passes 965 to 971.
  4. 6 August Pass 2107, the last number counted in the 2,031.

Read all 2,031 in the ledger

6parallel sessions
15weeks, solo
€800total tooling cost

// when it breaks

The pattern I had to invent

Weeks of fast iteration left every screen in the game holding broken references — the engine stores component links by ID, and after enough restructuring those IDs pointed at things that no longer existed. Eleven attempts to repair one screen conventionally all failed. So I stopped repairing.

The replacement pattern: disable everything the editor had serialised rather than destroying it, rebuild the entire interface from code at runtime, then re-point every reference at the freshly built objects. Downstream code cannot tell the difference. Applied across all thirteen screens, the worst offender went from 1,713 lines to 913 — smaller, faster, and it actually worked.

That call — stop fixing this, replace the mechanism — is not something a build pipeline arrives at on its own. It came from watching eleven failures and concluding the approach was wrong rather than the attempts. It is the same judgment I get paid for on client work, and it is the part that does not come out of a tool.

// the content pipelines

Not just code — everything the game is made of

The same pass discipline ran the asset production, because a game is mostly content and content rots the same way code does:

  • Art — every fighter portrait, environment and item icon produced through the same generate-review-regenerate-export loop. No asset store, no stock sprites — every asset came out of that one pipeline, so it all looks like it belongs together.
  • Music — an original score in music kits: the player picks one and it plays across the whole game.
  • Voice — the cast voiced, with lines regenerated until the read matched the scene.

The unglamorous half is the half that matters: one entire pass was nothing but moving item icons into the exact folders the loader expected. Pipelines are mostly that, and skipping it is why most of them quietly stop working.

// the economics

What it actually cost

I haven't found a sourced figure for what a studio would spend on this scope, so I won't quote one. My side of it I can show: the tooling for this build came to roughly €800 over the fifteen weeks, most of it the AI coding subscription.

That number is the argument for the method, and it is worth being precise about what it isn't. It is not an argument that the work is cheap — the fifteen weeks were mine, and the judgment in them is the expensive part. It is an argument that the ceiling on what one person can responsibly ship has moved, and that a business sitting on a backlog of "we'd need to hire for that" should re-check its assumptions.

// what transfers

The same system, pointed at your process

Strip out the game and the architecture is the deliverable: work split into slices that can run at once without colliding, a lock or ownership rule so they don't, a fixed pass shape ending in verification, and a written record so the next pass starts from fact instead of assumption. Pointed at a business, that is what a custom workflow build would be: find where the repetitive work actually goes, then build a pipeline that removes it, around the process you already run.

It is also the reason the rest of the work on this site holds up. The same discipline audited a multi-tenant SaaS against itself, found 355 things wrong with it, and worked through them in a twelve-pass fix program. A pipeline that cannot fail its own output is not a pipeline. It is a very fast way to ship a mistake.

Have repetitive work to remove? Let's talk

What it built: ChampChase →