Matchmaking reference

Game config

FieldDefault
key—A URL path segment
players—How many form a match
skillPool—A rating pool to bucket on. Omit for region only
snapshot—The multiplayer session a formed match is minted into
roomCodes.ttlSeconds900
roomCodes.maxUses9
queue.initialBandSkill width at enqueue
queue.widenPerSecondGrowth per second waited
queue.maxWaitSecondsAfter which the band is unbounded
queue.sweepSeconds5The cost dial

Top level: friends (default on), basePath (default /matchmaking). The queue block is the waiting queue’s dial set; the rest configures the other three ways in.

Routes

Shaped like every route in the kit, and refusing with an ordinary error code.

Every one is user — bearer or session.

Route
POST /matchmaking/games/:game/roomsOpen a room
POST /matchmaking/rooms/:code/join
POST /matchmaking/games/:game/invites
GET /matchmaking/invites
POST /matchmaking/invites/:id/accept
POST /matchmaking/invites/:id/decline
GET /matchmaking/friends
POST /matchmaking/friends/:userId/request
POST /matchmaking/friends/:userId/accept
POST /matchmaking/friends/:userId/decline
DELETE /matchmaking/friends/:userId
POST /matchmaking/games/:game/queue
GET /matchmaking/games/:game/queue
DELETE /matchmaking/games/:game/queue
GET /matchmaking/presenceWebSocket

There is no public surface. Every route binds to the authenticated user id, never to a client-supplied one. The friend routes mount only when friends is on.

Room codes

WXYZ-1234 — four letters, four digits.

Alphabets exclude I, O, 0 and 1. Join tolerates lowercase, whitespace and a missing dash.

Presence events

{ type: "match_found";    sessionId: string; gameKey: string }
{ type: "invite";         inviteId: string;  gameKey: string; from: string }
{ type: "friend_request"; from: string }

On connect: pending invites, and which friends are online.

Identity is a server-set header, stashed with serializeAttachment so it survives eviction.

Soft ceiling around 1,000 requests per second — one shared object. A throughput ceiling, not a bill.

Bindings

BindingKind
DBD1
MATCHMAKINGKVYou paste the namespace id
QUEUEDurable ObjectMatchmakingQueue
PRESENCEDurable ObjectMatchmakingPresence
SESSIONSDurable ObjectMultiplayer’s, not declared here

Both classes are exported from their own modules, never the package entry point.

Storage

pithy_matchmaking_invitesIndexed by invitee, carrying the session id once accepted
pithy_matchmaking_friendsOne row per pair, indexed both ways
KV matchmaking:<code>Room codes

Queue state is the queue object’s own storage. Presence is the live socket set. Neither is a row you keep.

Error codes

Code
matchmaking/room_not_found
matchmaking/room_full
matchmaking/invalid_code
matchmaking/invite_not_found
matchmaking/invite_forbidden
matchmaking/already_friends
matchmaking/friend_request_not_found
matchmaking/user_not_foundA screen name matching zero users, or several
matchmaking/not_queued

Seams

AbsentResult
AuthEvery route denies
RatingRegion-only bucketing
MultiplayerPairing runs; no session can be minted
ESC