Skip to content
AI Chessathon
DocsLeaderboardRules
Sign inRegister
DocsLeaderboardRulesSign inRegister

Participants

Build against this.

QuickstartAgent APIWire protocolMatch environmentClocks and scoringSubmissionsFailure reference

Quickstart

Fork the starter repo: a working agent, baselines to beat, and a harness that plays games locally under the real clock. Or start from scratch, below.

A submission is a zip. At its root, meaning not inside a folder:

agent.zip
├── agent.py            required
├── requirements.txt    optional, installed from PyPI
└── model files         anything else you need, 200 MB total

The smallest legal agent:

import chess
import random

def get_move(fen: str, time_left_ms: int) -> str:
    board = chess.Board(fen)
    return random.choice(list(board.legal_moves)).uci()

The base image ships Python 3.12 with torch (CPU), numpy, python-chess and onnxruntime preinstalled. Compiled wheels from PyPI are fine. Native binaries inside the zip are rejected at validation: ship Python source and list compiled dependencies in requirements.txt.

requirements.txt takes plain package names and version specifiers. No URLs, no index options, no local wheels, and wheels only, so a package with no Linux wheel fails the build. Your zip goes first on sys.path, so a file named after a module you import, chess.py or types.py, shadows the real one.

Agent API

agent.py must expose one function:

def get_move(fen: str, time_left_ms: int) -> str
NameTypeMeaning
fenstrthe position to move in, standard FEN
time_left_msintyour remaining clock in milliseconds
returnsstra legal move in UCI, e.g. e2e4 or e7e8q

One process serves one game, started fresh for every game. Load your model at import or on the first call: a 60 second init budget runs before the clock starts, and the process stays alive between moves, so state you keep in memory carries across your own moves. The referee claims threefold and fifty-move draws automatically, so an agent that wants to avoid a repetition tracks the positions it has been asked about.

Wire protocol

The runner talks to your process over stdin and stdout, one JSON object per line. You only implement get_move; the provided runner handles the wire. Each request:

{"fen": "rnbqkbnr/...", "time_left_ms": 87500}

Each response:

{"move": "e2e4"}
your colourthe side to move in the fen
time_left_msyour clock before this move; the increment lands after you move
output cap4096 bytes per move; past it the game is lost
malformed outputcounts as an illegal move, which loses the game

Your own output cannot corrupt this. The runner moves the protocol onto a private handle and points file descriptor 1 at stderr before importing your agent, so print is safe. Everything you write to stdout or stderr is discarded during rated games and shown back to you in the validation log, up to 8 KB.

Match environment

CPU1 dedicated core
Memory2 GB
Networknone, in either direction
GPUnone
Filesystemread-only, plus 256 MB scratch at /tmp, where HOME and the cache paths already point
Processes128; on one core, threads past the first cost you time
Hardwareidentical for every game; both agents on the same machine

No network means no hosted inference and no engine APIs, by construction. Everything your agent needs ships inside the zip.

Clocks and scoring

Time control120 s per side, plus 0.5 s per move
Init budget60 s before the clock starts
Game endFIDE rules; 300 plies without a result is adjudicated on material, else drawn
Ladderrated rounds every 2 hours, 08:00 to 22:00, ranked by Elo
Qualificationan 11-round Swiss over the locked submissions decides the top 48

Submissions

Size200 MB expanded
Rate6 uploads per team per rolling 24 hours
Which playsyour latest submission that passed validation
Validationbuild, then two smoke games, one as each colour; the verbatim log appears on your dashboard
Lock11 September 12:00; uploads close 11:00

Prohibited: Stockfish, Lc0, or wrappers around any existing engine. A learned model must materially drive move selection. Submissions are analysed and disqualification can be retroactive.

What you ship has to be source a judge can read, so a flagged game can be cleared by reading your agent instead of by statistics alone. Model weights are not binaries: .onnx, .safetensors and .pt are fine. Compiled dependencies come from PyPI, and a package you published yourself needs public source. Obfuscated or opaque agents are disqualified.

Failure reference

TerminationCauseResult
illegalillegal or malformed move, or output past the caploss
crashyour process exited, threw, or ran out of memoryloss
flagclock ran out mid-gameloss
initno ready line within the 60 s init budgetloss
adjudication300 plies without a resultmaterial decides, else draw
voidboth sides failedno result recorded
AI Chessathon

Sponsored by

EventFormatTeamRegisterArchive
LegalCompetition rulesPrivacy notice
ContactEmail us

© 2026 AI ChessathonMade by Advit Arora and Arham Shuaib