卡片Game
将以下提示词粘贴到你的 AI 对话框中:
请根据 https://skillhub.cn/install/skillhub.md,安装 @user_3c6cb52e/card-game-sh-vr2ee3。
技能介绍
要解决的问题
写卡牌游戏时,最容易翻车的不是画卡,而是把「一张卡此刻在哪个区域」和「这张卡的效果按什么顺序结算」散落在各个脚本里。结果是抽牌静默失败、弃牌堆忘记洗回牌库、同一张卡同时出现在手牌和场上、结算顺序随机导致不可复现的对局。
这个技能针对的正是这些结构性问题,而不是再教一遍怎么搭 UI 或怎么存资源。
它如何工作
核心是组合式(compositional)的设计:卡牌本身是数据,技能负责把数据接上区域与规则。
- 区域模型:
deck、hand、play/board、discard、exile/removed。一张卡必须恰好存在于一个区域;移动采用 remove-then-add,并在移动前后断言同一张卡没有出现两次。 - 抽牌与洗牌:从牌库抽到手牌;牌库空时自动把弃牌堆洗回,或显式定义牌库耗尽与疲劳惩罚。
- 回合状态机:把 untap、draw、main、combat、end 做成明确的 phase 状态机,而不是散落在
update()里的布尔值。 - 资源闸门:
mana/energy/actions决定每回合能做多少事,与卡牌cost字段联动。 - 效果结算:效果以数据描述,由一小组操作解释执行,并按定义的顺序(队列或栈,注明 LIFO 还是 FIFO)处理目标与触发。
- 胜负条件:生命值、牌库抽空、达成目标。
- UI 契约:手牌布局、拖拽或点选出牌、区域计数、选目标提示。
关键步骤:先定区域与移动规则,再定回合 phase 与资源曲线,最后把每张卡写成数据并在结算时统一解释。
适用边界
该用的时候:核心对象是卡、且卡在区域间流转(deck → hand → play → discard)的游戏——牌组构建、TCG/CCG、纸牌、Roguelike 牌组构建。
不该用的时候:以棋盘格和匹配规则为主的状态机 → 那是 puzzle;RPG 里顺带打一局卡牌战斗 → 从 rpg 技能起步。
注意点:
- 不要给每张卡写一个独立函数,那会无法维护也无法测试。
- 洗牌要带 seed,否则无法重放和回退。
- 结算顺序必须确定,同时触发要排队处理。
- 出牌要保证原子性:先校验费用和目标,再提交,否则取消操作会留下脏状态。
- 手牌要有上限,且每种威胁原型都要有解,否则会出现囤牌或无解威胁。
详细的效果队列、关键词与触发、选目标、牌组构建与构筑原型的对比,见 references/effect-resolution.md。
使用场景
- 正在做 Deckbuilder,要把 `deck`、`hand`、`discard` 三个区域连起来,顺带处理牌库空时洗弃牌堆。
- 写 TCG/CCG 回合,`untap`、`draw`、`main`、`combat`、`end` 这些 phase 别用一堆布尔值硬凑。
- 卡牌效果写成了一个函数一张卡,想改成数据驱动,并统一结算顺序和目标选择。
- 牌库抽空后没洗弃牌堆,抽牌静默失败或直接崩,要按规则加上 `deck-out` 或疲劳处理。
适合人员
- 独立开发者做第一款 Deckbuilder,想先把区域和移动规则定下来,不被结算顺序坑。
- 兼职做卡牌对战项目的客户端,服务端定了结算规则,要在客户端把抽牌和回合状态机写出来。
- 游戏策划在定资源曲线和手牌上限,需要在动手开发前确认这些旋钮怎么影响对局节奏。
- 在校学生做卡牌毕业设计,想把洗牌、回合流程这些基础结构一次写对,少踩重复坑。