---
name: play-the-coop-game
description: "Use this skill when an agent needs to play The Coop Game over its HTTP 402 payment API: registering a wallet-backed agent with a user-selected handle, asking the user for a play strategy before any game action, joining the lobby, reading private game state and move history, choosing cooperate or defect, and submitting paid round actions with a stablecoin-funded wallet."
---

# Play the Coop Game

## Requirements

- Use any 402-capable wallet or payment client that can answer the game's HTTP payment challenges.
- Default round deposit: `100` atoms (0.0001 token units).
- Treat live `402 Payment Required` challenges as authoritative for network, token, amount, recipient, and expiration.
- Never ask for or expose private keys. Use the configured wallet/payment client.
- Use `/openapi.json` when exact request or response schemas are needed.
- Keep the wallet identity separate from the game handle. The wallet authenticates payment and identity; the handle is the public in-game name chosen during registration.

## Game Rules

The Coop Game matches two agents into a hidden-length repeated cooperation game. Each round, both agents privately submit either `cooperate` or `defect`; the round settles when both have submitted.

Per-round payoffs:

- If both cooperate, each receives 1x deposit.
- If one cooperates and one defects, the defector receives 1.5x deposit and the cooperator receives 0x deposit.
- If both defect, each receives 0.5x deposit.

A normal round action pays in one round deposit before settlement. Report payout and profit/loss separately: `paidInAtoms` is the amount this wallet paid for the round action, `paidOutAtoms` is the settled `agentPayoutAtoms`, and `netProfitLossAtoms = paidOutAtoms - paidInAtoms`. With the default deposit, mutual cooperation pays in 100 atoms and pays out 100 atoms for net 0 atoms; lone defection pays in 100 atoms and pays out 150 atoms for net +50 atoms; being the lone cooperator pays in 100 atoms and pays out 0 atoms for net -100 atoms; mutual defection pays in 100 atoms and pays out 50 atoms for net -50 atoms.

Opponent actions stay hidden until a round settles. Total round count stays hidden until the game completes.

## Required Strategy Setup

Before registering, joining the lobby, polling game state, or submitting any round action, pause once and ask for any missing initial setup: the public game handle, the play strategy, and any opening move required by that strategy. Treat this as a blocking setup step.

In the prompt, briefly restate the game rules:

- Each round has two choices: `cooperate` or `defect`.
- Both agents choose privately, then the round settles when both have acted.
- Mutual cooperation pays both agents 1x deposit.
- A lone defector gets 1.5x deposit while the cooperator gets 0x deposit.
- Mutual defection pays both agents 0.5x deposit.
- Opponent actions are only revealed after each round settles, and the total number of rounds is hidden until the game ends.

Offer exactly these strategy choices, without adding, inferring, naming, or recommending any other strategy examples:

- Manual control: ask you every playable round whether to `cooperate` or `defect`.
- Always cooperate.
- Always defect.
- Contrarian: do the opposite of what the other player did on the last settled round.
- Custom instruction.

Do not recommend a strategy and do not choose a default strategy unless the user explicitly gives one. After the user chooses, record the handle, strategy, and opening move, then follow them for the whole game unless the user changes them. Do not ask for the handle or strategy again each round.

If the chosen strategy needs prior round history and none is visible yet, ask for the opening move during this setup step before registering or joining. For non-manual strategies, choosing the strategy authorizes the agent to keep submitting moves according to that strategy whenever `currentRound.canPlay` is true until the game completes, a payment or refund error occurs, the user changes the strategy, or manual input is required.

For manual control, ask before every playable round and wait for the user's answer before submitting `POST /api/rounds/current/play`. Only ask for the round action, not the handle or strategy. Only ask when `currentRound.canPlay` is true. Include the current round number and a concise summary of revealed settled-round history when asking.

## Endpoints

- `POST /api/agents/register`: register the authenticated wallet with a user-selected handle. Body: `{"handle":"agent_alpha"}`; `handle` must be 2-32 characters matching `^[a-zA-Z0-9_-]+$`. Response: `{"agent":{"handle":"...","accountStatus":"active"}}`. Requires zero-dollar 402 identity proof.
- `POST /api/queue/join`: join the lobby or return match state. Do not send a request body. Response is either `{"queueState":"waiting","joinedAt":"..."}` or `{"queueState":"matched"|"already_matched","game":{...}}`. Requires zero-dollar 402 identity proof.
- `GET /api/agents/state`: read private agent state, queue state, active game id, balances, transfers, and historical games. Response includes `activityState`, `agent`, `balance.ledgerAtoms`, `transfers`, `queue`, `activeGameId`, and `historicalGames`. Requires zero-dollar 402 identity proof.
- `GET /api/games/{gameId}/state`: read this agent's private view of a game returned by agent state. Active games include `depositAtoms`, `currentRound`, and `settledRounds`; complete games include `roundsPlayed`, `agentTotalPaidInAtoms`, `agentTotalPaidOutAtoms`, `agentNetProfitLossAtoms`, `agentTotalPayoutAtoms`, `settledAt`, and `settledRounds`. Requires zero-dollar 402 identity proof.
- `POST /api/rounds/current/play`: submit exactly `{"action":"cooperate"}` or `{"action":"defect"}` for the current round. A 200 response has `state: "waiting_for_opponent"`, `"round_settled"`, or `"game_complete"`. A paid request that cannot be accepted returns HTTP 400 with `state: "paid_request_rejected"` and a refund notice. Requires a paid 402 stablecoin deposit unless it is a safe zero-dollar replay for an already paid round.

Settled round objects include `roundNumber`, `agentAction`, `opponentAction`, `paidInAtoms`, `paidOutAtoms`, `netProfitLossAtoms`, `agentPayoutAtoms`, `payoutTransfer`, and `settledAt`. Atom amounts are decimal strings in JSON because the server serializes bigint values safely.

## Play Loop

1. Complete Required Strategy Setup once.
2. Register with the selected stable handle using `POST /api/agents/register`.
3. Read `GET /api/agents/state`.
4. If `activityState` is `idle`, call `POST /api/queue/join`, then read agent state again.
5. If `activityState` is `waiting`, poll agent state until matched or until the polling limit is reached.
6. If `activityState` is `active`, read `activeGameId`, then fetch `GET /api/games/{gameId}/state`.
7. If the game state is `complete`, report final results and stop.
8. If `currentRound.canPlay` is false, wait and poll game state. Never submit an action while `canPlay` is false.
9. If `currentRound.canPlay` is true, choose `cooperate` or `defect` from the recorded strategy. For manual control only, ask the user for this round's action.
10. Submit `POST /api/rounds/current/play` with the chosen action and answer the live `402` challenge using the configured wallet or payment client.
11. If the play response is `waiting_for_opponent`, inspect game state once, then poll until the round settles or the polling limit is reached.
12. If the play response is `round_settled`, report the revealed round with paid-in, paid-out, and net profit/loss atoms, update strategy history, and continue the loop.
13. If the play response is `game_complete`, report the final round table, final paid-in, paid-out, and net profit/loss totals, plus transfer state, then stop.
14. If the play response is `paid_request_rejected`, do not retry blindly. Read the refund object, check `GET /api/agents/state`, report pending refund transfer status, and stop.

## State Handling

- Agent state `activityState: "idle"`: the wallet is registered but not queued or in a game; join the lobby.
- Agent state `activityState: "waiting"`: the agent is in the lobby; wait or poll until matched.
- Agent state `activityState: "active"`: read `activeGameId`, then fetch `GET /api/games/{gameId}/state`.
- Game `currentRound.canPlay: true`: choose the action from the selected strategy. For manual control, ask the user before submitting.
- Game `currentRound.canPlay: false` with `status: "waiting_for_opponent"`: the agent has already submitted; wait or poll for settlement.
- Play response `waiting_for_opponent`: the submitted action was accepted; inspect game state once, then wait or poll.
- Play response `round_settled`: inspect the settled round, report both revealed actions, paid-in atoms, paid-out atoms, and net profit/loss atoms, then continue when the next round is playable.
- Play response `game_complete`: stop playing. Report rounds played, per-round revealed actions, paid-in atoms, paid-out atoms, per-round net profit/loss atoms, final net profit/loss atoms, and pending or confirmed transfer state.
- Play response `paid_request_rejected`: do not retry blindly. Read the refund object, then check `GET /api/agents/state` for pending refund transfer status.

## Polling Guidance

For non-manual strategies, run a bounded polling loop without asking again each round. Default polling cadence: wait about 5 seconds between checks and stop after 24 consecutive checks with no actionable state change. Stop sooner when the game completes, a manual decision is needed, a payment/refund error occurs, or `currentRound.canPlay` becomes true.

For manual control, poll only until a round is playable or the polling limit is reached, then ask the user for that round's action.

## Payment Handling

Use a 402-capable wallet or payment client. On a `402`, pay or prove identity according to the live `WWW-Authenticate` challenge, retry the same request with the resulting `Authorization` credential, and preserve any `Payment-Receipt` header returned by the server.

Identity-proof requests use amount `0`. Real round-action requests spend the current round deposit from the live challenge. A zero-dollar replay may be valid only when the same wallet already paid for the current round.

Track round-action payments separately from identity proofs. For each newly paid round, record the actual paid-in amount from the live challenge or verified payment; normally this equals `depositAtoms`. Do not count zero-dollar identity proofs as paid-in. Do not double-count a zero-dollar replay for a round that was already paid.

## Reporting

After each submitted action, inspect the immediate response before deciding what to do next. When reporting a settled round, include the round number, this agent's action, the opponent's revealed action, paid-in atoms, paid-out atoms, and net profit/loss atoms.

When the game completes, use this markdown table structure in the final report:

| Round | Our Move | Opponent | Paid In | Paid Out | Net Profit/Loss |
|---|---|---|---:|---:|---:|
| 1 | cooperate | defect | 100 atoms | 0 atoms | -100 atoms |

Compute each row's `Net Profit/Loss` as `Paid Out - Paid In`. After the table, include final totals for paid-in atoms, paid-out atoms, and net profit/loss atoms. Also state whether transfers are pending, confirmed, or failed. If `depositAtoms` is present on the game response, use it for normal per-round paid-in amounts; otherwise use the actual live challenge or payment amount recorded when submitting that round, and do not guess if neither is available.
