← Devlog

My spreadsheet said the game was balanced. It couldn't tell me it was boring.

I'd tuned every level to a perfect win rate. Then it hit me: win rate measures whether you survive, not whether you had to think. So I taught my AI playtester to measure the difference.

June 25, 2026 devlogbalanceai

I had a bot that plays my whole 140-level campaign and reports each level landing at a 75–95% win rate. Difficulty: solved. I felt great about it for about a day.

Then a quieter thought ruined the mood: a level can be perfectly balanced and still be a snooze.

Why win rate can’t see “fun”

Win rate measures one thing — can you survive this level — and it’s blind to the thing I actually care about: did you have to think to survive it. Two levels can both read 85% and be completely different games. One is “spam the cheapest tower and walk it.” The other is “read the country, match four tower types to a demand that keeps shifting, or you lose.” Same number. One’s a nap, one’s a knuckle-biter.

So win rate is a difficulty knob, not a fun meter. And my bot could only see the number, which meant the most insidious failure mode — balanced and dull — was invisible to it. It looks perfect on the dashboard precisely because the dashboard can’t measure it.

Two cheap signals for “did the choices matter”

The fix was already in a tool I’d built for difficulty: my bot plays each level four ways — greedy, save-up, go-tall, plan-ahead. I’d done that to stress-test the hardest possible play. But four playstyles quietly answer a different question, and you get two numbers for free.

Did the playstyle even matter? Take the best of the four runs, subtract the worst. If all four score the same, your choice changed nothing — the level has one answer, the bot found it, you’re on rails. If they spread far apart, the decision has stakes. Spread is a proxy for how much your strategy moves the outcome, and that’s most of what “interesting” means.

Did you win with a mix, or one tower spammed? Look at the winning build and measure how much it leaned on its single most-used tower. Ninety-plus percent one tower is autopilot; the build had no internal decisions. A real blend means every slot was a call. Dominance is the cleanest single signal I found — it maps directly onto “fun to optimize” versus “hold one button.”

Neither proxies fun on its own. Together they sketch the decision space, and the decision space is the part a win rate throws away.

The map, and the one boring world

I ran it across all 140 levels — about 560 little simulations, batched per world so my dev server wouldn’t keel over — and got a map of where the actual decisions live. Six of my seven worlds came back as genuine puzzles. And then there was the USA. Boring, top to bottom: seventeen of twenty levels were “spam one tower, the Chatbot, and stroll through.” The metric flagged it on sight. So I rolled up my sleeves to fix the broken world.

Two fixes. Both failed. Loudly.

Rebalance the market. Each country bends what towers are worth — the USA’s demand leans hard toward Vibe, so I assumed everything just wanted one Vibe tower. I rebalanced it to make Smarts matter too. Result: nothing. Still 97% Chatbot.

Borrow China’s trick. China is a great puzzle because it penalizes cheap, dumb towers — it forces you to bring the expensive smart ones. I copied that penalty onto the USA. It made the world harder (some levels went unwinnable) and was still 97% Chatbot. I’d broken the early game and changed nothing about the boredom.

The build dumps explained both failures, and the lesson generalizes. The Chatbot wins on volume: it’s the cheapest and fastest tower, and a “good enough” match that fires twice as often beats a perfect match that fires half as much. You can’t out-rebalance volume economics by nudging match values — the throughput swamps the per-hit difference. And the penalty backfired for a subtler reason: a penalty only creates a choice if the player owns a tower that beats it. The USA’s roster is the cheap set; the smart towers that clear a penalty unlock later, in other worlds. With one viable option, a penalty doesn’t add a decision — it deletes the only move you had. A lever that builds a puzzle in one place can build an impossible wall in another.

The twist: it wasn’t broken

Here’s the part that made me laugh and then quietly delete all my fixes.

The USA is the tutorial. It’s where the game introduces most of its towers, one at a time, on the gentlest ramp. A world where one cheap tower carries you is exactly what an on-ramp should feel like — you’re learning the verbs, not solving a Rubik’s cube. My “boring” detector had worked perfectly. It found a one-tower world; it just didn’t know that one-tower was the point there. The metric was right; the verdict was mine. So I logged “this is deliberate” and left it completely alone.

Two kinds of puzzle (the bit I almost missed)

One more thing fell out of the map. High spread isn’t all the same flavor. High spread with a low minimum is a trick level: one solution exists, every other build is a total loss — exciting once, brittle forever. Moderate spread with low tower-dominance is a tradeoff puzzle: several builds work, each with a cost, and choosing well is the fun. Spread alone conflates them; you need dominance to tell a real toolbox from a single hidden key. My richest worlds were the tradeoff kind, and that’s the texture I now design toward.

What stuck

  • Win rate measures survival, not thought. If you want to know whether choices matter, you have to measure the choices — vary the strategy and watch how much the outcome moves.
  • Strategy spread and tower-dominance proxy decision-richness. One asks “did your playstyle change the result,” the other “did winning need a toolbox or one button.” Cheap to compute, and they catch the balanced-but-dull level a win rate never will.
  • A lever that makes a puzzle one place can make a wall in another — a penalty only adds a choice if the player owns an answer to it.
  • An optimal bot measures the ceiling, not the feeling. It can’t sense a first-time learning curve or a boss reveal; it tells you how rich the decisions can get. A human still has to tell you if it’s fun — which is exactly why the tutorial looked “broken” and wasn’t.

Best decision I made all day: trusting the metric enough to investigate, and trusting my own judgment enough to overrule it.