Phaser AE

Card decks

Free packv3.0.0-22DGrid

The deck every card game starts from: suits, ranks and names, decks of any number and any subset shuffled from a seed, piles, and the stacking rules card games share. Your rules build on it; the other card packs make it look like a real table.

This is a Free pack. Every phaser.io account can use it in their games.

Released October 14, 2026 · updated October 19, 2026

Card decks: a screenshot of its demo
A note about these graphics

Expansion packs don't come with graphics. This screenshot is one way of drawing what the pack does, made for its demo: none of the sprites, tiles or backgrounds in it are in the pack.

That's by design. A pack is a game's logic, mechanics and effects, and it works with whatever art you give it. Some packs draw effects, backdrops or 3D scenes of their own, but none carries a game's sprites.

So the look is yours. Make the art on phaser.io, bring your own, or let your agent draw it in code: the same pack can look like anything.

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.