All skills

Build a card game: card data, deck/hand/discard zones, draw/shuffle/reshuffle, a turn structure, costs, and effect resolution. Use for a deckbuilder, TCG/CCG, or roguelike deckbuilder.

Use this Skill: https://skilld.dev/gh/gamedev-skills/awesome-gamedev-agent-skills/card-game

This session only. Nothing lands on disk.

referenceseffect-resolution.md

≈1.2k tokens on demand. Your agent reads this file only when SKILL.md points to it.

Card effect resolution and structure (depth)

Detail behind SKILL.md. Engine-neutral pseudocode. Models how card effects resolve, how triggers stack, and how deck construction shapes the game.

1. Effects as data + an interpreter

Define a small vocabulary of operations; every card is a list of them. Adding a card means adding data, not code. This keeps cards testable and prevents per-card spaghetti.

# A handful of ops cover most card games. Extend deliberately.
OPS = {
    "damage":     lambda fx, ctx: deal_damage(ctx.target(fx), fx["amount"]),
    "heal":       lambda fx, ctx: heal(ctx.target(fx), fx["amount"]),
    "draw":       lambda fx, ctx: ctx.owner.draw(fx["amount"]),
    "gain_res":   lambda fx, ctx: add_resource(ctx.owner, fx["amount"]),
    "summon":     lambda fx, ctx: summon(ctx.owner, fx["unit_id"]),
    "buff":       lambda fx, ctx: add_modifier(ctx.target(fx), fx["mod"]),
    "destroy":    lambda fx, ctx: move_to_discard(ctx.target(fx)),
}
def resolve_effect(fx, ctx):
    OPS[fx["op"]](fx, ctx)

2. The resolution queue / stack

When effects can trigger other effects (e.g. "when a creature dies, draw a card"), resolve through an explicit structure so order is deterministic:

  • Queue (FIFO): effects resolve in the order they were added. Intuitive for simple games.
  • Stack (LIFO): the most recently added effect resolves first — this is how trading card games model "responses" (the last thing said happens first). Choose one and document it.
# Stack model (pseudocode): pushing during resolution lets responses resolve first.
stack = []
def push_effect(fx, ctx): stack.append((fx, ctx))
def resolve_stack():
    while stack:
        fx, ctx = stack.pop()          # LIFO: last in resolves first
        resolve_effect(fx, ctx)        # may push more (triggers) -> they resolve next

Decide simultaneity rules up front: when several triggers fire at once, order them by a fixed rule (active player first, then by timestamp) so outcomes are reproducible.

3. Triggers and keywords

  • Triggers: "when X happens, do Y" (on-play, on-death, on-draw, start/end of turn). Register listeners by event; when the event fires, push the triggered effects onto the queue/stack.
  • Keywords: named, reusable abilities (e.g. taunt/guard, lifesteal, poison/DoT, shield). Implement each once as a modifier or trigger and tag cards with it — never re-implement per card.
# Event bus (pseudocode): triggers subscribe; effects fire when the event is published.
on("creature_died", lambda ev: [push_effect(t, ctx_for(t)) for t in triggers_for("on_death", ev)])

4. Targeting

  • Resolve targets at the moment of resolution (or at play, per your rules) and validate them — a target may have left the zone or died before the effect resolves; define "fizzle" behavior.
  • Make playing a card atomic: validate cost + legal targets first, then pay and commit. A cancelled or illegal play must leave zones exactly as they were.

5. Deckbuilder vs. constructed

Constructed (TCG/CCG) Deckbuilder (in-run)
Deck built Before the game, from a collection During play (draft/buy cards)
Variance Mulligans, draw order Reshuffle of a growing deck each "shuffle"
Power growth Fixed deck Deck thins/grows; combos emerge mid-run
Persistence Collection + decklists Run state (often roguelike: see roguelike)

In a roguelike deckbuilder, the deck is the build: adding/removing cards mid-run is the core progression. Keep run state separate from any meta-collection (see save-systems).

6. Shuffle fairness and consistency

  • Use a correct Fisher–Yates shuffle (engine RNG); naive "sort by random" is biased.
  • Seed the RNG if you want reproducible runs, replays, or deterministic undo.
  • For digital games, players perceive true-random as "streaky". Some games use a pity / smoothing system (e.g. bound how long before a needed resource appears). Decide intentionally; document it so balance math accounts for it.
def shuffle(cards, rng):                 # Fisher–Yates
    for i in range(len(cards) - 1, 0, -1):
        j = rng.range(0, i + 1)          # 0..i inclusive
        cards[i], cards[j] = cards[j], cards[i]

7. Mana / resource curves

  • The resource curve (how much you can spend by turn N) paces power. Cheap cards early, expensive payoffs later.
  • A deck's cost distribution (its "curve") determines consistency: too top-heavy and you can't act early; too cheap and you run out of gas. Balance card power against cost so a higher cost reliably buys more impact, with rarer cards bending the rule.

Source: SKILL.md on GitHub

No alerts1mo3 checks · Risk SAFE
  • Gen Agent Trust Hub1mo

    The skill provides architectural patterns and pseudocode for building card games, focusing on deck management and turn structures. It does not contain executable scripts, network requests, or external dependencies. No security risks were identified.

  • Socket1mo

    No alerts

  • Snyk1mo

    Risk: LOW · No issues

Signed by skilld at 3727d02. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub 3 days ago.

Activeupdated 2 months ago

README badge

README badge for gamedev-skills/awesome-gamedev-agent-skills/card-game