Skip to content

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)