NetworkManager in place of
UnityTransport supports two connection modes. One field selects the
mode:
Choosing Direct or Relay
Pick Direct when you control the host’s network path: LAN play,
a port-forwarded host, or a dedicated server. Pick Relay when the
host is an ordinary player’s machine behind NAT, or when you do not want
players to learn each other’s addresses.
Transport fields by mode
The high-altitude integration (L-HI, Netcode for GameObjects) configures aClutchCallTransport component. The low-altitude integration (L-LO,
raw NetworkDriver / Netcode for Entities) configures a
ClutchCallNetworkInterface struct.
In L-HI, after assigning the transport to
nm.NetworkConfig.NetworkTransport, you still call nm.StartHost() or
nm.StartClient() as usual. In L-LO, you pass the configured interface
to NetworkDriver.Create(iface).
Reachability requirements for Direct
Direct mode has no allocation step and no service in the middle. The host binds a QUIC/UDP listener and peers dial it:Address:Port
over UDP — QUIC is UDP, not TCP, so a TCP-only port forward or
load-balancer rule will not carry it. In practice that means one of:
- the host and clients are on the same LAN;
- the host’s router forwards the UDP port to the host machine;
- the host is a dedicated server with a routable address and the UDP port open inbound.
Creating an allocation and sharing a join code
Relay mode starts with an allocation, created from the console’s Allocations screen. The allocation represents the session on the relay fleet and yields a short join code. The host shares that join code with its players through whatever channel your game already uses — a lobby, an invite link, matchmaking metadata. The transport does not distribute join codes for you. You can also create an allocation from code. The host mints one, and each player redeems the join code. Do this before you start theNetworkManager, because the endpoint and the token must be in place
first:
Redeeming a join code: endpoint and token
A join code is not an address.JoinAsync redeems the code and gets back
three things:
- A nearest-relay endpoint. Endpoint selection is geo-DNS based, so two players in different regions redeeming the same code can land on different relay addresses for the same session. You do not hardcode a relay hostname.
- A JWKS-verified token. The relay checks this token on the connection. Your game code never constructs it; redemption is what produces it.
- The session namespace, assigned by the platform. See Session namespace below.
NetworkManager.
This is why Relay mode needs no Address or Port — supplying them has
no effect once ConnectionType is Relay. Conversely, a
RelayJoinCode is meaningless in Direct mode.
For background on how relay tokens are scoped and verified, see
Authentication.
Session namespace and max players
SessionNamespace is the session’s identity on the platform. It is
path-shaped:
my-session
and you get arena/<your-org-id>/my-session back.
This is what keeps two customers apart. Both can ask for the same session
name and still get two different namespaces, so neither can reach the
other’s tracks.
AllocateAsync, JoinAsync and ApplyAllocation all write the assigned
value onto the transport for you. Read it back from the allocation if you
need it:
SessionNamespace yourself. Use the same value on every peer. It applies
at both altitudes — the L-LO ClutchCallNetworkInterface takes the same
field alongside Role.
MaxPlayers is the session’s player ceiling, set on the transport in the
L-HI integration. The quickstart’s example value is 16; use the number
your game design calls for.
Path MTU per mode
The transport advertisesnet_max_datagram as the path MTU for the mode
in use:
Relay is lower because the relay path carries additional framing around
your payload. Size any single unreliable message to fit the smaller
of the two if you intend to support both modes from one build —
otherwise a snapshot that fits in a LAN Direct session will not fit once
the same code runs through the relay.
Deliveries that map onto QUIC reliable streams are not bounded by this
number in the same way; QUIC segments them for you. The ceiling matters
for the datagram-carried QoS levels. See the QoS / channel mapping table
on the Netcode quickstart screen for which
NetworkDelivery value lands
on which QUIC carrier.
Related
- Modalities overview
- Authentication — relay tokens and namespace scope
- Telemetry — QUIC handshake and transport metrics