Suit How to Make a Card Game (Browser Play Loop 2026)

By Arron R.16 min read
How to make a card game in 2026: model a fair 52-card deck and a scoring rule, wire the shuffle-deal-play-score cycle inside WizardGenie against three AI oppone

Most beginners who search "how to make a card game" want the feel of a real tabletop night - a green felt with a fanned thirteen-card hand at the bottom, three opponents around the rim, four cards played into the center in trick order with the suit-matching rule quietly enforced, a Queen of Spades bomb that lands on somebody else's scorecard, and a satisfying trick-collection sweep as the winner drags the four cards toward their pile - not a real-money platform with a shuffle audit trail and gambling licences on day one. Live card rooms are famously demanding at commercial scale because a single project juggles cryptographically fair shuffling, per-player state, correct legal-play validation, opponent AI that follows suit and ducks liability tricks plausibly, and a scoring model that handles special cases like shooting the moon. A browser card game aimed at a portfolio piece or a jam is a different animal. A coding agent scaffolds the deck, the shuffle, the trick validator, and the score sheet from a single prompt, and AI generation covers the felt, the card faces, the opponent portraits, and the shuffle and deal cues. On desktop or web, that means WizardGenie for the play-loop interpreter, AI Image Gen for the felt, cards, and opponent avatars, and SFX Gen for the shuffle riffle and card slides. This guide is the honest end-to-end for how to make a card game in 2026, as a weekend build you can actually finish, with Hearts as the worked example.

How to make a card game browser pipeline: shuffle a 52-card deck, deal, play tricks with legal-play validation, and score wired in WizardGenie with AI Image Gen felt and SFX Gen shuffle cues
The 2026 how to make a card game recipe: shuffle a fair 52-card deck, deal thirteen cards to four seats, play tricks under the follow-suit rule, and score - Hearts as the worked ruleset.

What how to make a card game actually means in 2026

The query "how to make a card game" hides three distinct intents. Some searchers want a physical-print how-to for designing a boutique deck with custom art and a rulebook - the sibling how to make a board game guide covers the tabletop-manufacturing end of that thread. A second intent is the deckbuilding roguelike family (Slay the Spire, Dominion, Balatro), where the deck itself evolves across a run - the how to make a deck builder game guide covers that draw-play-discard-reshuffle loop. The intent this article targets is the third: a browser card game that boots into a single-page HTML shell with a green felt table, four seats (you and three AI opponents), a fair Fisher-Yates shuffle of a 52-card deck, thirteen cards dealt to each seat, trick-taking play where each seat plays one card per trick and must follow the led suit if they can, a scoring rule for the ruleset in play, and a hand-end scoreboard that carries between hands. That is a weekend build, it demos the Sorceress toolset honestly, and it is the format most card game tutorial and javascript card game searchers actually want.

The card family this guide picks is Hearts. Hearts needs no trump, no bidding, and no melding, so the play loop stays legible; it is a four-player evasion game where hearts score one point each and the Queen of Spades scores thirteen, the loser is the first player to reach 100 points, and a single seat that manages to take every heart and the Queen in one hand "shoots the moon" and gives 26 points to the other three seats. The Hearts rules on Wikipedia (verified 2026-08-31) cover the full canonical ruleset including the passing phase, the two-of-clubs opening lead, and the "hearts must be broken" rule before hearts can be led - cite that page in your itch.io blurb so players know you shipped a standard Hearts variant, not a house-rule mashup. Swap in Spades by adding a bidding phase and treating spades as trump, or Whist by cycling trump each hand - the scaffolded model in Step 1 covers both with a rules-object swap and about forty lines of new code, so the base build is the honest starting point for any trick-taking card game.

The card game play loop in one minute (shuffle, deal, trick, score)

Five moving parts, cycled every hand. First, shuffle - a fresh 52-card deck runs through a Fisher-Yates pass so no shuffle pattern carries between hands. Second, deal - thirteen cards go to each of four seats in clockwise order starting from the seat left of the dealer, and the dealer button rotates one seat clockwise between hands. Third, lead the trick - the seat holding the two of clubs leads it on the first trick of a hand; subsequent tricks are led by the seat that won the previous trick. Fourth, follow suit - each remaining seat, clockwise, plays a legal card; a seat must follow the led suit if it holds any card of that suit, and if not, it may play any card in its hand (with the "no hearts and no Queen of Spades on the first trick" exception, and the "hearts must be broken" rule before hearts can be led). Fifth, score the trick - the highest card of the led suit wins the trick and drags the four cards to that seat's pile; hearts count one point each, the Queen of Spades counts thirteen. Repeat thirteen times per hand, tally points, deal again, and continue until any seat crosses 100 points - whoever is lowest at that moment wins. That five-step cycle, wrapped by a scoreboard between hands, is the whole html5 card game loop - passing, shoot-the-moon detection, and hand-end animation are polish on top.

Card game play loop state machine diagram showing shuffle, deal, lead trick, follow suit, and score trick with Hearts rules for hearts breaking and Queen of Spades scoring
The card game play loop: shuffle a 52-card deck, deal thirteen cards to four seats, lead the trick, follow suit clockwise, and score the trick winner - repeated thirteen times per hand.

Pick your engine for how to make a card game: Canvas, Phaser, or WizardGenie

Three good targets in 2026, each with a different trade-off. Plain HTML Canvas 2D is the honest default and the pick this guide recommends for a first build. A trick-taking card game is light on physics - there is no collision solver, no continuous motion outside of a short card-slide easing curve, and the biggest render loads are the static felt and the 52 card sprites, both of which are cheap. The MDN Canvas API reference (verified 2026-08-31) covers the drawImage sprite-atlas pattern that lets you pack all 52 card faces plus the card-back into a single texture and stamp any card at any table position with one blit. Cache the felt backdrop to an offscreen canvas once at boot, redraw only the moving card sprites and the current trick each frame, and the whole browser card game experience holds a stable 60 fps in any modern browser without any WebGL overhead.

Separate the simulation tick from the render frame - trick-taking card play is inherently turn-based and does not need per-frame simulation. A single tick fires when a player commits a card; everything between plays is either idle or animating a short card slide, off the render loop. This is the same discipline the sibling how to make a poker game guide uses for its betting loop and the how to make blackjack guide uses for its deal loop - a card game just runs the cycle thirteen times per hand instead of once.

Phaser v4.2.1 "Giedi" (released 9 July 2026, verified 2026-08-31 on the official Phaser stable download page) becomes the right pick when a browser card game wants Phaser's Scene system, tween library, and input plugins out of the box. Phaser scenes map cleanly to card-game screens - LobbyScene, TableScene, HandEndScene, GameOverScene - and Phaser's tween chain is a natural fit for the "deal thirteen cards to each seat, one card at a time, 40 ms apart" animation without hand-writing an easing loop. For a first hand where the card-slide animation is the biggest UX bet, Phaser saves an hour; for a pure vanilla-JavaScript learning build, plain Canvas is more instructive.

WizardGenie is not a separate card game engine - it scaffolds whichever of the two you pick from a single natural-language prompt. WizardGenie ships as both a desktop app (Windows installer with auto-update, available to Early Access supporters and above) and a no-install web build. Its coding-model lineup covers Claude Opus 4.7, Claude Sonnet 4.6, GPT-5.5, Gemini 3.1 Pro, DeepSeek V4 Pro, Kimi K2.5, Grok 4.2, and MiniMax M2.7 (verified 2026-08-31 in src/app/_home-v2/_data/tools.ts lines 767-774). For a first card game play loop, any frontier model scaffolds the deck-shuffle-deal-trick-score state machine in one prompt. Pair a frontier planner with a budget executor like DeepSeek V4 Pro or Kimi K2.5 for the typing pass - the dual-agent pattern lands most projects at roughly one-fifth the single-frontier cost.

Step 1 - model deck, hands, tricks, and the score sheet (Hearts as the worked example)

Nothing else in the pipeline matters if the deck is not fair and the legal-play validator is not correct. Start with a small, testable model:

const SUITS = ["c", "d", "h", "s"];
const RANKS = ["2","3","4","5","6","7","8","9","T","J","Q","K","A"];
const RANK_VALUE = Object.fromEntries(RANKS.map((r, i) => [r, i + 2]));

function freshDeck() {
  const deck = [];
  for (const s of SUITS) for (const r of RANKS) deck.push(r + s);
  return deck;
}

function shuffle(deck) {
  for (let i = deck.length - 1; i > 0; i--) {
    const j = Math.floor(Math.random() * (i + 1));
    [deck[i], deck[j]] = [deck[j], deck[i]];
  }
  return deck;
}

const state = {
  seats: [
    { id: "you",  name: "You",  hand: [], taken: [], score: 0 },
    { id: "ai1",  name: "Rook", hand: [], taken: [], score: 0 },
    { id: "ai2",  name: "Vera", hand: [], taken: [], score: 0 },
    { id: "ai3",  name: "Otto", hand: [], taken: [], score: 0 },
  ],
  dealerIndex: 0,
  trick: [],
  ledSuit: null,
  leaderIndex: 0,
  turnIndex: 0,
  handIndex: 0,
  heartsBroken: false,
  firstTrick: true,
};

function dealHand() {
  const deck = shuffle(freshDeck());
  for (let i = 0; i < 4; i++) state.seats[i].hand = deck.slice(i * 13, (i + 1) * 13);
  state.seats.forEach((s) => (s.taken = []));
  state.trick = [];
  state.ledSuit = null;
  state.heartsBroken = false;
  state.firstTrick = true;
  const twoOfClubs = "2c";
  state.leaderIndex = state.seats.findIndex((s) => s.hand.includes(twoOfClubs));
  state.turnIndex = state.leaderIndex;
}

function legalCards(seat) {
  const hand = seat.hand;
  if (state.firstTrick && state.trick.length === 0) return hand.filter((c) => c === "2c");
  if (state.trick.length === 0) {
    const nonHearts = hand.filter((c) => c[1] !== "h");
    if (!state.heartsBroken && nonHearts.length > 0) return nonHearts;
    return hand;
  }
  const followers = hand.filter((c) => c[1] === state.ledSuit);
  if (followers.length > 0) return followers;
  if (state.firstTrick) {
    const noPoints = hand.filter((c) => c[1] !== "h" && c !== "Qs");
    if (noPoints.length > 0) return noPoints;
  }
  return hand;
}

The Fisher-Yates shuffle above is the correct O(n) algorithm - the loop counter starts at the end and picks a random index only from the unshuffled prefix, which is what produces a uniform permutation. The common naive-shuffle bug of writing Math.floor(Math.random() * deck.length) on every iteration produces a biased distribution that leaves cluster patterns detectable after roughly fifty hands (the Fisher-Yates shuffle overview on Wikipedia, verified 2026-08-31, has the classic proof and the wrong-versus-right comparison). For a single-player casual browser card game, Math.random with Fisher-Yates is honest and passes casual scrutiny; for any build that ever ships against another human on the same URL, swap the RNG source for Crypto.getRandomValues (verified 2026-08-31 on MDN) to close the client-seed inspection attack.

The legal-play validator is the second must-get-right component. Unit-test six cases before you generate any art: the two of clubs is the only legal opening lead on the first trick; a seat that holds any club must play a club when clubs are led; a seat holding no clubs on the first trick may not play a heart or the Queen of Spades; a seat holding no hearts may still play the Queen of Spades on a diamond lead; hearts cannot be led until any player has been forced to discard a heart on a non-heart lead; the seat that captures a heart or the Queen of Spades sets heartsBroken = true. Those six tests catch ninety percent of javascript card game validator bugs and let the model swap in Spades or Whist rules with a rules-object edit instead of a rewrite.

Step 2 - wire the shuffle-deal-play-score cycle in WizardGenie

With the deck, the legal-play validator, and the score-sheet drafted, open WizardGenie. Drop in a bare index.html shell with a full-viewport canvas, a small HUD reading YOU 0 - ROOK 0 - VERA 0 - OTTO 0, and a hotkey table. Give the agent one paragraph: Build a browser Hearts card game. Four seats: one human (bottom) and three AI opponents (Rook, Vera, Otto) around a green felt table. Deal thirteen cards each from a Fisher-Yates-shuffled 52-card deck. The seat holding the two of clubs leads it on the first trick. Follow clockwise. Each seat must follow the led suit if it holds any card of that suit; if not, it may play any card in its hand, subject to two exceptions: no hearts or Queen of Spades on the first trick unless the seat has no other option, and hearts cannot be led until any player has been forced to discard a heart on a non-heart lead. The highest card of the led suit takes the trick. Hearts score one point each, the Queen of Spades scores thirteen. If a single seat takes all thirteen hearts and the Queen of Spades in one hand ("shoots the moon"), award 26 points to the other three seats instead. First seat to reach 100 points loses; whoever is lowest at that moment wins. AI opponents evaluate every legal card and prefer to duck point-heavy tricks: when leading, lead a low card of their longest non-hearts suit; when following, if they cannot beat the current trick winner they dump their highest liability card, if they can win a zero-point trick they take it with the lowest winner, if they can win but taking costs points they duck. Add a 10 percent randomness on tie-breaks so play does not feel mechanical. Log every trick to a hand-history panel on the right. Feed that to any coding model in the lineup and the interpreter scaffolds in under twenty minutes.

The remaining hour is polish via follow-up prompts. Add a legal-card highlight that dims the illegal cards in the human hand so a misclick is impossible - one selector loop over the 13-card fan and a CSS opacity toggle. Add a trick-collection sweep so the four played cards ease toward the winning seat over 300 ms with a card-slide SFX on each stack merge - fifteen lines of tween code. Add a timed AI turn so each AI opponent's play takes 400 ms with a small typing-indicator dot on their portrait, which reads as "thinking" and paces the trick naturally instead of firing all three AI plays in one frame. Add a hand-history log that records "Hand 1 - Trick 1: You lead 2C, Rook plays 5C, Vera plays KC (winner), Otto plays 7C" for the last three hands - fifty lines. Each item is a follow-up prompt, and the whole browser card game experience lands over a Saturday afternoon.

Optional siblings on the same base shell: for a single-decision card game against a dealer, borrow the deal loop from how to make blackjack. For a betting-round card game with hole cards and a community board, see how to make a poker game. For the classic single-player card game with foundations and a tableau, see how to make solitaire.

Step 3 - AI Image Gen card faces and table, SFX Gen shuffle and deal cues

A blank Canvas with rectangle-and-text placeholders reads as a debugger, not a card game. Two asset passes cover the whole html5 card game experience:

  • Felt, cards, and portraits - open AI Image Gen and prompt five 3:2 scene panels: a green casino felt table backdrop with four seat positions and a small trick-collection tray in the center, a single sprite sheet of all 52 card faces (13 ranks by 4 suits in a 13x4 grid) plus a matching card-back, and three opponent portraits (a stoic older man in a cowboy hat, a sharp-eyed woman with dark glasses, a smirking younger man in a hoodie). AI Image Gen ships every leading model in one panel including Nano Banana Pro, GPT Image 2, Seedream 5 Lite, Flux 2 Pro, Z-Image Turbo, and Grok Imagine (verified 2026-08-31 in src/app/_home-v2/_data/tools.ts lines 746-752). GPT Image 2 handles legible pip patterns on card faces best (the rank letters and suit symbols stay readable at small sizes); Nano Banana Pro carries mood best for the opponent portraits. Cost lands around 8 credits per generation - five generations for felt plus card sheet plus three portraits lands around 40 credits.
  • Shuffle and card SFX - open SFX Gen and describe four short clips: "riffled paper card deck shuffle, 3 seconds" for the pre-deal shuffle, "single wooden card sliding across felt, 200 ms" for each card play, "quick slap of a card being placed on a soft pile, 180 ms" for the trick collection sweep, "warm chime rising two notes, 400 ms" for the hand-end scoreboard reveal. SFX Gen bills per second of generated audio via getSeedAudioCreditCost at SEED_AUDIO_CREDITS_PER_SECOND = 1 (verified 2026-08-31 in src/app/sfx-gen/page.tsx lines 23-24), and four short cues total under 5 credits. Cap the single card slide at 200 ms so rapid trick play does not blow out the mix - the play rhythm depends on many small card slides per hand, not a single loud stinger. Optional: layer a low ambient bed from Music Gen ("slow jazz brush drum kit, 60 second loop") for atmosphere - about 15 credits and a real quality lift over silence.

Load the card sprite sheet as a single 13x4 atlas and draw each card with a single drawImage call at the right (col, row) offset - stamping 52 cards through 52 separate Image loads eats network cost and forces 52 texture uploads on WebGL-backed canvases. Do not chase a "perfect" first pass - a second AI Image Gen retry on the card sheet is cheap, but three retries per sheet is a signal to rewrite the prompt, not to reroll the seed.

Card game asset stack diagram showing AI Image Gen felt backdrop, 52-card face sheet, three opponent portraits, and SFX Gen shuffle riffle and card slide cues - about 45 credits total
The card game asset stack: AI Image Gen for felt, card faces, and opponent portraits, SFX Gen for the shuffle riffle and card slides - about 45 credits total.

Step 4 - playtest the browser card game like a jam judge

Before you share the build, run a five-minute checklist borrowed from card-game jam judges:

  1. The first hand lands inside thirty seconds - the app boots into a lobby or straight to the table, thirteen cards deal to each seat with a visible slide, and the two-of-clubs lead fires from the correct seat.
  2. Legal-play cannot be violated by misclick - illegal cards in the human hand are dimmed and unclickable; if the human holds a club and clubs are led, only their clubs light up; if hearts are not broken, hearts are dimmed on any lead attempt.
  3. The scoreboard never lies - after every hand, the sum of all four seat scores for the hand equals exactly 26 (thirteen hearts plus the Queen of Spades) unless someone shot the moon, in which case three seats received exactly 26 and the shooter received 0.
  4. The AI opponents feel like different people - Rook ducks liability tricks aggressively, Vera holds high cards too long, Otto tries to shoot the moon roughly once every fifteen hands; nobody is a pure random button masher and nobody is an unbeatable solver.
  5. The end-of-hand pass sequence is legible - after each hand, the passing phase (pass three cards left, right, across, none - cycling per hand) shows a clear "select three cards to pass" prompt for the human and animates the pass with a small card-fan slide.

Log issues as WizardGenie follow-ups, not rewrites. "Add a shoot-the-moon detector that awards 26 to the three non-shooters" is one prompt. "Swap the ruleset to Spades: cycle trump each hand, add a bidding phase, and score tricks against the bid" is another that reuses the whole trick model. The Sorceress tools guide lists every asset tool if you want to swap AI Image Gen portraits for hand-drawn opponent art or add a Speech Gen line for a table-talk taunt from Otto when he successfully dumps the Queen on you.

What how to make a card game costs on Sorceress in 2026

An honest budget for the stack above against the 2026 Sorceress rate card (verified 2026-08-31 against local source):

  • One AI Image Gen felt backdrop: ~8 credits (0.08 USD)
  • One AI Image Gen 52-card face sheet + card back: ~8 credits (0.08 USD)
  • Three AI Image Gen opponent portraits: ~24 credits (0.24 USD)
  • Four SFX Gen cues (shuffle riffle, card slide, trick sweep, hand-end chime): ~5 credits (0.05 USD)
  • Coding-model API time with planner + budget executor: under 0.30 USD

Total roughly 45 credits or 0.45 USD in generation, plus a small model bill. The free 100-credit signup grant covers this build outright, with headroom for a second card-sheet retry or an optional Music Gen jazz bed for the table ambience. Lifetime Early Access sits at 49 USD (LIFETIME_PRICE in src/app/plans/page.tsx line 51) if you want desktop WizardGenie with auto-update for the next jam. Credits convert at 100 per dollar (CREDITS_PER_DOLLAR in src/lib/models.ts line 69). Adding a bidding phase for a Spades reskin adds about 5 credits for two extra SFX cues (bid chime, over-trick sting), still well under the one-dollar ceiling this guide targets.

That is the whole path for how to make a card game as a browser play loop in 2026: model a fair Fisher-Yates deck and a correct legal-play validator, let WizardGenie scaffold the shuffle-deal-play-score cycle with three AI opponents from one prompt, dress the felt with AI Image Gen and layer card slides with SFX Gen, and ship the browser card game experience before the weekend ends. Hearts is the honest starting ruleset; when Spades, Whist, or Rummy call, the same base scaffold carries with a rules-object swap.

Frequently Asked Questions

What defines a card game as a genre in 2026?

A card game is any structured play with a shuffled deck as the primary state, per the card game overview on Wikipedia (verified 2026-08-31). The three big families a browser build usually targets are trick-taking games (Hearts, Spades, Bridge, Whist - each hand deals every card, players play one card per trick following suit if they can, the highest card of the led suit or a trump takes the trick), shedding games (Uno, Crazy Eights, President - each player tries to empty their hand first by matching a played card by rank or suit), and matching games (Rummy, Gin, Go Fish - players collect sets or runs by drawing and discarding). A fourth family, casino card games (poker, blackjack, baccarat) revolves around betting rounds instead of trick play and is covered separately in the how to make a poker game and how to make blackjack sibling guides. This article treats the trick-taking family as the primary path and uses Hearts as the worked example because it needs no trump card, needs no bidding phase, and lands the honest four-player play loop inside a weekend build.

How is how to make a card game different from how to make a deck builder game or how to make a poker game?

The differences are structural, not superficial. A deck builder game (Slay the Spire, Dominion) evolves the deck itself across a run - you draw, play, discard, and add or remove cards from a persistent deck between fights - and the sibling how to make a deck builder game guide covers that draw-play-discard-reshuffle loop end to end. Poker is a family of betting-round games where private cards, community cards, and staged betting rounds decide the pot, and the sibling how to make a poker game guide covers Texas hold'em as the worked example. A general card game tutorial covers the deck-shuffle-hand-play-score cycle abstractly and picks a specific ruleset (Hearts, Spades, Rummy) for the worked flow. This article picks Hearts because it needs no trump, no bidding, and no melding, so the play loop stays legible while the model is still generic enough to swap in Spades or Whist rules in a follow-up prompt.

How do I make an AI opponent for a card game that reads as fair without being trivially exploitable?

Three cheap heuristics carry a browser card game AI a long way for trick-taking play. First, always play a legal card - the AI must follow suit if it holds any card of the led suit, and must play a non-hearts card on the first trick per Hearts rules (verified 2026-08-31 on the Hearts Wikipedia page). Second, evaluate each legal card with a small scoring function: if the AI is leading, lead a low card of its longest non-hearts suit; if it is following and cannot beat the current trick winner, dump its highest liability card (Queen of Spades, high hearts); if it can win the trick and taking it costs zero points, take it with the lowest winning card; if it can win but taking costs points, duck with a low legal card. Third, add a small unpredictability - roughly 5 to 12 percent randomness on the tie-break so a strong player cannot predict every play. That trio ships three AI opponents that follow the suit rules, duck point-heavy tricks, and occasionally play sub-optimally in a way that reads as human - about 40 lines of code and roughly one hour of tuning. Advanced Monte Carlo tree search is not required for a browser card game; the goal is a fun play loop, not to beat a live-stream card sharp.

Do I need a cryptographically secure shuffle for a browser card game?

For a single-player casual browser card game against three AI opponents, a plain Math.random-backed Fisher-Yates shuffle is honest. The Fisher-Yates algorithm (verified 2026-08-31 on Wikipedia) produces a uniform permutation of a 52-card deck in O(n) time when the loop counter starts at the end and picks a random index only from the unshuffled prefix - the common naive-shuffle bug of picking a random index across the full length on every iteration produces a biased distribution that leaves patterns detectable after a few dozen hands. For any build that ever ships against another human on the same URL, or accepts real stakes, swap the RNG source for Crypto.getRandomValues (verified 2026-08-31 on MDN) to close the client-seed inspection attack. The client-authoritative deck is the honest limit for a browser build; server-authoritative dealing with commitment schemes is a separate project that lives outside a weekend jam.

How much does building a card game on Sorceress cost in 2026?

A first-project browser card game budgets like this against the 2026 Sorceress rate card (verified 2026-08-31 against local source). One AI Image Gen felt-table backdrop plus a 52-card face sheet plus three opponent portraits at roughly 8 credits per generation lands around 40 credits (5 generations). Four SFX Gen cues (shuffle riffle, single card slide, card slap on wood, trick collection sweep) at roughly one credit per second of generated audio total around 5 credits (SEED_AUDIO_CREDITS_PER_SECOND is 1 in src/app/sfx-gen/page.tsx line 23). Coding-model API time with a planner plus budget executor under 0.30 USD. Total roughly 45 credits or 0.45 USD in generation. The free 100-credit signup grant covers the build with plenty of headroom. Credits convert at 100 per dollar (CREDITS_PER_DOLLAR in src/lib/models.ts line 69). Lifetime Early Access is 49 USD (LIFETIME_PRICE in src/app/plans/page.tsx line 51) and unlocks the desktop WizardGenie with auto-update for the next jam.

Sources

  1. Card game - Wikipedia
  2. Hearts (card game) - Wikipedia
  3. Fisher-Yates shuffle - Wikipedia
  4. Phaser v4.2.1 Giedi stable download
  5. MDN - Canvas API
  6. MDN - Crypto.getRandomValues
Written by Arron R.·3,690 words·16 min read

Related posts