Cards
A card (kind: card) is a flat component that flips between a front
and a back. The front is required — a card must show something face-up —
and the back is optional, shared across the whole deck so a face-down stack
looks uniform.
Cards behave like every other component: players drag, flip, and deal them by hand. taybl doesn’t deal turns or enforce who may look at a card — that comes from the zone a card sits in (a face-down draw pile, an owner-only hand).
How to edit in the Studio
Open your game → Layout tab and select the card to set its name, front
art, and behaviors. Grouping cards into a deck — assigning a shared back and
a group id to a whole set at once — is done from the Decks tab of the
game-settings editor; see decks. The variants shorthand
below is an authoring/generation convenience rather than an inspector
control.
Card fields
| Field | Values | Default | What it does |
|---|---|---|---|
kind | card | — | Marks this component as a card |
faces.front | FaceBinding | — | Required. The face-up art (a card must have a front) |
faces.back | FaceBinding | .optional() | The shared face-down art; usually the same image across a deck. Set its rotation to 180 if the back scanned upside down — that turns the back alone and leaves the front as it is |
group | component id | .optional() | Deck id — lets setup place a whole deck at once (e.g. deck_standard_52) |
cardFace | CardFace | .optional() | A taybl-drawn composed face — see below |
variants | array of CardVariant (≥ 1) | .optional() | Authoring shorthand for a large unique deck — expanded at normalize time (below) |
Composed faces — a card taybl draws for you
A card’s front is normally one uploaded image (faces.front). But the
component-library card configurator can instead author a cardFace: a
structured face taybl draws live on the table from fields you edit — a header,
an art window (cardFace.artImage, an uploaded image that fills only the
middle, not the whole card), a type line, rules body, and up to four
independent corner value badges, each with its own value and colour. A
cardFace renders only when the card has no full-face faces.front.image, so
a fully-custom uploaded card is never overridden.
Generation authors these too. When your upload describes cards it has no
art for — a rules table listing them by name with columns of stats and an
ability — the AI fills the same fields: the name becomes the header, the
category column the type line, the ability column the body, and up to four
stat columns the corner badges. So a game built from a card list arrives
readable rather than as a deck of coloured rectangles. Every field is yours to
edit afterwards, here or by asking Pip.
The text sizes itself to fit — you never have to trim a name to make it work. The header is the same band on every card in a deck, so the art and rules below it line up from card to card, and a long title is set smaller (wrapping onto a second line if it needs to) rather than growing the bar or clipping. The type line and the rules text shrink the same way. The badges sit as quarter-round wedges in the card’s exact corners, and the name always keeps the width between them.
Hiding the parts you don’t use
Most cards use only some of the anatomy, so every part can be turned off.
Each one carries an eye button on its own field in the configurator and in
the layout-editor inspector: click it and that part stops being drawn, and its
editor collapses — there is nothing on the face left to edit. Corner badges
work the same way, one eye per corner. Under the hood these are
cardFace.show (header / art / type / body) and a show flag on each badge.
The art window starts hidden, because an empty one draws nothing but a placeholder. Turn its eye on when you have art for the card — that is also what reveals the upload control. Cards already saved in a game keep whatever they were set to.
Icons — a symbol when you have no art
A card with no artwork can still carry a symbol: pick an Icon on the card and taybl draws it in the art window. This is what stops an art-less deck reading as a wall of text — a sword on the attack cards, a coin on the treasures — and it needs no upload and no image files at all.
Choosing an icon turns the art window on for you, since that is where it is drawn.
Uploaded art always wins. If a card has art in its window and an icon, the art is what shows — an icon is the fallback, so you can set one across a whole deck and let real artwork replace it card by card as it arrives, without clearing anything.
The picker opens on a curated set grouped by theme — combat, resources,
status, places, nature, gear — and typing searches every
lucide icon, around 1,700 of them. Search matches icon
names only, so try the plain word for the thing you want (sword, castle,
droplet). Stored as cardFace.icon.
Pip can set icons too — “put a shield icon on every defence card” — though it chooses from the curated set rather than the full library.
A card shares the rest of its fields with every kind — see
components overview. Every card is flippable, so
it can always be turned face-down; the faces.back art (assigned in the
Decks flow) is what shows on the down side, and a card with no
back still flips to a generic back.
Variants — one entry for a whole unique deck
Most decks are a hundred different fronts sharing one back. Writing a
hundred near-identical card entries is tedious, so a card may instead carry a
variants[] list. The normalize pass expands it into one determinate
card per variant — each gets the variant’s own front, the parent card’s
shared faces.back, and the parent’s group. The runtime, renderer, and
validator only ever see the expanded ordinary cards; variants never reaches
them.
Each CardVariant has:
| Field | Values | Default | What it does |
|---|---|---|---|
id | lowercase snake_case | — | Becomes the expanded card’s id (parent_id + _ + this) |
front | FaceBinding | — | This variant’s determinate face-up art |
name | text | .optional() | Defaults to the parent card’s name |
count | integer ≥ 1 | .optional() | Copies of this variant (e.g. four of a value) |
properties | record of string / number / boolean | .optional() | Per-variant data tags (suit, rank) |
Playing cards
A card carrying a rank and a suit in its properties is drawn as a
standard playing card — the pip layout, the corner indices, the monogram
court — with no uploaded art and no cardFace to author. That is what the
Standard deck library entry builds, and what the built-in card games
(Hearts, War, Go Fish, Crazy Eights) use.
The vocabulary is fixed, because the renderer reads it directly:
| Property | Values | What it means |
|---|---|---|
suit | spades · hearts · diamonds · clubs · joker | Picks the pip and the ink — hearts and diamonds are red |
rank | 2–10 literal, 11 Jack, 12 Queen, 13 King, 14 Ace, 15 joker | The printed index; the numbers sort the way a game expects |
jokerInk | red · black | Jokers only — they carry no suit to take a colour from |
Set those on a card you built by hand and it draws the same way. An uploaded
faces.front.image still wins over the drawn face, so real card art always
takes precedence.
Related
- Components overview — shared fields
- Decks — grouping cards and assigning a shared back
- Zone roles — draw piles, hands, discards
- Zone visibility — who can see a card’s front
- Setup automation — shuffling and dealing a deck