Pure Python · Zero Dependencies · Full Bo3

The Modern metagame,
simulated.

21,795 cards. 16 decks. 6,000 Bo3 matches. An EV-based AI brain that mulligans, sequences spells, predicts blocks, and tracks what your opponent is holding — all in 0.68 seconds per match.

0
Cards in DB
0
Modern Decks
0
Bo3 Matches
0
Lines of Python
Architecture
Six layers, one pipeline
From MTGJSON card data to interactive HTML dashboards — every layer has a single responsibility and zero external dependencies.
Data layer
MTGJSON cards, decklists, gameplans, strategy profiles
21,795 cards
Engine layer
Rules, state machine, stack, combat, 115 card effects
3,160 lines
AI layer
EV scoring, clock evaluation, Bayesian inference, combat sim
14 modules
Simulation runner
CLI + Python API: matrix, matchups, Bo3, audit, trace
run_meta.py
Output pipeline
Heatmap dashboard, Bo3 replayer, deck guides
3 products
Claude skills
4 reusable automation pipelines for the full workflow
4 skills
Output
Three production products
Standalone HTML. No server, no build step. Open in any browser.

Metagame matrix

16×16 interactive heatmap. Click any cell for card-level data, sideboard plans, and matchup insights.

Card statsWeighted WRSB guide
64%

Deck guide

7-step pipeline: sim data to opening hands, matchup spread, sideboard plans, and game plan phases.

Sim-verifiedHand analysis
T2 Boros casts Ragavan (+8.2 EV) T3 Zoo: Fatal Push targeting Ragavan T4 Boros: Phlage, drain 3 (clock: 5→3)

Bo3 replayer

Interactive match viewer with collapsible turns, SVG life chart, AI reasoning toggle, and keyboard navigation.

Life chartEV traces
Metagame
16 tournament-sourced decks
Decklists from Modern Challenge and League results. April 2026 meta shares.
Affinity6% Domain Zoo3% Boros Energy21% Eldrazi Tron7% Jeskai Blink9% Pinnacle Affinity2% 4c Omnath4% Dimir Midrange3% Living End4% Amulet Titan4% Ruby Storm6% 4/5c Control7% Izzet Prowess5% Azorius Control (WST)7% Azorius Control7% Goryo's Vengeance4%
T1 (5%+) T2 (3-4%) Field
Match replays
43 interactive Bo3 replays
Step through every turn. See the AI's reasoning, life totals, and board state. Click any matchup.
Affinity vs Domain Zoo Affinity vs Azorius Control Affinity vs Boros Energy Affinity vs Dimir Midrange Affinity vs Dimir Affinity vs Domain Zoo Affinity vs Etron Affinity vs Zoo Amulet T3 Titan Amulet vs Affinity Amulet vs Affinity Azorius Control vs Boros Energy Azorius Control vs Affinity Azorius Control vs Boros Energy Azorius Control vs Boros Energy Azorius vs Boros Boros Energy vs Domain Zoo Boros vs Affinity Boros vs Affinity Trace Boros vs Affinity Trace Boros vs Zoo Dimir Midrange vs Boros Energy Domain Zoo vs Affinity Energy Affinity Goryos Vengeance vs Boros Energy Goryos Vengeance vs Boros Energy Izzet Prowess vs Eldrazi Tron Living End Cascade Living End vs Boros Energy Living End vs Boros Living End vs Jeskai Blink Living End vs Ruby Storm Pinnacle Affinity vs Affinity Pinnacle Affinity vs Affinity Ruby Storm vs Boros Energy Ruby Storm vs Boros Energy Ruby Storm vs Dimir Midrange Ruby Storm vs Dimir Midrange Ruby Storm vs Dimir Storm T4 Grapeshot Storm vs Boros Wst vs Etron Zoo vs Affinity
The AI brain
Every decision is an EV comparison
Click any step to see how the AI thinks through each main phase decision.
1
Snapshot board
ev_evaluator.py
2
Check game plan
gameplan.py
3
Score all plays
ev_player.py
4
Bayesian discount
bhi.py
5
Simulate combat
turn_planner.py
6
Execute best play
strategic_logger.py

Board snapshot

Capture the full board state into a lightweight EVSnapshot: life totals, creature power, mana available, storm count, energy, evasion power, lifelink power. This is the input to every scoring function — fast to create, cheap to project forward.

EVSnapshot { my_life: 17, opp_life: 14, my_power: 6, my_clock: 3, opp_clock: 5 }
Performance
6,000 matches under the microscope
Every metric traceable to a game log. Every win rate backed by 50 Bo3 matches per pairing.

Win rates by deck (meta-weighted)

Scoped to T1/T2 opponents as defined by mtgtop8.com

Game resolution

How 6,000 simulated Bo3 matches ended

AI strategy grades

6-expert LLM judge panel · auto-refreshed from PROJECT_STATUS.md

Game length distribution

Average turns by archetype matchup type
Metagame matrix
14 × 14 matchup heatmap
Click any cell for matchup breakdown. Click a deck name to see its full profile.
Accuracy
Graded C- by a 6-expert panel
Click any deck bar to see why it's on or off target. Shaded bands show the expected tournament range.
Rules & engine
B
Combat & threats
B-
Mulligan & openers
C+
Mana & sequencing
C
Combo & storm
C
Control & interaction
D
Win rate validation vs tournament consensus
Shaded band = expected range. Click any row for root cause.
Transparency
What works, and what doesn't — yet
Fixed
Creature deployment for aggro
Guide of Souls now +2.6 EV (was -7.6). Aggro decks deploy T1 one-drops correctly.
Location: ai/ev_evaluator.py — removal projection
Before: Ragavan -7.6 EV (projected removal killed it)
After: Ragavan +8.2 EV, Guide of Souls +2.6 EV
Impact: Boros Energy 64% WR (was ~30%)
Fixed
Goryo's Vengeance combo chain
Full combo fires: Faithful Mending → bin Griselbrand → Goryo's → draw 14 cards.
Location: ai/combo_chain.py + engine/card_effects.py
Faithful Mending correctly discards to graveyard
Goryo's Vengeance targets creature in GY
Griselbrand: pay 7 life → draw 7, repeat
Fixed
First strike combat simulation
Two-phase damage correctly models first strike vs regular combat.
Location: ai/turn_planner.py — _simulate_combat()
Phase 1: first/double strike creatures deal damage
Phase 2: SBA check, then regular damage
Fixes: Ragavan surviving 1/1 blocks
Fixed
Chalice of the Void X selection
Now adaptive — picks X based on opponent's CMC distribution.
Location: engine/game_state.py:1354-1370
Scans opponent decklist CMC curve
Picks X = mode of opponent's spell CMCs
Before: hardcoded X=1 every game
Fixed
6 high-impact interaction effects
T3feri (bounce+draw), Supreme Verdict (uncounterable wipe), Blood Moon, Goblin Bombardment, Celestial Purge, Thraben Charm.
Location: engine/card_effects.py (174 new lines, 115 total registered effects)
T3feri: bounce best threat + draw — fixes Jeskai Blink
Supreme Verdict: uncounterable board wipe — fixes control matchups
Blood Moon: strips non-R production from opponent only, boards out vs R-aggro
Impact: Boros vs ETron 80% (Blood Moon wrecks Tron lands)
Fixed
Storm patience + combo sequencing
Storm decks now wait for critical mana before going off. Shock lands + reanimate priority fixed.
Location: ai/ev_player.py + engine/card_effects.py
Storm: patience threshold prevents premature fizzles
Combo: shock lands tap correctly during chain
Reanimate: priority ordering fixed for Goryo's + Living End
Fixed
Threat-based removal targeting
Removal now prioritizes Cranial Plating and equipment over vanilla creatures. Counters fire vs Affinity threats.
Location: ai/ev_player.py + ai/response.py
_threat_score() evaluates: equipment > engines > evasion > power
Cranial Plating: top removal priority
Kappa Cannoneer: counter-worthy threat
Impact: Affinity opponents now interact correctly
Fixed
Blood Moon shared CardDatabase corruption
Blood Moon was corrupting shared card templates, breaking all subsequent games. Now uses instance-level overrides.
Location: engine/card_database.py + engine/game_state.py
Critical: Blood Moon modified shared CardDatabase templates
Fix: per-game instance overrides, never touch templates
Impact: Boros 94.9% → 78.6% (opponents could cast spells again)
Fixed
Construct Token power scaling
Construct Tokens now scale with artifact count correctly. Sent Affinity to 91.9% WR.
Location: engine/card_effects.py + engine/game_state.py
Construct Token: P/T = artifact count (was static 0/0)
Nettlecyst Germ token: now 0/0 base + equipment P/T
Impact: Affinity 85% → 91.9% (correct token scaling)
Fixed
Guide of Souls energy exploit
Was auto-producing energy on ETB and attack without meeting conditions. Now only triggers on actual lifegain events.
Location: engine/card_effects.py
Before: free energy every turn, Boros 94% WR
After: energy only from lifegain triggers
Impact: Boros 94% → 78.6% → 72.6% (honest WR)
Fixed
Urza's Saga Ch.III legend rule
Saga tutor was creating duplicate legendary artifacts, then legend rule killed both. Now checks existing copies.
Location: engine/card_effects.py
Before: tutor Mox Opal #2 → legend rule kills both
After: skip tutor if legendary copy exists
Impact: Affinity no longer self-destructs tutoring
Fixed
Planeswalker EV scoring
Planeswalkers now scored by loyalty abilities and board impact. 4c Omnath jumped 29% → 56% WR.
Location: ai/ev_player.py
Before: Wrenn and Six = -0.1 EV (no PW case)
After: PW base EV by loyalty + ability assessment
Impact: 4c Omnath 29% → 56%, Jeskai Blink improved
Fixed
Wrath cast on empty board
X-cost board wipe gate v3: returns -999 EV when no opponent creatures present. Three iterations to stabilize.
Location: ai/ev_evaluator.py + ai/ev_player.py
Gate v1: opp_creature_count == 0 check
Gate v2: include token creatures
Gate v3: stable across 3 matrix reruns
Impact: Azorius no longer wastes wraths
P1 Open
Storm ritual mid-chain penalty
Patience fix and sequencing improvements applied, but Ruby Storm still at 29% WR. Expected range recalibrated to 25-50%.
Location: ai/ev_player.py:428
Storm patience threshold prevents premature fizzles
Combo sequencing improved for shock lands + rituals
But 20x mid-chain penalty still suppresses chaining
Audit conclusion: structural weakness, not just tuning
Roadmap
Infrastructure proposals — 9 hours, zero AI changes
Six concrete improvements from the Legacy codebase, scoped to infrastructure only. The EV engine stays untouched.
Plugin deck architecture
~2 hours · HIGH impact
Drop-file deck registration. One file per deck, auto-discovered at import. No more editing 3 files to add a deck.
Template dashboard
~3 hours · HIGH impact
Separate data from presentation. Design lives in template, data constants swapped in. Eliminates "dashboard looks different after rebuild".
Parallel processing
~1 hour · 3× speedup
Multiprocessing pool for matrix runs. 95 min → ~32 min on 4 cores. Same API, transparent to callers.
Meta audit + outlier detection PARTIAL
scan_results.py (246 lines) implemented · run_history.json tracking 17 artifacts
Expected WR ranges per deck. Auto-flag when sim diverges from tournament reality. Would have caught Affinity 82%, Omnath 29%, Storm 37% immediately.
Symmetry validation
~30 min · finds engine bugs
Run both orderings for every matchup. Flag when d1_wr + d2_wr deviates >10% from 100%. Catches p1/p2 asymmetry bugs.
Provenance footer
~20 min · traceability
Every output shows: date, deck count, games/pair, seed range, engine version. Know exactly which run produced the data.
Total: ~9 hours · No AI engine changes · 3× faster iteration · Zero-edit deck additions
Ecosystem
Two simulators, cross-pollinating
Legacy and Modern share the best ideas from each architecture.
38

Legacy — MTGSimClaude

2.5ms per game. 19 per-deck strategy functions with card-level knowledge. Explicit Force of Will priority tables. 137/137 rules tests. Accepted 5 Modern modules: strategic logger, clock evaluation, BHI, declarative gameplans, symmetry averaging.

15

Modern — MTGSimManu

Full Bo3 with sideboarding. Clock-based evaluation. Bayesian hand inference. Combat simulation. LLM-audited. Adopting 6 Legacy infra proposals: plugin decks, template dashboard, parallel processing, meta audit, symmetry validation, provenance footer.

Legacy → Modern · 6 infra proposals · ~9h
Plugin deck architecture, template dashboard, parallel processing (3× speedup), meta audit with expected ranges, symmetry validation, provenance footer.
Status: accepted, in backlog
Modern → Legacy · 5 modules accepted
Strategic logger (279 ln), clock evaluation (328 ln), BHI (275 ln), declarative gameplans, symmetry averaging. Maintained by Modern — kept portable.
Status: accepted, modules shared cross-project