# Netcode (Unity) — Cookbook

> Task snippets for the Unity transport: install, swap UnityTransport, pick lanes, read RTT, run headless, mint tokens.

Short, copy-pasteable answers to the questions that come up porting a Unity
Netcode project onto ClutchCall. Each assumes the
`com.clutchcall.transport` package is installed and a `NetworkManager` is
in the scene. For the full surface see
[SDK methods](/modalities/netcode/sdk-methods).

## How do I install the package?

Add it via **Package Manager → Add package from git URL**:

```text
https://github.com/clutchcall/core-sdk.git?path=unity/com.clutchcall.transport
```

## How do I swap `UnityTransport` for ClutchCall?

Remove the `UnityTransport` component from the `NetworkManager` and add
`ClutchCallTransport`, then point Netcode at it.

```csharp
var nm = GetComponent<NetworkManager>();
nm.NetworkConfig.NetworkTransport = nm.GetComponent<ClutchCallTransport>();
```

## How do I configure the relay + token in code?

Set the inspector fields from C# before starting the session.

```csharp
var t = nm.GetComponent<ClutchCallTransport>();
t.RelayHost = "relay.clutchcall.dev";
t.Token     = await FetchRoomTokenAsync("duel-42", "alice");
t.RoomId    = "duel-42";
```

## How do I start a host vs a client?

Host/server vs client is chosen by **Netcode**, not the transport — the same
calls you used with UTP.

```csharp
nm.StartHost();    // authority: opens the room's authority namespace
// or
nm.StartClient();  // joins: announces a discovery namespace to the host
```

## How do I send on the unreliable (datagram) lane?

Pick `Unreliable` delivery for high-frequency, latest-wins traffic. It rides a
single QUIC datagram — no head-of-line blocking, no retransmit.

```csharp
// In a NetworkBehaviour RPC:
[Rpc(SendTo.Server, Delivery = RpcDelivery.Unreliable)]
void SubmitInputRpc(InputPayload input) { /* ... */ }
```

## How do I send a reliable, must-arrive message?

Use `Reliable*` delivery for spawns, despawns, and control RPCs. It rides a MoQT
subgroup stream — ordered and guaranteed.

```csharp
[Rpc(SendTo.ClientsAndHost, Delivery = RpcDelivery.Reliable)]
void AnnounceWinnerRpc(ulong clientId) { /* ... */ }
```

## How do I read the current RTT to a peer?

`GetCurrentRtt` returns the QUIC transport's smoothed RTT in milliseconds.

```csharp
var transport = nm.GetComponent<ClutchCallTransport>();
double rttMs = transport.GetCurrentRtt(clientId);
```

## How big can an unreliable payload be?

Query the live max datagram size and keep latest-wins deltas under it; spill
anything larger onto a reliable RPC.

```csharp
int maxBytes = nm.GetComponent<ClutchCallTransport>().MaxPayloadSize();
if (snapshot.Length <= maxBytes) SendUnreliable(snapshot);
else                             SendReliableChunked(snapshot);
```

## How do I react to players joining and leaving?

Use Netcode's standard callbacks — peer join/leave is surfaced through them, not
a transport-specific event.

```csharp
nm.OnClientConnectedCallback  += id => roster.Add(id);
nm.OnClientDisconnectCallback += id => roster.Remove(id);
```

## How do I mint a room-scoped token?

Mint a short-lived token from your control-plane API and hand it to the
transport — don't bake a static secret into the build.

```csharp
async Task<string> FetchRoomTokenAsync(string room, string player) {
    var resp = await http.PostAsJsonAsync(
        "https://api.clutchcall.dev/rooms/token",
        new { room, player });
    return (await resp.Content.ReadFromJsonAsync<TokenResp>()).Token;
}
```

## How do I run a headless dedicated server?

Build a **dedicated-server (or headless) player** and start the host on launch.
Editor batch mode does not drive Netcode — you need a built player.

```csharp
void Start() {
    if (Application.isBatchMode) {
        nm.GetComponent<ClutchCallTransport>().RoomId = Args.Get("room");
        nm.StartServer();
    }
}
```

## How do I run the ECS racing sample over ClutchCall?

Open the
[ECS-Network-Racing-Sample](https://github.com/Unity-Technologies/ECS-Network-Racing-Sample),
swap `UnityTransport` for `ClutchCallTransport` on its `NetworkManager`, set
the relay host + token, and build a player. The full walkthrough is in
[Recipes](/modalities/netcode/recipes).

## How do I pin the relay's TLS certificate?

Set the certificate hash in the inspector (or in code) for environments that pin
instead of relying on the public trust store.

```csharp
nm.GetComponent<ClutchCallTransport>().ServerCertificateHash = pinnedHash;
```

## How do I handle a dropped connection?

The QUIC session reconnects under the hood. Watch `OnTransportFailure` for the
unrecoverable case and re-enter matchmaking.

```csharp
nm.OnTransportFailure += () => {
    Debug.LogWarning("transport failed; returning to lobby");
    SceneManager.LoadScene("Lobby");
};
```

## Related

  - **[SDK methods](/modalities/netcode/sdk-methods)** — The component, inspector fields, and UTP surface.
  - **[Recipes](/modalities/netcode/recipes)** — Worked end-to-end examples.
