logo

Babylon.js Market

DeckDealer

tabletop-casino · poker

DeckDealer

1
High-Roller DealerBonus figureHigh-Roller Dealer
Unlock

Install with the CLI:

bjs download DeckDealer

DeckDealer

A 52-card deck and a round-robin deal queue, both reproducible from a seed.

What it does

DeckDealerSystem owns the card state for one round. On attach it builds a shuffled 52-card deck and a table of seats from the component params, then waits on the EventBus. A deck.dealRequest deals the next card in the queue — one to each seat per round, then the community (river) cards once seats are filled — and broadcasts deck.dealt with the card, its target, and how many cards remain. Pass { all: true } to flush the rest of the queue at once, one deck.dealt per card. A deck.resetRequest reshuffles and clears every hand, then broadcasts deck.reset.

The shuffle is a Fisher-Yates pass over an injectable RNG. With a non-empty roomCode the RNG is a Mulberry32 stream keyed by roomCode + handNumber: two clients that pass the same pair build the identical deck, so a deal stays synchronized across peers without sending the card order over the wire. Leave roomCode empty and the shuffle uses Math.random. Cards are plain string IDs (queen_of_spades), so anything that draws them listens for deck.dealt and reads card + target.

Use it in a scene

A scene is just data — a list of entities, each with its components. At startup the SceneLoader turns this JSON into a live world; edit the file and reload to rebuild it.

Fastest path

bjs download scene DeckDealer

Pulls this exact scene into your project and runs it — no copy-paste. Add --all to grab the components and assets it needs too.

Or build it from scratch with the bjs CLI:

  1. 1Scaffold a project
    npm create @babylonjsmarket/arcade@latest my-game

    World, renderer, and dev server — ready to run.

  2. 2Install dependencies
    cd my-game && npm install
  3. 3Add DeckDealer
    bjs download DeckDealer

    Copies its source into src/ so the scene resolves.

    First time? Run bjs login once.

  4. 4Paste the scene into src/scenes/arcade-room.ts and run
    npm run dev

    SceneLoader builds the world from the JSON; reload to rebuild.

JSON
{
  "Dealer": {
    "components": {
      "DeckDealer": {
        "playerCount": 4,
        "cardsPerPlayer": 2,
        "riverSize": 5,
        "localIndex": 0,
        "roomCode": "table-7",
        "handNumber": 0
      }
    }
  }
}

Props

PropTypeDefaultMeaning
playerCountnumber4Seats at the table.
cardsPerPlayernumber2Cards dealt to each seat (round-robin).
riverSizenumber5Shared community cards dealt after seats fill.
localIndexnumber0Index of the local seat, found via getLocalPlayer.
roomCodestring""Seed half. Non-empty opts into the deterministic shuffle; empty uses Math.random.
handNumbernumber0Seed half. Bump it between hands to reshuffle from a new, still-reproducible order.

Events

DirectionNameConstantPayload
Emitsdeck.dealtDeckDealerEvents.DEALT{ card, target, remaining }target is { type: 'player', playerIndex } or { type: 'river' }.
Emitsdeck.resetDeckDealerEvents.RESET{ remaining } — the full count after reshuffle.
Listensdeck.dealRequestDeckDealerInputEvents.DEAL_REQUEST{ all?: boolean } — omit all for one card, true for the whole queue.
Listensdeck.resetRequestDeckDealerInputEvents.RESET_REQUEST{} — reshuffle and clear every hand.

Dependencies

None. DeckDealer is self-contained card state — no sibling components, no renderer calls. A playable poker scene pairs it with whatever draws the cards (a mesh-per-card system listening for deck.dealt) and a UI that issues deck.dealRequest.

Notes

  • One dealer per scene: requests route to the first entity carrying a built DeckDealer, so author a single dealer.
  • The deal order is cardsPerPlayer full rounds of one-per-seat, then riverSize river cards — never interleaved. Set cardsPerPlayer: 0 for a river-only deal, or riverSize: 0 for hands-only.
  • The seed is the multiplayer seam: same roomCode + handNumber ⇒ same deck on every client. Reusing one RNG instance across createDeck/resetDeck would advance its stream, so the System builds a fresh seeded RNG for each shuffle — a reset reproduces the seed's order, it doesn't continue the previous stream.
  • dealNext returns null (and the System emits nothing) when the queue is finished or the deck is empty, so an over-eager deck.dealRequest is a no-op rather than an error.

More like this

PokerTableCards
PokerTableDirector
CardFan
EnemySpawner
ObstacleField
PokerAI
PokerAIBill
PokerAICali
PokerAIRandy
PokerAIShark
PokerAISurge
PokerAITilt
PokerBetting
PokerHUD
PokerHandEval
PokerInput
PokerMultiplayer
PokerSeating
TurnPacer

Was this page helpful?

We read every note — tell us what's working and what isn't.

↑↓ NavigateEnter SelectEsc CloseCtrl+K Open Search