Entry 003 - The locked exit
The two-stage player turn was the prerequisite for everything that followed, and it's easy to undervalue a prerequisite when the thing it enabled is what you remember.
Before the dual-slot model, each input resolved as a flat tick: player acts, state updates, done. After it, each turn is a proper (player act, enemy react) pair - the player moves, then all enemy intents resolve, then evaluation happens. That sounds like a minor structural change, and mechanically it is. What it unlocks is meaningful depth-limited search. Bot v2 at searchDepth=2 could now evaluate: "if I attack here, the enemy counterattacks there, and then I'm this far from the exit with this much HP." Two plies of real consequence instead of two plies of noise.
First 1000-seed depth-2 sweep: ~58% win rate. The data revealed the routing problem immediately - the bot was threading around enemies and walking straight to the exit without engaging. The evaluation function had no reason to kill if the exit was available, so it didn't. The engine allowed it; the bot optimised for it.
So we added the kill-incentive loop: carrier-marked pickups (good drops only on carrier kills), a threshold-locked exit that requires a minimum kill count before it opens, a clear bonus for finishing the floor. The design intent was to make killing worth doing. The immediate result was a near-total softlock (bot infinite move loop with no level resolution): win rate 49.9%, softlock 50.1%. The bot now engaged, but it couldn't chain "kill carrier → exit unlocks → walk to exit" at depth-2. That sequence is five or six plies deep. The bot would kill the carrier, see the exit still far away in the current state, ignore that the exit had just unlocked, and spend the rest of its turns running into a door it treated as unreachable. Softlock.
The diagnostic took longer than the fix, partly because I spent time looking for a non-existent RNG leak. The real culprit turned out to be a floor template that had quietly reverted: exitUnlockThreshold: 0.6 on a two-enemy floor means ceil(0.6 × 2) = 2, which is full clear - the exit doesn't open until both enemies are dead. A depth-3 spike (200 seeds) confirmed the horizon hypothesis: 99.5% win rate at depth-3, where "kill → unlock → walk" is visible in a single search. The structure was fine; the bot just couldn't see far enough. The fix was one guard in the eval function: gate the exit-distance pull on state.exitUnlocked. If the exit is locked, don't reward walking toward it. Win rate: 86.3%.
Here is where I should be honest about how the work was actually done. A Claude Code session (CC) handled all implementation throughout - the eval function guard, the sweep harness, the floor template edits, the persona weight tuning. A separate Claude advisor session handled the design work: reading balance reports, speccing fixes, deciding which hypotheses to test and in what order. The two-agent loop is closer to pair programming with a fast, tireless colleague than anything else. I make the design calls; CC builds; the advisor reads the data back and we iterate.
More simulation engine changes extended this further. Run scoring, five named bot personas (Optimal, Score Chaser, Completionist, Threshold Runner, Novice), and an upgrade rarity classification system were all designed in that advisory loop, specced explicitly, and handed to CC to implement. The five personas exist primarily as a measurement instrument. When the same upgrade looks wildly different across five behavioural footprints, you've learned something you couldn't learn from a single-bot sweep.
The rarity classification loop - iterating power bands, moving upgrades between common, rare, and legendary tiers, watching the deltas converge toward the expected ranges - ran three passes of the same spec → sweep → interpret → re-spec cycle. Each pass takes about twenty minutes when CC is implementing and the harness is running 5000 seeds across all five personas. The bar for "let's try it" dropped to near-zero. That changed how I think about design decisions more than any specific result did.
What I'm watching for: the tradeoff between efficiency and accidental discovery. The AI loop finds the correct path faster; it also skips the wrong turns where sometimes the interesting detours live.