# 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 ```text 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 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): ```json { "id": "strike", "name": "Strike", "type": "attack", "cost": 1, "effects": [{ "type": "damage", "amount": 6 }] } ``` ```text 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 | Setting | Default | Meaning | |---|---|---| | `starterDeck` | `[]` | card ids of the starting deck; repeat an id for copies | | `drawPerTurn` | 5 | cards drawn at the start of each player turn | | `handLimit` | 10 | a full hand stops drawing; a card made in a full hand goes to the discard | | `rewardChoices` | 3 | cards offered by a reward | | `rarity` | fight 60/37/3, elite 50/40/10, boss rare only, shop 50/37/13 | rarity 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 | Hook | Mutable | Asked | |---|---|---| | `card.play` | `cost` | before the energy is spent; cancelling refuses the play, the card stays in hand | | `card.draw` | `count` | before each draw (reason turn, effect or draw) | | `card.add` | `upgraded` | before a card joins the deck | | `card.remove` | - | before a card is removed | | `card.upgrade` | - | before a card is upgraded | | `card.offer` | `kind`, `count` | before 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).