Rating reference

Config

rating({
  games: [
    { key: "duel", algorithm: "elo", xp: { win: 20, draw: 10, loss: 5 } },
  ],
  serverAuthoritative: true,
  recordScope: "rating:record",
})
Game fieldDefault
key—A URL path segment
algorithm—elo · glicko · trueskill · your own id
players2Must be within the algorithm’s supported range
poolthe game keyName one to share a ladder
xp—Per outcome
levels—Worst to best. Classified on read
hideSkillfalseStill drives matchmaking
sharedRoomCountsfalseWhether a game with a friend earns XP
algoParams—Validated by the algorithm

Top level: serverAuthoritative (default true), recordScope, basePath (default /rating). Which algorithm to name is the algorithms; what pool does is pools; the calls are Using Rating. Refusals carry an ordinary error code.

Algorithms

PlayersTeamsSkill numberMain dial
elo2noThe ratingK, default 32
glicko2norating − 2·RDτ, default 0.5
trueskill2+yesμ − 3·σβ, τ, draw probability

Validated at assembly, not at the first result.

A pool is rated by exactly one algorithm, and changing it is a new pool rather than a migration.

Routes

RouteVerified by
POST /rating/games/:game/outcomesuser + record scope when server-authoritative
GET /rating/games/:game/meuser
GET /rating/games/:game/players/:userIduser

No public surface. Without auth composed, every route denies.

The outcome body

{ "ranks": { "u1": 1, "u2": 2 } }

Finishing place per user id. 1 wins; ties share a place.

Nothing else — pool from config, algorithm from the pool, timestamp from the server.

The table

pithy_rating_ratings — one row per (pool, player).

Column
The algorithm’s state blobValidated against the recorded algorithm on read
SkillIndexed — a matchmaking bucket is a range read
XPMonotonic
Games played
Updated at

No board table, no history table, no config in the database.

Bindings

BindingKind
DBD1

pithy add rating writes it into every environment. Nothing needs provisioning beyond the database you already have.

Error codes

Code
rating/game_not_found
rating/pool_not_found
rating/record_forbiddenServer-authoritative, and no record scope
rating/unknown_algorithm
rating/unsupported_player_countCaught on deploy, not at the first result
rating/invalid_paramsThe algorithm refused them

Registering your own

registerRatingAlgorithm(yourAlgorithm) in your Worker entry, before the capability assembles.

Declare an id, a params schema with defaults, a state schema, supported player counts, and pure initial, update and skill functions.

ESC