Open-source lobby / signaling control plane for hosts that use the
recomp-net delay-sync
library. Run your own matchmaking server, or point clients at a community
instance.
It is not part of the recomp-net library tree — peers still exchange
gameplay inputs over recomp-net (LAN UDP or ICE) after lobby handoff.
This server owns:
- WebSocket JSON lobby for MotK / psxrecomp / SNES hosts (docs/WS_LOBBY.md)
- HTTP
/v1game-filtered rooms (docs/LOBBY.md) - Slot and
session_id/ endpoint handoff - ICE signal relay (waiting-room RTT and pre-join mod transfer) and optional short-lived TURN credentials
It does not run the guest sim, never sees gameplay inputs, and does not carry mod-package bytes (those go host↔peer over ICE).
Architecture: docs/HOW_IT_WORKS.md
Coturn / ICE TURN: docs/COTURN.md
Privacy: docs/PRIVACY.md
Secrets: docs/SECURITY.md
| Endpoint | Use |
|---|---|
GET /stats |
JSON live counts (waiting vs in-match) + process totals |
GET /stats/ui |
Browser glance page (auto-refresh) |
GET /metrics |
Prometheus scrape |
Match starts carry the game that was launched:
recomp_match_starts_total{surface="ws|http",game="..."},
recomp_match_players_total{...} (seats summed over starts), and
recomp_matches_active{...} for what is being played right now. Game names come
from clients, so labels are normalized and bounded — with
LOBBY_GAME_ALLOWLIST set only those games get their own label, otherwise the
first METRICS_GAME_LABEL_LIMIT (default 64) do and the rest fold into other.
/stats carries the same breakdown as JSON (ws_match_starts_by_game,
http_match_starts_by_game).
See docs/PRIVACY.md for what is (and is not) recorded.
Clients often default to ws://127.0.0.1:8765 for local bring-up.
cp .env.example .env
# BIND_ADDR=0.0.0.0:8765 is the MotK-friendly default
cargo run
# optional: cargo run -- --debugOverride the client with PSX_NET_LOBBY_URL or SNES_NET_LOBBY_URL if needed.
Leave JWT secrets empty for local no-auth HTTP /v1 mode, or set them for auth
testing.
- Copy
.env.example→.envand setBIND_ADDR. - Optional auth: set
REQUIRE_AUTH=trueandJWT_SECRET_CURRENT(see docs/SECURITY.md). - Optional Coturn for ICE/TURN: run coturn separately, then set
COTURN_*soGET /v1/turn-credentialscan mint short-lived creds. Critical:COTURN_STATIC_AUTH_SECRETmust match coturn’sstatic-auth-secret. Full turnserver example and TLS notes: docs/COTURN.md. - Put TLS at a reverse proxy (e.g. nginx) in front of public lobby
deployments (
wss:///https://). Give coturn its own valid certs for TURNS (tls-listening-port, usually5349) so peers get secure relay globally — see docs/COTURN.md. - Point game clients at
ws://your-host:8765(orwss://…behind TLS).
Never commit .env — it is gitignored.
Public reference lobby (when available):
ws://netplay.retcomm.net:8765.
MIT — see LICENSE.