Unity SDK
Complete guide to integrating the Tez realtime engine into your Unity project. Native C# bindings, automatic reconnects, and cluster-aware room routing.
Overview
The Tez Unity SDK is a native C# package that wraps the high-performance Rust client library via FFI. It provides a thread-safe API with automatic main-thread event delivery, so you can focus on gameplay without worrying about networking internals.
The SDK handles the full lifecycle: UDP handshake, room joins, delta-compressed state synchronization, reliable actions, chat, custom events, automatic reconnection with exponential backoff, and transparent cluster redirects when your room lives on a different node.
Installation
Quick Start
Architecture
TezEventDispatcher (MonoBehaviour)
Polls the native client once per frame in Update(). Raises C# events on the Unity main thread. Add one to any GameObject.
TezClient (C# wrapper)
High-level API wrapping the native FFI handle. Thread-safe command enqueue, event draining, and snapshot mirror queries.
TezNative (P/Invoke)
Raw C ABI bindings matching the Rust #[repr(C)] structs byte-for-byte. Fully blittable — no marshalling overhead.
tez_client.dll (Native)
Pre-compiled native library. One dedicated IO thread per client handles UDP, heartbeats, reconnection, and cluster redirects.
API Reference
TezClient
High-level client. Thread-safe; all methods are cheap lock-protected enqueues.
Connect(addr, token?, room?)UnreliableCreate a client and start connecting. Non-blocking. Progress arrives via events.
JoinRoom(name)ReliableJoin or switch to a named room. Survives reconnects and cluster redirects.
LeaveRoom()ReliableLeave the current room. Stops re-joining after reconnects.
SendInput(vx, vy, facing)UnreliableUnreliable movement input. Rate-limited by server tick rate (default 30Hz).
SendAction(kind, target)ReliableReliable gameplay action. Target 0 broadcasts to the room; non-zero targets a specific peer.
SendChat(text)ReliableReliable chat message delivered to all room members (sender excluded).
SendCustom(kind, data)ReliableReliable host-defined event with binary payload (max 256 bytes). Fully extensible.
Players(sink)UnreliableCopy the locally mirrored room state. Each entry has peer, pos, vel, facing.
PeerIdUnreliableOwn peer ID assigned by the server (0 while not connected).
StateUnreliableCurrent connection phase (0-5): Disconnected → Handshaking → Joining → Connected.
TezEventDispatcher
MonoBehaviour bridge. Polls the native client in Update() and raises C# events on the main thread.
Connected(peerId, tickRate)Handshake accepted. You have a peer ID and know the server tick rate.
RoomJoined(roomId)Room membership confirmed. You can now send input and receive state deltas.
Redirected(addr)Cluster redirect in flight. Automatic — the client rebinds and re-handshakes.
Disconnected(reason)Session ended. Reason: 0 = voluntary stop, 1 = timeout, 2 = redirect loop.
Reconnecting(attempt)Reconnect attempt started with exponential backoff.
PlayerJoined(peer, room)A new player entered your room.
PlayerLeft(peer, room, reason)A player left your room. Reason: 0 = voluntary, 1 = timeout.
ActionReceived(peer, kind, target)A reliable gameplay action from another player.
ChatReceived(peer, text)A chat message from another room member.
CustomReceived(peer, kind, payload)A host-defined custom event with binary data.
RttMeasured(microseconds)Heartbeat round-trip time from the latest Pong.
TezPlayer (Snapshot Mirror)
One entry per player visible in the current room. Updated every server tick.
| Field | Type | Description |
|---|---|---|
| peer | uint | Unique peer ID assigned by the server |
| x | float | Position X (authoritative, from server) |
| y | float | Position Y (authoritative, from server) |
| vx | float | Velocity X (last submitted input) |
| vy | float | Velocity Y (last submitted input) |
| facing | float | Facing angle in radians |
Connection Lifecycle
Disconnected
Phase 0No active connection. The client is idle or has been stopped.
Handshaking
Phase 1Hello packets are being sent. Waiting for the server to respond with Welcome.
Joining
Phase 2Handshake complete. A JoinRoom request is pending.
Connected
Phase 3Fully connected in a room. Input, actions, and state sync are active.
Redirecting
Phase 4Cluster redirect received. Rebinding to the owning node.
Reconnecting
Phase 5Connection lost. Exponential backoff reconnect in progress.
Authentication
Servers started with --auth-key <hex> require a 48-byte HMAC-SHA256 token for each connection. The token format is:
Your backend mints tokens and passes them to TezClient.Connect(addr, token, room). Without an auth key (dev/LAN mode), any token — including none — is accepted.
Code Examples
Features
IL2CPP & Mono
Works with both scripting backends. Fully blittable structs — zero marshalling overhead.
Main-Thread Events
All callbacks fire on the Unity main thread via Update(). No thread-safety headaches.
Auto Reconnect
Exponential backoff on timeout. Room is remembered and re-joined after reconnect.
Cluster Redirects
Transparent room routing across nodes. The client follows redirects automatically.
Delta Compression
Only changed fields cross the wire. Position, velocity, and facing are diffed per tick.
3 Included Samples
Movement, Actions & Chat, and Snapshot Mirror samples to get started quickly.
Server Configuration
--bindUDP address to listen on (default: 0.0.0.0:9000)
--tick-rateServer simulation ticks per second (default: 30)
--room-capacityMaximum players per room (default: 64)
--peer-timeout-secsEvict peers after this much silence (default: 10s)
--auth-keyShared secret for HMAC handshake tokens (empty = open dev mode)
--max-sessionsHard cap on concurrent sessions (default: 100,000)
--dtlsOptional DTLS endpoint for encrypted connections
--metricsOptional Prometheus /metrics endpoint for monitoring
Ready to build?
Tez is currently free. Get your server address and start building multiplayer features in Unity today.