card-game

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Card Game

卡牌游戏

A playbook for card games — card data, the deck/hand/discard zones, the turn structure, and how card effects resolve. This is a compositional skill: it models cards as data and wires them to UI. It does not re-teach data assets or UI nodes; it defines the zone model, the draw machinery, and the effect-resolution rules that keep a card game correct and bug-free.
一份卡牌游戏指南——涵盖卡牌数据、牌库/手牌/弃牌区、回合结构以及卡牌效果的结算方式。这是一项组合式技能:将卡牌建模为数据并与UI关联。它不会重新讲解数据资源或UI节点;而是定义区域模型、抽牌机制以及效果结算规则,确保卡牌游戏运行正确且无bug。

When to use

使用场景

  • Use when building any game where the core objects are cards moving between zones (deck → hand → play → discard): deckbuilder, TCG/CCG, solitaire, roguelike deckbuilder.
  • Use when designing draw/shuffle/reshuffle, turn structure, card costs, or how effects resolve.
When not to use: board/tile state with matching rules →
puzzle
. RPG with an incidental card battler → start from
rpg
. For defining cards as assets, use
godot-resources
/
unity-scriptableobjects
; for the hand/drag UI, use
godot-ui-control
.
  • 当构建核心对象为卡牌并在不同区域间移动(牌库→手牌→战场→弃牌区)的游戏时使用:卡组构筑游戏、TCG/CCG、纸牌接龙、Roguelike卡组构筑游戏。
  • 当设计抽牌/洗牌/重洗、回合结构、卡牌消耗或效果结算逻辑时使用。
不适用场景: 包含匹配规则的棋盘/tile状态游戏→使用
puzzle
技能。附带卡牌战斗系统的RPG游戏→从
rpg
技能开始。若要将卡牌定义为资源,使用
godot-resources
/
unity-scriptableobjects
;若要实现手牌拖拽UI,使用
godot-ui-control

Core loop

核心循环

Draw to your hand → spend resources to play cards → effects resolve and change the board → end the turn (cleanup/discard) → opponent/next phase → repeat until a win condition. Depth comes from the combinations a hand allows; the engine's job is to resolve them unambiguously.
抽牌到手牌→消耗资源打出卡牌→效果结算并改变战场状态→结束回合(清理/弃牌)→对手/下一阶段→重复直至达成胜利条件。 游戏深度来自手牌允许的组合玩法;引擎的职责是明确无误地解析这些组合。

Must-have systems

必备系统

  1. Card data — id, name, cost, type, text, and an effect spec (data, not code).
  2. Zones — deck (draw pile), hand, play/board, discard, exile/removed; cards live in exactly one.
  3. Draw + shuffle + reshuffle — draw from deck to hand; reshuffle discard into deck when empty.
  4. Turn structure — phases (untap/draw/main/combat/end) as a state machine.
  5. Resource system — mana/energy/actions that gate how much you do per turn.
  6. Effect resolution — apply a card's effects in a defined order; handle targets and triggers.
  7. Win/loss condition — life total, deck-out, objective.
  8. UI — hand layout, drag/drop or tap-to-play, zone counts, targeting affordances.
  1. 卡牌数据——ID、名称、消耗、类型、描述文本以及效果规格(数据形式,而非代码)。
  2. 区域系统——牌库(抽牌堆)、手牌、战场/桌面、弃牌区、放逐/移除区;每张卡牌始终仅属于一个区域。
  3. 抽牌+洗牌+重洗——从牌库抽牌到手牌;牌库为空时将弃牌区重洗入牌库。
  4. 回合结构——将阶段(重置/抽牌/主要/战斗/结束)作为状态机实现。
  5. 资源系统——mana/能量/行动点数,限制每回合可执行的操作次数。
  6. 效果结算——按既定顺序应用卡牌效果;处理目标选择与触发事件。
  7. 胜负条件——生命值、牌库耗尽、目标达成。
  8. UI系统——手牌布局、拖拽/点击出牌、区域卡牌计数、目标选择提示。

Design knobs

设计调节项

KnobEffectNotes
Starting hand / draw-per-turntempo, consistencyMore draw = less variance.
Hand size limithoarding vs. useDiscard down at end of turn.
Deck size (min)consistencySmaller = more reliable combos.
Resource curvewhat's playable when"Mana curve" paces power.
Card rarity / power budgetbalanceStronger cards cost more / are rarer.
Determinism vs. randomnessskill vs. swingShuffle + random effects add variance.
Reshuffle rulesdeck-out, fatigueReshuffle discard, or punish empty deck.
Removal / answerscounterplayEvery threat needs an answer in the pool.
调节项影响说明
初始手牌数量/每回合抽牌数节奏、稳定性抽牌越多,随机性越低。
手牌上限囤积vs使用回合结束时弃牌至上限。
牌库最小规模稳定性规模越小,组合玩法越可靠。
资源曲线不同阶段可玩卡牌“mana曲线”控制节奏与强度。
卡牌稀有度/强度预算平衡性强力卡牌消耗更高/稀有度更高。
确定性vs随机性技巧vs运气洗牌+随机效果增加变数。
重洗规则牌库耗尽、疲劳将弃牌区重洗入牌库,或对空牌库进行惩罚。
移除/应对手段反制玩法每个威胁都需要在卡牌池中存在对应的应对手段。

Patterns

模式示例

1. Zones + draw with automatic reshuffle

1. 区域系统+自动重洗的抽牌机制

python
undefined
python
undefined

Pseudocode. A card is in exactly one zone at a time; moving = remove here, add there.

伪代码。每张卡牌同一时间仅属于一个区域;移动操作=从当前区域移除,添加至目标区域。

def draw(n): for _ in range(n): if not deck: if not discard: # truly empty: deck-out (lose, or take fatigue) on_deck_out(); return deck.extend(discard) # reshuffle discard into deck discard.clear() shuffle(deck, rng) # use a seeded RNG (see save-systems for replays) hand.append(deck.pop())
undefined
def draw(n): for _ in range(n): if not deck: if not discard: # 完全空牌:牌库耗尽(失败,或触发疲劳) on_deck_out(); return deck.extend(discard) # 将弃牌区重洗入牌库 discard.clear() shuffle(deck, rng) # 使用带种子的随机数生成器(参考存档系统实现回放) hand.append(deck.pop())
undefined

2. Card as data + effect resolution

2. 卡牌数据化+效果结算

python
undefined
python
undefined

Pseudocode. Effects are a data list interpreted by the engine — not bespoke code per card.

伪代码。效果为数据列表,由引擎解析——而非每张卡牌编写定制代码。

card = { "id": "fireball", "cost": 3, "type": "spell", "effects": [ {"op": "damage", "amount": 6, "target": "chosen_enemy"} ], } def play(card, caster): if resources[caster] < card.cost: return False # can't afford resources[caster] -= card.cost move(card, from_zone=hand, to_zone=play_or_discard(card)) for fx in card.effects: resolve_effect(fx, caster) # one interpreter handles every card return True
undefined
card = { "id": "fireball", "cost": 3, "type": "spell", "effects": [ {"op": "damage", "amount": 6, "target": "chosen_enemy"} ], } def play(card, caster): if resources[caster] < card.cost: return False # 资源不足,无法打出 resources[caster] -= card.cost move(card, from_zone=hand, to_zone=play_or_discard(card)) for fx in card.effects: resolve_effect(fx, caster) # 一个解析器处理所有卡牌 return True
undefined

3. Turn structure as a phase machine

3. 回合结构作为阶段状态机

python
undefined
python
undefined

Pseudocode. Fixed phases keep timing windows (triggers, priority) unambiguous.

伪代码。固定阶段确保时间窗口(触发事件、优先权)明确无误。

PHASES = ["untap", "draw", "main", "combat", "end"] def take_turn(player): for phase in PHASES: enter_phase(player, phase) # fire "on_phase" triggers here if phase == "draw": draw(1) if phase == "main": await player_plays_cards() if phase == "combat": resolve_combat() if phase == "end": discard_to_hand_limit(player); clear_temporary_effects()
undefined
PHASES = ["untap", "draw", "main", "combat", "end"] def take_turn(player): for phase in PHASES: enter_phase(player, phase) # 在此触发“进入阶段”事件 if phase == "draw": draw(1) if phase == "main": await player_plays_cards() if phase == "combat": resolve_combat() if phase == "end": discard_to_hand_limit(player); clear_temporary_effects()
undefined

Pitfalls / failure modes

常见陷阱/失败模式

  • A card existing in two zones at once → duplication/loss bugs. Enforce "exactly one zone"; move = remove-then-add, and assert no card appears twice.
  • Forgetting to reshuffle → draws silently fail or crash on empty deck. Reshuffle discard, or define deck-out/fatigue explicitly (Pattern 1).
  • One function per card → unmaintainable and untestable. Make effects data interpreted by a small set of operations (Pattern 2).
  • Ambiguous effect order / simultaneous triggers → nondeterministic outcomes. Resolve in a defined order (a queue or stack); document LIFO vs. FIFO (refs).
  • Unseeded shuffle in a game that needs replays/undo → can't reproduce. Use a seeded RNG.
  • No hand limit / no answers → degenerate hoarding or unbeatable threats. Add a hand cap and ensure removal exists for every threat archetype.
  • Targeting state leaks → a cancelled play leaves the board mid-targeting. Make play atomic: validate cost + targets first, then commit.
  • 一张卡牌同时存在于两个区域→导致卡牌复制/丢失bug。强制“每张卡牌仅属于一个区域”;移动操作=先移除再添加,并断言卡牌不会重复出现。
  • 忘记重洗→牌库为空时抽牌静默失败或崩溃。重洗弃牌区,或明确定义牌库耗尽/疲劳规则(参考模式1)。
  • 每张卡牌对应一个函数→难以维护和测试。将效果设计为数据,由少量操作解析(参考模式2)。
  • 效果顺序模糊/触发事件同时发生→结果不确定。按既定顺序(队列或栈)结算;文档说明LIFO或FIFO规则(参考资料)。
  • 需要回放/撤销功能的游戏中使用无种子洗牌→无法复现操作。使用带种子的随机数生成器。
  • 无手牌上限/无应对手段→出现囤积卡牌或无法击败的威胁。添加手牌上限,并确保每个威胁类型都有对应的移除手段。
  • 目标选择状态泄露→取消出牌后战场仍处于目标选择状态。使出牌操作原子化:先验证资源+目标,再执行操作。

Composition (build it from these skills)

组合构建(基于以下技能)

  • Card content:
    godot-resources
    /
    unity-scriptableobjects
    — define each card as a data asset.
  • UI:
    game-ui-ux
    for layout, scaling, and focus navigation;
    godot-ui-control
    for hand layout, drag/drop, zone counts, and targeting prompts.
  • Persistence/replays:
    save-systems
    for collection, run state (roguelike deckbuilder), and seeded replays.
  • Opponent AI:
    game-ai
    for an AI that evaluates playable cards and picks targets.
  • Animation/feedback: the engine animation skill for card movement;
    audio-design
    for cues.
  • Scripting:
    godot-gdscript
    /
    unity-csharp-scripting
    for the effect interpreter.
  • 卡牌内容:
    godot-resources
    /
    unity-scriptableobjects
    ——将每张卡牌定义为数据资源。
  • UI:
    game-ui-ux
    用于布局、缩放和焦点导航;
    godot-ui-control
    用于手牌布局、拖拽、区域计数和目标选择提示。
  • 持久化/回放:
    save-systems
    用于卡牌收集、运行状态(Roguelike卡组构筑游戏)和带种子的回放。
  • 对手AI:
    game-ai
    用于评估可打出卡牌并选择目标的AI。
  • 动画/反馈: 引擎动画技能用于卡牌移动;
    audio-design
    用于音效提示。
  • 脚本:
    godot-gdscript
    /
    unity-csharp-scripting
    用于效果解析器。

References

参考资料

  • For the effect queue/stack, keywords/triggers, targeting, deckbuilder vs. constructed archetypes, and shuffle fairness, read
    references/effect-resolution.md
    .
  • 关于效果队列/栈、关键词/触发事件、目标选择、卡组构筑vs预设卡组类型以及洗牌公平性,请阅读
    references/effect-resolution.md