# SDK methods

> Install com.clutchcall.transport via UPM, swap UnityTransport for ClutchCallTransport, and the inspector + UTP surface.

The netcode SDK is a **Unity Package Manager (UPM)** package, not a typed
client library. You install it. You add one component in place of
`UnityTransport`. Unity Netcode then drives it through the standard
`INetworkInterface` surface. You configure it in the **inspector** (or in C#).
The public method surface is **UTP's own**. The package forwards it to the
QUIC + MoQT substrate.

## Install (UPM git URL)

Add the package to your Unity project via **Package Manager → Add package from
git URL**:

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

**manifest.json:**
```json
{
  "dependencies": {
    "com.clutchcall.transport": "https://github.com/clutchcall/core-sdk.git?path=unity/com.clutchcall.transport",
    "com.unity.netcode.gameobjects": "1.x"
  }
}
```

> **NOTE:**
> The package depends on `com.unity.transport` (it implements UTP's
> `INetworkInterface`). It works with both **Netcode for GameObjects** and
> **Netcode for Entities**. Pin Netcode to a version compatible with your Unity
> editor. The transport tracks UTP's stable interface, not a specific Netcode
> release.

## Swap the transport

In your network manager prefab, **remove `UnityTransport` and add
`ClutchCallTransport`** as the transport component. Unity Netcode discovers
it the same way that it discovers UTP. No other wiring changes are necessary.

  1. **Select the NetworkManager**
Open the prefab (or scene object) that holds your `NetworkManager`.
  2. **Replace the transport component**
Remove the existing `UnityTransport` component. Add
    `ClutchCallTransport`. If `NetworkManager.NetworkConfig.NetworkTransport`
    referenced the old component, point it at the new component.
  3. **Configure relay host + token**
Set the relay host and an auth token in the inspector. This is the same
    way that you configure a relay endpoint for UTP.

## Component: `ClutchCallTransport`

`ClutchCallTransport` is a `NetworkTransport` (Netcode) that implements UTP's
`INetworkInterface`. It is the only type that you reference directly.
Everything else is standard Netcode.

### Inspector fields

- **`Relay Host`** (`string`, required) — The FirstByte relay endpoint, e.g. `relay.firstbyte.fast`. Players dial the   nearest POP behind this host.

- **`Token`** (`string`, required) — The FirstByte auth token that authorizes the QUIC session. Mint a   short-lived, room-scoped token from your control-plane API. Do not ship a   static secret in the build.

- **`Room Id`** (`string`) — The room / match namespace that this player joins. The host and the clients   of the same match share one `Room Id`.

- **`Server Certificate Hash`** (`string`) — Optional pinned certificate hash for the relay's TLS 1.3 certificate. Use it   in environments that pin the certificate instead of the public trust store.

- **`Max Datagram Size`** (`int`, default `path MTU`) — Upper bound for the unreliable (QUIC datagram) channel. `MaxPayloadSize()`   reads it back. The transport rejects payloads larger than this. It does not   fragment them.

### Configure from C#

You can set the same fields in code before `StartHost` / `StartClient`:

```csharp
using Unity.Netcode;
using FirstByte.Transport; // namespace shipped by com.clutchcall.transport

var nm = GetComponent<NetworkManager>();
var transport = nm.GetComponent<ClutchCallTransport>();

transport.RelayHost = "relay.firstbyte.fast";
transport.Token     = await FetchRoomTokenAsync("duel-42", "alice");
transport.RoomId    = "duel-42";

// Host (authority) vs client is chosen by Netcode, not the transport:
nm.StartHost();   // or nm.StartClient();
```

## UTP method surface

The package implements `INetworkInterface`. Thus the methods that you call are
**Unity Netcode / UTP methods**. The transport forwards each one to the
QUIC + MoQT substrate. These methods matter most for porting:

| UTP / Netcode call | What the transport does |
| ------------------ | ----------------------- |
| `StartHost()` / `StartServer()` | opens the **authority namespace** on the relay |
| `StartClient()` | publishes a **discovery namespace** + per-peer channels, announces to the host |
| `Send(..., NetworkDelivery)` | maps **reliable** delivery to a subgroup stream, **unreliable** to a QUIC datagram |
| `GetCurrentRtt(clientId)` | returns the QUIC transport's **smoothed RTT** in ms |
| `MaxPayloadSize()` | returns the live **max datagram size** for the unreliable lane |
| `DisconnectLocalClient()` / `DisconnectRemoteClient()` | drops the session; the peer leaves every roster via namespace teardown |
| `Shutdown()` | closes the QUIC connection and all tracks |

### NetworkDelivery → lane mapping

Unity's `NetworkDelivery` enum selects the lane:

| `NetworkDelivery` | Lane |
| ----------------- | ---- |
| `Reliable`, `ReliableSequenced`, `ReliableFragmentedSequenced` | MoQT subgroup stream (ordered, guaranteed) |
| `Unreliable`, `UnreliableSequenced` | QUIC datagram (lossy, latest-wins) |

> **TIP:**
> Send high-frequency, latest-wins traffic (transforms, tick snapshots, inputs)
> as `Unreliable`. Keep `Reliable*` for spawns, despawns, and RPCs. This is the
> same discipline as with UTP. The transport only realizes each lane over QUIC
> instead of UDP.

## Events

The transport shows the connection lifecycle through Netcode's standard
callbacks. You do not subscribe to transport-specific events:

| Netcode callback | Fires when |
| ---------------- | ---------- |
| `NetworkManager.OnClientConnectedCallback` | a peer's discovery namespace is announced and accepted |
| `NetworkManager.OnClientDisconnectCallback` | a peer's session drops / namespace tears down |
| `NetworkManager.OnServerStarted` | the authority namespace is open |
| `NetworkManager.OnTransportFailure` | the QUIC session fails unrecoverably |

```csharp
nm.OnClientConnectedCallback += id => Debug.Log($"peer joined: {id}");
nm.OnClientDisconnectCallback += id => Debug.Log($"peer left: {id}");
```

## Non-Unity engines

The Unity component is a thin wrapper over a shared C++ **star session**
(host + N peers with reliable + unreliable + discovery). To integrate a
non-Unity engine, you implement a small set of engine-side hooks: **discovery**,
**RTT**, **max-datagram**, **capture-time telemetry**, and the **datagram-lane
mapping**. You reuse the rest of the session machinery. For a fully typed,
language-native surface (TypeScript / Python / Go / Rust / Java / C#) without
Unity, use the **[Games SDK](/modalities/games/sdk-methods)**. It exposes the
same `state` / `input` / `event` channels directly.

  
    ```ts
    import { Games } from "clutchcall_connect/games";

    const me = new Games({
      relayHost: "relay.firstbyte.fast",
      token:     await fetchRoomToken("duel-42", "alice"),
      roomId:    "duel-42",
      playerId:  "alice",
    });
    me.subscribeState(bytes => render(deserialize(bytes)));
    const input = await me.publishInput();
    ```
  
  
    ```python
    from clutchcall.games import Games

    me = Games(relay_host="relay.firstbyte.fast",
               token=fetch_room_token("duel-42", "alice"),
               room_id="duel-42", player_id="alice")
    me.subscribe_state(lambda b: render(deserialize(b)))
    inp = me.publish_input()
    ```
  

## Related

  - **[Cookbook](/modalities/netcode/cookbook)** — This page has copy-paste snippets for the common porting tasks.
  - **[Games SDK](/modalities/games/sdk-methods)** — This is the typed, non-Unity surface for the same wire model.
