# soku.cleista.cc

> A fan site for Touhou Hisoutensoku (Touhou 12.3): the netplay host list, replays, frame data for all 20 characters and player ratings. Frame data and ratings have a public, versioned JSON API. Prefer it to fetching the HTML pages.

Frame data is measured by simulating each move in a port of the game's engine: startup, active and recovery frames, frame advantage (corner, against Sanae, no cancel), damage, proration, cancels, invulnerability and other states, bullets, per skill level and held/whiffed variants. Ratings are Whole-History Ratings over the games the site's referee judged, per player and per character; only players the public leaderboard shows are in the API.

## API

- [API documentation](https://soku.cleista.cc/api): endpoints, parameters, limits, versioning
- [OpenAPI 3.1](https://soku.cleista.cc/api/v1/openapi.json): machine-readable description
- [Frame data index](https://soku.cleista.cc/api/v1/framedata): characters and the data build id
- [A character's moves](https://soku.cleista.cc/api/v1/framedata/reimu): summary per move
- [One move](https://soku.cleista.cc/api/v1/framedata/reimu/5a): everything about it; ?level=, ?charged=1, ?outcome=whiff for variants
- [Find a move](https://soku.cleista.cc/api/v1/framedata/resolve?character=okuu&q=hell%20geyser): from notation ("f5a", "6[a]", "alt 236b"), card id ("sc209"), card name or cost ("5 card")
- [Ratings leaderboard](https://soku.cleista.cc/api/v1/ratings): ?character=&min=&status=&community=&q=&limit=&offset=
- [Look up players](https://soku.cleista.cc/api/v1/ratings/players?names=a,b,c): up to 100 in-game names or handles per request; POST {"names":[...]} to the same URL takes up to 1000; a name several people play under answers with its default player plus alsoPlayedAs: [{ label, handle? }]
- [All players](https://soku.cleista.cc/api/v1/ratings/export.json): every rated player, all statuses, one precompressed file (about 3 MB raw); check computedAt and send If-None-Match
- [Ratings by range](https://soku.cleista.cc/api/v1/ratings/ranges?rmin=1500&rmax=1900): per-character win rate and play share plus the matchup matrix for a custom range; ?rmin=&rmax= (multiples of 25), gmin=&gmax= (games played), from=&to= (YYYY-MM), close=1; /api/v1/ratings/ranges/players?char=&vs= lists a cell's top 10 players
- [Character stats](https://soku.cleista.cc/api/v1/stats/characters?window=30d): picks, play share and win rate per character; ?window=7d|30d|all
- [Card usage](https://soku.cleista.cc/api/v1/stats/characters/reimu/cards?window=30d): per card, the share of the character's decks that run it, copies and win rate with and without it

## Rules

- Use the JSON API, not the HTML pages: the pages are heavy and marked noindex.
- Limits per address: 120 requests a minute for frame data, 60 for ratings, 120 for character stats; then 429 with Retry-After.
- Send If-None-Match with the ETag you got; 304 means nothing changed. Frame data changes only when its build id does.
- Within /api/v1/ changes only add fields or endpoints.
- Please link back to https://soku.cleista.cc when you show the data.
- Contact: @maristocrat in #hisouten on Discord.

## Optional

- [Frame data pages](https://soku.cleista.cc/framedata)
- [Ratings page](https://soku.cleista.cc/ratings)
