← All reports

AI Sequencing Fix & Combat Pacing - Results

Generated: June 29, 2026. Companion to healthcare_balance_report.md and
battle_progression_report.md (which still show pre-fix HP values for the
four enemies touched here - see "Stale numbers elsewhere" below).


The bug

Enemy.cs's GetSequencePriority() gave any card with a BlockEffect a
flat priority of 1000 - unconditionally higher than every Attack card -
for any enemy with AiPersonality.Defensive or Optimal. GetCardScore()
does weight Block by an HP-aware panic tier (0.5x at safe HP up to 3.0x
near death), but that nuance never mattered: the categorical sequence
priority always won the sort, so these enemies played 100% of their Block
before touching a single Attack card, every single turn, regardless of how
much HP they had banked.

Combined with a few Defensive decks that are heavy on Block/Heal and light
(or, in Maintenance Drone's case, completely empty) on direct damage, this
produced near-deadlocks: a Monte Carlo sim (scripts/simulate_ttk_healthcare.py,
80 trials x real running HP, not an averaged-HP estimate) measured Maintenance
Drone dealing 0.0 average damage to the player and Claims Adjuster taking
140-200+ turns to resolve in the worst case, against the healthy 9-15 turn
fights produced by Aggressive-personality enemies (which never used this
block-first rule).

The fix (3 surgical changes)

  1. Enemy.cs GetSequencePriority() - Block-laying cards only get the
    forced priority-1000 slot below 50% HP. At 50%+ HP they tie with
    everything else at priority 0, so GetCardScore()'s panic-tier weighting
    (already written, just previously overridden) actually decides whether
    Block or Attack is the better play that turn.
  2. Character_MaintenanceDrone.tres - swapped 2x Bedside Manner (heal,
    redundant with the 3x Clinical Trial it already runs) for 2x Standard
    Consultation (Attack, 7 dmg + 4 Block) so the deck has guaranteed direct
    damage instead of relying entirely on Quarterly Growth, which only fires
    if there's spare energy left after Block - rare given its curve.
  3. HP trim pass on the four enemies that were still the longest fights
    after #1/#2 landed: Claims Adjuster 100→80, Maintenance Drone 145→125,
    Orbital Coordinator 165→140, Regional CEO (boss) 130→115 (~12-20% cuts,
    lighter on the boss to keep it the tier's toughest fight).

Measured results

Stall rate (neither side dies within 200 simulated turns) dropped to 0%
across all 72 enemy x player x mode combinations
- the structural deadlock
is gone. Per-tier average battle length (turns until someone dies), floor
mode = worst case (no conditional bonuses trigger) vs ceiling = best case:

Tier Floor avg length Ceiling avg length
Family 12.3 7.0
MidTier 22.9 5.7
MegaCorp 18.8 12.4

Ceiling-mode (competent play, conditionals landing) is now consistently in
a healthy 4-25 turn range for every single matchup - comparable to
Slay-the-Spire pacing, down from multi-hundred-turn stalls pre-fix.

A more honest read of "floor mode"

Floor-mode numbers are still long for a few matchups (e.g. Claims Adjuster
vs Hustler: 89.6 turns). Trimming enemy HP barely moved this number, and in
one case (Claims Adjuster) it got slightly worse between runs. The reason
isn't noise from the fix - it's that in these specific floor-mode
matchups the player has a 0% win rate
. The battle "length" being measured
there is actually "how many turns the player survives before dying," which
is governed by the enemy's damage output and the player's own block/HP, not
the enemy's HP pool at all. Cutting Claims Adjuster's HP can't shorten a
fight the player isn't winning in the first place.

This reframes the remaining problem: it's not pacing in those specific
floor-mode matchups, it's raw difficulty - certain starter decks
(Hustler glass-cannon, Plague Doctor) are underpowered against certain
Defensive grunts in their worst-case draw. That's a deck-power-level
question, not a "battles take too long" question, and is out of scope for
this pass - flagging it as a candidate for the next deck-balance pass rather
than papering over it with more HP trims.

Stale numbers elsewhere

battle_progression_report.md and healthcare_balance_report.md still
show the pre-trim HP values for Claims Adjuster (100), Maintenance Drone
(145), Orbital Coordinator (165), and Regional CEO (130), and don't reflect
Maintenance Drone's new Standard Consultation cards. Not rewritten here -
same "stale baseline, needs its own pass" situation as the syntheses already
documented in healthcare_balance_report.md's Implementation Status
section.

What's NOT done

See ai_revamp_roadmap.md for the larger initiative this fix is the first
slice of - the categorical-priority-with-score-tiebreak pattern still has
known rough edges (Chairman/Maintenance Drone special-casing, Quarterly
Growth's narrow energy window, no equivalent fix yet for Aggressive's
raw-score sort potentially overvaluing low-impact damage cards).