Implement the game as the authority
The game owns the rules and all authoritative episode outputs. A player proposes actions; it never writes the score or changes another seat’s state directly. The container must:- read its concrete config from the runner-provided URI;
- report healthy only after it can accept player connections;
- authenticate each player slot and serve the game-defined player protocol;
- expose live player and global browser surfaces;
- validate actions and advance the game state;
- write results that match the declared results schema; and
- write replay bytes that the declared viewer can load.
Fail clearly, then keep the episode moving
Crash during startup when required configuration is missing. A half-configured game creates artifacts that nobody can trust. Once play begins, keep failures bounded:1
Wait for players
Use a finite connection deadline. Missing seats must not block the episode forever.
2
Request an action
Give each decision a finite deadline appropriate for the game’s pace.
3
Validate the response
Check both its data shape and whether it is legal in the current state.
4
Recover predictably
Explain invalid input, allow bounded retries, then apply the documented baseline action.
Build the browser surfaces
The same game image supports three audiences:- Player client: a slot-specific interface for observing and acting.
- Global viewer: a read-only view of a live episode.
- Replay viewer: a view of recorded state and actions.
Ship a small, dependable player set
Every manifest declares at least one bundled player. These players make local examples and certification work without an external policy submission. Always include a scripted player that:- uses no large language model (LLM);
- returns legal actions for every reachable observation;
- handles malformed or unexpected input without leaving the game loop; and
- exits cleanly when the episode ends.
Keep players as clients
A player readsCOWORLD_PLAYER_WS_URL, connects to the encoded slot and token, speaks the game protocol, and exits.
It does not start the game or orchestrate other containers.
A player may upload one optional debugging artifact. It must upload before its bounded teardown window closes. The
exact limits and environment variable live in the player contract.
A single Docker image can serve the game and bundled players. Give each runnable a different run command in the
manifest. Separate images are also valid when the implementations need different dependencies.
Exercise every bundled player
Certification confirms that every declared bundled player started. The certification fixture must include each player ID in at least one seat. Do not declare planned players that cannot complete the smoke episode. Add them only when their image, command, and protocol implementation work.Use Paint Arena as a concrete example
Paint Arena keeps the complete surface in one project:game/server.pyowns the rules, routes, results, and replay;game/client/contains the player, global, admin, and replay pages;game/docs/specifies the player and global protocols;player/player.pyimplements a deterministic sweep player; and- one image uses different commands for its runnable roles.