Architecture
This document describes the recommended production architecture for FigNet:
- Control plane over WSS (TLS required) for authentication, matchmaking, room discovery, and issuing join tickets.
- Data plane over RUDP (ENet/LiteNetLib-style) for high-rate in-room gameplay traffic.
It is intentionally transport-agnostic and focuses on the system shape and the security boundaries.
See also Configuration for the configuration schema and recommended settings to run this architecture.
Architecture at a glance
Components
- Client
- Control Transport: WebSocket Secure (
wss) for login + lobby + room join negotiation. - Game Transport: RUDP connection (ENet/LiteNetLib) used only after receiving a server-issued join ticket.
- Control Transport: WebSocket Secure (
- Gateway/Lobby Server (Control Plane)
- Terminates TLS (WSS).
- Authenticates the user/player.
- Creates rooms / assigns servers.
- Issues JoinTickets for RUDP.
- Room/Game Server (Data Plane)
- Accepts RUDP connects.
- Validates JoinTickets.
- Runs authoritative gameplay or relays, depending on your game model.
Diagram (control + data plane)
flowchart LR
C[Client] -->|WSS (TLS required)| L[Gateway/Lobby]
L -->|JoinTicket + room endpoint| C
C -->|RUDP + JoinTicket| R[Room/Game Server]
C -->|Optional: keep WSS open for control| L
Node diagrams
Server Node Architecture Diagram

Client Node Architecture Diagram

Connection lifecycle
State machine
stateDiagram-v2
[*] --> WSS_Connected
WSS_Connected --> HelloDone: HELLO/HELLO_ACK
HelloDone --> Authed: AUTH/AUTH_OK
Authed --> LobbyReady
LobbyReady --> TicketIssued: JOIN_ROOM_RESPONSE(ticket)
TicketIssued --> RUDP_Connected: RUDP transport connect
RUDP_Connected --> InRoom: RUDP_JOIN_OK
WSS_Connected --> Disconnected
HelloDone --> Disconnected
Authed --> Disconnected
LobbyReady --> Disconnected
TicketIssued --> Disconnected
RUDP_Connected --> Disconnected
InRoom --> Disconnected
Sequence diagram
sequenceDiagram
autonumber
participant C as Client
participant L as Lobby (WSS/TLS)
participant R as Room Server (RUDP)
C->>L: WSS Connect (TLS required)
C->>L: HELLO (protocolVersion, capabilities, appName)
L-->>C: HELLO_ACK (selectedVersion, serverCaps, limits)
C->>L: AUTH (token / platform ticket / guest)
L-->>C: AUTH_OK (sessionId, userId, expiresAt, claims?)
C->>L: JOIN_ROOM_REQUEST (roomId or matchmaking params)
L-->>C: JOIN_ROOM_RESPONSE (roomEndpoint, joinTicket, ttl)
C->>R: RUDP Connect (transport handshake)
C->>R: RUDP_JOIN (joinTicket, clientNonce)
R-->>C: RUDP_JOIN_OK (peerId, roomSessionId, serverNonce)
Note over C,R: Gameplay traffic begins (EntityUpdate, RoomEvent, etc.)
Security model
TLS requirement
FigNet assumes:
- All control-plane connections use WSS with TLS required.
- All user credentials/tokens are exchanged only on the control plane.
This keeps the most sensitive operations on a transport with well-understood security properties.
RUDP admission control
RUDP traffic is authorized by a JoinTicket minted by the Lobby over TLS.
- The Room Server must validate the ticket before accepting gameplay messages.
- The ticket should be short-lived and one-time-use.
Why not encrypt gameplay traffic?
You can add encryption later, but the minimal secure design is:
- Authenticate + mint ticket over TLS.
- Validate ticket for RUDP admission.
- Use the RUDP library's reliability/ordering features for transport properties.
If you later want confidentiality on RUDP, add an AEAD layer negotiated via the ticket or a post-join key exchange.
Operational guidance
Recommended timeouts and limits
- Handshake timeout: 5 seconds (existing server behavior already disconnects unregistered peers after a short grace period).
- JoinTicket TTL: 10-30 seconds.
- Max outstanding callbacks per connection: configurable; default low (e.g., 64) to prevent abuse.
- Max frame size:
- WSS: enforce a max payload size at the websocket layer.
- RUDP: enforce max packet size per channel.
Reconnect strategy (recommended)
- WSS control plane
- Reconnect and re-authenticate; obtain new tickets as needed.
- RUDP data plane
- Client requests "rejoin" over WSS and obtains a fresh ticket.
- Room server can optionally accept a reconnect token for state recovery.
Module boundaries
- Core should own:
- envelope format
- version negotiation
- authentication handshake primitives
- ticket issuance/validation interface
- Modules should own:
- gameplay semantics (rooms, entities, voice)
- per-message authorization rules (e.g., ownership, roles)