Not translated yet — showing English.
Under the hood: transport & the hub
An architecture reference, not a surface you call. Nothing on this page appears in the API you write against: there is no socket, channel, envelope or retry for you to manage. Core Concepts names the stack; the mechanism lives only here, so that an architect can check what the SDK does with a dropped connection, a disabled module or a message that must arrive exactly once.
The layer stack
Five layers, top down: user space, modules, primitives, the hub, and the transport adapters under it. The top two are user space; everything below is the SDK's own business.
- User space is your code. It sees modules, and the vocabulary stops there.
- Modules are the applied layer: rooms, matchmaking, inventory, leaderboards. They form a graph, not a tree, which is what the hub has to resolve when one of them is switched off (Inheritance & Composition is the shape itself).
- Primitives are the first implementation everything references: data, events, RPC, groups. A module is a named assembly of primitives plus its own rules.
- The hub is the controller: dependency injection, module mounting, the user session, state recovery, message quality of service, and routing each inbound message to the module mounted for it.
- Transports are adapters onto a protocol. Several exist; the hub treats them alike.
Transports are adapters
There will be more than one transport, and they differ in ways that would otherwise leak into every module:
| Axis | Range |
|---|---|
| Shape | message-driven or request-driven |
| Channels | single-channel or multi-channel |
| State | with connection state recovery, or without |
| Protocol | TCP or UDP |
Today that means WebSocket, the PlayServ UDP transport, and plain HTTP. Each one is an adapter behind its own implementation details, and each exposes the same thing upward: a transport session. The hub holds a session, never a socket, so nothing above the adapter reasons about the network interface.
One transport session at a time
One transport channel and one transport session at a time. Running a backend transport for leaderboards while a master-client transport carries the live session is out of scope, and no API signature depends on several channels being open. Until a later version says otherwise, the single-session shape is the contract.
The hub hides the transport completely
Downward, the hub speaks the transport interface. Upward, it offers state, events and the user session. Module code and game code are equally unable to tell which transport is underneath, or how the hub batched a call, or what it did to get back to a consistent state after a gap.
- The user session belongs to the hub, not to a module. Reconnect, resume and state recovery happen once, at the hub, for everything mounted on it.
- Message QoS belongs to the hub, not to the data module. Envelopes, retries and packing are hub mechanics.
Message QoS: three levels
A module declares only the delivery guarantee it needs:
| Level | Meaning |
|---|---|
at least once | redelivered until acknowledged; the receiver tolerates duplicates |
at most once | sent once, never retried; loss is acceptable |
exactly once | deduplicated and acknowledged; the expensive one, used where it is required |
How the guarantee is met is the hub's concern, not the module's and not yours.
DI, mounting, and disabled modules
The hub instantiates modules and mounts them — at the root or in a namespace — resolving each module's dependencies on the primitives and on other modules. A build that does not need a module does not mount it. Mounting is namespaced, and a second module claiming an already-occupied mount point is rejected at mount time — composition fails there, never at the first call into it.
Because modules form a graph, switching one off has consequences downstream, and the hub takes exactly one of two paths:
- Disable the dependent chain. Every module that needs the missing one is switched off too, and its interfaces are absent rather than failing.
- Declare degraded functionality. The dependents stay mounted and announce what they can no longer do.
There is no third path: a mounted module never quietly drops the operations it can no longer perform, so a disabled dependency is always observable.
What stays above the line
Every promise on the module pages is kept above it: an entity mutation is the network operation, a hook is a typed function, a join is one call. The stack's names may reach you — Core Concepts points here — but nothing below the line is a call your code makes. Those layers exist so the promises above survive a transport change.
What you will meet — the delivery context your handlers run on, when a handle ends, and the in-memory implementation you test against — is one page up: Threads, Lifetime and Testing.