Skip to main content

Python SDK for building and running Game Arena competition bots

Project description

Game Arena Python SDK

Build Python bots for Game Arena. Implement on_move(); the SDK handles authentication, matchmaking, game connections, and the turn protocol.

Requires Python 3.11+. Game rules and board formats live in the Bot Docs page of the Game Arena web app.

Install and prepare

pip install --upgrade game-ai-arena-sdk

Use SDK 0.6.0 or newer for continuous ranked play.

Create a bot in the web app and save its Bot ID and API key. The key may only be shown once. Then configure the matchmaker URL supplied by your administrator:

export MATCHMAKER_URL="wss://<arena-host>/matchmaking/ws"

Use ws:// only for an arena served without HTTPS.

Your first bot

This complete FlipFlop bot chooses a random legal move:

import random

from game_ai_arena_sdk import Bot, GameStateLoop, Move, start_continuous


class MyBot(Bot):
    async def on_move(self, state: GameStateLoop) -> Move:
        piece = random.choice(state.legal_moves)
        destination = random.choice(piece.valid_moves)
        return Move(from_pos=piece.pos, to_pos=destination)


bot = MyBot(bot_id="YOUR_BOT_ID", api_key="YOUR_API_KEY")

if __name__ == "__main__":
    start_continuous(bot)
python my_bot.py

start_continuous() verifies and displays the bot's registered game and arena before joining ranked matchmaking. Its compact live display shows the runner state, opponent, Bot Run record, and last committed result without flooding the terminal. Its commands are pause, resume, status, stop, help, display compact, and display verbose. Commands remain editable while games update the display. Stop and Ctrl-C finish any active game before disconnecting.

Adapt it for your game

Always choose from state.legal_moves, then preserve the fields required by that game:

Game GameType Returned Move
FlipFlop 3x3 GameType.FLIPFLOP_3X3 Move(from_pos=piece.pos, to_pos=destination)
FlipFlop 5x5 GameType.FLIPFLOP_5X5 Move(from_pos=piece.pos, to_pos=destination)
FlipFour GameType.FLIPFOUR Also pass side for a piece in "HAND"
Amoeba GameType.AMOEBA Also pass the legal move's splitting value
# FlipFour
side = piece.name if piece.pos == "HAND" else None
return Move(from_pos=piece.pos, to_pos=destination, side=side)

# Amoeba
return Move(
    from_pos=piece.pos,
    to_pos=destination,
    splitting=piece.splitting,
)

Missing these fields is a common cause of INVALID_MOVE.

Build a better bot

The random bot only proves the connection works. A stronger bot should:

  1. Parse state.board using its game's documented format.
  2. Evaluate every legal action from state.my_side using heuristics, search, or a model.
  3. Return the best action with its game-specific fields intact.
  4. Run in Practice Mode before entering ranked play.

Keeping this logic in choose_move(state) -> Move separates bot strategy from SDK lifecycle code.

Execution modes

start*() functions block and suit ordinary scripts. run*() functions are coroutines for code that already uses asyncio.

Need API
Interactive continuous ranked play (recommended) start_continuous(bot, display="compact")
Headless continuous ranked play await run_continuous(bot, game_type)
One ranked game start(bot, game_type) / await run(bot, game_type)
One practice game start_practice(...) / await run_practice(...)
Custom continuous controls ContinuousRunner

start_continuous() detects the registered game and adds terminal controls. Compact display is the default; pass display="verbose" or switch modes while running. Redirected input or output automatically uses plain verbose output. Headless run_continuous() requires an explicit GameType and returns the final immutable RunnerStatus, including safe failure details when the runner fails.

Practice Mode connects directly to a room from the web app and does not affect rating:

from game_ai_arena_sdk import start_practice

start_practice(
    bot,
    room_id="ROOM_ID_FROM_PRACTICE_ARENA",
    game_server_ws="wss://GAME_SERVER_URL_FROM_PRACTICE_ARENA",
)

For custom operation, ContinuousRunner provides pause(), resume(), status(), stop(), and wait().

If phase visibility changes while the bot is queued, the continuous runner rejoins automatically on the same Bot Run and preserves whether it was paused. A switch to Blind removes an earlier rating from public status and the compact display even when the bot is already playing.

Core data

Type Important fields
GameStateLoop board, my_side, current_turn, legal_moves
PieceMovesInfo name, pos, valid_moves, optional splitting
Move from_pos, to_pos, optional side, optional splitting
MatchFinishedResult result, end_reason, opponent, run, finished_at, optional rating
RunnerStatus state, run, opponent, last_result, safe failure fields

board is game-specific. legal_moves is the server-provided set of allowed actions. MatchFinishedResult is immutable and arrives after a continuous ranked result is committed; its rating is absent during phases that hide it.

Lifecycle hooks

Override only what you need. on_move() is the only required hook.

Hook Called when
on_move(state) -> Move Your turn requires a move
on_ready() The SDK connects
on_queue_entry() The bot joins matchmaking
on_queue_exit() The bot leaves the queue or finds a match
on_match_found(game_id) A game is assigned
on_room_joined(room_id) The game room is joined
on_game_start(state) Gameplay starts
on_game_end(winner, state) Gameplay ends
on_match_finished(result) The ranked result is committed in continuous play
on_disconnect(reason) Reserved for disconnect notifications

There is no on_error hook. Handle decision errors inside on_move() and SDK failures around the chosen entry point.

Errors and troubleshooting

Game-server protocol failures raise GameArenaProtocolError with code, message, and optional details. Continuous play fails closed after an uncertain failure instead of silently joining another game.

Problem Check
Authentication rejected Bot ID and API key
INVALID_MOVE Use legal_moves; preserve side or splitting
Cannot connect Arena hostname and ws:// versus wss://
Two test bots never match Bots owned by the same user cannot match
Continuous play stops Read the display or RunnerStatus.failure_code and failure_message; unsafe requeueing is prevented

For game rules, coordinates, strategy, arena URLs, and deeper troubleshooting, open Bot Docs in the Game Arena web app.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

game_ai_arena_sdk-0.6.0.tar.gz (31.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

game_ai_arena_sdk-0.6.0-py3-none-any.whl (46.5 kB view details)

Uploaded Python 3

File details

Details for the file game_ai_arena_sdk-0.6.0.tar.gz.

File metadata

  • Download URL: game_ai_arena_sdk-0.6.0.tar.gz
  • Upload date:
  • Size: 31.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for game_ai_arena_sdk-0.6.0.tar.gz
Algorithm Hash digest
SHA256 5803d1e4e39b64138101bf7e59b3766c58101f901657687d7b2af69127daccd9
MD5 27c3acf148d62c1d9dbb764691ec1cc7
BLAKE2b-256 16394931c6ea20f86e27803bc351cefa1907238faee9f38ce799835f5b09d67c

See more details on using hashes here.

File details

Details for the file game_ai_arena_sdk-0.6.0-py3-none-any.whl.

File metadata

File hashes

Hashes for game_ai_arena_sdk-0.6.0-py3-none-any.whl
Algorithm Hash digest
SHA256 d6ee99a86a7abf4b4c12f4f4be10067c81fdb40c89c553beb1fa6cf1fbf49ec4
MD5 92b60eb5fe83693925fdf5a5a78a168f
BLAKE2b-256 f254b1a581cc3eac82f57d4cd14d533f93052384af3f423d262f9ad61118f507

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page