# Matchmaking & rating

There is no queue to join. Register a bot, keep it `active`, and the
scheduler seats it for you.

## Modes

A mode is the clock the game runs under. A bot registers into one mode for
its lifetime and is rated only against that mode; each mode has its own
leaderboard (`/leaderboard?mode=…`).

| mode | per frame | lead | forfeit after | rest between matches | wall clock |
| --- | --- | --- | --- | --- | --- |
| `live` | 16.7 ms | 2 frames | 5 s of game time | 2 min | 12 min |

- **`live`**: the engine runs on a real 60 Hz clock. A frame is polled every
  16.7 ms whether or not your pad has arrived; a missing pad is neutral. The
  lead is 2 frames. For bots hosted near the arena.

The rules, the stream and the pads are identical across modes; only when the
engine advances differs.

## One match per tick

Matchmaking runs on a fixed tick (every 5 seconds). Each tick starts at most
one match: among the `active` bots of a mode that are not already playing and
have rested since their last match (the mode's *rest between matches*), it
seats the two closest in rating. Two bots of one account never meet: the
scheduler skips that pair and seats the next-closest. Ports are a coin flip.
The number of matches running at once is capped by the box (one engine process
per match), so bots may wait a few ticks when the arena is busy. A bot plays at
most one match at a time.

## Rating

Ratings are [openskill](https://openskill.me) (Weng-Lin): each bot carries
`mu` (estimated skill) and `sigma` (uncertainty), starting at `mu = 25`,
`sigma = 25/3`. The number shown everywhere is the conservative estimate
`rating = mu − 3σ` — new bots start at 0 and climb as sigma shrinks.

A win is placement 1, a loss placement 2; a draw is placement 1 for both and
rates as a tie. Forfeits are rated like any other loss. The leaderboard ranks
every bot with at least one completed match; per-match rating deltas appear
on match records once the match completes.

## Missed games

A **miss** is a match your bot never joined: it was seated and either never
accepted the socket or never sent a thing — no pick, no pad. Sending anything
is not a miss. Misses count consecutively; any answered match resets the count.

After **10 consecutive misses** the scheduler offers the bot a seat only
every **3 hours** instead of its mode's usual rest, so a dead server stops
bleeding rating. If a miss streak grows a **week** old, the bot is set to
`paused`. Changing the bot's `status` (pause or unpause) also resets the count
immediately — fix your server, flip it back to `active`, and it plays on the
next tick.

## Wall clock

A match still running past its mode's wall clock is **aborted**: no
placements, no rating changes. A game ends on stocks or the 8-minute timer
long before the clock does; aborts mean something broke.

## Seed and replay

Every match has a random seed the engine is started with; it becomes public
when the match ends. The replay is the `.slp` file the engine wrote —
identical to what both bots were streamed — at `GET /matches/{id}/replay.slp`
once the match completes. `GET /matches/{id}` carries the result: stage,
characters, stocks and percent per port, frames played, how it ended, who won.
`GET /matches` pages backwards with `before=<matchId>`, up to the newest
10,000 matches. The arena MAY delete replays after a retention period; the
record stays, and `replayBytes` is `null` once the replay is gone.
