The pack
cards
function cards(): Pack<{ cards: CardsApi }>
The cards pack: the deck and its piles. Pure logic, so it needs no backend and runs headless.
Helpers
buildDeck
function buildDeck(decks = 1, faceUp = false, only: DeckOptions = {}): Card[]
decks ordered decks, suit-major in the order given (Ace→King by default), uid'd in build order.
cardId
const cardId = (c: Pick<Card, 'suit' | 'rank'>): string=> …
Face label "As", "Td", "Kc" — rank + suit initial. NOT unique in 2-deck games.
cardName
const cardName = (c: Pick<Card, 'suit' | 'rank'>): string=> …
Human name, e.g. "Ace of Spades".
isCourt
const isCourt = (rank: Rank): boolean=> …
True for the court cards (J/Q/K) — they get a face panel, not pips.
makePile
const makePile = (id: string, kind: PileKind, cards: Card[] = []): Pile=> …
A pile: its id, its kind and its cards (default none).
rankLabel
function rankLabel(rank: Rank): string
Short rank label: A, 2..10, J, Q, K.
RANKS
const RANKS: Rank[]
All thirteen ranks, Ace to King.
shuffle
function shuffle<T>(arr: T[], rng: Rng): T[]
Fisher–Yates in place, drawing from the kernel's seeded stream (createRng(seed)), so a seed reproduces the shuffle.
shuffledDeck
const shuffledDeck = (seed: number, decks = 1, only: DeckOptions = {}): Card[]=> …
A shuffled deck (or decks decks, of the cards only names). Same seed → same deal.
stackAlternating
const stackAlternating = (moving: Card, onto: Card): boolean=> …
Descending, alternating colour (Klondike/FreeCell tableau build).
stackDescending
const stackDescending = (moving: Card, onto: Card): boolean=> …
Descending, any suit (Spider's looser drop rule).
stackFoundation
const stackFoundation = (moving: Card, onto: Card): boolean=> …
Foundation build: UP in the same suit, A→K.
stackSameSuit
const stackSameSuit = (moving: Card, onto: Card): boolean=> …
Descending, same suit (Spider runs).
SUIT_GLYPH
const SUIT_GLYPH: Record<Suit, string>
The Unicode pip glyph (for a text HUD; the face art draws vector pips).
suitColor
const suitColor = (suit: Suit): CardColor=> …
Diamonds + hearts print red; clubs + spades black.
SUITS
const SUITS: readonly ["clubs", "diamonds", "hearts", "spades"]
The four French suits, in conventional bridge order (♣ ♦ ♥ ♠).
top
const top = (p: Pile): Card | undefined=> …
Returns the top card of a pile, or undefined when the pile is empty.
Types
Card
interface Card
One card. uid is the stable per-INSTANCE key (Spider deals two decks, so
cardId alone collides) — key your sprites by uid. faceUp is presentation
state the journal tells you when to change.
uid: number— Stable per-instance key — unique even across two decks.suit: Suit— The suit of this card.rank: Rank— The rank of this card, 1 (Ace) to 13 (King).faceUp: boolean— True when the face shows. The journal tells you when to change it.
CardColor
type CardColor = 'red' | 'black'
The print colour of a suit.
CardsApi
type CardsApi = typeof kit
game.cards — the deck, its shuffles, piles and stacking rules, as one namespace.
DeckOptions
interface DeckOptions
Which cards a deck holds: a subset of the suits and ranks (default all of both). A piquet deck is ranks 1 and 7 to 13; a euchre deck 1 and 9 to 13.
suits?: readonly Suit[]— The suits in each deck, in order. Default all four.ranks?: readonly Rank[]— The ranks in each suit, in order. Default Ace to King.
Pile
interface Pile
A pile is a kind + an ordered list (index 0 = bottom) + a stable id.
id: string— Stable id:stock,waste,t0..,f0..,c0..— the presenter's key.kind: PileKind— The role of this pile.cards: Card[]— The cards, index 0 at the bottom.
PileKind
type PileKind = 'stock' | 'waste' | 'foundation' | 'tableau' | 'cell'
The role a pile plays on the table.
Rank
type Rank = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13
1 = Ace … 11 = Jack, 12 = Queen, 13 = King.
Suit
type Suit = (typeof SUITS)[number]
One of the four suit names.


