Unity tutorial — build multiplayer with Lattice¶
A complete, hands-on guide to the Lattice Unity binding (com.lattice.netcode): a thin,
idiomatic layer over the Lattice C core (liblattice) reached through P/Invoke. You get a
NetworkRunner, replicated NetworkObjects, RPCs, custom events, and authority transfer — all
driven from Unity's FixedUpdate.
This tutorial teaches the real API that actually runs, grounded in code you can read in the repository. Every method name, signature, and snippet is taken from the shipped binding and the working sample; where something is a stub or only partially wired, we say so plainly.
Two Lattice deployment paths
Lattice supports a self-hosted / P2P path (you run the authoritative server or a player hosts) and a managed path (matchmaking via the control plane). This tutorial focuses on the Unity client and the self-hosted / listen-server flow first — that is the path the working sample exercises end to end — then shows the control-plane login and matchmaking flow and states exactly how far it is wired. See Getting Started for the server-side picture.
What you'll build¶
By the end you will have rebuilt the repository's networked tic-tac-toe + chat sample from
first principles: a host that is both the authoritative server and player X, a client that connects
and plays O, a replicated board object, host-validated moves, and a chat channel — all over the
real NetworkRunner.
The sample lives at samples/unity-tictactoe/ and is verified headlessly (no editor) by a .NET
harness that drives a full two-player match over the real native library — so the netcode you learn
here is proven, not hypothetical.
Chapters¶
| # | Chapter | What it covers |
|---|---|---|
| 00 | This page | Overview and orientation |
| 01 | Setup | Add com.lattice.netcode; the native plugin per platform |
| 02 | Your first runner | NetworkRunner: host vs client, the FixedUpdate tick, Connect |
| 03 | Logging in | auth /login + /guest → an access token; the social-client SDK |
| 04 | Lobbies & matchmaking | The Matchmaker helper: one-call JoinAsync, parties, errors; the raw /matchmake → /resolve routes |
| 05 | Networked objects | Register types, Spawn, replicated state, OnSpawned/OnStateUpdated |
| 06 | RPCs | Rpc + targets + reliability |
| 07 | Events & presence | SendEvent/OnEvent, the object-less message channel |
| 08 | Authority | Host-authoritative validation; RequestAuthority/OnAuthorityChanged |
| 09 | Full walkthrough | Tic-tac-toe end to end, referencing the real sample files |
How to read this¶
Chapters build on each other. If you are brand new, read them in order. If you already know a Fusion-style netcode API, skim 02 and jump to 05.
Do not use the Fusion-compat StartGame(StartGameArgs) overload
The binding ships a Photon-Fusion compatibility layer so ported Fusion projects compile. Its
NetworkRunner.StartGame(StartGameArgs) overload, SessionInfo, LobbyInfo, and
JoinSessionLobby are compile-stubs that do not connect — they exist only so ported code
builds. This tutorial teaches the real StartGame(LatticeGameMode, port) + Connect(...)
path that the sample actually uses.
Verified against: bindings/lattice-unity/com.lattice.netcode/Runtime/FusionCompat/NetworkRunner.Simulation.cs:181.
Conventions¶
csharpblocks are real or faithfully-adapted binding code.- Verified against: notes cite the source file (and line) a claim is grounded in.
- Where a feature is a stub or only partially wired, a warning admonition calls it out.