Commit Graph

4 Commits

Author SHA1 Message Date
ctan 7591614460 feat(cli): add --transcript option 2026-09-04 23:34:12 +02:00
ctan 625e8c56b9 feat(runner): wire spell registry in CLI and Monte Carlo 2026-09-04 23:02:21 +02:00
ctan c88d8fd6f4 refactor(loaders): unify combatant loader, migrate PC features/spells
Rename monster.py → combatant.py with _KNOWN_FEATS lookup table
that resolves feat name strings to AbilitySpec constants (Power Attack,
Iron Will, Toughness, Weapon Focus, etc.). Unknown feats produce
minimal AbilitySpec (data preserved for future implementation).

Migrate all 8 PC JSONs (data/pcs/) with complete feat/spell lists
extracted from Foundry sheets — including traits, racial abilities,
and all spells. Monsters (goblin, orc) unchanged (no feats/spells).

Update all imports, add backward-compatible aliases (load_monster,
MonsterLoadError), update CLI to use load_combatant.

Gate: 377 tests, ruff clean, basedpyright clean.
2026-08-17 22:49:50 +02:00
ctan a21e234b41 feat(runner): Monte Carlo runner, closed-form metrics and balance CLI
Adds the S6 layer on top of the deterministic combat engine:
- metrics.py: closed-form binomial statistics (win rate, standard error,
  3-sigma confidence band) with clamped degenerate proportions.
- runner.py: EncounterSpec/Side definitions, per-run SeededRng streams,
  global duplicate-id disambiguation, attrition averages per combatant.
- cli.py: pf1e-sim entry point producing a French balance report with
  win rates, 3-sigma bands, draws, rounds, and attrition.
- Movement fix: greedy straight-line heuristic could oscillate at walls;
  _step_toward now follows the true shortest path via an unbounded
  Dijkstra cost field from the target (Grid.reachable budget=None).
- Regression tests: melee unit routes around a wall and engages; grid
  unbounded-budget coverage.
2026-08-17 22:49:50 +02:00