mcpField
C
cube-wizard

cube-wizard

github.com/dan-blanchard其他22211 次安装2 天前更新
代码仓库

关于 cube-wizard

cube-wizard 是用于构建和调整 MTG 轮抽牌池的技能,可从现有列表或参考牌池开始,并按流程进行评估。它要求依据 Scryfall 的卡牌规则文本提出建议,并提供平衡度、主题、合法性和轮抽模拟工具。

主要功能

  1. 01解析或克隆牌池
  2. 02核验 Scryfall 规则文本
  3. 03牌池平衡与主题审计
  4. 04检查赛制合法性和稀有度
  5. 05模拟补充包与轮抽
  6. 06导出为 CubeCobra CSV

适用场景

  1. 01将 CubeCobra 列表转为完整牌池
  2. 02按设计目标调整牌池
  3. 03检查赛制合法性与主题覆盖
  4. 04测试补充包并比较牌池版本

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/dan-blanchard/mtg-skills --skill cube-wizard

安装后在 Claude Code 中输入/cube-wizard确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

CONTEXT.md
pyproject.toml
uv.lock

详细介绍

Cube Wizard

从头开始构建 MTG 轮抽池(克隆知名参考轮抽池并进行自定义),或调整现有轮抽池。轮抽池是为轮抽精心挑选的卡牌池,通常包含 360–720 张牌。与套牌不同,平衡性体现在卡牌池层面——包括原型的可供轮抽程度、每种双色组合的信号密度、修色牌密度,以及整个卡池的费用曲线形态。每项建议都必须以 Scryfall 上实际的卡牌 Oracle 文本为依据,绝不能依赖训练数据。

此技能分为两个阶段。**阶段 1(获取轮抽池)**确定用户如何获取轮抽池:解析现有牌表(路径 A),或克隆参考轮抽池(路径 B)。两条路径都会生成轮抽池 JSON 和已填充数据的缓存。**阶段 2(调整)**无论轮抽池来自哪条路径,都会对其运行相同的 10 步流程。

铁律

**绝不臆测卡牌的效果。**引用任何卡牌的异能之前,必须通过辅助脚本查阅其 Oracle 文本。训练数据不等于 Oracle 文本。

**例外(仅限原型构思):**在阶段 1 路径 B 的自定义意图访谈中,当用户构思原型和主题时,可以使用训练数据来建议主题名称(衍生物、牺牲、+1/+1 指示物等)。但凡是你建议加入轮抽池的卡牌,都必须先根据 Scryfall Oracle 文本进行验证,用户才能接受——将所有候选卡牌名称写入 JSON 列表,并通过一次调用批量查询:

scryfall-lookup --batch <candidates.json> --bulk-data <bulk-path> --cache-dir <wd>/.cache

支持的轮抽池格式

格式默认大小卡牌池稀有度筛选指挥官牌池备注
vintage540完整永恒赛制—否Powered(允许使用 Power 9)
unpowered540完整永恒赛制—否默认禁用 Power 9
legacy540Legacy 合法—否适用 Legacy 禁牌表
modern540Modern 合法—否适用 Modern 禁牌表
pauper540完整永恒赛制仅普通否—
peasant540完整永恒赛制普通 + 非普通否—
set360单个系列—否如果所有卡牌属于同一系列,则自动检测
commander540Commander 合法—是单独轮抽专用指挥官补充包
pdh540完整永恒赛制普通(主牌)是指挥官:非普通

格式是可选元数据,而非硬性限制。“猫狗部族轮抽池”或“设有预算上限的轮抽池”都完全可行——在符合需求的格式稀有度/合法性筛选基础上叠加限制即可。轮抽池 JSON 中的 designer_intent 区块会记录用户的具体目标。


进度跟踪

**开始前,先创建 TaskCreate 列表。**第一个问题决定路径;请据此创建任务。

阶段 1:路径 A(解析现有轮抽池)
  • 获取/读取轮抽池
  • 解析为规范轮抽池 JSON
  • 填充卡牌数据
阶段 1:路径 B(克隆参考轮抽池)
  • 访谈
  • 选择参考轮抽池
  • 获取 + 解析 + 填充数据
  • 基线审查
阶段 2:调整(适用于两条路径)
  1. 基线指标
  2. 确认设计者意图
  3. 平衡性仪表板
  4. 原型审查
  5. 强度等级审查
  6. 自我质询
  7. 提出更改
  8. 补充包模拟
  9. 定稿/导出
  10. 实测游戏测试(可选)

每项任务一开始就标记为 in_progress,完成时立即标记为 completed——不要批量更新。


设置(首次运行)

uv sync --directory <skill-install-dir>
download-mtgjson

后续运行中,如果 .venv 已存在且批量数据为最新(24h),则跳过 uv sync。


工具说明

面向用户的 stdout + JSON 旁文件(关键设计)

每个轮抽池 CLI 都会向 stdout 输出简短的易读摘要,并将完整结构化输出写入旁文件 JSON,其中包含 Full JSON: <path> 页脚。采用这种模式是因为若将 540 张以上卡牌的轮抽池 JSON 原样输出到 stdout,会占用过多上下文。

**脚本之间的串联通过文件路径实现,而非管道传递 JSON。**需要特定字段时,使用 Read 并结合 offset/limit 选择性读取旁文件。只有下游脚本需要 stdout 上的完整数据时(很少见),才传入 --json。

JSON 文件写入

对于任何包含牌名的 JSON 文件,请使用 Write 工具。 撇号 (例如 “Ashnod's Altar”)会破坏 heredoc 和内联 Python 中的 shell 引号。 Write 工具的权限可以在整个会话中缓存;python3 -c "..." 则每次都会重新提示。

临时文件路径

在会话中重复使用以下固定路径:/tmp/cube-cuts.json、 /tmp/cube-adds.json、/tmp/cube-candidates.json、/tmp/cube-themes.json。

/tmp 文件会跨会话保留。在会话开始时,首次 Write 之前,先 Read 每个计划重复使用的临时路径;或者依次运行 Write,并在执行依赖它的 Bash 调用之前确认成功。切勿在同一条消息中批量执行 Write(/tmp/foo.json) + Bash(tool reading /tmp/foo.json)。

路径要求
  • 只能使用绝对路径。 uv 会将工作目录重新定位到 skill 安装目录;相对路径会解析到错误的根目录。
  • 缓存目录: 始终使用 <working-dir>/.cache,而不是 skill 安装目录。
  • 重新水合: 每次编辑 cube 后,都要对新的 cube JSON 重新运行 scryfall-lookup --batch。水合缓存以 SHA 为键;旧缓存会静默失效。
CubeCobra 获取注意事项

对于某些端点,CubeCobra 会向普通 Python UA 返回 403。cubecobra-fetch 会通过回退到使用 curl 的 web_fetch,透明地处理此问题。获取优先级:cubeJSON(最丰富——包含主牌表/待选牌表划分、设计师标签和单牌覆盖设置)→ CSV → 纯牌表。如果三种方式都失败,用户可以从 CubeCobra UI 手动导出,然后将文件传给 parse-cube。

平衡检查仅供参考,不代表通过/未通过

cube-balance 会报告观测到的指标与常规参考范围的对比情况(例如“移除牌密度为 22–28%”)。如果某个 cube 超出范围,它不会将其标记为有问题。单色蓝 cube、组合技 cube 或猫狗部族 cube 都可能合理地偏离常规预期。请将参考范围理解为“典型情况”,而非“必须遵守”。

参考范围来自 Riptide Lab 和 Star City Games 的共识,以及 Lucky Paper 的 “How Many Lands Should You Include in Your Cube” 数值。

cube-balance 和 archetype-audit 的正则表达式范围警告

这两个工具共用位于 mtg_utils.theme_presets 的规范预设库(PRESETS dict + get_preset(name) / matches(name, card) API)。每个预设都带有测试样例,用于固定其对已知牌的行为,确保更新不会悄然导致回归。cube-balance 的移除检查委托给 removal 预设,而 archetype-audit --preset <name> 会按名称加载预设。

移除检测使用 removal 预设(摧毁/放逐/反击/伤害/弹回/格斗/-X)。该预设经过调校,范围较宽松——对于仅供参考的指标,允许出现误报。如果密度看起来不对,可以通过运行以下命令抽查:

card-search --bulk-data <path> --oracle "<your regex>" --color-identity <ci>

除了范围较广的 removal 总类预设外,还提供六种按类型细分的移除密度预设:creature-removal、artifact-removal、enchantment-removal、land-removal、planeswalker-removal 和 universal-removal(Vindicate / Beast Within / Maelstrom Pulse / Nicol Bolas 风格)。类型预设较严格(只匹配牌名中提及该类型的牌);universal-removal 是单独的类别——若要统计所有能应对神器的牌,请将 artifact-removal + universal-removal 相加。注意:同一张牌被多个预设匹配是预期情况(Lightning Bolt 通过“任意目标”伤害机制,同时匹配 creature-removal 和 planeswalker-removal)。

对于 archetype-audit,主题可以来自 --preset <name>(库中预设,经过测试),也可以来自 --theme name=regex(自定义,未经验证)。自定义正则表达式的精确度完全取决于用户编写的正则表达式。

规范 Cube JSON 架构
{
  "cube_format": "vintage|unpowered|legacy|modern|pauper|peasant|set|commander|pdh",
  "target_size": 540,
  "name": "Regular Cube",
  "drafters": 12,
  "pack_size": 15,
  "packs_per_drafter": 3,
  "source": "cubecobra:<id>",
  "cloned_at": "2026-04-18T12:34:56Z",
  "designer_intent": {
    "description": "<from CubeCobra overview>",
    "tags": ["unpowered", "vintage"],
    "stated_archetypes": [
      {"name": "tokens"},
      {"name": "graveyard",
       "members": ["reanimate", "self-mill", "graveyard-cast"]},
      {"name": "Boros Equipment", "regex": "equip|attach"}
    ]
  },
  "pack_templates": {},
  "balance_targets_override": {},
  "commander_pool": [
    {"name": "Atraxa, Praetors' Voice", "quantity": 1, "scryfall_id": "..."}
  ],
  "cards": [
    {"name": "Lightning Bolt", "quantity": 1,
     "cube_color": "R", "cube_cmc": 1.0,
     "tags": ["burn"], "scryfall_id": "..."}
  ],
  "total_cards": 540
}

每个条目有以下三种形式之一:

  • {"name": NAME} — 预设引用。NAME 必须是 theme_presets.PRESETS 中的键(运行 archetype-audit --list-presets 查看 完整目录)。
  • {"name": NAME, "members": [PRESET, ...]} — 原型组。NAME 是总括标签;每个 members 条目都必须是已知预设。 读取 stated_archetypes 的工具会将该组作为一个整体报告, 同时仍会跟踪各个组成预设。
  • {"name": NAME, "regex": PATTERN} — 自定义匹配器(用于旧版主题,或 预设库未涵盖的 Cube 专属主题)。

所有 Cube CLI 都接受这种形式。已填充的缓存位于 <working-dir>/.cache/<sha>.json,以 SHA 为键,因此重复填充缓存不会产生变化。


决策表

任务工具
拉取 CubeCobra Cubecubecobra-fetch <id-or-url> --output-dir <wd>
解析 Cube 列表 / CSV / JSONparse-cube <path> --cube-format <fmt> --output <wd>/cube.json
填充卡牌数据scryfall-lookup --batch <cube.json> --bulk-data <path> --cache-dir <wd>/.cache
Cube 核心指标cube-stats <cube.json> <hyd.json>
平衡性仪表板cube-balance <cube.json> <hyd.json> [--check <name>]
赛制合法性 + 稀有度审计cube-legality-audit <cube.json> <hyd.json>
原型验证archetype-audit <cube.json> <hyd.json> --theme name=regex
通过预设库进行原型验证archetype-audit <cube.json> <hyd.json> --preset <name>(可重复;参见 --list-presets)
列出可用的预设主题archetype-audit --list-presets
显示各主题匹配到的卡牌在任意 archetype-audit 调用中添加 --show-matches
桥接卡牌提供 ≥2 个主题时,包含在 archetype-audit 输出中
比较 Cube 修订版本cube-diff <old.json> <new.json> [--old-hydrated <h> --new-hydrated <h> --metrics]
模拟开包pack-simulate <cube.json> <hyd.json> --seed N --pack-size 15
压力测试轮抽可行性pack-simulate ... --simulate-drafts 100
查找候选卡牌card-search --bulk-data <path> --oracle "<regex>" --color-identity <ci>
检查 Cube 预算price-check <cube.json> --bulk-data <path>
查找意外的无限连招combo-search <cube.json>
导出为 CubeCobra CSVexport-cube <cube.json> --format csv --output <wd>/cube.csv
引用 MTG 综合规则rules-lookup --rule <n> / --term <keyword> / --grep "<regex>"
获取 Scryfall 单卡裁定rulings-lookup --card "<name>" --bulk-data <path>
深入规则问题(原型合法性、关键字互动)通过 Skill 工具调用 rules-lawyer 技能
规则顾问

Cube 设计偶尔会遇到规则问题——“这个连招在该赛制中真的可行吗?”“这个触发是否必须执行?”“层系统如何处理这个静态效应?”对于简单的关键字或术语问题,运行 rules-lookup --term <keyword>。对于任何复杂问题(层、替代效应、多条规则的交互),通过 Skill 工具调用 rules-lawyer 技能;该技能会升级处理,并调用已加载相关 CR 章节的子 Agent。

每个会话中,首次调用 rules-lookup 前运行一次 download-rules --output-dir <working-dir>(24 小时新鲜度检查,模式与 download-mtgjson 相同)。


第 1 阶段:获取 Cube

开场问题:“你有现成的 Cube 列表想要调整吗?还是想从一个知名参考列表开始构建新的 Cube?”

路径 A:解析现有 Cube
  1. 获取 Cube 列表。 以下方式任选其一:
    • CubeCobra ID 或 URL → cubecobra-fetch <id> --output-dir <wd>
    • 本地文件(CubeCobra CSV、纯文本等)——按原样使用
  2. 解析为规范的 Cube JSON。
    parse-cube <wd>/<cube>.json --cube-format <fmt> --output <wd>/cube.json
    
    如果用户未指定格式,parse-cube 会自动检测 set Cube(所有卡牌共用一个系列代码),否则默认使用 vintage 格式。
  3. 补全卡牌数据。
    scryfall-lookup --batch <wd>/cube.json --bulk-data <wd>/default-cards.json --cache-dir <wd>/.cache
    
  4. 确认范围。 阅读 cube.json.designer_intent.description 和 tags——这些内容为第 2 阶段的工作流提供所需的上下文。如果 Cube 声明了原型,请运行 archetype-audit --from-cube,直接处理 预设引用和分组。只有预设库未覆盖的主题才询问用户提供正则表达式 查询。
路径 B:克隆参考 Cube
  1. 访谈。 按以下顺序进行:
    • Cube 格式(参见“支持的 Cube 格式”表)
    • 目标大小(360 / 450 / 540 / 630 / 720,默认值取决于格式)
    • 选秀玩家人数 / 补充包大小(默认值来自 cube_config.SIZE_TO_DRAFTERS)
    • 参考 Cube 选择:根据所选格式,展示 cube_config.REFERENCE_CUBES 中的硬编码选项,以及“粘贴 CubeCobra URL”,以便用户提供熟悉的 Cube。使用 AskUserQuestion(遵循最多 4 个选项的限制——在文本消息中 列出所有选项,让用户任选)。
    • 自定义意图(开放式):“你想基于这个参考 Cube 做哪些更改? 添加一个原型?移除特定卡牌?部族主题? 预算上限?还是只调整基准配置?”
    • 预算(可选):纸牌版美元预算上限
    • 限制(可选):不允许快速法术力、无限连招、部族限制、 单系列、单色等
  2. 获取 + 解析 + 补全数据。 对参考 Cube 的 CubeCobra ID 执行与 路径 A 相同的命令。
  3. 基准评审。 对未修改的参考 Cube 运行 cube-stats 和 cube-balance。向用户展示基准结果,让他们在开始自定义之前 确认起点符合意图。

第 2 阶段:调整工作流

无论 Cube 来自路径 A(现有 Cube)还是路径 B(克隆的参考 Cube),均使用相同的 9 个步骤。使用 TaskCreate 跟踪 进度。

步骤 1:基准指标
cube-stats <cube.json> <hyd.json>
cube-balance <cube.json> <hyd.json>

记录观察到的颜色分布、费用曲线、去除牌密度、修正牌密度,以及指挥官池 构成(如有)。这些数据是步骤 7 影响验证的调整前基准。

步骤 2:确认设计者意图

向用户概述 Cube 声明的意图:

  • 格式、大小、选秀玩家人数
  • 来自 CubeCobra 概览的设计者描述(或路径 B 访谈中的自定义 意图)
  • 声明的原型(如有)
  • 明确限制

请用户确认或调整。将任何澄清内容保存到 cube.json.designer_intent.stated_archetypes 条目中(预设、分组或 自定义正则表达式形式),供步骤 4 使用。

步骤 3:平衡仪表板与合法性审计

已在步骤 1 中计算;与用户逐项查看各部分,并记录任何有意为之的“超出典型 范围”项目(例如:“是的,去除牌密度较低,因为我希望这个 Cube 以生物为主。”)。

另运行机械合法性审计:

cube-legality-audit <cube.json> <hyd.json>

与 cube-balance 不同,这是一项硬性约束检查:错误表示违反格式规则, 应在发布前修复。检查项:

  • 稀有度筛选——例如,Pauper Cube 中包含一张稀有牌(如果可用,则使用 Scryfall 的 legalities.pauper;否则使用默认印刷版本的稀有度,并在 Peasant 中标记为警告)。
  • 合法性键——例如,Modern Cube 中包含一张在 Modern 赛制中不合法的牌。
  • 禁牌表——例如,unpowered Cube 中包含 Power 9 卡牌。
  • 指挥官池稀有度——例如,PDH 指挥官必须是非普通牌。

任何严重性为 error 的违规都必须修复(替换卡牌或更改 Cube 格式)。严重性为 warn 的项目需要人工核实(默认印刷版本的稀有度变化、缺失的合法性数据)。

第 4 步:原型审查

如果主题符合库中的预设之一,优先使用 --preset <name>,而不是手写正则表达式。可用类别:

  • 关键词异能:飞行、警戒、践踏、敏捷、死触、系命、先攻、连击、延势、威慑、守军、闪现、辟邪、不灭、守护、保护、占卜、监视、级联、返照、踢击、循环、召现、忍术、扬威、精熟、反抗、调查、地落、掘穴、奇迹、风暴、感染、剧毒、发掘、延缓、不息、存活、佩带、磨牌。
  • 去除(广义):removal(总类)、board-wipe。
  • 按类别划分的去除:creature-removal、artifact-removal、enchantment-removal、land-removal、planeswalker-removal、universal-removal(Vindicate / Beast Within / Maelstrom Pulse)。
  • 强制牺牲(法令):edict(总类)、creature-edict、artifact-edict、enchantment-edict、land-edict、planeswalker-edict、universal-edict(类似 Vindicate、由对手选择)。
  • 回合操控:extra-turns、extra-combats、extra-upkeeps——以“额外进行一次该阶段”的收益为核心,是 Obeka / Aurelia / Godo 原型的基础。
  • 功能类:牌库顶操控、自磨、反击咒语、弹回、弃牌、导师、衍生物、牺牲出口、直伤、复活、从坟墓场返回、戏法、抓牌、得生命、+1/+1 指示物、闪烁。

这些预设经过已知卡牌的测试,并与 cube-balance 共用,因此不同会话中的结果保持一致。使用 archetype-audit --list-presets 查看完整目录。添加 --show-matches,即可查看与每个主题匹配的卡牌。

archetype-audit <cube.json> <hyd.json> \
    --preset tokens \
    --preset reanimate \
    --preset counterspell \
    --show-matches

对于 PDH 轮抽方块,传入 --include-commanders,将 commander_pool 条目与主牌池卡牌一并纳入主题密度计算。此选项默认关闭,以确保非 PDH 轮抽方块的现有输出保持不变。

对于没有匹配预设的主题,可使用 --theme name=regex:

  • spells-matter=(instant|sorcery) you (control|cast)
  • energy=gets? \{E\}
  • counters=\+1/\+1 counter
archetype-audit <cube.json> <hyd.json> \
    --preset tokens \
    --theme "spells-matter=(instant|sorcery) you (control|cast)" \
    --theme "counters=\\+1/\\+1 counter"

输出会报告每个主题的密度、每个公会的密度、孤立信号(仅在一种颜色中出现的收益牌)以及桥接卡牌(支持多个主题的卡牌——构筑设计中优先考虑的连接部分)。

与用户确认任何卡牌少于 3–4 张的主题是否应关闭——Lucky Paper 的常见问题解答指出,一个原型“只需 3–4 张卡牌”即可用于轮抽;低于此门槛就不算原型。

第 5 步:强度等级审查

进行两项检查:

  1. 价格异常值(作为强度的替代指标):通过 price-check <cube.json> --bulk-data <path> 标记价格达到 $50+ 和 $100+ 档位的异常卡牌。
  2. 意外的无限连招——轮抽方块最需要担心的是无关卡牌组成双卡无限连招,扭曲轮抽环境:
    combo-search <cube.json>
    
    combo-search 的目标范围是牌组,但也适用于轮抽方块 JSON(两者都采用 cards[] 结构)。与用户一起审查被标记的连招。
第 6 步:自我质询(硬性门槛)

按照 deck-wizard 第 8 步的模式,并行调用 Agent——一个提出方案,另一个提出质疑。质疑者的提示词应聚焦于轮抽方块特有的失效模式:原型供给不足(移除辅助牌却不补充收益牌)、引入颜色失衡、信号稀释(新卡牌不支持任何主题)、强度异常值以及修正手段受扰。

向两个 Agent 提供以下信息:

  • 轮抽方块声明的原型和设计者意图
  • 当前的 cube-stats + cube-balance 基线
  • 当前 archetype-audit 各主题的密度
  • 拟议的移除/添加卡牌(来自调整会话)
步骤 7:提出变更

通过 Write 工具将删减项/新增项写入 /tmp/cube-cuts.json 和 /tmp/cube-adds.json。重新生成 Cube JSON(应用删减项/新增项),重新水合数据, 并重新运行第 2 阶段指标:

cube-diff <old-cube.json> <new-cube.json> \
    --old-hydrated <old-hyd.json> --new-hydrated <new-hyd.json> --metrics

继续之前,先与用户一起审查差异。

常见替换标准——根据诊断信号决定删减项/新增项:

  • 移除密度异常(步骤 3):按原型标签替换移除项。
  • 原型低于 LP 最低要求(步骤 4):添加支持牌,或通过 stated_archetypes 组添加与之相关的统领牌。
  • 强度异常牌(步骤 5):如果价格标记的牌会扭曲轮抽,就将其移除;combo-search 找到的组合可能需要移除其中一张牌。
  • 颜色卡地率高(来自步骤 10 的测试报告,自定义赛制):将双点费牌({C}{C})替换为同一原型中的单点费同类牌。使用 card-search --oracle "<archetype pattern>" --color-identity <C> 查找候选牌,然后用 scryfall-lookup 逐张核实。
  • 原型组建率低于 30%(步骤 10):添加 2–3 张支持牌,或调整 Cube JSON 中该原型的组定义。

如果替换候选牌与 Cube 中已有牌冲突(热门替换牌经常会遇到这种情况),使用带有更严格筛选条件的 card-search 缩小候选范围。提交前,务必通过 scryfall-lookup 核实每张替换牌的法术力费用——切勿仅凭训练数据中的牌张费用就轻信。

步骤 8:补充包模拟
pack-simulate <new-cube.json> <new-hyd.json> --seed 1 --pack-size 15
pack-simulate <new-cube.json> <new-hyd.json> --seed 1 --pack-size 15 --simulate-drafts 100

目视抽查几个初始补充包,然后查看 100 个补充包的总体分布。如果某个类别严重不足,或颜色分布看起来不理想,请返回步骤 7。

步骤 9:定稿/导出
export-cube <new-cube.json> --format csv --output <wd>/<cube-id>-updated.csv

将 CSV 交给用户,并告知他们使用 CubeCobra 的 “Replace with CSV Import” 功能,将变更推送回上游。

步骤 10:实证测试

运行时机:

  • 标准 Cube 赛制: 可选。步骤 1–9 的静态信号已涵盖大多数决策;如果想要对局匹配平衡数据,可以运行循环赛/轮抽。
  • 已注册模拟器模块的自定义赛制(即赛制名称是 mtg_utils/_custom_format/__init__.py:FORMAT_REGISTRY 中的键): 必需。静态工具无法洞察赛制特有的动态情况;在该赛制的实际规则下,模拟器是诊断颜色卡地和原型组建情况的唯一方法。目前注册表中只有一个条目:shared_library。
  • 没有模拟器模块的自定义赛制: 提议先编写一个,再继续。告知用户该赛制尚未进行模拟,向他们展示赛制模块契约(setup/run_turn/ is_terminal 以及 DEFAULT_PLAYERS / DEFAULT_TURNS / SUPPORTS_ARCHETYPES;_custom_format/shared_library.py 是参考实现),并询问是现在添加模块,还是在方案报告中注明该限制后按步骤 1–9 继续。未经确认不得编写模块——赛制规则必须由用户提供,不能依赖训练数据。

两种互补信号。调用时,两者都要运行。

循环赛(对局匹配平衡):

playtest-gauntlet cube.json --hydrated cube-hydrated.json \
  --games-per-pair 100 --seed 1 --output playtest-gauntlet.json

循环赛测试哪些原型分为三个优先级:

  1. --gauntlet path/to/manifest.json — 显式覆盖文件
  2. cube.designer_intent.stated_archetypes — 如果其中有内容,挑战组会根据每个已声明的原型生成一套牌,并根据立方体实际牌池自动推断颜色和 curve_target (每个原型的主题匹配器会按颜色标识和 CMC 统计卡牌数量)。若要覆盖某个原型的推断结果,可在其 stated_archetype 条目中添加可选的 gauntlet: 块:
    {
        "name": "Aristocrats",
        "members": ["sacrifice", "death-trigger"],
        "gauntlet": {"colors": ["B", "W"], "shape": "midrange",
                     "curve_target": {"2": 5, "3": 7, "4": 6}}
    }
    
    shape 可选 aggro|midrange|control|combo 之一,并会在主题匹配结果之上加入标准评分先验;省略该字段则完全依赖主题驱动评分。
  3. 回退方案:如果 stated_archetypes 缺失或为空,则使用 mtg_utils/data/gauntlets/<format>.json 中按格式设置的默认值(标准的四种形态——Mono-Red Aggro、Azorius Control、Golgari Midrange、Izzet Combo——均含显式 shape 字段)。

报告以 4×4 胜率矩阵呈现(如果 stated_archetypes 有 N 个条目,则为 N×N)。标记任何 > 60% / < 40% 的单元格(与均衡值相差 10 个百分点)——默认 M=100 时,二项分布 95% 置信区间为 ±10 个百分点,因此相差 10 个百分点具有统计学意义,较小的差异则属于噪声。

轮抽(轮抽平衡):

playtest-draft cube.json --hydrated cube-hydrated.json \
  --pods 4 --players 8 --seed 1 --output playtest-draft.json

报告汇总 32 套轮抽套牌的每套套牌空场测试结果,并显示: 平均卡色缺失率、T4 时的平均地牌数、原型分布、构筑失败情况。

**法术力模型注意事项:**每套套牌的空场测试会统计地牌,以及每张具有 Scryfall produced_mana 的非地永久物(法术力石、法术力生物,以及 Treasure/Gold/Eldrazi-Spawn 生成器等法术力衍生物生成器),将衍生物生成器近似视为每回合约 1 点法术力来源,而不模拟其触发或牺牲。因此,衍生物加速的统计是大致的,而非精确的。报告轮抽结果时请注明这一点。

**结果反馈:**如果 playtest-gauntlet 标记出不平衡情况,请在删牌与加牌的讨论中纳入这些结果。向导不会根据对战测试输出自动删牌——用户会阅读两份报告并自行决定。

**自定义赛制:**如果立方体面向某个非标准赛制,且该赛制的模块已在 FORMAT_REGISTRY 中注册(目前为 shared_library),请使用 playtest-custom-format,而非 playtest-gauntlet / playtest-draft。如果该赛制未在注册表中,请先按照上文“没有模拟器模块的自定义赛制”指南操作,再继续。

如果立方体的 designer_intent.stated_archetypes 中有内容(预设引用和/或 {name, members} 原型组),--from-cube 会自动提取这些内容:

playtest-custom-format cube.json --hydrated cube-hydrated.json \
  --format-module shared_library --from-cube \
  --turns 10 --games 1000 --seed 0 --output report.json

对于临时原型列表(或要在立方体声明的原型之上添加内容),可传入 --preset NAME(可重复指定)和/或 --archetype-group NAME=PRESET1,PRESET2,...,以内联方式声明上层原型:

playtest-custom-format cube.json --hydrated cube-hydrated.json \
  --format-module shared_library \
  --preset top-manipulation --preset removal --preset cantrip \
  --archetype-group graveyard=reanimate,flashback,graveyard-return,self-mill \
  --turns 10 --games 1000 --seed 0 --output report.json

模拟器会运行 N 场游戏 × T 个回合 × P 名玩家,跟踪市场动态和各原型的组装情况,并报告相关比率,但不会模拟战斗或完整的卡牌结算。v1 仅提供 --format-module shared_library;每种新赛制对应一个 Python 模块。

解读报告——两级信号。

始终可用(每个自定义赛制模块都会报告这些内容):

  1. 卡色缺失率。模拟器使用考虑法术力符号数量的法术力模型({U}{U} 需要 2 点实际的 U 法术力,而不能只是法术力池中有 U 的任意 2 点法术力)。比率高说明存在法术力符号负担——对于该赛制的颜色修正密度,需要特定颜色法术力的卡牌过多。 可调整的因素:
    • 将双符号卡牌({U}{U} → {1}{U})替换为单符号同类卡牌——这通常是影响最大的替换方式。
    • 增加同色地牌密度(增加每种颜色的双色地,或在该赛制使用的区域中增加对应颜色的基本地)。
    • 查找候选卡牌:针对立方体的原型模式,使用 card-search --bulk-data <path> --oracle "<pattern>" 查找现有卡牌的低符号费用版本。
  2. 各原型的组装率。 低于约 30% 的原型在实际对局中很少能凑齐。可调整的参数:
    • 提高辅助牌密度(Lucky Paper 至少需要 3–4 张牌;模拟器的 K=4 阈值与此一致)。
    • 对于包含多种机制的原型(坟场 = 复活 + 闪回 + 从坟场返回 + 自磨),声明 --archetype-group,或在 stated_archetypes 中添加 {name, members} 条目,以显示大类原型的实际密度。某个子机制只有 4 张牌时可能显得不足,但大类原型有 20 张牌时就很扎实。
    • 连接牌(横跨 2 个或更多原型的牌)可在不占用额外牌位的情况下提高大类原型的组装率——通过 archetype-audit 的 bridge-cards 输出对其进行追踪。

特定赛制(因模块而异)。 每种赛制的报告区块都会显示仅适用于该赛制机制的指标。请阅读相关模块,了解其追踪的内容。示例:

  • shared_library 会报告市场动态——利用率、被放逐/弃掉的牌,以及每回合的牌库效果。利用率达到 65% 以上表示状况良好;30%–40% 则表明玩家很少愿意从市场选牌。可调整的参数:重新平衡曲线/颜色牌池,直至利用率上升。
  • 未来的赛制模块会显示各自的指标(例如,指挥官区赛制可能会报告指挥官施放回合分布;级联补充包赛制可能会报告补充包之间的信号传递情况)。添加新模块时,请在此处添加相应的可调整参数条目。

首次运行前提:playtest-install-phase(约 5–10 分钟,一次性)是运行 gauntlet 的必要条件(使用 phase-rs)。Draft 和 custom-format 均为纯 Python,无需安装。


步骤 11:打印代理牌(可选)

当用户想要打印立方池以进行实体选秀时:

fetch-art --from-deck cube.json --by-name        # ~15s; populates art catalog
proxy-print --kind cards --deck cube.json --out cube-cards.pdf

就 proxy-print 的用途而言,立方池 JSON 与套牌 JSON 结构兼容(指挥官 + 牌,不含备牌)。除非立方池有意包含你希望单独打印的产出衍生物的增益牌,否则请跳过 --kind tokens。版面详情和目录设置请参阅 proxy-printer/SKILL.md。


立方池与套牌的区别

部分套牌向导工具适用于立方池,部分则不适用:

可直接使用(共享相同的 cards[] 结构):

  • card-search、scryfall-lookup、download-mtgjson、price-check
  • combo-search——查找意外出现的无限组合确实很有用
  • card-summary、mark-owned、web-fetch

不适用(依赖套牌专属假设):

  • mana-audit——要求套牌为 60 张或 100 张
  • legality-audit——要求遵循赛制套牌构筑规则
  • parse-deck——请改用 parse-cube
  • cut-check——用于检测套牌中的指挥官组合/协同
  • build-deck、deck-stats、deck-diff——已有立方池版本
  • export-deck——请改用 export-cube
  • set-commander、find-commanders、edhrec-lookup、mtga-import——与立方池无关

参考资料

在第 2 步(设计意图)或第 6 步(自我审视)期间,值得通过 WebFetching 阅读的哲学文章。Lucky Paper 没有 API;当对话涉及文章探讨的设计问题时,Agent 应按需获取文章。


致谢

立方专属逻辑(轮抽类别分类器、适用于 9/11/15 张牌的补充包模板)移植自 dan-blanchard/cube-utils (基于 MIT 许可证,使用时注明出处)。

评论

支持 Markdown