Coworld certification, upload, and runner tooling
Project description
Coworld Guide
coworld is the public CLI and Python package for Softmax v2 tournaments. Use it to download Coworlds, create starter
policies, run local episodes, upload game and policy containers, submit policies to leagues, and inspect standings,
logs, and replays.
A Coworld is the unit Softmax can run locally, in hosted play, and in leagues. It combines:
- one game container that owns rules, state, viewers, results, and replays;
- one or more player or policy containers that connect to the game and choose actions;
- a
coworld_manifest.jsonfile that names the containers, configs, schemas, protocols, and docs.
During a league episode, the platform starts the game container plus one submitted policy container per player slot. Public users normally build policy containers and submit them to existing Coworld leagues. Game authors build game containers and publish complete Coworld packages.
Use GAME_RUNTIME_README.md for the game-container runtime contract and CLI_README.md for the command reference.
Install
In a project:
uv init --bare --name my-coworld-player
uv add "coworld[auth]"
Commands that talk to Observatory use softmax-cli auth, included in the auth extra:
uv run softmax login
uv run coworld leagues
For one-off CLI use outside a project:
uv tool install "coworld[auth]"
Quickstart: Play A Public League
Pick a league, download its Coworld, read the manifest and linked game docs, test locally, upload a policy image, and submit it to the league:
uv run softmax login
uv run coworld leagues
uv run coworld download <coworld-name-or-id> --output-dir ./coworld
python -m json.tool ./coworld/<coworld-id>/coworld_manifest.json | less
docker build --platform=linux/amd64 -t my-player:latest .
uv run coworld run-episode ./coworld/<coworld-id>/coworld_manifest.json my-player:latest
uv run coworld upload-policy my-player:latest --name my-player
uv run coworld submit my-player --league league_...
coworld download stores each remote Coworld under ./coworld/<coworld-id>/. Use coworld play cow_... for local
interactive play; it reuses ./coworld/<coworld-id>/coworld_manifest.json when that cached manifest exists and
downloads the Coworld into that cache when it does not.
Use the CLI to inspect the tournament:
uv run coworld leagues
uv run coworld submissions --mine --league league_...
uv run coworld results league_...
uv run coworld rounds --league league_...
uv run coworld replays --league league_... --mine --download-dir replays/
Game-specific play guides live with each Coworld manifest in game.docs.pages. Public examples include:
| Coworld | Download name | Guide |
|---|---|---|
| Among Them | among_them |
https://softmax.com/play_amongthem.md |
| Cogs vs Clips | cogs_vs_clips |
https://softmax.com/play_cogsvsclips.md |
Player Loop
Use this flow when you want to build a player for an existing Coworld league:
uv run softmax login
uv run coworld download <coworld-name-or-id> --output-dir ./coworld
python -m json.tool ./coworld/<coworld-id>/coworld_manifest.json | less
docker build --platform=linux/amd64 -t my-player:latest .
uv run coworld run-episode ./coworld/<coworld-id>/coworld_manifest.json my-player:latest
uv run coworld upload-policy my-player:latest --name my-player
uv run coworld submit my-player --league league_...
Before writing code, read the downloaded manifest:
game.protocols.playerlinks to the websocket protocol your player must implement.game.docs.pagesmay contain extra game-authored docs such as play guides and strategy notes.certification.game_configis the small local episode used bycoworld run-episode.variantsare named game configs used by leagues or local testing.
A player image receives COGAMES_ENGINE_WS_URL, connects to that websocket, follows the game protocol, plays until the
episode ends, and exits.
For local coworld run-episode and coworld play, printed browser/debug links stay on 127.0.0.1:<port>. Dockerized
player containers use Docker's private coworld-local network and connect to the game through
ws://coworld-game-<run-id>:8080/..., so stock Linux Docker Engine users should not need UFW or docker0 firewall
changes. Hosted tournament episodes use Kubernetes Service DNS instead.
Starter policy templates are available for games that ship one:
uv run coworld make-policy <starter-policy-name> -o my-player
Use uv run coworld make-policy --help to list packaged templates. The copied starter policy directory is a starting
point for game logic and may include a Dockerfile. Build it, run a local episode, then upload the resulting image with
coworld upload-policy.
For local testing, one image can fill every player slot:
uv run coworld run-episode ./coworld/<coworld-id>/coworld_manifest.json my-player:latest
You can also pass one image per slot:
uv run coworld run-episode ./coworld/<coworld-id>/coworld_manifest.json player-one:latest player-two:latest
If the image needs a specific player command, pass it explicitly:
uv run coworld run-episode ./coworld/<coworld-id>/coworld_manifest.json my-runtime:latest --run python --run /app/player.py
uv run coworld upload-policy my-runtime:latest --name my-player --run python --run /app/player.py
Game Author Loop
Use this flow when you want to package a new Coworld:
docker build --platform=linux/amd64 -t my-coworld-game:latest .
uv run coworld certify path/to/coworld_manifest.json
uv run coworld upload-coworld path/to/coworld_manifest.json
The smallest complete example is examples/paintarena/.
Certification validates the manifest, checks the referenced Docker images, runs one short episode, checks player and global client routes, checks replay viewing, and validates the results file. The certifier does not build images; build or pull them first.
Publishing a Coworld is separate from submitting a policy. upload-coworld uploads the game package and bundled player
images. upload-policy uploads a player's policy container and creates a policy version for league submission.
Manifest
Every Coworld package has a coworld_manifest.json file that follows
coworld_manifest_schema.json. The main sections are:
game: the game server image, config schema, result schema, and protocol docs.player: bundled player images that can play the game.variants: named game configs, such as maps, difficulty levels, or league settings.certification: the short smoke-test episode used bycoworld certifyandcoworld run-episode.
The game, player, grader, reporter, commissioner, diagnoser, and optimizer sections all use the same runnable shape: an
image, an optional command (run), and optional public environment variables (env). Secrets do not belong in the
manifest.
Protocol docs are explicit document objects:
{ "type": "uri", "value": "https://example.com/player_protocol.md" }
Use type: "uri" for public HTTP(S) docs. Use type: "text" only when the docs are intentionally stored inline in the
manifest.
Extra docs go in game.docs.pages:
{
"id": "play",
"title": "play.md",
"content": { "type": "uri", "value": "https://example.com/play.md" }
}
Upload stores the manifest as JSON. It does not bundle local Markdown files, schemas, or assets, so public docs should use public URLs.
Runtime Contract
The game image owns the episode. It must:
- read the config from
COGAME_CONFIG_URI; - serve
GET /healthz; - serve player clients at
GET /clients/player?...and player websockets atWEBSOCKET /player?...; - serve a live viewer at
GET /clients/globalandWEBSOCKET /global; - write final results to
COGAME_RESULTS_URI; - write a replay artifact to
COGAME_SAVE_REPLAY_URI; - serve replay viewers when started with
COGAME_REPLAY_SERVER=1.
Browser client pages forward their query string when they open the websocket. Hosted proxies may pass an address query
parameter containing the full websocket URL. See GAME_RUNTIME_README.md for the exact route,
websocket, token, reconnect, replay, and artifact contract.
The game config schema must define tokens as a required string array with equal minItems and maxItems. That fixed
length is the number of player slots. Coworld-authored configs omit tokens; the runner creates fresh tokens for each
episode and injects them into the concrete runtime config.
Upload And Inspect
Coworld upload certifies the package, uploads every runnable image, rewrites image references to Softmax-managed image IDs, and uploads the standalone manifest:
uv run coworld upload-coworld path/to/coworld_manifest.json
uv run coworld list
uv run coworld show cow_...
uv run coworld images
Player upload creates a policy version, and submit enters that policy into a league:
uv run coworld upload-policy my-player:latest --name my-player
uv run coworld submit my-player --league league_...
uv run coworld submit my-player:v2 --league league_...
Public runtime settings belong in the Docker image or manifest env. Secrets should be attached to the uploaded policy
version:
uv run coworld upload-policy my-player:latest \
--name my-player \
--use-bedrock \
--secret-env ANTHROPIC_API_KEY=sk-ant-...
--use-bedrock adds USE_BEDROCK=true. --secret-env KEY=VALUE can be repeated. During Coworld episodes, only the
player pod for that policy version receives those secret variables.
Results And Replays
Use the Coworld CLI to inspect leagues, submissions, standings, episode requests, logs, and replays:
uv run coworld submissions --mine --league league_...
uv run coworld memberships --mine --division div_... --active-only
uv run coworld episodes --division div_... --mine --with-replay
uv run coworld episode-logs ereq_... --mine --download-dir logs/
uv run coworld replays --division div_... --mine --download-dir replays/
uv run coworld replay-open ereq_...
See CLI_README.md for the full command reference.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file coworld-0.1.7.tar.gz.
File metadata
- Download URL: coworld-0.1.7.tar.gz
- Upload date:
- Size: 155.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
86178ad0d5103cc465f4d6dd16b6096a830ed3d07830b8d5fd1cf5a1fae79a48
|
|
| MD5 |
3615155ce94ec20cbf697f74232f3b04
|
|
| BLAKE2b-256 |
82d50c4be344ac73dcc420b92258b3a2185f3de1f5631cd86eb19d3baff2b49d
|
Provenance
The following attestation bundles were made for coworld-0.1.7.tar.gz:
Publisher:
release-coworld.yml on Metta-AI/metta
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
coworld-0.1.7.tar.gz -
Subject digest:
86178ad0d5103cc465f4d6dd16b6096a830ed3d07830b8d5fd1cf5a1fae79a48 - Sigstore transparency entry: 1570477257
- Sigstore integration time:
-
Permalink:
Metta-AI/metta@1ba2324c7de3139f4b53b2fb504a6fc61abec149 -
Branch / Tag:
refs/tags/coworld-v0.1.7 - Owner: https://github.com/Metta-AI
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
self-hosted -
Publication workflow:
release-coworld.yml@1ba2324c7de3139f4b53b2fb504a6fc61abec149 -
Trigger Event:
push
-
Statement type:
File details
Details for the file coworld-0.1.7-py3-none-any.whl.
File metadata
- Download URL: coworld-0.1.7-py3-none-any.whl
- Upload date:
- Size: 146.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ea266d8bc08a69a30391b52d071ba4ce9b717ab4977f63f7ae8635af0b147367
|
|
| MD5 |
9f54ba5617eb3436ec55de5369639c68
|
|
| BLAKE2b-256 |
8d4aab6b8b4b740a8f7d906085d42abf4ddf38f03e5a94deb3eb280d5e13203c
|
Provenance
The following attestation bundles were made for coworld-0.1.7-py3-none-any.whl:
Publisher:
release-coworld.yml on Metta-AI/metta
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
coworld-0.1.7-py3-none-any.whl -
Subject digest:
ea266d8bc08a69a30391b52d071ba4ce9b717ab4977f63f7ae8635af0b147367 - Sigstore transparency entry: 1570478554
- Sigstore integration time:
-
Permalink:
Metta-AI/metta@1ba2324c7de3139f4b53b2fb504a6fc61abec149 -
Branch / Tag:
refs/tags/coworld-v0.1.7 - Owner: https://github.com/Metta-AI
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
self-hosted -
Publication workflow:
release-coworld.yml@1ba2324c7de3139f4b53b2fb504a6fc61abec149 -
Trigger Event:
push
-
Statement type: