# Play Among Them Daily

This is the Among Them version of the **Participate in this league** flow. It takes you from an empty folder to a
submitted Dockerized Coworld policy in the public **Among Them Daily** league.

Use these terms throughout the guide:

- **Coworld**: a downloadable game package with a manifest, game image, baseline player images, docs, and local test
  settings.
- **Softmax Observatory**: the Softmax web dashboard at `https://softmax.com/observatory/v2` for leagues, submissions,
  standings, episode logs, and replays.
- **League**: a public competition page inside Softmax Observatory. **Among Them Daily** is the league used here.
- **Division**: a league tier or grouping, identified by a `div_...` id, where submitted policies are placed for
  matches.
- **Policy**: your player code.
- **Policy image**: the Docker image that packages your policy so Softmax can run it.
- **Submission**: a request to add one uploaded policy image to a league.
- **Placement match**: the automated tournament-side validation game that runs after submission. It checks that your
  policy image starts, connects, plays, and can be placed into the league before regular standings appear.
- **Replay**: a saved episode you can reopen in a browser after a local or tournament game finishes.

Every status update while following this guide should emit:

- `Progress: [###-----] N/8`
- `Current step: Step N of 8 - ...`
- `What this step is doing: ...`
- `Next step: ...`
- `Links to open: ...`

You will do eight steps:

1. Install software and create a project.
2. Sign in and find the current league.
3. Download the game package.
4. Run the bundled baseline players locally.
5. Watch a local episode or replay.
6. Edit the starter policy.
7. Build and test your policy image.
8. Upload, submit, and watch placement matches.

Keep the **Among Them Daily** league page open:

1. Open `https://softmax.com/observatory/v2`.
2. Choose **Leagues**.
3. Open **Among Them Daily**.

That page is the source of truth for the current `league_...` id, submission status, placement-match status,
standings, episode logs, and replays.

## Before You Start

You need Docker running, `uv`, and a Softmax account.

Install links:

- Docker Desktop: `https://www.docker.com/products/docker-desktop/`
- `uv`: `https://docs.astral.sh/uv/getting-started/installation/`
- Softmax: `https://softmax.com/`

The full flow has two local checkpoints before you submit:

- a baseline episode proves the downloaded game package works on your machine
- a policy episode proves your Docker image can connect to the local game server and finish an episode

After you submit, the league runs placement matches. While that is happening, your submission may show `pending` or
`processing`. When placement passes, the submission becomes `placed` and appears as an active league player. If
placement fails, inspect the logs, fix the image, upload a new version, and submit again.

## Step 1 Of 8: Install Software And Create A Project

- **Progress:** `[#-------] 1/8`
- **Current step:** Step 1 of 8 - install the software and create a local policy project.
- **What this step is doing:** Verifies Docker and `uv`, installs the Coworld CLI in your project, and writes the starter
  policy source plus Dockerfile.
- **Next step:** Sign in and find the current **Among Them Daily** league.
- **Links to open:** Docker Desktop and `uv` install links from **Before You Start** if either version check fails.

Check your local tools:

```bash
docker --version
uv --version
```

Create the player project:

```bash
mkdir amongthemstarter-project
cd amongthemstarter-project
uv init --bare --name amongthemstarter-project
uv add "coworld[auth]"
uv run coworld make-policy among_them -o amongthemstarter
```

Done when `uv run coworld --help` works and `amongthemstarter/` exists.

To list packaged starter templates, run:

```bash
uv run coworld make-policy --help
```

## Step 2 Of 8: Sign In And Find The League

- **Progress:** `[##------] 2/8`
- **Current step:** Step 2 of 8 - authenticate and identify the league you will submit to.
- **What this step is doing:** Logs into Softmax and finds the current `league_...` id for **Among Them Daily**.
- **Next step:** Download the Among Them Coworld package.
- **Links to open:** `https://softmax.com/observatory/v2`, then **Leagues** -> **Among Them Daily**.

Login with either:

```bash
uv run softmax login
```

or on a remote or headless machine, copy the token from `softmax login` and run:

```bash
uv run softmax set-token '<TOKEN>'
```

Confirm that `coworld` can see the public v2 leagues, then inspect the current **Among Them Daily** league:

```bash
uv run coworld leagues
uv run coworld leagues league_...
uv run coworld divisions --league league_...
```

Done when the CLI can list leagues and you have the current `league_...` id from the **Among Them Daily** page. Keep the
current `div_...` id too if you want to inspect memberships or replay links from the CLI after submission.

## Step 3 Of 8: Download The Game

- **Progress:** `[###-----] 3/8`
- **Current step:** Step 3 of 8 - download the game manifest and baseline images.
- **What this step is doing:** Pulls the Coworld package and local Docker image tags needed for local play.
- **Next step:** Run a baseline episode locally.
- **Links to open:** None yet. Use the local manifest path printed below.

```bash
uv run coworld download among_them
uv run python -m json.tool ./coworld/<coworld-id>/coworld_manifest.json | less
```

`coworld download` stores the package under `./coworld/<coworld-id>/`, pulls the runnable game and bundled baseline
player images, and tags those images locally for `coworld play`. Use the `Coworld:` ID printed by the download command
in the paths below.

Read the manifest before writing your player. It includes the game image, bundled baseline player image, protocol docs,
player guide, submission guide, optimizer guide, variants, and certification fixture. The key runtime contract is
`game.protocols.player`: your player process must connect to `COGAMES_ENGINE_WS_URL`, speak that websocket protocol,
play until the episode ends, and exit.

Done when `./coworld/<coworld-id>/coworld_manifest.json` exists and the manifest opens cleanly.

## Step 4 Of 8: Run The Baseline Locally

- **Progress:** `[####----] 4/8`
- **Current step:** Step 4 of 8 - verify the downloaded game runs before adding your policy.
- **What this step is doing:** Runs the short certification fixture with the bundled baseline player containers.
- **Next step:** Watch a local episode or replay.
- **Links to open:** None if this command is non-browser only.

For a quick non-browser check, run:

```bash
uv run coworld run-episode ./coworld/<coworld-id>/coworld_manifest.json --timeout-seconds 120
```

Done when the command finishes without errors. This means the game image, bundled baseline players, Docker networking,
and local runner are all working before you test your own policy.

## Step 5 Of 8: Watch A Local Episode

- **Progress:** `[#####---] 5/8`
- **Current step:** Step 5 of 8 - inspect the local game visually.
- **What this step is doing:** Starts a local playable episode and opens the browser viewer.
- **Next step:** Edit the starter policy.
- **Links to open:** The printed **Global client** URL while the episode is running, then the printed **Replay client**
  URL after replay starts.

To watch a live local episode, start the manifest's default playable variant:

```bash
uv run coworld play <coworld-id>
```

This runs the manifest's default playable variant, starts the game container, starts the baseline player containers, and
opens the global viewer in your browser. If the browser does not open, open the printed **Global client** URL manually.
Stop the command with `Ctrl-C` when you are done watching, or let the episode finish if you want a replay file.

The printed browser links use `127.0.0.1:<port>` because they are for your host browser. Dockerized players use
`COGAMES_ENGINE_WS_URL` on Docker's private `coworld-local` network, so Linux Docker Engine users should not need UFW or
`docker0` firewall changes for local Among Them runs.

When the episode finishes, the command prints a replay path. To reopen the completed episode:

```bash
uv run coworld replay ./coworld/<coworld-id>/coworld_manifest.json <REPLAY_PATH>
```

Open the printed **Replay client** URL to inspect the completed local episode.

Done when you have watched a local episode or reopened its replay.

## Step 6 Of 8: Edit The Starter Policy

- **Progress:** `[######--] 6/8`
- **Current step:** Step 6 of 8 - edit your policy code.
- **What this step is doing:** Changes the starter behavior before you build a Docker image.
- **Next step:** Build and test your policy image.
- **Links to open:** The local source file `amongthemstarter/amongthemstarter.nim`.

Open `amongthemstarter/amongthemstarter.nim` to edit the starter policy. It navigates to tasks, holds the action button
while stopped to complete them, reports bodies, and votes from observed evidence.

Done when your policy changes are saved.

## Step 7 Of 8: Build And Test Your Policy Image

- **Progress:** `[#######-] 7/8`
- **Current step:** Step 7 of 8 - build your Docker image and prove it can finish a local episode.
- **What this step is doing:** Packages your policy as a Docker image and runs it against the local certification
  fixture.
- **Next step:** Upload the image, submit it to the league, and watch placement matches.
- **Links to open:** For visual debugging, the printed **Global client** URL from `coworld play`.

Build and test the policy image with the same short run:

```bash
docker build --platform=linux/amd64 -t amongthemstarter:latest ./amongthemstarter
uv run coworld run-episode ./coworld/<coworld-id>/coworld_manifest.json amongthemstarter:latest --timeout-seconds 120
```

Done when the custom-image run finishes without errors. This is the closest local check before uploading: your image has
started, connected through `COGAMES_ENGINE_WS_URL`, played the websocket protocol, and exited after the episode.

If a local episode fails or you want the raw local artifacts, start here:

```bash
ls coworld/<coworld-id>/results
ls coworld/<coworld-id>/results/logs
```

For visual debugging, run the same image in the local viewer:

```bash
uv run coworld play <coworld-id> amongthemstarter:latest
```

If your image needs a custom command, test with that command:

```bash
uv run coworld play <coworld-id> amongthemstarter:latest --run python --run /app/player.py
```

## Step 8 Of 8: Upload, Submit, And Watch Placement Matches

- **Progress:** `[########] 8/8`
- **Current step:** Step 8 of 8 - submit your tested image to **Among Them Daily**.
- **What this step is doing:** Uploads your Docker image to Softmax, submits it to the league, then checks the
  tournament-side placement-match status.
- **Next step:** Wait for placement matches to finish, then inspect standings, logs, and replays after matches run.
- **Links to open:** `https://softmax.com/observatory/v2`, then **Leagues** -> **Among Them Daily**. Also open any replay
  links shown on that page after matches complete.

```bash
uv run coworld upload-policy amongthemstarter:latest --name "$USER-amongthemstarter"
uv run coworld submit "$USER-amongthemstarter" --league league_...
```

Done when `submit` prints a submission id and status.

First check that your submission exists:

```bash
uv run coworld submissions --mine --league league_...
```

If the status is `pending` or `processing`, the league is running placement matches. Placement matches are not the final
daily standings round. They are the gate that verifies the uploaded image runs under tournament infrastructure and can
be placed into the league. After placement passes, the submission becomes `placed`.

After matches run, use the **Among Them Daily** page for standings, logs, and replays. You can also check from the CLI:

```bash
uv run coworld memberships --mine --division div_... --active-only
uv run coworld episodes --division div_... --mine --with-replay
uv run coworld results league_...
uv run coworld rounds --league league_...
```

## Notes

- Use the league page for the current `league_...` id.
- For command details, run `uv run coworld --help`.
- `coworld play` runs a named manifest variant for local watching. `coworld run-episode` uses the short certification
  fixture.
- If `coworld play` says a `coworld/...:downloaded` image is missing, rerun `uv run coworld download among_them` to
  refresh the local image tags.
- Both `coworld run-episode` and `upload-policy` support optional `--run python --run /app/player.py` for custom
  entrypoints.
