Card deck

Usage guide of cards.deck: cards as data, draw/hand/discard/exhaust piles, energy costs, keywords, upgrades, rewards by rarity, settings, the cards.deck service, events and the card.* hooks.

Source: module-kits:kits/cards_deck/usage/en.mdView Markdown source

Also read offline — CLI: grip-forge docs cards-deckMCP tool: gripforge_docs { "topic": "cards-deck" }

Cards for turn-based fights (cards.deck) #

What it is for #

cards.deck manages a deck played inside the fights of combat.turns: draw pile, hand, discard, exhaust and powers, energy costs (or X), keywords, upgrades and card rewards rolled by rarity. The kit knows no card: they are the cards documents of your game. It requires combat.turns and game.engine.

Turn it on #

gripforge_gamekit_install   { project_id: "gkp_…", id: "cards.deck" }
gripforge_gamekit_configure { project_id: "gkp_…", id: "cards.deck",
                              config: { "starterDeck": ["strike", "strike", "guard"], "drawPerTurn": 5 } }

First example #

<!-- test: kits/game_engine/host/tests/combat_turns.rs::cards_are_drawn_played_and_discarded --> A card is a document of the cards collection. Start a fight, play a card by its uid (and an enemy id when it needs a target):

{ "id": "strike", "name": "Strike", "type": "attack", "cost": 1, "effects": [{ "type": "damage", "amount": 6 }] }
combat.turns.start([["brute"]])        -> 5 cards drawn
cards.deck.play("c1")                  -> { ok: false, reason: "target" }
cards.deck.play("c1", "e1")            -> { ok: true }

A refused play answers { ok: false, reason } with no_fight, not_your_turn, not_in_hand, unplayable, energy or target. At the end of the turn the hand is discarded, and an empty draw pile is refilled by shuffling the discard.

Settings and defaults #

SettingDefaultMeaning
starterDeck[]card ids of the starting deck; repeat an id for copies
drawPerTurn5cards drawn at the start of each player turn
handLimit10a full hand stops drawing; a card made in a full hand goes to the discard
rewardChoices3cards offered by a reward
rarityfight 60/37/3, elite 50/40/10, boss rare only, shop 50/37/13rarity weights (common, uncommon, rare) per kind of reward

Card fields: type (attack, skill, power, status, curse), rarity, cost (0 to 9 or "x"), target (enemy, all_enemies, random_enemy, self, none), effects, keywords (exhaust, retain, ethereal, innate, unplayable), triggers (a power: on a combat.turns hook, effects), upgrade and description. Pile effects added to the effect language of combat.turns: draw, discard, exhaust, add_card, upgrade_hand.

Services, events, variables #

  • cards.deck (service): deck(), reset(), addCard, removeCard, upgradeCard, piles(), pile(name), hand(), canPlay(uid, target), play(uid, target), draw(n), offerReward({ kind }), reward(), takeReward(i), skipReward(), rollCards(count, label, kind), select(uid), selected(), viewer(open?), views(cards, lang?, upgraded?), stats().
  • Events: cards.played, cards.refused, cards.shuffled (the discard became the draw pile), cards.offered, cards.added, cards.removed, cards.upgraded.
  • Variables: cards.deck_size, cards.draw, cards.hand, cards.discard, cards.exhaust.
  • Content verbs: add_card_to_deck (action) and deck_has_card (condition).

Hooks and modding #

HookMutableAsked
card.playcostbefore the energy is spent; cancelling refuses the play, the card stays in hand
card.drawcountbefore each draw (reason turn, effect or draw)
card.addupgradedbefore a card joins the deck
card.remove-before a card is removed
card.upgrade-before a card is upgraded
card.offerkind, countbefore a reward is rolled

All hooks are cancellable. Moddable: the settings above and the cards collection.

Limits #

No card art or card game rules beyond the effect language: new effects come from combat.turns. A fight is required to play a card. The hand and deck screens are drawn by the kit; other interfaces read views().

Versions #

Kit 1.2.0 (views() added); service cards.deck 1.0.0; hooks since 1.1.0 (game.engine 1.2 extension contract).