Brick & Mortar

How It's Made · Step 16 of 27

Step16

Balancing 50 levels with bots that play them

· 4 min read

tower-defensebalancebotstesting

A fortified snowfield at night under a deep blue sky.

The wave generator from last week wrote 1,910 waves. They were a curve, not a game: no human had played most of them. We needed to know which levels were impossible, which were trivial and which were a good evening. We did not want to play fifty levels fifty times to find out, so we built players.

Three bots

The TdBot is a test harness that plays a Tower Defense level headless through exactly the same commands a human issues: place a tower, buy a unit, upgrade, sell. It is forbidden from cheating, so no free credits, no kills and no damage. It has three profiles:

The idea is a bracket. A level that BALANCED cannot win is probably too hard for a normal player. A level that POOR wins is probably too easy. The result is a log line per wave and a final line per run: won, with how much of the base is left, or lost on which wave.

On 16 October the first read was grim: on the first ten generated levels, BALANCED won 4, POOR won 1 and GREEDY won none.

The tuning layer

Editing 50 levels by hand would break the generator's curve. So we added a tuning layer, scripts/td_tune.py, which sits on top of the generator's output and applies per-level numbers from one table. It is data-only, re-runnable, and can reset a level to its base. The knobs:

Then a loop: run the bots on a level, read where it died, move one or two knobs, run again. We wrote a small script, td_why.py, to look at why a level was lost.

The effect on a typical level, from the log. Level 7 before: BALANCED lost at wave 13 of 30. After tuning (the last wave scaled to about a fifth): won with 95 per cent of the base left. Level 4, before: lost on the last wave of 25. After, with a slightly smaller final wave: won on all three seeds, with 52 to 82 per cent of the base left.

The Tower Defense interface over brick apartment blocks in falling snow
Red Square, snowing, with the interface on.

By 21 October (revision 41) BALANCED could hold 36 of the 50 levels. Seven more levels were turned in that single pass. Fourteen were still lost, and their death waves are written in one table so the next pass starts where the last stopped. The next day nine sea levels were turned.

What a bot cannot tell you

What we would do differently

Try it yourself

If your game has a rule set, write a player that follows it and give it three personalities. You will find the impossible level and the trivial one in an afternoon, and you will have saved your own time for the part only you can judge.

Next: Seventy achievements, a fake Steam and the friend build (22 October 2026)

Start at Step 1All 27 steps

Written afterwards from our project notes and commit history; dated to when the work happened.