# PlayDev for agents: start here

These pages are online-only. Fetch this guide at the start of a publish task, and re-read a linked page right before you act. Do not work from a saved copy.

PlayDev is a free indie catalog (browser + downloads). A human says something like **«Опубликуй игру на playdev.ru»** or **«Publish my game to playdev»**. You create a submission for their account; a human moderator reviews it before the game appears in the catalog. You never publish straight to the public catalog.

There are two equal paths. Pick by what your sandbox allows:

- **A. CLI** (`npx playdev-cli`): one command, zips the build for you.
- **B. Plain HTTP** (`curl`): if running `npx` / a downloaded script is not allowed here (many agent sandboxes block code from external packages), either ask the human to allow it, or use the curl recipe below. It does exactly what the CLI does.

## A. CLI: one command

If the user has a finished browser game (HTML5 / JS / TS / Canvas / WebGL / Phaser / Three.js / PixiJS, or a Godot/Unity web export), build it and run **from the project root**:

```sh
npx playdev-cli init                    # once: creates playdev.json, fill it from the game itself
npx playdev-cli publish . --dry-run     # check what would be sent
npx playdev-cli publish .               # finds index.html in ./, dist/, build/, public/, out/
```

- `playdev.json` is searched from the build folder up to the current folder, so `publish ./dist` from the root also works. `cover` is relative to `playdev.json`; the `slug` is written back into the same file.
- **Login without a terminal.** Your stdin is not a TTY, so `publish` without a token does not block: it prints the code, `approve_url` and `expires_at` and exits with code **2**. Show the URL to the human (the code is valid **30 minutes**). After they approve, run `npx playdev-cli login --wait` (add `--timeout 110` if your shell has a time limit, repeat if it times out), then run `publish` again.
  The same in two explicit steps: `npx playdev-cli login --no-wait --json` → `npx playdev-cli login --wait`.
- Token goes to `~/.config/playdev/credentials.json` (mode 0600). Never commit it.
- Next runs (with `slug` in `playdev.json`) upload a new release: `npx playdev-cli publish . --version 1.2.0 --changelog-title "Patch" --notes "What changed"`. `--title` is only the game title.
- No npm? `curl -fsSL https://playdev.ru/cli/playdev.mjs -o playdev.mjs && node playdev.mjs publish .` (Node 18+, no deps, same file as the npm package).

MCP clients (Claude Code, Cursor, Codex, Copilot, Windsurf) can use the same thing as tools: `npx -y playdev-cli mcp` → `playdev_login`, `playdev_login_status`, `playdev_publish`, `playdev_push_release`, `playdev_list_games`, `playdev_about`. Config snippets: [snippets.md](https://playdev.ru/agents/snippets.md).

## B. No npx? Plain HTTP

Same flow as the CLI, with `curl` only. Base URL: `https://playdev.ru`.

### 1. Pairing (the human approves a code)

```sh
API=https://playdev.ru

curl -s -X POST "$API/api/agent/pairings" \
  -H 'accept: application/json' -H 'content-type: application/json' \
  -d '{"agent_name":"Claude Code"}'
# 201 {"code":"ABCD-EFGH","approve_url":"https://playdev.ru/agent-link/ABCD-EFGH","poll_token":"…","expires_at":"…"}
```

Tell the human: open `approve_url`, sign in or sign up (free), approve the code. The code is valid **30 minutes** (`expires_at`).

### 2. Poll until approved

```sh
POLL_TOKEN=…   # poll_token from step 1
curl -s -o poll.json -w '%{http_code}\n' "$API/api/agent/pairings/poll?poll_token=$POLL_TOKEN"
# 202 pending · 200 {"access_token":"…","user":{…}} (shown ONCE) · 403 denied · 410 expired
```

Poll every 3–5 s, or stop and ask the human to tell you when they approved. Save `access_token` outside the game repo, e.g. as `{"api":"https://playdev.ru","token":"…"}` in `~/.config/playdev/credentials.json` (then the CLI can reuse it). Delete `poll.json`.

### 3. Zip the build and submit

```sh
(cd dist && zip -qr ../game.zip .)      # index.html must be at the root of the ZIP

curl -s -X POST "$API/api/agent/games/submit" \
  -H "Authorization: Bearer $ACCESS_TOKEN" -H 'accept: application/json' \
  -F 'title=My Game' \
  -F 'description=What the game is, how to play, what it is made with.' \
  -F 'short_description=One line pitch.' \
  -F 'type=light' \
  -F 'platforms_json=["Web"]' \
  -F 'genres[]=Аркада' \
  -F 'age_rating=0+' \
  -F 'ai_tools_json=[{"slug":"claude","label":"Claude","categories":["code"]}]' \
  -F 'cover=@cover.png' \
  -F 'build=@game.zip'
# 201 {"message":"Заявку отправили на модерацию.","game":{"id":…,"slug":"…","status":"pending","genres":[…],"build":{…},"is_playable":true},"notices":[…]}
```

- Platforms: send `platforms_json` (JSON array, what the CLI sends). `platforms[]=Web` is also accepted; do not send both.
- `notices` in the response lists anything the server normalized (e.g. an AI tool label replaced with the catalog name, an unknown genre). Check it and tell the human.
- Next release: `POST $API/api/agent/games/{slug}/release` with `build=@game.zip`, optional `version`, `changelog_title` + `changelog_body`. Details: [publish-game.md](https://playdev.ru/agents/publish-game.md).

## Fields reference

- **Genres** (up to 3, exact names): Экшен, Приключение, Казуальная, Симулятор, Стратегия, РПГ, Головоломка, Платформер, Шутер, Хоррор, Рогалик, Выживание, Новелла, Аркада, Гонки, Спортивная, Файтинг, Ритм, Настольная, Образовательная. Live list: `GET https://playdev.ru/api/genres` (`genres[].name`).
- **Cover**: optional but strongly recommended. JPG, PNG, WebP or GIF, up to 8 MB, 16:9 recommended, from 1400×788 (it is shown up to that size).
- **Age rating**: `0+` `6+` `12+` `16+` `18+` `unrated`.
- **AI tools** (`ai_tools_json`): honest list of AI used, `[]` if none. Objects `{slug, label, categories, note?}`; slugs from the catalog (`chatgpt`, `claude`, `gemini`, `cursor`, `copilot`, `midjourney`, `suno`…), categories `art`, `sound`, `code`, `text`, `video`, `other`. The page shows the catalog name for the slug; put product details like "Claude Code" into `note`.

## Rules

1. **Moderation only.** `POST /api/agent/games/submit` creates a game with status `pending`. Do not promise the human that the game is live in the catalog until moderation approves it.
2. **Authorization.** You must pair once: the human approves a code while signed in. You never ask for their password.
3. **Token.** Save `access_token` outside the game repo. Never commit it. Ability: `agent:publish` only.
4. Prefer reading the game files yourself for title, description, genre. Ask the human only what you cannot know.

## What only the human does

- Approve your pairing code.
- Wait for moderation (or reply to a rejection in the studio).
- Revoke agent tokens in the account if needed (`DELETE /api/me/agent-tokens/{id}` while signed in as them — you cannot do that with the agent token).

## Related

- Machine overview: https://playdev.ru/llms.txt
- Full publish API steps: [publish-game.md](https://playdev.ru/agents/publish-game.md)
- OpenAPI (publish API): https://playdev.ru/sdk/openapi/agent.v1.yaml
- AGENTS.md / Cursor / Claude Code snippets: [snippets.md](https://playdev.ru/agents/snippets.md)
- SDK integrate prompts: https://playdev.ru/prompt-integrate.txt
- Human submit UI (fallback): https://playdev.ru/submit
