@chipzen-ai/bot
v0.5.0
Published
Build, test, and deploy poker bots for the Chipzen AI competition platform
Maintainers
Readme
@chipzen-ai/bot
[!WARNING] Beta software (pre-1.0). This SDK is in active development; the public API may change between minor versions before 1.0. Pin to a specific version in production. Report issues at chipzen-ai/chipzen-sdk/issues.
The JavaScript adapter for the Chipzen AI poker
competition platform. Wraps the WebSocket protocol so your bot only
has to implement decide(state) -> action.
Install
npm install @chipzen-ai/bot # or pnpm / yarnNode 20+ supported. Also runs cleanly on Bun (the IP-protected starter
Dockerfile uses bun build --compile to ship your bot as a single
binary). Single runtime dependency: ws.
Minimal bot
import { Bot, Action, GameState, runBot } from "@chipzen-ai/bot";
class MyBot extends Bot {
decide(state: GameState): Action {
if (state.validActions.includes("check")) return Action.check();
return Action.fold();
}
}
await runBot(process.env.CHIPZEN_WS_URL!, new MyBot(), {
token: process.env.CHIPZEN_TOKEN,
});The SDK handles the Layer-1 transport handshake, Layer-2 game-state
parsing, ping/pong, request-id echoing, action_rejected retries,
and reconnect. Subclass Bot, override decide(), return an
Action. That's the entire surface for a working bot.
Big Bad Bots (the robot-fighting game, in beta) has its own base
class: extend BigBadBotsBot and implement act(state), one fight tick;
chooseBody(), bid() and fit() have legal defaults. chipzen-sdk
validate runs the Big Bad Bots conformance checks on it. Big Bad Bots
support ships in @chipzen-ai/bot 0.4.0 and later; see the
JavaScript Big Bad Bots quickstart
and the Rusher starter.
Other games. A bot plays No-Limit Hold'em unless it declares otherwise.
To declare the games it can play, pass supportedGames to runBot or
runExternalBot, a list of game_type strings; it goes on the client
hello as supported_games. Leaving it out declares
nothing ("poker only") and keeps the hello unchanged.
2-7 Triple Draw (draw27) is supported: declare
supportedGames: ["poker", "draw27"] and branch on state.isDrawPhase in
decide(). On a draw turn return Action.discard(cards) (card strings or
0-based positions into state.holeCards, at most state.maxDiscard) or
Action.standPat(); the optional decideDraw(state) hook, which defaults
to a stand pat, is there to delegate to. Betting turns are fixed limit
(state.minRaise == state.maxRaise).
decide(state: GameState): Action {
if (state.isDrawPhase) return this.decideDraw(state);
// your betting logic
}Pineapple OFC (ofc) is supported: declare
supportedGames: ["poker", "ofc"]. Every OFC turn offers exactly
["place"]; the shape of a legal answer lives in the state
(state.cardsToPlace, state.place, state.mustDiscard,
state.rowCapacity). Return
Action.place([[card, row], ...], discard): exactly state.place
placements and state.mustDiscard discards, each card once, within each
row's free capacity. An illegal placement is rejected, not clamped. The
optional decidePlacement(state) hook returns a legal (not good) placement
to delegate to.
decide(state: GameState): Action {
if (state.validActions.includes("place")) return this.decidePlacement(state);
// your betting logic
}See DEV-MANUAL §2.8.
Lifecycle hooks (onMatchStart, onRoundStart, onPhaseChange,
onTurnResult, onRoundResult, onMatchEnd) are optional —
override them if you need to maintain per-match or per-hand state
between turns.
Field naming
The user-facing API uses idiomatic camelCase
(state.validActions, state.holeCards). The on-the-wire JSON the
protocol uses is snake_case (valid_actions, your_hole_cards) —
defined in the
protocol spec.
The parser in parseGameState translates between the two.
What the SDK is for (and what it isn't)
The SDK does three things and nothing else:
- Protocol adapter — your bot doesn't hand-roll WebSockets.
chipzen-sdk validate— pre-upload conformance check, equivalent to the Python CLI.- IP-protected Dockerfile recipe —
bun build --compilemulti-stage build that produces a single executable instead of shipping your.ts/.jssource.
It does not include a local match simulator, hand evaluator, or opponent pool. Upload review only checks that your bot speaks the protocol (a short scripted mini-match); you learn how strong it is from the real matches it plays on the platform (challenges, tournaments and seasons, with ratings and replays).
Reference
Full developer documentation lives in the chipzen-sdk repo:
- DEV-MANUAL — SDK reference, lifecycle hooks, performance budgets, container contract, troubleshooting.
- QUICKSTART — write a bot, validate it, package it.
- Protocol spec — Layer 1 (Transport) + Layer 2 (Poker game state). Authoritative.
- Bot runtime security model — what the platform enforces on uploaded bots.
- Python adapter
— same SDK shape in Python (pip install
chipzen-bot).
License
Apache-2.0. See the LICENSE file in the repo.
