# Cookbook

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

This page has short, copy-pasteable answers to common questions about porting
a Unity Netcode project onto FirstByte. Each answer assumes that the
`com.clutchcall.transport` package is installed, and that a
`NetworkManager` is in the scene. For the full surface, see
[SDK methods](/modalities/netcode/sdk-methods).

## How do I install the package?

Add the package 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 FirstByte?

Remove the `UnityTransport` component from the `NetworkManager`. 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 you start the session.

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

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

**Netcode** chooses host/server vs client, not the transport. Use the same
calls that 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 travels
in a single QUIC datagram. There is no head-of-line blocking and 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 travels on
a MoQT subgroup stream. Delivery is 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. Keep latest-wins deltas under it. Send
anything larger on 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. They show peer join/leave. There is no
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. Give the token to the
transport. Do not bake a static secret into the build.

```csharp
async Task<string> FetchRoomTokenAsync(string room, string player) {
    var resp = await http.PostAsJsonAsync(
        "https://api.firstbyte.fast/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**. 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 FirstByte?

1. Open the
   [ECS-Network-Racing-Sample](https://github.com/Unity-Technologies/ECS-Network-Racing-Sample).
2. Swap `UnityTransport` for `ClutchCallTransport` on its `NetworkManager`.
3. Set the relay host + token.
4. 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). Use this in
environments that pin the certificate instead of the public trust store.

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

## How do I handle a dropped connection?

The QUIC session reconnects internally. Watch `OnTransportFailure` for the
unrecoverable case. Then re-enter matchmaking.

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

## Related

  - **[SDK methods](/modalities/netcode/sdk-methods)** — This page covers the component, the inspector fields, and the UTP surface.
  - **[Recipes](/modalities/netcode/recipes)** — This page has worked end-to-end examples.
