Skip to content

Fight simulator stage 3: sweeps, real worlds, CSV and the fight table - #93

Merged
calebl merged 1 commit into
mainfrom
fm/ta-fight-sim-3
Oct 30, 2026
Merged

calebl merged 1 commit into
mainfrom
fm/ta-fight-sim-3

Conversation

@calebl

@calebl calebl commented Oct 30, 2026

Copy link
Copy Markdown
Contributor

Stage 3 of the fight simulator (stages 1 and 2: #91, #92): sweeps, real worlds, CSV and the fight table. No rule change, and the CI reference fights are unchanged (fight --check sim still agrees on all 10).

  • Grid sweeps (sim::sweep): a matchup file's sweep: key, e.g. {player.stats.level: [3, 4, 5, 6], foes.0.stats.level: [1, 2, 3]}. Each key is a dotted path into the file, so any key a matchup reads can be swept (stats, counts, story.*, policy.*). Each point is the file with its values set, read again in full.
  • Real worlds (sim::world): --database FILE --story TITLE [--levels A..B] fights each of the story's hostiles against its protagonist at each level. The database is serialized into memory and the file is closed before anything is read, so it is never written. Stat blocks come from the world, and fights run in the arena, so no room writer is needed. A NULL stat is rolled for each seed. An optional matchup file sets seeds, carrying and policy.
  • --fight-table FILE|- (sim::export::fight_table): JSON with each matchup's P(win) and its interval, P(died/fled/stalled), and hp_loss (the share of all fights that cost N HP and were survived; this plus p_died sums to 1).
  • --csv: one row per matchup, with every rate, its interval and the means. A grid with no flag prints a one-row-per-matchup text table.
  • Tests (tests/sim.rs): a sweep point plays the same fights seed for seed as its matchup written out alone. A world run leaves the file byte-identical, fights every hostile at every level, and plays what its stat blocks would. The fight table's probabilities sum to 1. Plus unit tests for grid expansion, levels and CSV quoting. The README "Measuring fights" section is updated.

Sample grid

cargo run --release --bin fight -- sim/matchups/levels-grid.yml: the house body (d8, abilities 10) at player levels 3–6 against one d10 foe at levels 1–3, attacking to the end, told driver, seeds 1..2000:

player.stats.level  foes.0.stats.level  fights     won  won 95%           died   fled  rounds  hp left
3                   1                     2000   0.907  [0.894, 0.919]  0.092  0.000    2.63     9.73
3                   2                     2000   0.579  [0.557, 0.600]  0.421  0.000    3.40     6.26
3                   3                     2000   0.230  [0.212, 0.249]  0.770  0.000    3.72     4.64
4                   1                     2000   0.977  [0.969, 0.982]  0.024  0.000    2.72    13.95
4                   2                     2000   0.792  [0.774, 0.809]  0.208  0.000    3.77     9.09
4                   3                     2000   0.451  [0.429, 0.472]  0.549  0.000    4.39     6.37
5                   1                     2000   0.997  [0.993, 0.998]  0.004  0.000    2.74    18.63
5                   2                     2000   0.914  [0.901, 0.926]  0.086  0.000    3.95    12.62
5                   3                     2000   0.664  [0.643, 0.684]  0.336  0.000    4.86     8.71
6                   1                     2000   1.000  [0.997, 1.000]  0.001  0.000    2.74    23.57
6                   2                     2000   0.968  [0.959, 0.974]  0.033  0.000    4.03    16.83
6                   3                     2000   0.828  [0.810, 0.843]  0.172  0.000    5.16    11.60

@calebl
calebl merged commit 84d90e0 into main Oct 30, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant