logo

Babylon.js Market

Unlock

Install with the CLI:

bjs download PokerBetting

PokerBetting

The money and the turns of a poker hand — chips, pot, antes, and the betting-round state machine, with NPCs stepping through injected strategy callbacks.

What it does

PokerBettingSystem runs a hand. On poker.dealRequest it seats every player with a fresh stack, pulls the ante from each into the pot, opens a betting round, and steps the leading NPCs until the first human is up. NPC seats decide through a strategy callback you supply; a human seat pauses the round and waits for input.

A human's choice arrives one of two ways: poker.actionSubmitted (a HUD button, { type }) or poker.turnAction (a raw action for the active seat, { playerId?, action }). Either way the director runs the action's chip math — check / call / bet / raise / all-in / fold — marks the seat folded when needed, awards the whole pot the instant only one seat remains, and steps the trailing NPCs.

After any chip movement it broadcasts poker.chips (every stack plus the pot). It also emits poker.currentTurn whenever the live seat changes, poker.actionRequired with the menu offered to a waiting human, poker.actionTaken once per seat that acts, and poker.handOver when a hand ends on the last fold.

The chip math (applyAction, awardPot) and the turn machine (stepBettingRound, submitHumanAction) are exported helpers you can call directly; the System is the EventBus wiring around them.

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 PokerBetting

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 PokerBetting
    bjs download PokerBetting

    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
{
  "Table": {
    "components": {
      "PokerBetting": {
        "playerIds": ["player", "npc0", "npc1"],
        "humanPlayerIds": ["player"],
        "startingStack": 500,
        "ante": 5,
        "minBet": 10
      }
    }
  }
}

Start a hand by emitting poker.dealRequest. Assign NPC strategies before the deal with world.getSystem(PokerBettingSystem)?.setStrategies(map) or by handling poker.strategies in your own glue.

Props

PropTypeDefaultMeaning
playerIdsstring[]["player", "npc0", "npc1"]Seat ids in betting order.
humanPlayerIdsstring[][playerIds[0]]Seats the round pauses on for input.
startingStacknumber500Chips each seat starts a hand with.
antenumber5Forced bet pulled from every seat at the deal.
minBetnumber10Minimum opening bet, and the increment on a raise.

Events

DirectionNameConstPayload
inpoker.dealRequestPokerBettingInputEvents.DEAL_REQUEST{}
inpoker.actionSubmittedPokerBettingInputEvents.ACTION_SUBMITTED{ type }
inpoker.turnActionPokerBettingInputEvents.TURN_ACTION{ playerId?, action }
outpoker.chipsPokerBettingEvents.CHIPS{ players: Record<id, { stack, bet }>, pot }
outpoker.currentTurnPokerBettingEvents.CURRENT_TURN{ playerId | null }
outpoker.actionRequiredPokerBettingEvents.ACTION_REQUIRED{ playerId, actions }
outpoker.actionTakenPokerBettingEvents.ACTION_TAKEN{ playerId, action }
outpoker.handOverPokerBettingEvents.HAND_OVER{ winnerId }

The emitted poker.actionTaken is a different name from the poker.turnAction input on purpose — sharing one name would make the System re-hear its own emissions on the bus.

Strategies

An NPC seat acts through an NpcStrategy callback: (playerId, availableActions, context?) => ActionType. The component owns the ActionType union, the standardActions menu, and the NpcStrategy type, but never imports a concrete AI — pass strategies in. With no strategies assigned, every NPC plays randomStrategy (uniform pick from the offered actions). A strategy may write a StrategyReasoning onto the optional context for a HUD to read back.

Dependencies

None. The director carries no rendering and no sibling components; it runs entirely over the EventBus. The example scene adds a camera, a light, and a felt box only so the hand has something to sit on.

Notes

  • One hand per scene: events route into the first entity carrying a PokerBetting component.
  • A bet, raise, or all-in is capped at the seat's stack, so a short stack goes all-in rather than into the negative; antes are capped the same way.
  • submitHumanAction (called for both poker.actionSubmitted and poker.turnAction) records the human's action and steps the NPCs behind them in one call. The System applies each recorded action's chips exactly once via an appliedCount cursor, so the auto-stepped NPCs are never double-charged.
  • A poker.turnAction with a playerId that isn't the active seat is dropped; omit playerId to target whoever is up.
  • The cores (createChipState, createBettingRound, …) are exported, deterministic, and dependency-free — drive a whole hand in a test without a World.

More like this

PokerAI
PokerAIBill
PokerAICali
PokerAIRandy
PokerHUD
PokerInput
PokerMultiplayer
PokerTableDirector
TurnPacer
BallReset
CardFan
DeckDealer
GameConfig
Goal
MissionDirector
PokerAIShark
PokerAISurge
PokerAITilt
PokerHandEval
PokerSeating
PokerTableCards
SoccerDirector
WaveDirector

Was this page helpful?

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

↑↓ NavigateEnter SelectEsc CloseCtrl+K Open Search