Skip to content
SLAY2

Evidence & methods

A ledger, not a leaderboard

Every number on this site is either exact arithmetic over a rule listed below, a clearly labelled heuristic, or a measured simulator result with its sample size and interval. Where nothing has been measured, this page says “not yet evaluated”. Last audited rules apply to Slay the Spire 2 main v0.107.1.

Rule register

45 rules, each with its evidence

  • 29

    Verified against the game's own logic or official statements

  • 2

    Corroborated by independent secondary sources

  • 1

    Single secondary source or unverified

  • 13

    Recorded fact (build, implementation note)

Evidence classes: E1 inspection of the game’s own logic for v0.107.1 (read-only, local, nothing redistributed) · E2 official Mega Crit statements · E3/E4/E5 published wikis and calculators · E6 SLAY2’s own exact computation. A rule is “verified” only when its logic was read or officially stated, not merely repeated by a wiki.

Run structure

RuleWhat the game doesEvidence
RUN-1A run has exactly 3 acts. Act index 0 = Overgrowth *or* Underdocks, 1 = Hive, 2 = Glory. DeprecatedAct has index -1 and is never used. "Act 1-4" in third-party simulators counts four act *models*, not four acts.

E1 Models.Acts/{Overgrowth,Underdocks,Hive,Glory,DeprecatedAct}.cs (Index), Models/ActModel.cs GetRandomList, Models/ModelDb.cs ActsByIndex; E3

VERIFIED-E1

RUN-2After the last act's boss, the game enters the scripted TheArchitect event room; when it completes (IsVictoryRoom) WinRun() ends the run as a victory. The event contains no player-damaging logic, so *win = clear the final act (both bosses at A10)*. There is no Heart, no keys, no Act 4.

E1 Runs/RunManager.cs EnterNextAct/WinRun, Models.Events/TheArchitect.cs

VERIFIED-E1

RUN-3Underdocks (alternate Act 1) must be unlocked; in single player an undiscovered non-default act takes priority, then the game rolls between available acts.

E1 ActModel.GetRandomList; E3 /acts

VERIFIED-E1

RUN-4Double Boss (A10): the last act additionally gets a second, different boss chosen at run start from that act's other boss encounters (up-front RNG - hidden until shown).

E1 RunManager.cs (act setup loop); E5

VERIFIED-E1

RUN-5Act map: 7 columns; 17/17/16/15 floors (Overgrowth/Underdocks/Hive/Glory) in solo, one fewer room in co-op; 3 merchants; 5 elites (8 with A1); first room is a fight; elites/rests never in first five rooms; a rest site always precedes the boss.

E3 /acts

SECONDARY

Ascension (cumulative: level N includes 1..N)

RuleWhat the game doesEvidence
ASC-1Enum: 0 None, 1 SwarmingElites, 2 WearyTraveler, 3 Poverty, 4 TightBelt, 5 AscendersBane, 6 Inflation, 7 Scarcity, 8 ToughEnemies, 9 DeadlyEnemies, 10 DoubleBoss. Max = 10 (maxAscensionAllowed). HasLevel(x) = level >= x. There is no A11-A20.

E1 Entities.Ascension/AscensionLevel.cs, AscensionManager.cs; E5; E3

VERIFIED-E1

ASC-2A3 Poverty: encounter gold min/max = (int)(base * 0.75) (truncating): monster 7-15, elite 26-33, boss 75 (base 10-20 / 35-45 / 100).

E1 Models/EncounterModel.cs, Helpers/AscensionHelper.cs

VERIFIED-E1

ASC-3A4 Tight Belt: -1 potion slot. A5: Ascender's Bane added to the starting deck (floor 1).

E1 AscensionManager.ApplyEffectsTo

VERIFIED-E1

ASC-4A6 Inflation: card removal costs 100 + 50*n instead of 75 + 25*n (n = removals used). (Older "Gloom: fewer rest sites" text is stale.)

E1 Entities.Merchant/MerchantCardRemovalEntry.cs; E5 (changed v0.103.2)

VERIFIED-E1

ASC-5A7 Scarcity: see CARD-3..CARD-6 and UPG-1.

E1 Odds/CardRarityOdds.cs, Factories/CardFactory.cs

VERIFIED-E1

ASC-6A2 Weary Traveler (Ancients heal 80% of missing HP), A1 (+3 elites), A8/A9 (enemy HP / damage)

E5, E3

CORROBORATED

Card reward rarity (the "rare offset")

RuleWhat the game doesEvidence
CARD-1Rarity roll with offset o: draw r ~ U[0,1); T_rare = baseRare + o (not clamped); rare if r < T_rare; uncommon if r < baseUncommon + T_rare; else common. Hence P(rare)=clamp(baseRare+o,0,1) and the uncommon/common boundary shifts with the offset (regular fight at the -5 start: 0 / 35 / 65 %, not 0 / 37 / 63 %).

E1 Odds/CardRarityOdds.cs RollWithoutChangingFutureOdds; E3 wording

VERIFIED-E1

CARD-2Base odds (rare / uncommon): regular 3% / 37%, elite 10% / 40%, shop 9% / 37%, boss 100% rare (offset ignored in the roll).

E1 CardRarityOdds.GetBaseOdds; E3; E4

VERIFIED-E1

CARD-3A7 base rare: regular 1.49% (not 1.5), elite 5%, shop 4.5%; uncommon unchanged.

E1 CardRarityOdds.RegularRareOdds/EliteRareOdds/ShopRareOdds; E3 (E4 prose omits it)

VERIFIED-E1

CARD-4After each card of an Encounter-sourced reward whose odds type is Regular/Elite/Boss: rare -> offset = -0.05; non-rare -> offset = min(offset + growth, 0.40). Cards in a pack are rolled sequentially, so later cards see earlier results; cards after a rare in the *same* pack restart from -0.05.

E1 CardRarityOdds.Roll, Factories/CardFactory.cs RollForRarity

VERIFIED-E1

CARD-5Boss rewards also reset the counter (Roll(BossEncounter) returns Rare -> offset = -0.05) even though the roll ignores the offset. (sts.wiki only says "offset ignored".)

E1 CardRarityOdds.Roll

VERIFIED-E1

CARD-6Shop cards read the offset without advancing it (RollWithoutChangingFutureOdds(Shop)); non-encounter sources (events, relic packs such as Orrery) use RollWithBaseOdds: rare if r < baseRare, uncommon if r < baseUncommon (not cumulative) -> 3 / 34 / 63 % at A0 regular odds. Neither advances the counter.

E1 CardRarityOdds, CardFactory.cs; E3 ("3% / 34% / 63%")

VERIFIED-E1

CARD-7If no eligible card exists at the rolled rarity, the roll steps to the next-higher rarity with wrapping (GetNextAllowedRarity). A card is then drawn uniformly from the eligible cards of that rarity not already in the pack.

E1 CardFactory.cs

VERIFIED-E1

CARD-8Derived published checks that my model reproduces exactly: offset table (28 cells incl. A7), "1+ rare right after a rare": regular 0 %, elite 16.95 %; stationary run averages regular 19.72 % / elite 30.91 %.

E6 vs E3, E4

CORROBORATED

CARD-9Per-player odds sets (co-op: each seat has its own counters).

E1 Odds/PlayerOddsSet.cs

VERIFIED-E1

Upgrades on reward cards

RuleWhat the game doesEvidence
UPG-1After each pack card: r ~ U[0,1); if the card is upgradable: odds = actIndex * scaling for non-rare cards (scaling = 0.25, A7 0.125), 0 for rares; upgrade if r <= odds. => Act 1: 0 %, Act 2: 25 % (12.5 % A7), Act 3: 50 % (25 % A7). Shop cards never upgrade (base -999999999). Relics/events may modify via hooks (not modelled).

E1 Factories/CardFactory.cs RollForUpgrade, UpgradedCardOddScaling; E3

VERIFIED-E1

Potions

RuleWhat the game doesEvidence
POT-1Stored chance c starts 0.40. After each eligible fight: threshold = c + (Elite ? 0.25*0.5 = 0.125 : 0); r ~ U[0,1); if forced

POT-2Forced drops (Hook.ShouldForcePotionReward, e.g. White Beast Statue) also decrement c in v0.107.1. Beta v0.108.0 changed this ("no longer decreases your normal potion odds"). Pin per build.

E1; E2 beta v0.108.0 notes

VERIFIED-E1

POT-3Dropped potion rarity: r<=0.10 rare, r<=0.35 uncommon, else common => 10 / 25 / 65 %.

E1 Factories/PotionFactory.cs; E3, E4

VERIFIED-E1

POT-4v0.107.1 fixed a bug where the follow-up potion odds could rise instead of fall after an elite potion reward. Data from builds before 0.107.1 is not comparable.

E2 (v0.107.1 notes)

VERIFIED

Unknown "?" rooms

RuleWhat the game doesEvidence
UNK-1Counters start at base: fight 0.10, elite -1 (disabled), treasure 0.02, shop 0.03. One roll r ~ U[0,1]; scan fight -> (elite) -> treasure -> shop accumulating only positive counters; the first with r <= cumulative wins; otherwise event (1 - sum of positive counters).

E1 Odds/UnknownMapPointOdds.cs Roll; E4

VERIFIED-E1

UNK-2After each roll the rolled type resets to its base; every other enabled type gains +base (hook-modifiable). Counters reset to base between acts (ResetToBase). The marginal event/fight/shop/treasure mix for the n-th "?" of an act: 85/10/3/2, 71.13/19/5.91/3.96, 60.34/25.30/8.56/5.80, 53.47/28.27/10.80/7.46, 49.94/28.62/12.56/8.88, 48.35/27.83/13.80/10.03 %.

E1; E6 vs E4 table

VERIFIED-E1

UNK-3A profile's very first run is scripted: first two "?" rooms are events, the third is a monster fight.

E1 (UnlockState.NumberOfRuns == 0)

VERIFIED-E1

UNK-4Not modelled: the room-type *blacklist* supplied by callers and relic hooks (ModifyUnknownMapPointRoomTypes, ModifyOddsIncreaseForUnrolledRoomType).

E1

Merchant

RuleWhat the game doesEvidence
SHOP-1Stock: 5 character cards of types [Attack, Attack, Skill, Skill, Power] (rarity rolled per slot via shop odds, fallback by card type), one uniformly random character slot on sale; 2 colorless cards (one Uncommon, one Rare); 3 relics (two rarity-rolled 50/33/17 % common/uncommon/rare, one "Shop"-rarity); 3 potions; one card-removal service.

E1 Entities.Merchant/MerchantInventory.cs, RelicFactory.RollRarity; E3

VERIFIED-E1

SHOP-2Card price = round(base * U[0.95,1.05]); base common 50 / uncommon 75 / rare 150; colorless base x1.15 rounded (86 / 173); on sale: integer /2.

E1 MerchantCardEntry.cs

VERIFIED-E1

SHOP-3Relic price = round(MerchantCost * U[0.85,1.15]); MerchantCost: common 175, uncommon 225, rare 275, shop 200. Potion price = round(base * U[0.95,1.05]), base common 50 / uncommon 75 / rare 100.

E1 Models/RelicModel.cs, MerchantRelicEntry.cs, MerchantPotionEntry.cs

VERIFIED-E1

SHOP-4Card removal cost = Base + Increase * removalsUsed; A0: 75 + 25n; A6+: 100 + 50n.

E1 MerchantCardRemovalEntry.cs

VERIFIED-E1

SHOP-5Final price may be modified by relic hooks (ModifyMerchantPrice); not modelled.

E1 MerchantEntry.Cost

Gold

RuleWhat the game doesEvidence
GOLD-1Combat gold = uniform integer in [min, max]: monster 10-20, elite 35-45, boss 100 (Poverty: see ASC-2); scaled by the room's GoldProportion in special encounters (e.g. escaped Gremlins).

E1 Rewards/GoldReward.cs, EncounterModel.cs, RewardsSet.cs

VERIFIED-E1

Draw mathematics (no game source needed)

RuleWhat the game doesEvidence
DRAW-1Drawing n cards without replacement from N with K targets: P(>=1)=1-C(N-K,n)/C(N,n); full PMF is hypergeometric. Valid only for a uniformly shuffled draw pile with no reshuffle during the draw; retain/ethereal/exhaust/innate/discard/orbs/shuffle-triggers invalidate it (the UI must say so).

E6 (pure math)

Build/patch facts

RuleWhat the game doesEvidence
BLD-1Main v0.107.1 (2026-06-18 "Major Update #2"), Steam build 23811903. Beta v0.111.0 (2026-08-13), build id 24724944 (2026-08-14 update). Newest announcement at retrieval: Neowsletter 2026-09-25 ("can't give a specific timeline ... for the next patch").

E2, E4, E1 GAME_VERSIONS.md

BLD-2v0.107.1 replaced the PRNG (xoshiro256): seeds from earlier builds do not reproduce; seeds must never be compared across builds.

E2

BLD-3Beta v0.108-v0.111 changed several card rarities (e.g. Echoing Slash, Bloodletting, Cruelty, Dominate, Accelerant, Flanking, Ignition) and White Beast Statue's potion interaction. Pools and odds are therefore build-specific.

E2

BLD-4Act-3 boss Doormaker was removed and replaced by Aeonglass (main v0.107.1).

E2

Implementation status (engines, tests) - updated 2026-10-25

RuleWhat the game doesEvidence
UPG-1upgrade.ts

G P

DRAW-1draw.ts, combinatorics.ts

G B Q

POT-5Potion rolls happen after normal fights, elites and bosses; elites add +12.5 points to the roll only. The final boss gives no gold, cards, potion or relic.

E1 Rewards/RewardsSet.cs; E3 sts.wiki card-rewards page

CARD-10Relics that change card packs (Prayer Wheel: second regular pack after fights; White Star: all-rare pack after elites; Lasting Candy; Driftwood: reroll; Pael's Wing: sacrifice; Orrery: five packs from base odds; Dingy Rug/Prismatic Gem: pool changes; Molten Egg/Silver Crucible/Lava Lamp: upgrades) are not modelled; the advisor must say "relic X changes this" instead of silently using base rules.

E3 sts.wiki

SHOP-6Merchant relics from treasure rolls are common 50 % / uncommon 33 % / rare 17 %; elite relics use the same split.

E3, E4

How the exact odds are checked

Four independent layers

  1. Independent implementation

    A separate Python oracle (exact fractions) generated 720 golden cases across 14 kinds of question; the TypeScript engine must match every one with exact equality.

  2. Published tables

    The pity-offset table (28 cells, A0 and A7), base odds, after-a-rare chances, run averages, the “?” table, shop price ranges, card removal and gold ranges are asserted against what the wikis publish.

  3. Brute force and properties

    Hypergeometric draws are compared with explicit subset enumeration, reshuffles with permutations, and posteriors with enumeration of every outcome path. Property tests cover distributions that must sum to exactly one.

  4. Mutation checks

    Deliberately changing a rule constant (the A7 rate, the boss reset) makes the suite fail, which shows the tests can see the rules they claim to protect.

Known limit: the game compares 32-bit floats, SLAY2 uses ideal decimals; the difference is below 1e-6 and is stated on every result.

Simulator results · research only

What a third-party simulator says about simple policies

Parity with the live game unverified

These runs use a community Python re-implementation of STS2, driven by SLAY2’s own harness (it classifies simulator errors and timeouts instead of counting them as losses). They are baselines for building better policies, not statements about real win rates. 14 simulated games have been won so far: rules_v2 7 of 1,996 completed games (held-out seeds; 7 of 7 wins re-run and replayed hash for hash); rules_v2 6 of 1,994 completed games (held-out seeds; 6 of 6 wins re-run and replayed hash for hash); rules_v2 1 of 1,987 completed games (held-out seeds; 1 of 1 wins re-run and replayed hash for hash); the intervals below show how uncertain each batch is.

PolicyCohortCompleted gamesWinsWin rate (95% Wilson)Mean floorPartition
random_legalladder-random_legal-ironclad-a0-first_run-train-n100Ironclad A0 · first-run (scripted)10000.00% (0.00%–3.70%)4.9development (train partition): not a held-out result
random_legalladder-random_legal-ironclad-a0-veteran-train-n2000Ironclad A0 · veteran profile199900.00% (0.00%–0.19%)4.47development (train partition): not a held-out result
random_legal40 of 40 sampled games re-derivedrandom_legal-ironclad-a0-veteran-val-n2000Ironclad A0 · veteran profile200000.00% (0.00%–0.19%)4.48held-out
rules_v140 of 40 sampled games re-derivedrules_v1-defect-a0-veteran-val-n2000Defect A0 · veteran profile199900.00% (0.00%–0.19%)15.93held-out
rules_v1rules_v1-ironclad-a0-veteran-train-n300Ironclad A0 · veteran profile30000.00% (0.00%–1.26%)18.29development (train partition): not a held-out result
rules_v140 of 40 sampled games re-derivedrules_v1-ironclad-a0-veteran-val-n2000Ironclad A0 · veteran profile199700.00% (0.00%–0.19%)18.08held-out
rules_v140 of 40 sampled games re-derivedrules_v1-necrobinder-a0-veteran-val-n2000Necrobinder A0 · veteran profile199700.00% (0.00%–0.19%)17.63held-out
rules_v140 of 40 sampled games re-derivedrules_v1-regent-a0-veteran-val-n2000Regent A0 · veteran profile198700.00% (0.00%–0.19%)13.54held-out
rules_v140 of 40 sampled games re-derivedrules_v1-silent-a0-veteran-val-n2000Silent A0 · veteran profile199900.00% (0.00%–0.19%)13.36held-out
rules_v2 (values=experiments/cardvalue/defect-a0-v1.json)1,999 of 2,000 games re-derived exactly40 of 40 sampled games re-derivedrules_v2-defect-a0-veteran-val-n2000Defect A0 · veteran profile199670.35% (0.17%–0.72%)21.3held-out
rules_v2rules_v2-ironclad-a0-veteran-dev-n500Ironclad A0 · veteran profile49900.00% (0.00%–0.76%)21.12development (dev partition): not a held-out result
rules_v22,000 of 2,000 games re-derived exactly40 of 40 sampled games re-derivedrules_v2-ironclad-a0-veteran-val-n2000Ironclad A0 · veteran profile199460.30% (0.14%–0.65%)21.07held-out
rules_v2 (values=experiments/cardvalue/necrobinder-a0-v1.json)1,997 of 2,000 games re-derived exactly40 of 40 sampled games re-derivedrules_v2-necrobinder-a0-veteran-val-n2000Necrobinder A0 · veteran profile199900.00% (0.00%–0.19%)19.63held-out
rules_v2 (values=experiments/cardvalue/regent-a0-v1.json)2,000 of 2,000 games re-derived exactly40 of 40 sampled games re-derivedrules_v2-regent-a0-veteran-val-n2000Regent A0 · veteran profile198710.05% (0.01%–0.28%)17.84held-out
rules_v2 (values=experiments/cardvalue/silent-a0-v1.json)1,998 of 2,000 games re-derived exactly40 of 40 sampled games re-derivedrules_v2-silent-a0-veteran-val-n2000Silent A0 · veteran profile200000.00% (0.00%–0.19%)14.34held-out
search_v1before isolation fixsearch_v1-ironclad-a0-veteran-train-n200Ironclad A0 · veteran profile20000.00% (0.00%–1.88%)16.04development (train partition): not a held-out result
search_v3 (scope=boss)before isolation fixsearch_v3-boss-ironclad-a0-veteran-dev-n500Ironclad A0 · veteran profile50000.00% (0.00%–0.76%)21.91development (dev partition): not a held-out result

Paired comparisons

Two policies played the same seeds, so the difference is measured seed by seed. Only seeds where both reached a win or a death count; anything else is listed as excluded, never scored as a loss.

A vs BPaired gamesMean floor A · BA − B (95% bootstrap)Past the Act-1 boss A · BWins A · BPartition
rules_v1 vs random_legalIronclad A0 · veteran · sha 0a442434261997 (+3 excluded)18.08 · 4.48+13.60 (+13.31 to +13.90)43.3% · 0.0%p = 8.1e-2610 · 0held-out
rules_v1 vs search_v1before isolation fixIronclad A0 · veteran · sha fb860edec220018.41 · 16.04+2.38 (+1.24 to +3.54)44.5% · 28.0%p = 0.000180 · 0development (train partition): not a held-out result
rules_v2 (values=experiments/cardvalue/defect-a0-v1.json) vs rules_v1Defect A0 · veteran · sha e08a4a4b151996 (+4 excluded)21.30 · 15.93+5.37 (+5.00 to +5.75)76.2% · 34.5%p = 7.2e-1677 · 0held-out
rules_v2 vs rules_v1Ironclad A0 · veteran · sha 6c62f583791991 (+9 excluded)21.05 · 18.08+2.96 (+2.61 to +3.32)65.1% · 43.3%p = 8.8e-576 · 0held-out
rules_v2 (values=experiments/cardvalue/necrobinder-a0-v1.json) vs rules_v1Necrobinder A0 · veteran · sha c1158801ba1997 (+3 excluded)19.62 · 17.63+1.99 (+1.69 to +2.30)62.1% · 47.8%p = 5.9e-300 · 0held-out
rules_v2 (values=experiments/cardvalue/regent-a0-v1.json) vs rules_v1Regent A0 · veteran · sha 091ffbceb81978 (+22 excluded)17.85 · 13.54+4.32 (+4.00 to +4.63)49.7% · 14.0%p = 3.9e-1541 · 0held-out
rules_v2 (values=experiments/cardvalue/silent-a0-v1.json) vs rules_v1Silent A0 · veteran · sha f8da0207311999 (+1 excluded)14.34 · 13.36+0.97 (+0.74 to +1.20)18.5% · 11.5%p = 8.5e-130 · 0held-out
search_v3 (scope=boss) vs rules_v2before isolation fixIronclad A0 · veteran · sha fcc65c6198499 (+1 excluded)21.90 · 21.12+0.78 (+0.29 to +1.27)71.9% · 64.1%p = 3.8e-60 · 0development (dev partition): not a held-out result

Reading these honestly

  • For Ironclad, mean floor rises from 4.5 (random legal moves, 2000 games) to 18.1 (hand-written rules, 1997 games), so the harness does measure skill.
  • rules_v1 reached more floors than random_legal: +13.60 floors for rules_v1 relative to random_legal (95% bootstrap interval +13.31 to +13.90, 1997 paired games); rules_v1 took 1.7× as long per game. Past the Act-1 boss: 43.3% for rules_v1 and 0.0% for random_legal (865 games only rules_v1, 0 only random_legal; exact McNemar p = 8.1e-261).
  • rules_v1 reached more floors than search_v1: +2.38 floors for rules_v1 relative to search_v1 (95% bootstrap interval +1.24 to +3.54, 200 paired games); search_v1 took 19.7× as long per game. Past the Act-1 boss: 44.5% for rules_v1 and 28.0% for search_v1 (54 games only rules_v1, 21 only search_v1; exact McNemar p = 0.00018).
  • rules_v2 (values=experiments/cardvalue/defect-a0-v1.json) reached more floors than rules_v1: +5.37 floors for rules_v2 (values=experiments/cardvalue/defect-a0-v1.json) relative to rules_v1 (95% bootstrap interval +5.00 to +5.75, 1996 paired games); rules_v2 (values=experiments/cardvalue/defect-a0-v1.json) took 1.1× as long per game. Past the Act-1 boss: 76.2% for rules_v2 (values=experiments/cardvalue/defect-a0-v1.json) and 34.5% for rules_v1 (937 games only rules_v2 (values=experiments/cardvalue/defect-a0-v1.json), 106 only rules_v1; exact McNemar p = 7.2e-167).
  • rules_v2 reached more floors than rules_v1: +2.96 floors for rules_v2 relative to rules_v1 (95% bootstrap interval +2.61 to +3.32, 1991 paired games); rules_v2 took 1.4× as long per game. Past the Act-1 boss: 65.1% for rules_v2 and 43.3% for rules_v1 (608 games only rules_v2, 175 only rules_v1; exact McNemar p = 8.8e-57).
  • rules_v2 (values=experiments/cardvalue/necrobinder-a0-v1.json) reached more floors than rules_v1: +1.99 floors for rules_v2 (values=experiments/cardvalue/necrobinder-a0-v1.json) relative to rules_v1 (95% bootstrap interval +1.69 to +2.30, 1997 paired games); rules_v1 took 1.1× as long per game. Past the Act-1 boss: 62.1% for rules_v2 (values=experiments/cardvalue/necrobinder-a0-v1.json) and 47.8% for rules_v1 (468 games only rules_v2 (values=experiments/cardvalue/necrobinder-a0-v1.json), 182 only rules_v1; exact McNemar p = 5.9e-30).
  • rules_v2 (values=experiments/cardvalue/regent-a0-v1.json) reached more floors than rules_v1: +4.32 floors for rules_v2 (values=experiments/cardvalue/regent-a0-v1.json) relative to rules_v1 (95% bootstrap interval +4.00 to +4.63, 1978 paired games); rules_v2 (values=experiments/cardvalue/regent-a0-v1.json) took 1.1× as long per game. Past the Act-1 boss: 49.7% for rules_v2 (values=experiments/cardvalue/regent-a0-v1.json) and 14.0% for rules_v1 (771 games only rules_v2 (values=experiments/cardvalue/regent-a0-v1.json), 65 only rules_v1; exact McNemar p = 3.9e-154).
  • rules_v2 (values=experiments/cardvalue/silent-a0-v1.json) reached more floors than rules_v1: +0.97 floors for rules_v2 (values=experiments/cardvalue/silent-a0-v1.json) relative to rules_v1 (95% bootstrap interval +0.74 to +1.20, 1999 paired games); rules_v1 took 1.3× as long per game. Past the Act-1 boss: 18.5% for rules_v2 (values=experiments/cardvalue/silent-a0-v1.json) and 11.5% for rules_v1 (263 games only rules_v2 (values=experiments/cardvalue/silent-a0-v1.json), 123 only rules_v1; exact McNemar p = 8.5e-13).
  • search_v3 (scope=boss) reached more floors than rules_v2: +0.78 floors for search_v3 (scope=boss) relative to rules_v2 (95% bootstrap interval +0.29 to +1.27, 499 paired games); search_v3 (scope=boss) took 16.7× as long per game. Past the Act-1 boss: 71.9% for search_v3 (scope=boss) and 64.1% for rules_v2 (55 games only search_v3 (scope=boss), 16 only rules_v2; exact McNemar p = 3.8e-6).
  • Batches on the “train” partition are development results, not held-out evidence.
  • Ascension 10 results from this simulator would not be Double Boss results (see gaps).

Known simulator gaps

  • G1-double-boss-not-enteredA10 Double Boss is not modelled: the second Act-3 boss is rolled but the map has no second boss point and the run is won after the first boss (game: StandardActMap.SecondBossMapPoint, one row above the boss). Simulator A10 win rates are therefore NOT Double Boss win rates.
  • G2-a8-hp-scalingLiving Shield, Scroll of Biting and The Merchant??? ignore the A8 HP increase (97 of 100 audited enemy rows match).
  • G3-sovereign-blade-crashis_sovereign_blade(None) raises in rare power/attack interactions (~1 in 2,000 random games); such games are reported as simulator_error and excluded from win rates.
  • G4-rng-familyThe simulator ports .NET System.Random; the game uses xoshiro256** (v0.107.1). Distributions match where audited, but no seed reproduces a live run and per-card roll order differs.
  • G5-no-live-parityState transitions have not been compared with a live STS2 build (no owned game in this environment).
  • G6-undefined-name-in-reward-rollA reward path calls `_roll_random_relic_rewards`, a name the pinned simulator never defines (NameError): 2 of 2,000 rules_v1 validation games ended as simulator_error and are excluded from win rates, never counted as losses.
  • G7-no-legal-actionsIn 1 of 2,000 rules_v1 validation games the run was not over but the simulator offered no legal action; the episode is reported as simulator_error and excluded from win rates.
  • G8-dragon-fruit-lucky-fysh-shopBuying a card in a shop while holding Lucky Fysh (+15 gold per card added) and Dragon Fruit (max HP on gold gained) raises `TypeError: unhashable type: 'PlayerState'` in the pinned simulator (Dragon Fruit's gold handler looks the owner up in a dict keyed by creature). Seen in 1 of 2,000 rules_v1 Silent validation games (seed 605866524, Act 2); the episode is reported as simulator_error and excluded from win rates and paired comparisons.
  • G9-particle-wall-loopRegent's Particle Wall (catalog: 0 energy and 2 stars; gains block and returns to hand) is offered again at cost 0 after every play in the pinned simulator, and the rules policies keep playing it: 33 of 5,000 Regent exploration games (0.66 %) reached the 20,000-step limit with block in the hundreds of thousands. Such games end as timeout, are excluded from card values and paired comparisons and are never read as losses. Whether the simulator charges the stars was not examined; the policies have no guard against replaying a card that returns to hand.
  • G10-first-game-card-id-shiftThe pinned simulator caches some card lookups lazily; the first lookup of a card in a process takes the next card-instance id without returning it (e.g. the first upgrade of a Vicious card, via capture_self_mutating_card_progress). So a game's ids, and in rare situations a pile (Anger's added copy was missing from the discard pile), depended on how many games its process had already played. The harness now puts every process in the same state before its first game (warmup.py, ADR-037); batches written before that fix were produced with the first games of each worker in the other state, and are checked by `audit rederive`.

Every batch is reproducible from a sealed seed manifest; content hashes: ladder:570dd90b36 · ladder:3ab5c40521 · random_legal:6039113dcd · rules_v1:2773566cc7 · rules_v1:f0b6fb7eec · rules_v1:cb67cffc76 · rules_v1:ef7ce115f7 · rules_v1:20345eef47 · rules_v1:ebf95798ba · rules_v2:b4a6768e1e · rules_v2:c6d0120c6c · rules_v2:70a62f3df4 · rules_v2:124099adcf · rules_v2:a20b58d12a · rules_v2:b9f4863b17 · search_v1:5edbd67004 · search_v3:9c6212b8c8

Simulator results · research only

What randomised drafting says a card is worth

Parity with the live game unverified

In simulated runs the card-reward choice was replaced, 60% of the time, by a random pick among the offered cards and “skip”. Chance rather than taste decided which cards reached the Act-1 boss, so a regression of “got past the boss” on the deck, the HP, the potions and the relics gives each card a marginal value: the change in log-odds from one more copy. The protocol and the way each value is judged (a held-out test of whether playing by the values beats playing by the hand-written ratings, written down before the held-out games were played) are the same for every class.

Defect

validated in simulation

3,212 simulated Defect runs reached the Act-1 boss; 40.3% got past it. The model predicts held-out games with AUC 0.903 (log-loss 0.385 against 0.492 without the cards); intervals resample whole game seeds (200 draws). 21 of 92 measured cards have an interval above zero, 13 below, 58 include it. Correlation with the hand-written rating the advisor uses (Spearman): 0.27.

Highest measured values · Defect
CardValue95% intervalOddsRuns
Claw+1.86+1.61 to +2.17×6.4429
Adaptive Strike+1.52+1.04 to +2.11×4.691
Bulk Up+1.47+1.26 to +1.75×4.3564
Ball Lightning+1.46+1.27 to +1.70×4.3722
Rocket Punch+0.84+0.58 to +1.14×2.3415
Lightning Rod+0.79+0.57 to +1.08×2.2391
Lowest measured values · Defect
CardValue95% intervalOddsRuns
Double Energy−0.88−1.38 to −0.33×0.4270
Capacitor−0.66−1.06 to −0.22×0.52117
Shatter−0.63−1.12 to −0.17×0.5396
Defragment−0.60−1.08 to −0.15×0.5551
Fusion−0.55−1.10 to +0.00×0.5865
Hotfix−0.54−0.89 to −0.27×0.58328
  • Past the Act-1 boss

    34.5% → 76.2%

    p = 7.2e-167

  • Mean floor reached

    15.93 → 21.30

    +5.37 (+5.00 to +5.75)

  • Wins

    0 → 7

    p = 0.016, each re-derived

Does acting on the Defect values help? (pre-registered test)

rules_v2 is rules_v1 with one change: it takes the offered card with the largest measured value if that value is above zero (and the deck is under 32 cards), otherwise it skips. Both played the same 2,000 held-out seeds (1,996 completed by both). Past the Act-1 boss: 76.2% for rules_v2 (values=experiments/cardvalue/defect-a0-v1.json) and 34.5% for rules_v1 (937 games only rules_v2 (values=experiments/cardvalue/defect-a0-v1.json), 106 only rules_v1; exact McNemar p = 7.2e-167). Mean floor reached 21.30 against 15.93 (+5.37, 95% bootstrap interval +5.00 to +5.75). Wins: 7 against 0 (p = 0.016). Significance level for this class: 0.0125; the primary endpoint passed.

Ironclad

validated in simulation

3,812 simulated Ironclad runs reached the Act-1 boss; 40.9% got past it. The model predicts held-out games with AUC 0.871 (log-loss 0.439 against 0.503 without the cards); intervals resample whole game seeds (200 draws). 15 of 95 measured cards have an interval above zero, 6 below, 74 include it. Correlation with the hand-written rating the advisor uses (Spearman): 0.31.

Highest measured values · Ironclad
CardValue95% intervalOddsRuns
Rampage+1.74+1.58 to +2.00×5.7493
Fight Me!+1.12+0.99 to +1.34×3.1647
Anger+0.70+0.56 to +0.88×2.0871
Thrash+0.55+0.19 to +0.86×1.752
Taunt+0.47+0.30 to +0.70×1.6483
Brand+0.46+0.15 to +0.77×1.6117
Lowest measured values · Ironclad
CardValue95% intervalOddsRuns
Whirlwind−0.47−0.77 to −0.22×0.63234
Infernal Blade−0.36−0.59 to −0.11×0.70115
Armaments−0.28−0.54 to −0.07×0.75493
Feel No Pain−0.26−0.57 to +0.02×0.77141
Unmovable−0.26−0.46 to −0.02×0.7744
Drum of Battle−0.25−0.48 to −0.07×0.78463
  • Past the Act-1 boss

    43.3% → 65.1%

    p = 8.8e-57

  • Mean floor reached

    18.08 → 21.05

    +2.96 (+2.61 to +3.32)

  • Wins

    0 → 6

    p = 0.031, each re-derived

Does acting on the Ironclad values help? (pre-registered test)

rules_v2 is rules_v1 with one change: it takes the offered card with the largest measured value if that value is above zero (and the deck is under 32 cards), otherwise it skips. Both played the same 2,000 held-out seeds (1,991 completed by both). Past the Act-1 boss: 65.1% for rules_v2 and 43.3% for rules_v1 (608 games only rules_v2, 175 only rules_v1; exact McNemar p = 8.8e-57). Mean floor reached 21.05 against 18.08 (+2.96, 95% bootstrap interval +2.61 to +3.32). Wins: 6 against 0 (p = 0.031). Significance level for this class: 0.05; the primary endpoint passed.

Necrobinder

validated in simulation

3,389 simulated Necrobinder runs reached the Act-1 boss; 44.0% got past it. The model predicts held-out games with AUC 0.915 (log-loss 0.367 against 0.406 without the cards); intervals resample whole game seeds (200 draws). 18 of 91 measured cards have an interval above zero, 11 below, 62 include it. Correlation with the hand-written rating the advisor uses (Spearman): 0.43.

Highest measured values · Necrobinder
CardValue95% intervalOddsRuns
Melancholy+1.30+1.05 to +1.68×3.7337
Hang+1.06+0.56 to +1.53×2.981
Undeath+0.91+0.31 to +1.52×2.586
Fetch+0.81+0.54 to +1.15×2.3322
Delay+0.79+0.55 to +1.07×2.2493
Flash of Steel+0.71+0.24 to +1.20×2.030
Lowest measured values · Necrobinder
CardValue95% intervalOddsRuns
Neurosurge−0.92−1.32 to −0.56×0.40172
End of Days−0.75−1.18 to −0.25×0.4733
Time's Up−0.58−1.13 to −0.05×0.5636
Putrefy−0.58−1.15 to −0.08×0.5674
Reanimate−0.47−1.05 to −0.04×0.6241
Spoils Map−0.44−0.85 to −0.05×0.65170
  • Past the Act-1 boss

    47.8% → 62.1%

    p = 5.9e-30

  • Mean floor reached

    17.63 → 19.62

    +1.99 (+1.69 to +2.30)

  • Wins

    0 → 0

    p = 1.0

Does acting on the Necrobinder values help? (pre-registered test)

rules_v2 is rules_v1 with one change: it takes the offered card with the largest measured value if that value is above zero (and the deck is under 32 cards), otherwise it skips. Both played the same 2,000 held-out seeds (1,997 completed by both). Past the Act-1 boss: 62.1% for rules_v2 (values=experiments/cardvalue/necrobinder-a0-v1.json) and 47.8% for rules_v1 (468 games only rules_v2 (values=experiments/cardvalue/necrobinder-a0-v1.json), 182 only rules_v1; exact McNemar p = 5.9e-30). Mean floor reached 19.62 against 17.63 (+1.99, 95% bootstrap interval +1.69 to +2.30). Wins: 0 against 0 (p = 1.0). Significance level for this class: 0.0125; the primary endpoint passed.

Regent

validated in simulation

2,703 simulated Regent runs reached the Act-1 boss; 22.4% got past it. The model predicts held-out games with AUC 0.898 (log-loss 0.323 against 0.398 without the cards); intervals resample whole game seeds (200 draws). 12 of 88 measured cards have an interval above zero, 14 below, 62 include it. Correlation with the hand-written rating the advisor uses (Spearman): 0.07.

Highest measured values · Regent
CardValue95% intervalOddsRuns
Kingly Punch+2.25+2.05 to +2.65×9.5334
Shining Strike+1.79+1.57 to +2.26×6.0325
Kingly Kick+1.55+1.26 to +1.96×4.7277
Bulwark+0.65+0.26 to +1.05×1.9150
Hegemony+0.59+0.34 to +0.87×1.8479
Gather Light+0.59+0.33 to +0.92×1.8500
Lowest measured values · Regent
CardValue95% intervalOddsRuns
Spoils Map−0.65−1.08 to −0.20×0.52131
Celestial Might−0.52−0.93 to −0.20×0.60273
Alignment−0.48−0.79 to −0.18×0.62270
Reflect−0.47−0.86 to −0.06×0.62372
Radiate−0.43−0.93 to −0.04×0.65180
Bundle of Joy−0.42−0.94 to −0.00×0.6661
  • Past the Act-1 boss

    14.0% → 49.7%

    p = 3.9e-154

  • Mean floor reached

    13.54 → 17.85

    +4.32 (+4.00 to +4.63)

  • Wins

    0 → 1

    p = 1.0, each re-derived

Does acting on the Regent values help? (pre-registered test)

rules_v2 is rules_v1 with one change: it takes the offered card with the largest measured value if that value is above zero (and the deck is under 32 cards), otherwise it skips. Both played the same 2,000 held-out seeds (1,978 completed by both). Past the Act-1 boss: 49.7% for rules_v2 (values=experiments/cardvalue/regent-a0-v1.json) and 14.0% for rules_v1 (771 games only rules_v2 (values=experiments/cardvalue/regent-a0-v1.json), 65 only rules_v1; exact McNemar p = 3.9e-154). Mean floor reached 17.85 against 13.54 (+4.32, 95% bootstrap interval +4.00 to +4.63). Wins: 1 against 0 (p = 1.0). Significance level for this class: 0.0125; the primary endpoint passed.

Silent

validated in simulation

2,332 simulated Silent runs reached the Act-1 boss; 10.7% got past it. The model predicts held-out games with AUC 0.878 (log-loss 0.241 against 0.263 without the cards); intervals resample whole game seeds (200 draws). 14 of 75 measured cards have an interval above zero, 10 below, 51 include it. Correlation with the hand-written rating the advisor uses (Spearman): 0.43.

Highest measured values · Silent
CardValue95% intervalOddsRuns
Dramatic Entrance+1.07+0.43 to +1.65×2.941
Noxious Fumes+0.86+0.24 to +1.32×2.4109
Footwork+0.81+0.54 to +1.10×2.3430
Flash of Steel+0.75+0.01 to +1.38×2.131
Leading Strike+0.70+0.33 to +1.09×2.0204
Echoing Slash+0.59+0.04 to +1.15×1.8127
Lowest measured values · Silent
CardValue95% intervalOddsRuns
Acrobatics−0.88−1.42 to −0.39×0.42249
Spoils Map−0.82−1.16 to −0.44×0.44119
Bubble Bubble−0.76−1.09 to −0.36×0.4752
Speedster−0.75−1.13 to −0.33×0.4766
Calculated Gamble−0.73−0.95 to −0.43×0.4857
Expertise−0.66−1.20 to −0.22×0.52241
  • Past the Act-1 boss

    11.5% → 18.5%

    p = 8.5e-13

  • Mean floor reached

    13.36 → 14.34

    +0.97 (+0.74 to +1.20)

  • Wins

    0 → 0

    p = 1.0

Does acting on the Silent values help? (pre-registered test)

rules_v2 is rules_v1 with one change: it takes the offered card with the largest measured value if that value is above zero (and the deck is under 32 cards), otherwise it skips. Both played the same 2,000 held-out seeds (1,999 completed by both). Past the Act-1 boss: 18.5% for rules_v2 (values=experiments/cardvalue/silent-a0-v1.json) and 11.5% for rules_v1 (263 games only rules_v2 (values=experiments/cardvalue/silent-a0-v1.json), 123 only rules_v1; exact McNemar p = 8.5e-13). Mean floor reached 14.34 against 13.36 (+0.97, 95% bootstrap interval +0.74 to +1.20). Wins: 0 against 0 (p = 1.0). Significance level for this class: 0.0125; the primary endpoint passed.

  • Simulated, not measured in the live game: the simulator has not been compared with a running STS2 build.
  • Specific to the pilot: the rules policy plays the cards, so a card it plays badly is undervalued and one it plays well is overvalued. Synergies are not modelled (the model is additive; a small neural network did not predict held-out games better).
  • A value is conditional on the HP, potions and relics a run brought to the boss; it is not a tier list, and shops, events and rests were not randomised.
  • Data, code and the test protocols are in the repository: experiments/cardvalue/defect-a0-v1.json (sha 4e3cd4615738…), experiments/cardvalue/ironclad-a0-v1.json (sha 8b3fe2f4d88b…), experiments/cardvalue/necrobinder-a0-v1.json (sha 5634d67a81f7…), experiments/cardvalue/regent-a0-v1.json (sha 1a8d0a8861db…), experiments/cardvalue/silent-a0-v1.json (sha fa088419e45e…).

Not yet evaluated

Things this site does not know

Advisor win delta
The card advisor's own index is still a heuristic and says so. Measured values from simulated runs exist (above and on the codex) and a policy that follows them beat the hand-written ratings in simulation, but the advisor does not use them yet and nothing here is a win probability for the live game.
Live-game parity of the simulator
Not verified: no owned game copy was available. Simulator win rates are model output.
Beta build v0.111.0
Unsupported: rules not verified (card rarities and the White Beast Statue potion interaction already differ).
Co-op
Unsupported: per-seat odds exist in the game, scaling and shared decisions are unverified.
Neural policies
None deployed, and no advice on this site comes from a neural network. A research combat network trained locally has not beaten the rules baseline on held-out simulated combats (record: experiments/rl/results in the repository).