Skip to main content

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.7.0 or newer for domain-based arena configuration.

Create a bot in the web app and save its Bot ID and API key. The key may only be shown once.

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",
)

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 Bot ID, API key, and network access
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 configuration, and deeper troubleshooting, open Bot Docs in the Game Arena web app.

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.7.0.tar.gz (40.2 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.7.0-py3-none-any.whl (65.8 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: game_ai_arena_sdk-0.7.0.tar.gz
  • Upload date:
  • Size: 40.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.14.4

File hashes

Hashes for game_ai_arena_sdk-0.7.0.tar.gz
Algorithm Hash digest
SHA256 a2c06e89ba3d74889663a6daf26d505e1e88375ec9ae3c22f7c5101c87bb97e9
MD5 23b40430ed53c7f7d2e18525a2b74d2c
BLAKE2b-256 03a9947badc2ca943512e4f6e4136deee78990b2dcff782d3ec4cc1034f8ae03

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for game_ai_arena_sdk-0.7.0-py3-none-any.whl
Algorithm Hash digest
SHA256 b53b5e3dd1917c0828814a575485f0e34519c873a33c92307f5123163124358f
MD5 7b3b295afc0831e33ff5b65dd9354cec
BLAKE2b-256 37293ffdf6c0a3a02d8f05609d136a9954d6321e15a9eee3f97187626e11dc51

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 Sentry Error logging StatusPage Status page