lattice-director — Fleet, matchmaking & session resolution¶
Registers game-server fleet instances, matchmakes players, and mints short-lived session
tokens for the netcode handshake. Source:
control-plane/lattice-director/src/LatticeDirector/Program.cs.
- Verifies lattice-auth access tokens offline via
Auth:Jwks. - Mints its own session tokens:
iss=lattice-director,aud=lattice-gameserver,alg=EdDSA, TTL 2 min. Claims:sid, hdl, ep, sub, region, iat, exp, jti. - DTOs use snake_case.
Fleet / service discovery (server-facing)¶
Gated by the X-Fleet-Token header (shared secret, constant-time compared). When Fleet:Token
is unset (dev), the endpoints are open.
| Method · Path | Purpose | Body → Response |
|---|---|---|
POST /fleet/register |
register an instance | {instance_id, endpoint, region, modes[], capacity, load?} → FleetAckResponse{instance_id, status, available} |
POST /fleet/heartbeat |
keep-alive | {instance_id, load?} → FleetAckResponse (status "alive"); 404 if expired |
POST /fleet/deregister |
drain/remove | {instance_id, load?} → 204 / 404 |
Matchmaking & session directory (player-facing)¶
Requires a Bearer access token (lattice-auth).
| Method · Path | Purpose | Body → Response |
|---|---|---|
POST /matchmake |
find/allocate a session | {region, mode, party?:string[], max_players?} → MatchmakeResponse{session_handle, session_id, endpoint, region, mode, player_count, max_players}; 409 on failure |
POST /resolve |
exchange a handle for a connect ticket | {session_handle} → ResolveResponse{endpoint, session_token, session_id} (mints the session token bound to the caller's sub) |
GET /sessions/{id} |
session status | SessionStatusResponse{session_id, session_handle, endpoint, region, mode, player_count, max_players} |
party omitted ⇒ the caller's own sub. The session_token from /resolve is what you pass to
lattice_runner_connect as the connect token.
Infra¶
| Method · Path | Purpose |
|---|---|
GET /.well-known/jwks.json |
director's session-token public keys (verified by game servers) |
GET /healthz, GET /readyz |
liveness / readiness |
sequenceDiagram
participant GS as Game server
participant DI as director
participant C as Client
GS->>DI: POST /fleet/register (X-Fleet-Token)
loop every few seconds
GS->>DI: POST /fleet/heartbeat
end
C->>DI: POST /matchmake (Bearer access)
DI-->>C: session_handle (placed on a registered instance)
C->>DI: POST /resolve {session_handle}
DI-->>C: {endpoint, session_token}
C->>GS: connect(endpoint, session_token)