sts2-bot/docs/research
0xrsydn f249349dd8 docs(research): TypeSafe best-practice gap analysis
Read the vendor documentation against what the bot actually does, and separate
what is measured from what is merely by construction.

Adopt structured criteria where disambiguation costs us -- measured on card
play, the structured shape picked the same card 6/6 with margin 0.425 -> 0.473,
so it is a small effect worth having at irreversible decisions, not a blanket
rewrite.

What the measurements KILLED, recorded so it is not retried:

  * A fight-level plan asked as a Score was unusable on 4 of 6 combat states,
    confidence as low as 0.01. Fight-level planning stays in code.
  * "A bigger margin means a better play" is not supported: the same question
    repeated on the same state returned 0.04 -> 0.24 and 0.36 -> 0.02. We have
    no optimal-action label, so a higher margin is evidence of noise, not skill.

Also records three correctness fixes that are independent of any model question:
enemy block counted twice in the lethal search, the executor ignoring player
statuses, and `relic_select` asking `good_relicN` while reading `relicN`.
2026-09-22 06:09:16 +07:00
..
01-game-engine-and-mod-surface.md Add design doc and research notes 2026-09-22 00:01:22 +07:00
02-system-one-jev.md Add design doc and research notes 2026-09-22 00:01:22 +07:00
03-sts2mcp-interface.md Add design doc and research notes 2026-09-22 00:01:22 +07:00
04-state-shapes.md Add design doc and research notes 2026-09-22 00:01:22 +07:00
05-failure-modes.md Add design doc and research notes 2026-09-22 00:01:22 +07:00
06-decision-architecture.md Add design doc and research notes 2026-09-22 00:01:22 +07:00
07-run-log.md Add design doc and research notes 2026-09-22 00:01:22 +07:00
08-what-actually-wins.md docs(research): what actually wins in Slay the Spire 2 2026-09-22 06:09:16 +07:00
09-typesafe-best-practice.md docs(research): TypeSafe best-practice gap analysis 2026-09-22 06:09:16 +07:00
README.md Add design doc and research notes 2026-09-22 00:01:22 +07:00

STS2 Bot — Research Notes

Living notes on reverse-engineering Slay the Spire 2 and driving it with a TypeSafe System One (Jev) decision model.

These documents record what was measured, not what was assumed. Where a claim comes from a live test, the evidence is quoted. Where something is a guess, it says so.

Contents

# Document Covers
01 Game engine and mod surface Engine, assemblies, the official mod loader, manifest schema
02 System One / Jev What Jev is, measured latency and cost, the arithmetic failure
03 STS2MCP interface The community mod, version drift, rebuilding from source
04 State shapes Every verified JSON shape, per state_type
05 Failure modes Every infinite loop found live, with its fix
06 Decision architecture The three-layer design and why the split is where it is
07 Run log Results per run, with seeds and outcomes

Architecture summary lives in ../DESIGN.md.

How to add a finding

  1. Prefer a measurement over an inference. Quote the command and the output.
  2. Put game facts in 01/03/04, model facts in 02, bugs in 05.
  3. Record the date and the game build (v0.107.1 today). Both move.
  4. When a finding is later disproved, do not delete it. Mark it superseded and say what replaced it. The wrong turn is often the useful part.

Environment these notes were taken on

Item Value
Game build v0.107.1, commit 59260271
Platform macOS (arm64), Steam
Engine Godot 4.5.1 (.NET), runtime .NET 9.0.7
Mod STS2MCP, rebuilt from upstream main @ 55e0648
Model jev-latest resolving to jev-1.13.0

Rebuilding the mod

STS2MCP release 0.4.0 is broken on this game build. See 03. To rebuild:

cd ~/sts2-bot/vendor/STS2MCP
nix shell nixpkgs#dotnet-sdk_9 --command bash -c '
  dotnet build STS2_MCP.csproj -c Release -o out/STS2_MCP \
    -p:STS2GameDir="$HOME/Library/Application Support/Steam/steamapps/common/Slay the Spire 2"'
cp out/STS2_MCP/STS2_MCP.dll \
   "$HOME/Library/Application Support/Steam/steamapps/common/Slay the Spire 2/SlayTheSpire2.app/Contents/MacOS/mods/"

Then restart the game. Mods load only at process start.

Testing

Two suites, both offline. Run them before every session.

python3 test_brain.py    # 54 assertions — structural / programmatic
python3 test_facts.py    # 29 assertions — arithmetic and parsing

test_brain.py is the important one for catching usage bugs. It asserts that every state_type produces an action legal for that state, that every action the decision layer can emit is declared somewhere, and that every fallback respects its own inputs. It needs no model and no running game.

It was added after a session in which four separate infinite loops and three hardcoded fallbacks were found by hand. Most of them would have been caught here.