fix(runner): aggregation creates per-id accumulators on demand so summoned creature ids in result.stats no longer KeyError run_encounter (totals were seeded from the deployed roster only); duplicate summons of one creature id share a stats slot - noted as a limitation, pinned by a summon-encounter report test

This commit is contained in:
2026-09-19 16:56:48 +02:00
parent 2e2873f331
commit 7fefce4653
2 changed files with 85 additions and 3 deletions
+11 -3
View File
@@ -190,11 +190,16 @@ def run_encounter(
states = build_states(spec)
if spell_registry is None:
spell_registry = load_spell_registry(SPELLS_DIR)
ids = [s.combatant.id for s in states]
wins = {side.name: 0 for side in spec.sides}
draws = 0
total_rounds = 0
totals = {cid: CombatantStats() for cid in ids}
# Accumulate whatever ids the engine reports: summoned creatures act in the
# battle and appear in result.stats, so seeding from the initial states
# only would KeyError on them. Ids seen for the first time get a fresh
# accumulator. Known limitation: two summons of the same creature id share
# one engine stats slot (the engine keys _LiveStats by id), so their
# attrition is merged, not split.
totals: dict[str, CombatantStats] = {}
transcript: tuple[str, ...] | None = None
for index in range(runs):
if index > 0:
@@ -217,7 +222,10 @@ def run_encounter(
wins[result.winner] = wins.get(result.winner, 0) + 1
total_rounds += result.rounds
for cid, stats in result.stats.items():
current = totals[cid]
current = totals.get(cid)
if current is None:
totals[cid] = stats
continue
totals[cid] = CombatantStats(
hits=current.hits + stats.hits,
crits=current.crits + stats.crits,