Commit Graph

4 Commits

Author SHA1 Message Date
prosolis
519964fb01 J1: Extra Attack now fires in turn-based combat
The class-identity audit (98ba416) wired Extra Attack via the new
resolvePlayerSwings helper, but only SimulateCombat (auto-resolve)
called it. The turn-based engine — every !fight/!attack and every
elite/boss gate the sim drives via autoResolveCombat — still called
single-swing resolvePlayerAttack, so Fighter L11+ got 1 swing/turn at
the gates instead of 3. The audit close-out was correct in spirit but
half-applied.

J1 baseline matrix surfaced it: Fighter L12 cleared 100% of T2 forest
but 2% of T3 manor and 7% of T4 underdark, with %boss_reached at 100%
across the board. The wall was the boss-room damage exchange, not
mid-zone attrition. Trace dump on a sample fight: Fighter dealt 79
dmg in 14 rounds (7 hits / 9 swings) — exactly one swing per round —
versus 167 enemy dmg. With multi-swing wired in, the same fight ends
in 7 rounds with the boss dead, Fighter at 87/168 HP, 16 hits in 19
swings.

n=100 matrix after the fix:
  Fighter L12 manor:     2% → 100% clr
  Fighter L12 underdark: 7% → 98%  clr
  Fighter L12 forest:    94% → 100% (no leader regression)
Mage cells unchanged (J2 territory). Rogue cells within noise.

Sim infra changes that landed alongside (needed to read the J1
signal):

* expedition_sim auto-arms class-default defensive abilities
  (Second Wind / Healing Word) via the new simAutoArmEnabled toggle
  + trySimAutoArm helper, hooked before applyArmedAbility in both
  combat builders. Production code paths untouched (toggle stays
  off). Without this the sim simulated a player who never types
  !arm, which under-counts class survival.
* SimResult.Combats captures per-fight turn-log summaries (rounds,
  hits/misses, damage by side, AC values inferred from RollAgainst)
  so future J-phase questions can dig into the engine without
  re-running the matrix.
* sim_results/run_matrix.sh fans the matrix across (class,level,zone)
  cells via xargs -P (one process per cell — each owns its global
  sqlite handle). ~6× wall-clock speedup on a 14-core box; n=100
  matrix runs in ~3min.
* sim_results/summarize.sh gains p50_yld_clr + %boss_reached columns
  so future sweeps don't conflate "reaches boss" with "clears zone".

Baselines:
  sim_results/baseline_j0_n100.jsonl       — pre-fix (1350 rows)
  sim_results/baseline_j1_extra_attack.jsonl — post-fix (4500 rows)

Phase J state: J0 baseline locked, J1 done. T5 dragons_lair still
0% clear universally (J3). Mage T2+ wall still real (J2).
2026-05-17 14:11:39 -07:00
prosolis
5eb3cac992 Sim hardening + H4 calibration findings → Phase J plan
Harden expedition-sim with the three layers a real player carries:
race mods (+1 Human across the board), tier-appropriate equipment
(weapon/armor/helmet/boots/tool promoted from tier 0 to a level-mapped
tier), and a lean consumables bundle (2 heals + 1 buff at T2-T4,
3 heals + 2 buffs at T5). Capture material yields in SimResult so
calibration sweeps actually read out the H4 signal.

Three sweeps in sim_results/ (n=10): bare baseline, +gear/race,
+lean consumables. Headline: yield is gated by combat survival, not
charge counts. Fighter and Mage hit a sharp wall at T3+ even kitted;
no class extracts the T5 dragons_lair boss. Tuning charges before
fixing class survival would over-tune against a strawman, so H4
is now flagged blocked on Phase J.

Phase J appended to gogobee_harvest_charges_plan.md:
J0 baseline at n=30, J1 Fighter T3+ wall, J2 Mage T2+ wall,
J3 T5 boss (sim artifact vs over-tuned vs raid content),
J4 validation matrix.
2026-05-17 13:37:21 -07:00
prosolis
a8f8be6f40 Sim runner: day-cycle fast-forward, auto-combat, log capture
RunExpedition now drives expeditions end-to-end through the production
plugin paths:
- TickDay calls deliverRecap + deliverBriefing with a synthetic clock
  anchored on exp.StartDate, advancing one day per call without
  real-time waits.
- Autopilot bursts use compact mode so elite gates auto-resolve inline.
- Boss / surviving elite gates are auto-resolved via handleFightCmd +
  looped handleAttackCmd until the session flips Won/Lost/Fled.
- Forks resolve to path 1 deterministically.
- SimResult exposes StopCode, Walks, DayTicks, Threat, plus the full
  dnd_expedition_log projected as SimLogEntry rows.
2026-05-17 13:12:34 -07:00
prosolis
ebea2b430a Sim scaffold: cmd/expedition-sim drives synthetic expeditions
SimRunner re-uses production plugin code paths against a fresh sqlite DB —
SendDM no-ops without a Matrix client, so ground truth comes from the DB.
BuildCharacter persists adv+dnd character rows with class-appropriate
ability scores and spell slots; RunExpedition loops !expedition run with
stall detection until the autopilot halts or the expedition closes.

The cmd binary is a thin orchestrator: one flag-driven run, JSON output.
Per-room structured logging, day-cycle fast-forward, and matrix batching
are next session.
2026-05-17 12:55:23 -07:00