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
42 lines
2.4 KiB
YAML
42 lines
2.4 KiB
YAML
# Simulation-only card substitutions.
|
|
#
|
|
# Some cards are `AI:RemoveDeck:All` in Forge because the AI genuinely cannot
|
|
# evaluate them -- not because nobody wrote logic. Forcing those on makes the AI
|
|
# play them badly, which is worse than not playing them. Instead we swap in a
|
|
# functionally similar card the AI CAN pilot, so the deck's SHAPE is simulated
|
|
# correctly (the removal slot still does removal) even though the specific card
|
|
# differs.
|
|
#
|
|
# decklist.txt remains the source of truth. This map applies ONLY when building
|
|
# the .dck for simulation, and every substitution is recorded in the run's JSON
|
|
# metadata and printed in reports.
|
|
#
|
|
# IMPORTANT: per-card statistics for a substituted card describe the STAND-IN,
|
|
# not the real card. Never read "Terminate had a 40% win rate" as a fact about
|
|
# Beast Within. This trades per-card precision for whole-deck realism.
|
|
|
|
substitutions:
|
|
# Blocked because it gives the opponent a 3/3 -- the AI can't weigh that downside,
|
|
# even though it already has working targeting logic (AITgts$ Card.cmcGE4).
|
|
# Feed the Swarm is the same slot: cheap unconditional removal, and it also hits
|
|
# enchantments, so it is closer to Beast Within's flexibility than Terminate.
|
|
# DEVIATION: Beast Within hits ANY permanent at instant speed; Feed the Swarm is
|
|
# a sorcery limited to creatures/enchantments and costs life.
|
|
Beast Within: Feed the Swarm
|
|
|
|
# Blocked because of `Cost$ 2 B PayLife<X>` -- an X-cost paid with LIFE, which
|
|
# the AI has no logic to size. Blasphemous Edict is a fixed-cost mass sacrifice.
|
|
# DEVIATION: Deluge is scalable, symmetric and dodges indestructible; the Edict
|
|
# is an edict effect that opponents choose for, so it kills different creatures.
|
|
Toxic Deluge: Blasphemous Edict
|
|
|
|
# Blocked because "draw X, then discard 3" is a symmetrical drawback it can't
|
|
# evaluate. Umbral Collar Zealot is a repeatable sac-for-value outlet the AI can
|
|
# pilot, keeping the "sacrifice converts to cards" slot filled.
|
|
# DEVIATION: far smaller effect, and a creature rather than an enchantment.
|
|
Greater Good: Umbral Collar Zealot
|
|
|
|
# Black Sun's Zenith and Cauldron of Souls are also AI-blocked but are NOT
|
|
# substituted: no close AI-playable analogue exists, and swapping them would
|
|
# distort the -1/-1 theme more than leaving the slot inert. They stay in the
|
|
# deck, remain uncast, and are reported as "never cast (AI-blocked)".
|