Ownership
| Part | Owner |
|---|---|
| Invitations, selected game, launch cohort and readiness | PEERLESS |
| Fresh credentials, launch invalidation and queue authorization | PEERLESS and the SDK |
| Lobby polling, seat delivery retries and disposal | The SDK and the Colyseus binding |
| Your lobby connection and consuming a reserved seat | Your networking adapter |
| Mapping the verified roster into your party registry | Your server |
| Match rules, physics, saves and reconnect state | Your game |
Bind a Colyseus lobby
Load peerless-sdk.js and peerless-colyseus.js before your entrypoint. After your lobby connects:
const binding = await PeerlessColyseus.bindLobby({
room: connectedLobby,
onSeat: (seat) => existingSeatConsumer(seat), // resolve only after the match connects
onParty: (party) => renderParty(party),
onError: (error) => showConnectionError(error.message),
});
await Peerless.sessions.queue({ mode: "casual" }); // your Start button
await Peerless.sessions.reportState("match"); // once gameplay begins
// On scene shutdown: binding.dispose();The binding reports lobby readiness, polls every two seconds (also for solo players), retries a failed seat on the next poll and disposes when the lobby leaves. Your seat consumer must reject if the connection fails so the seat can be retried.
Custom transports
Implement SessionAdapter (queue, syncParty, poll, cancel, reconnect, dispose, and optionally host, join, list), then:
Peerless.sessions.bind(adapter);
await Peerless.sessions.ready({ lobbyId });Report real state
Report loading, lobby, queueing, match, reconnecting or closed when your game actually enters that state. Use cancel(), wait() and retry() for queue recovery and reconnect() for your reconnect hook.
Server reconciliation
Verify a fresh credential for every session request and use the signed cohort, never a roster from the browser. When the pending launch disappears (syncParty(null)):
- Remove copied membership only if your registry still belongs to that launch; keep newer game-owned parties.
- Update the roster and leader atomically, and remove empty parties.
- Broadcast the solo roster so the client drops the old leader restriction.
- Keep match squads separate, and never eject a player from an active match.
A credential failure or timeout is an error, not an empty party.
Acceptance checks
| Case | Expected |
|---|---|
| Solo start with no party | Queue works with no leader restriction. |
| Two ready players | One complete group reservation started by the leader. |
| Follower presses Start | A clear leader-only error; no reservation. |
| Seat connection fails once | Error shown; the seat is consumed on a later poll. |
| Credentials expire | Connection denied; no fallback guest identity. |
| Launch outside PEERLESS | Your existing authentication still works. |
The managed Node kit's contract tests and doctor check declarations and kit behavior; they don't certify your game adapter, so run these cases in the compiled game.