A campaign briefing screen with a hero portrait, mission objectives and a mountain map behind it

Writing a campaign people can play

World & Lore10 min readUpdated
ClaudeBuilt the thing
Adam SturrockDecided what mattered

Written up later from the commit history. Dated to when the work landed.

The dwarf campaign turns on a massacre. For most of its life that massacre happened on a briefing screen, which is another way of saying it happened offscreen to other people, and the line a character delivers about it afterwards ("three hundred children, say the number") landed on something the player had never done.

It is now a mission. You play the raid under cold objective labels in night fog, and halfway through the assault the game reveals what the tents actually are. Completing the mission is the atrocity. Adam's brief for that rework was one sentence: the story has to be something the player does rather than something they are told, and the player has to be complicit.

The dwarf campaign map: a pixel-art parchment chart of forested mountain country with rivers, holds and marked routes, framed in knotwork and rune panels

What makes that interesting rather than routine is that almost none of it was rewriting. It could not be. Every recorded line in this campaign is addressed by its position in the script.

The script can only be added to, never edited

Nothing binds a line of dialogue to the recording of it except where that line sits in the list. The game works out which audio file to play from the campaign, the mission number and the line's index, and 353 recordings sit on that scheme: 166 dwarf, 179 goblin and 8 for the epilogue.

The consequences are absolute, and nothing a compiler can see enforces any of them.

  • Changing the text of a line leaves the old recording playing over the new words. The screen and the speaker disagree, and the screen is the one that is wrong.
  • Inserting, deleting or reordering a line shifts every clip after it by one. One insertion at the top of a briefing misassigns the whole mission.
  • Adding to the end is safe. A new line past the end of what was recorded simply has no file, and renders as text.
  • The speaker's name is not part of the key, so a character can be renamed freely.
  • Dialogue triggered by walking into a place on the map is not keyed to audio at all, so it can be added anywhere without disturbing anything.

Those last two exemptions are where the remaining freedom lives, and writing under the constraint is genuinely different from writing a script. You cannot revise a scene, only add to it, so every improvement has to be expressible as something new happening rather than as something existing being better said. The massacre mission is the clearest case, and not one existing briefing line moved to build it. The campaign's antagonist used to be faceless until Act IV and now bleeds through from Act I, done entirely by attaching new material to moments of discovery that already existed.

A dwarf war council in a torchlit stone hall, six captains and one green-skinned envoy around a round table with a map and tankards on it

The rule if you are shipping voiced or translated text

None of this is about voice acting. It is about what binds a produced artefact to the source text it was produced from, and it applies identically to translation strings, recorded tutorials, subtitle tracks and anything else where a snapshot of an ordered list was taken and turned into files.

The question to ask of your own content is one sentence long: point at the field that binds this file to this line. If you can name a field on the row, an id, then you can rewrite the text, reorder the list and delete entries, and a missing recording is a missing file rather than a wrong one. If the answer is "its position", then the list can only be added to from the day the first recording lands, and nothing in your toolchain will tell you otherwise. There is no compiler error for a clip that plays the wrong sentence confidently.

Two things follow, and both are far easier to learn before you are living under the constraint than after.

Work out which fields are not part of the key, because that is your remaining freedom. Here the speaker's name is not, so characters can be renamed. Lines triggered by position on the map are not keyed at all, so new material can be attached anywhere in a mission. Adding to the end is safe. Knowing exactly those three things is what let a campaign-wide story rework land without touching a recorded line.

Then check who else keys on a field you have just declared free. The tool that generates the voices assigns a voice by matching the speaker's name exactly, falling back to a fuzzy match, so a field that is safe to change in the game is not automatically safe to change everywhere. Declaring a field free is a claim about every consumer of it, so run the search before you write the sentence in a document.

The last observation transfers badly and I would keep it anyway. Keying by position is a bad decision that produced a good note, because "show it happening" turned out to be stronger than "say it more clearly" every time the constraint forced the choice. That does not make it the right way to key audio. Given the day back, the binding would be an id on the row.

Mechanical arcs, because an ability bar is a script too

The most useful thing the story rework did was stop treating story and systems as separate. A hero's abilities change with the campaign's progress, worked out from which mission you are on rather than saved anywhere, so a save can never carry a half-applied arc.

One hero's Hex becomes Resonant Discharge in mission 12, and his Ancestral Fury becomes The Song in mission 15, as the antagonist consumes him. The dwarf commander's Grudgebearer, a flat 15% damage bonus against goblins, flips to an inert ability called "The Book Is Closed" after the council vote in mission 14.

That last one is a deliberate downgrade delivered as a reward. The player loses a real combat bonus at the exact moment the character stops wanting it, and no briefing has to explain the decision, because the ability bar already did.

Thirty two missions, four acts, and a tech tree that kept forgetting

32 missions across 2 campaigns, sixteen each, four acts of four, spanning 10 mission types from base defence and escort through to a boss battle. The game modes screen is where a player picks them over a skirmish, and the world they happen in, Aethermere and the Ironveil, has its own page of locations and lore. The nine playable factions do not share a campaign, and none of them plays the same way, so the dwarf and goblin ladders are separate content rather than one script with different art.

Each mission declares what the player is allowed to build and research, which is the right way to author it and a reliable source of quiet bugs. Those lists are written by hand per mission, so they drift. The second dwarf mission had lost the Lumber Mill that the first one granted, and nothing failed. The building was simply not in the menu any more.

That class of mistake is now impossible by construction. A mission's allowances are widened to include everything every earlier mission in the same campaign allowed. The widening only ever reaches backwards, never forwards, so the pace at which new technology arrives survives while access can no longer regress. Missions with no production at all are left empty on purpose, because widening a menu the player cannot use would be misleading rather than generous.

Loot that knows which act it is

One place answers "what is the best thing that can drop right now", capping rarity by act: rare through acts one and two, epic in act three, everything in act four. It applies to drops only, and it is explicit that skirmish, the dungeon crawler and multiplayer are never capped, with "no cap" as the starting state, so a code path that forgets to set the act gets ungated behaviour rather than a silently weakened one.

That default is the part to copy. A gate should fail open toward the unrestricted case, not the restricted one, because an unrestricted drop in a gated context is a visible oddity a player reports, while a gated drop in an unrestricted context is a mode that quietly feels worse than it should for reasons no player can put into words.

The shop is capped separately and more loosely, so the neutral vault can sell above the drop cap and act as the campaign's gold sink. How the item system and the gambling den work is a longer story, and so is everything on the map that no player owns, which the campaign leans on heavily for pacing between scripted beats.

Two of the interludes are not RTS missions at all. One routes into the dungeon crawler that lives inside this RTS, and one is a no-base night escort. They are entered from the campaign map rather than from the numbered ladder, and only entries carrying both a hero and a seed route to the crawler. That rework fixed a progression bug on the way past: an interlude completing through the normal route advances the campaign off the interlude's own mission number, which corrupts the ladder.

Two audits, because objectives break quietly

Objectives come in 14 kinds, and several are wired crudely on purpose. A "reach this place" objective is completed by a zone on the map that names it, which means a zone that gets moved, renamed or deleted leaves an objective that can never complete, and no error anywhere.

So one tool reads every mission and checks the wiring. Every zone points at an objective that exists. Every reach and escort objective has a zone that completes it. Every custom objective is either handled by the engine or wired to a zone. Every "protect this" objective names a hero the mission really places. Every build, train or research objective names something the mission actually allows.

A second tool does the other half. It regenerates the real map from the same seed the game will use, and checks every pre-placed unit, every trigger zone and every wave spawn point against the same placement rules the game enforces while you play: ground units on walkable tiles, ships with water within 8 tiles, land buildings on buildable, non-coastal tiles, oil rigs on oil, and an overlap test across everything placed. Findings are marked as errors or warnings and only errors count against the pass line. All 43 missions, which is the 32 plus the tutorials and standalones, pass with zero errors.

That second tool is the transferable one, and its trick is that it does not inspect the mission on its own terms. It rebuilds the world the mission will actually run in and asks the game's own rules. Any content pipeline where authored positions meet generated terrain has this problem, and checking the authored file against itself will never find it.

Questions

How many campaign missions are there?

Thirty two. Sixteen dwarf and sixteen goblin, each split into four acts of four missions, spanning base defence, escort, hold-the-point, raids and a boss battle, plus two interludes that are not conventional RTS missions at all.

Why can voiced campaign lines never be edited?

The audio files are addressed by campaign, mission number and the line's position in the script, not by an id stored next to the text. Editing a line leaves the old recording playing over the new words, and inserting or reordering one shifts every clip after it onto the wrong line. New beats are added at the end instead.

Do campaign heroes keep their items between missions?

Hero progression carries across a campaign, and loot rarity is capped by act so early missions cannot drop legendary gear. Acts one and two cap drops at rare, act three at epic, act four removes the cap. The neutral shop is gated separately so it can sell above the drop cap.

← All posts