# Introduction

stomped is a competitive arena for Super Smash Bros. Melee bots. You write a
bot, host it as an HTTP server, and register its URL. stomped does the rest: it
matches your bot against others by rating, runs the game server-side on a
headless Slippi Dolphin, and opens a WebSocket to your bot for each match —
the game arrives as the raw `.slp` event stream, your controller state goes
back, frame by frame. Win games, climb the ladder.

The game is Melee NTSC 1.02 under the default competitive ruleset: 1v1, 4
stocks, 8 minutes, no items, six legal stages. Bots never run the game; they
read frames and send pads. A bot registers into a **mode** — the same game
under a given clock. `live` runs a real 60 Hz clock, for bots hosted near the
arena.

Getting on the ladder is two steps: **sign in to the dashboard with your
email, then enter your bot's URL.** That's it — the bot enters matchmaking on
the next tick. A one-file starter bot lives in the stomped repo under
`examples/starter-bot`.

This reference is generated from the same contract the server implements —
it can't drift. Machine-readable copies live at stable URLs:

- `/openapi.json` — this entire reference as an OpenAPI 3.1 document,
  including the rules and the play protocol.
- `/llms.txt` — a map of every artifact, for AIs.

stomped's Ed25519 platform public key — which signs every connection stomped makes
to your bot — is published at `GET https://api.stomped.dev/.well-known/stomped.json`
as `{"publicKey": "<base64 raw 32 bytes>"}`.

## Limits

Normal use — registering a few bots, iterating on one, polling your match
history — never touches these; they exist to keep the arena responsive.

- An account holds at most **20 API keys**. There is no cap on bots; bots of
  one account are never matched against each other.
- Requests are rate limited per account — per IP when anonymous: registering
  a bot or changing its URL **10/min** (each one triggers the deploy check),
  other writes **30/min**, match reads (`/matches`, records, replays)
  **120/min**, everything else **600/min**.
- Over a limit you get `429` with a `Retry-After` header (seconds). Back off
  that long and the request succeeds.
