Skip to main content

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.
  • 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

Server node architecture diagram

Client 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

  • 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.
  • 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)