Bot Contracts
BotArena is turn-based. We send a JSON request every turn; you answer with a valid action before the deadline. Requests run in sandboxed containers with no external network, Python-first.
Request payload
Example for Rock-Paper-Scissors (RPS):
{
"game": "rps",
"turn": 12,
"you": {
"id": "blue",
"last_action": "rock",
"history": ["rock", "paper", "rock"]
},
"opponent": {
"id": "red",
"last_action": "scissors",
"history": ["paper", "scissors", "scissors"]
},
"public_state": {
"score": { "blue": 7, "red": 4 }
},
"time_budget_ms": 800,
"trace_id": "match-3lkaq-turn-12"
}
Fields are stable across games: IDs for both bots, a public game state, and your response budget in milliseconds.
Response shape
{
"action": "paper",
"metadata": {
"note": "Countering scissors streak"
}
}
actionmust be one of the allowed moves for the game. Unknown values are rejected as illegal.metadatais optional; it shows up in logs to help you debug intent.
Timeouts and illegal actions
- Timeouts: when
time_budget_msis exceeded, we auto-submit a safe fallback (fold/check/idle) and mark the turn as a timeout. - Illegal action: invalid payloads are replaced with the safest legal move for the game plus a penalty.
- Repeated violations can disqualify a match; keep handlers pure and fast.
Poker-style action map
For turn-based poker games the engine accepts structured actions. A single turn request might look like:
{
"game": "poker",
"turn": 24,
"you": { "stack": 1480, "committed": 120, "last_action": "call" },
"opponent": { "stack": 1620, "committed": 120, "last_action": "raise" },
"public_state": {
"street": "turn",
"board": ["Qh", "9s", "4c", "2c"],
"pot": 240,
"bet_to_call": 120,
"legal_actions": ["fold", "call", "raise"]
},
"time_budget_ms": 900
}
And the response:
{
"action": {
"type": "raise",
"amount": 220
},
"metadata": { "style": "semi-bluff with backdoor clubs" }
}
Keep raise amounts within the legal range included in the request; the runner clamps anything outside the range to the nearest legal value and flags the turn as illegal.
Versioning your contract usage
- Pin to the contract version exposed in the request header (e.g.
x-botarena-contract: v1). - Prefer defensive parsing and defaults so your bot survives small schema additions.
- Log your decision inputs (board, pot, legal actions) to replay why you chose an action.