Docs

Quickstart

Build a bot that speaks our turn-based contract, runs inside a sandboxed container, and survives the arena. Python is first-class; other runtimes follow the same shape.

Every match is a request/response loop. The arena sends a structured turn request, your bot responds with an action under a tight deadline, and the engine validates it. Timeouts or illegal actions default to safe fallbacks (fold/check/idle) plus a penalty.

What you need

  • Python 3.10+ (current first-class runtime) and a virtual environment.
  • Your bot code kept stateless between runs; BotArena snapshots no external state.
  • Deterministic logic that finishes within the per-turn budget (sub-second in ranked play).

1) Create a bot file

Author a handler that accepts the turn request and returns an action payload. Keep imports light and prefer pure functions so the sandbox can cold-start quickly.

# bot.py
from typing import Any, Dict

def handle_turn(request: Dict[str, Any]) -> Dict[str, Any]:
    """Simplest possible Rock-Paper-Scissors bot."""
    history = request["you"].get("history", [])
    if history:
        # Mirror the opponent's last move; deterministic and quick.
        last = request["opponent"]["last_action"]
        move = {"rock": "paper", "paper": "scissors", "scissors": "rock"}[last]
    else:
        move = "rock"

    return {
        "action": move,
        "metadata": {"style": "mirror-then-punish"},
    }

2) Respond to the contract

The runner calls your handler with a JSON payload that includes the current turn number, public game state, and your last action. Return only valid actions for the game; invalid values are rejected and scored as illegal moves.

{
  "turn": 3,
  "game": "rps",
  "you": { "id": "blue", "history": ["rock", "paper"] },
  "opponent": { "id": "red", "last_action": "rock" },
  "time_budget_ms": 800
}

3) Test locally

  • Run against the local runner for deterministic simulations.
  • Log only structured, concise messages; noisy stdout is truncated inside the sandbox.
  • Measure response latency. When the budget is exceeded, the container is cut off and the turn is forfeited.

4) Upload and join an arena

Package your bot (code + lockfile) and upload it in the dashboard. Pick an arena, confirm the game, and monitor the live match log. New uploads become immutable builds; you can roll forward by promoting a new build.

Next steps

  • Read the Bot Contracts to see every field we send and validate.
  • Use the Python Quickstart to add strategy and simple memory.
  • Join a low-stakes test room before ranked to watch timeout/illegal-action handling.