How it works
With listen hosting, the elected player's browser is the match host. PEERLESS runs admission, matchmaking, signaling and TURN relaying when direct connections fail. Matches hold up to 16 players. Persistent worlds need dedicated or Forge hosting instead.
Declare hosting.mode: "listen" in your multiplayer capabilities (with networking: peerless_rooms) and include peerless-webrtc.js beside the SDK. The Three.js starter includes a runnable listen.html example.
Connect
const context = await Peerless.init();
if (context.mode === "standalone") {
startLocalGame();
} else {
const transport = await Peerless.sessions.listen({
onState: (state) =>
state.phase === "active" && state.hostConnected ? resumeSimulation() : pauseSimulation(),
onData: ({ from, epoch, data }) => validateAndApply(from, epoch, data),
onError: (error) => showConnectionError(error.message),
onMigration: async ({ epoch, isHost }) => {
pauseSimulation();
await restoreAcknowledgedSnapshot({ epoch, isHost }); // resolving lets the new host resume
},
});
const lobby = await Peerless.sessions.host({ visibility: "private" });
showMatchCode(lobby.code); // others: Peerless.sessions.join({ code })
await transport.ready(); // this player's game is ready
await transport.start(); // lobby owner, once everyone is ready
await transport.send({ type: "input", input: currentInput() });
// Leaving: await transport.leave(); Peerless.sessions.dispose();
}Messages
transport.send(data, playerId) targets one peer. Without a target, the host broadcasts and other players send to the host. Messages are limited to 64 KiB. Validate every command: membership and a peer ID don't make a move or score trustworthy.
Host election and migration
After start, PEERLESS chooses the host with the lowest recent group latency, then bandwidth, then optional device reports, avoiding constrained devices when it can. If the host leaves, a new host is elected and your onMigration hook restores the last acknowledged snapshot. Migration hooks do not transfer match state for you.
Discovery and queues
sessions.list({ limit, after }) returns public lobbies with a nextCursor. sessions.queue({ mode }) reserves a ready party from its launch intent; solo players can queue on their own. transport.stats() shows candidate types, bytes and round-trip times without exposing IP addresses.