Migrates the reaper-king-no-more proof of concept into decks/reaper-king-no-more/
as the first deck under a shared tools/ engine, so the repo can hold many
Commander decks instead of one implicit one.
- tools/deckctx.py: new shared DeckContext, resolves --deck / $MTG_DECK / cwd,
loads a deck's config.yaml, and derives color identity from the commander's
own card data (never a hardcoded color combination).
- cards.py: drop the JUND=frozenset("BRG") constant; jund_legal() renamed to
identity_legal(card, identity); DB() takes an explicit blacklist_path since
the blacklist is per-deck, not shared.
- combos.py, roles.py, similar.py, similar_text.py, bracket_check.py: take
--deck, use the deck's real identity instead of Jund/BRG.
- power.py, card_stats.py, forge_report.py: OURS deck-name constant now comes
from the deck's config (name: / commander), matched via DeckContext instead
of hardcoded "Reaper King No More".
- to_dck.py, batch_run.py, ab_test.py: .dck filename and [metadata] Name= are
derived from the deck (slug / config name), not a hardcoded "reaper.dck".
- generate.py: RECIPES and make_variants.py's VARIANTS (deck-specific
hypotheses) moved out of Python into decks/reaper-king-no-more/variants.yaml;
protected cards now come from config.yaml's protected: list instead of a
hardcoded set.
- New tools/mtg dispatcher: `tools/mtg decks/<name> <tool> [args...]` runs any
tool against any deck without cd-ing into its directory.
- data/ (Scryfall/MTGJSON/Spellbook bulk, ~1.2GB, gitignored) and embeddings.npz
move to the repo root as shared, commander-format-wide data.
- docs/howto.md: moved from the deck dir (it documents the tool, not the deck)
and updated its example commands to the real generalized CLI.
- README.md: rewritten to describe the multi-deck repo and point at
decks/reaper-king-no-more as the reference example.
Verified after the change: bracket_check, combos, and roles against
reaper-king-no-more reproduce the exact PASS/11-combos/role-profile numbers
from before the move; generate.py --list now loads recipes from YAML;
make_variants.py reproduces all 7 hand-curated variants including the
mikaeus FAIL control case; to_dck.py derives the right Name= and filename;
variant.py and compare.py reproduce decks/README.md's original numbers
exactly. The original POC at ~/mtg/reaper-king-no-more is untouched.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QPKgLYpMR8szWNFXyK1XNu
83 lines
3.9 KiB
Markdown
83 lines
3.9 KiB
Markdown
# decks/
|
|
|
|
Forge simulation results and deck analysis, one directory per **archetype variant**.
|
|
|
|
Each variant is a hypothesis: change a few cards, then measure what it does to legality, combo density, and win rate. Every file here is generated — see *regenerating* below.
|
|
|
|
## variants
|
|
|
|
| variant | bracket 3 | vacuum combos | combos | sac outlets | cmdr synergy | lands | avg MV | Forge win rate |
|
|
| --- | --- | --- | --- | --- | --- | --- | --- | --- |
|
|
| [`no-mikaeus/`](no-mikaeus/) ⭐ | **PASS** | 0 | 11 | 8 | 6 | 36 | 3.02 | 29% (24g) |
|
|
| [`fast-ramp/`](fast-ramp/) | **PASS** | 0 | 11 | 8 | 6 | 36 | 2.84 | 33% (6g) |
|
|
| [`lean-outlets/`](lean-outlets/) | **PASS** | 0 | 10 | 5 | 7 | 36 | 2.97 | — |
|
|
| [`commander-focus/`](commander-focus/) | **PASS** | 0 | 7 | 7 | 10 | 36 | 3.03 | — |
|
|
| [`heavy-removal/`](heavy-removal/) | **PASS** | 0 | 7 | 8 | 8 | 36 | 2.95 | — |
|
|
| [`low-curve/`](low-curve/) | **PASS** | 0 | 11 | 8 | 9 | 36 | 2.67 | — |
|
|
| [`mikaeus/`](mikaeus/) | **FAIL** | 7 | 39 | 8 | 6 | 36 | 3.08 | — |
|
|
| [`aggro-hate/`](aggro-hate/) | **PASS** | 0 | 9 | 6 | 5 | 36 | 3.03 | 50% (2g) |
|
|
| [`card-engine/`](card-engine/) | **PASS** | 0 | 10 | 8 | 6 | 36 | 2.97 | — |
|
|
| [`go-wide/`](go-wide/) | **PASS** | 0 | 10 | 8 | 6 | 36 | 2.97 | 0% (2g) |
|
|
| [`grindy/`](grindy/) | **PASS** | 0 | 9 | 6 | 5 | 36 | 2.92 | 100% (1g) |
|
|
| [`opponent-facing/`](opponent-facing/) | **PASS** | 0 | 9 | 5 | 10 | 36 | 2.92 | — |
|
|
| [`proliferate/`](proliferate/) | **PASS** | 0 | 10 | 5 | 5 | 36 | 3.08 | — |
|
|
|
|
⭐ = current baseline
|
|
|
|
## the hypotheses
|
|
|
|
**`no-mikaeus`** — Baseline. Aristocrats + -1/-1, every combo needs board state.
|
|
|
|
**`fast-ramp`** — fast-ramp
|
|
|
|
**`lean-outlets`** — The deck runs 8 sac outlets and probably needs ~5. Cut 3 for interaction and card advantage -- does consistency actually drop?
|
|
|
|
**`commander-focus`** — The commander only steals from OPPONENTS' creatures, but the deck's -1/-1 engine mostly counters our own. Push counters onto their board.
|
|
|
|
**`heavy-removal`** — Bracket 3 pods interact. Trade combo redundancy for removal and see whether surviving longer beats assembling faster.
|
|
|
|
**`low-curve`** — Avg MV is 3.02 and the engine lands ~T6. Cut the top of the curve entirely -- does the deck come online sooner and win more?
|
|
|
|
**`mikaeus`** — Does the highest-leverage combo card (28 combos) stay legal? Expected FAIL: goes infinite with every sac outlet.
|
|
|
|
**`aggro-hate`** — aggro-hate
|
|
|
|
**`card-engine`** — card-engine
|
|
|
|
**`go-wide`** — go-wide
|
|
|
|
**`grindy`** — grindy
|
|
|
|
**`opponent-facing`** — opponent-facing
|
|
|
|
**`proliferate`** — proliferate
|
|
|
|
## layout
|
|
|
|
```
|
|
decks/<variant>/
|
|
decklist.txt the 100 cards, "N Card Name" per line
|
|
bracket.txt bracket-3 + house-rule check
|
|
combos.txt combos already in the deck, and one card away
|
|
sim/ Forge runs, one triple per batch:
|
|
<stamp>.log raw Forge output, every game
|
|
<stamp>.txt human-readable report
|
|
<stamp>.json machine-readable results
|
|
README.md generated summary
|
|
```
|
|
|
|
## regenerating
|
|
|
|
```bash
|
|
python3 tools/make_variants.py # rebuild every decklist from the spec
|
|
python3 tools/variant.py <name> # analysis for one variant (~10s)
|
|
python3 tools/variant.py <name> --sim 24 # + 24 Forge games (~25 min)
|
|
python3 tools/compare.py # rebuild this file
|
|
```
|
|
|
|
The decklists are generated from `tools/make_variants.py`, which holds each variant as a cut/add list against the baseline. Change the baseline and every variant follows. Analysis files are rewritten each run; **sim runs are additive**, so batches accumulate and stay comparable.
|
|
|
|
## reading the win rates
|
|
|
|
Forge's AI is heuristic and **weak at combo decks** by its own documentation. Ours is a combo deck, so the AI under-plays it. Treat win rates as a **floor** and as evidence the deck functions and its cards interact — not as a power rating. Random baseline in a 4-player pod is 25%. Opponents are stock Commander precons (roughly bracket 2).
|
|
|