5.7 KiB
OpenSpec Change: network-plugin-session
- Change ID: network-plugin-session
- Package:
@suaveplan/network-plugin-session(new) - Status: PROPOSED
- Type: new-package
- Date: 2026-04-29
Why
The tiered mesh network provides peer-to-peer connectivity, but it has no concept of logical player groupings — sessions. A session is a scope within which peers see each other, exchange state, and interact. Sessions can be nested: a parent session (free-roam open world) contains child sessions (missions, heists, races), which may contain further nested sessions (mission phases, instanced interiors). This is the pattern used by GTA V Online, Destiny, The Division, and many other multiplayer games.
Without session management, every peer in the mesh receives every message from every other peer. Sessions provide:
- Visibility isolation — peers only receive state from peers in their session branch
- Nested hierarchies — missions inside free-roam, phases inside missions
- Session-scoped host nomination — each session elects its own host for state authority
- Capacity enforcement — hard caps per session type (free-roam: 30, mission: 4, race: 8)
- Graceful transitions — joining/leaving sessions without dropping mesh connection
- Parent state inheritance — sub-sessions can optionally receive read-only state from parent (weather, time, world events)
What changes
- ADDED:
SessionPluginclass implementingNetworkPlugin. - ADDED:
SessionManager— maintains the session tree, handles create/destroy/join/leave/move operations. - ADDED:
Session— represents one session node in the tree:id,parentId,hostId,peers[],capacity,rules,state. - ADDED:
SessionRouter— intercepts outgoing messages and filters delivery to peers in the target session scope only. - ADDED:
SessionHostElection— per-session host nomination, independent of mesh Tier 0 host. A peer can be host of multiple sessions. - ADDED:
SessionTransitionManager— handles join/leave/move with state snapshot transfer and forwarding tunnel. - ADDED:
ParentStateBridge— optionally replicates read-only parent state into child sessions (e.g., world time, weather). - ADDED:
SessionCapacityEnforcer— rejects joins when capacity exceeded; can trigger session split. - ADDED:
SessionRegistry— tracks all known sessions in the mesh, their hosts, and their peer counts. - ADDED:
NETWORK_SESSION_CODES— frozen error registry.
Session hierarchy model
Mesh (all connected peers)
└── Session: "freeroam-01" (capacity: 30, host: Peer-A)
├── Peer-A (host)
├── Peer-B
├── Peer-C
├── Peer-D
└── Session: "mission-heist-01" (capacity: 4, host: Peer-B)
├── Peer-B (host)
├── Peer-C
├── Peer-D
└── Session: "phase-drill" (capacity: 2, host: Peer-C)
├── Peer-C (host)
└── Peer-D
Rules:
- A peer can be in exactly one leaf session at a time.
- A peer implicitly belongs to all ancestor sessions (for parent state bridge).
- Messages sent within a session are delivered only to peers in that session or its descendants.
- Messages sent "upward" (to parent) are delivered to the parent session host only.
- Each session has its own host, elected independently via the same governance scoring.
Out of scope
- Game-specific state replication (entities, physics, AI) → gaming packages (
gaming-ecs,gaming-r3f-networking). - Matchmaking (finding which session to join) →
gaming-lobby,gaming-matchmaking. - Party system (persistent friend group) →
gaming-party. - Persistence (saving session state to disk) → future
network-plugin-session-persistence.
Source mapping
This change derives from the session concepts in ../suaveplan/enterprise/game-server.md (§sessions) and ../suaveplan/enterprise/lobby.md, but is a new design — suaveplan has no equivalent network-layer session plugin.
| Requirement | Source lines | Notes |
|---|---|---|
| Session management | game-server/README.md §Sessions |
reworded; suaveplan had session stubs in game-server, not network layer |
| Session host | game-server/README.md §Sessions |
reworded; host per session, not per mesh |
| Capacity limits | lobby/README.md §Capacity |
reworded; per-session, not per-lobby |
Requirements with no source line
| Requirement | Justification |
|---|---|
| Session-scoped message routing | Defensive — prevents free-roam state flooding mission peers |
| Nested session hierarchies | Required for GTA V-style missions-within-free-roam |
| Parent state bridge | Required so mission players still see world time/weather |
| Per-session host election | Required so mission host can be closest to mission peers, not free-roam host |
| Session transition with snapshot | Required for seamless join/leave without mesh disconnect |
Verification approach
src/session/session.spec-conformance.test.ts— pins create, destroy, join, leave, move.src/router/router.spec-conformance.test.ts— pins message delivery scope, upward routing, parent bridge.src/election/election.spec-conformance.test.ts— pins per-session host election, independent of mesh host.src/transition/transition.spec-conformance.test.ts— pins join/leave/move with state snapshot.src/capacity/capacity.spec-conformance.test.ts— pins capacity enforcement, rejection, split trigger.src/registry/session-registry.spec-conformance.test.ts— pins session tree tracking, peer counts.tests/dep-graph.test.ts— pins no direct import of webrtc or gaming packages.
Migration impact
None — additive only.