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
39 lines
2.1 KiB
Text
39 lines
2.1 KiB
Text
# Combo.ai -- an AI profile for piloting an aristocrats / sacrifice deck.
|
|
#
|
|
# Sparse by design: AiProfileUtil falls back to AiProps defaults for any key not
|
|
# listed, so this file contains ONLY deliberate deviations from Default.ai. Each
|
|
# one has a mechanistic reason -- a change a competent human pilot would obviously
|
|
# also make. Changes that only move win rate without such a story are overfitting
|
|
# to Forge's evaluation function and are NOT included.
|
|
#
|
|
# Use for OUR seat only (-a Combo Default Default Default). Tuning opponents too
|
|
# would just shift the baseline and teach us nothing.
|
|
|
|
# --- Sacrifice: the core of the archetype -------------------------------------
|
|
# Default ships ENABLE=false, which disables the GENERIC sacrifice fallback: any
|
|
# sac outlet lacking a card-specific `AIPreference:SacCost` hint is then simply
|
|
# never fed. For a deck built on sacrificing creatures this is fatal.
|
|
SACRIFICE_DEFAULT_PREF_ENABLE=true
|
|
SACRIFICE_DEFAULT_PREF_MIN_CMC=0
|
|
# Default 2 -- covers everything in the deck, not just cheap creatures.
|
|
SACRIFICE_DEFAULT_PREF_MAX_CMC=6
|
|
SACRIFICE_DEFAULT_PREF_ALLOW_TOKENS=true
|
|
# Default 135 is roughly a vanilla 1/2: anything better than a token was ineligible
|
|
# as fodder. 400 lets the AI feed real creatures to Yawgmoth and Carrion Feeder,
|
|
# which is the entire point of the deck.
|
|
SACRIFICE_DEFAULT_PREF_MAX_CREATURE_EVAL=400
|
|
|
|
# --- Tokens are fuel ----------------------------------------------------------
|
|
# Token bodies are sac fodder here, not board presence. Always make them.
|
|
TOKEN_GENERATION_ABILITY_CHANCE=100
|
|
|
|
# --- Trading is upside, not a cost -------------------------------------------
|
|
# A normal deck avoids trades; an aristocrats deck WANTS its creatures to die,
|
|
# because dying is what triggers the payoffs. Default is 0.
|
|
CHANCE_TO_ATTACK_INTO_TRADE=60
|
|
ATTACK_INTO_TRADE_WHEN_TAPPED_OUT=true
|
|
RANDOMLY_ATKTRADE_ONLY_ON_LOWER_LIFE_PRESSURE=false
|
|
|
|
# --- Don't hoard mana for combat tricks we don't run --------------------------
|
|
# Default 100 holds mana for Main 2. This deck would rather deploy the engine.
|
|
RESERVE_MANA_FOR_MAIN2_CHANCE=0
|