01 — Setup¶
Before any netcode, you need two things in your Unity project:
- the
com.lattice.netcodepackage (the managed C# binding), and - the native plugin
liblatticefor each platform you build for.
The managed code is useless without the native library — every call ultimately P/Invokes into
liblattice (Linux .so, Windows .dll, macOS .bundle, and so on).
Verified against: bindings/lattice-unity/com.lattice.netcode/package.json,
bindings/lattice-unity/com.lattice.netcode/Plugins/README.md.
Requirements¶
- Unity 2021.3 or newer. The package manifest declares
"unity": "2021.3"; the sample project targets 2022.3 LTS. - A build of
liblatticefor your target platform (see step 2).
1. Add the com.lattice.netcode package¶
The binding is a standard Unity Package Manager (UPM) package. The sample references it by local
file path in Packages/manifest.json:
{
"dependencies": {
"com.lattice.netcode": "file:../../../bindings/lattice-unity/com.lattice.netcode",
"com.unity.modules.imgui": "1.0.0"
}
}
Verified against: samples/unity-tictactoe/Packages/manifest.json.
You have three practical options:
Point manifest.json at the package folder on disk. Best while developing against a checkout of
the repo.
Copy the whole com.lattice.netcode/ folder into your project's Packages/ directory. Unity
imports it as an embedded package.
Add it via Window → Package Manager → + → Add package from git URL if you host the binding in a git repository. (The sample uses the local-path form.)
After Unity resolves the package you will have the Lattice and Lattice.Interop namespaces
available, plus the Lattice.Runtime assembly your own asmdef can reference.
com.lattice.netcode/
├── package.json
├── Runtime/
│ ├── Lattice.Runtime.asmdef reference this from your game asmdef
│ ├── NetworkRunner.cs StartGame / Connect / Tick / Spawn / Rpc / SendEvent …
│ ├── NetworkObject.cs managed view of a replicated object
│ ├── NetworkTypeSchema.cs type registration (FieldSpec / RegisterType)
│ ├── Attributes.cs [Networked] / [Rpc] / [OnChanged]
│ └── Interop/LatticeNative.cs the P/Invoke surface (public ABI only)
├── Editor/… prefab-catalog tooling
└── Plugins/… native lib per platform
Verified against: bindings/lattice-unity/README.md (Layout section).
Reference the runtime assembly¶
Your gameplay scripts live in their own assembly definition. Reference Lattice.Runtime so they
can see NetworkRunner and friends — exactly as the sample's asmdef does:
TicTacToe.Sample.asmdef → references Lattice.Runtime
Verified against: samples/unity-tictactoe/README.md (project layout) and
samples/unity-tictactoe/Assets/TicTacToe/Scripts/TicTacToe.Sample.asmdef.
2. Install the native plugin per platform¶
Each platform's build of the core goes under Plugins/<Platform>/<arch>/. Unity's per-plugin
import settings restrict each binary to its target. The DllImport name is "lattice", which Unity
resolves to the correct file for the running platform.
Verified against: bindings/lattice-unity/com.lattice.netcode/Runtime/Interop/LatticeNative.cs:231
(public const string Lib = "lattice";).
| Platform | File in Plugins/… |
How it's produced |
|---|---|---|
| Linux x86_64 | Linux/x86_64/liblattice.so |
native-snapshot/build.sh — checked in, headless-verified |
| Windows x86_64 | Windows/x86_64/lattice.dll |
core build-windows.sh — checked in |
| macOS (universal) | macOS/lattice.bundle |
core macOS build (arm64 + x86_64) |
| Android arm64 | Android/arm64-v8a/liblattice.so |
NDK build |
| iOS | iOS/liblattice.a |
static, IL2CPP |
Verified against: bindings/lattice-unity/com.lattice.netcode/Plugins/README.md.
Only Linux and Windows binaries are checked in
In the repository, only the Linux .so and Windows .dll are present under Plugins/.
The macOS/, Android/, and iOS/ folders exist as import-setting placeholders (.meta
files) but you must build those binaries yourself from the core's cross-platform build (task
CP1) and drop them into the matching folder. The binding code is identical across platforms
because it targets the stable C ABI.
Verified against: Plugins/ directory listing —
Plugins/Linux/x86_64/liblattice.so and Plugins/Windows/x86_64/lattice.dll are the only
binaries; other platform folders contain only .meta files.
Building the Linux .so yourself¶
If you're working from the repo and the .so is missing, build it from the binding's decoupled
snapshot of the core:
Verified against: samples/unity-tictactoe/headless/run.sh:11-15 and
bindings/lattice-unity/README.md ("Building & running").
Set the plugin import settings¶
In the Unity editor, select each native file under Plugins/ and, in the Inspector's Plugin
import settings, tick only the platform/architecture it belongs to (e.g. the .so → Linux
x86_64 only). This prevents Unity from trying to load the wrong binary on the wrong platform.
This step needs the editor
Plugin import settings are editor-only metadata. The headless verification path (below) resolves the library a different way, so it doesn't exercise this — but a real Unity build does.
3. Verify it loads¶
There is no editor in the reference environment, so the binding is proven by a headless .NET
harness that points DllImport("lattice") at the built .so via a custom resolver and drives a
real two-player match. You can run it to confirm your native build works before touching Unity:
cd samples/unity-tictactoe/headless
bash run.sh # loopback transport
bash run.sh udp # real localhost UDP
A healthy run ends with:
Verified against: samples/unity-tictactoe/headless/run.sh,
samples/unity-tictactoe/headless/Program.cs, and samples/unity-tictactoe/README.md
("Latest result").
In Unity itself, the native library is resolved automatically by the plugin import settings — you
don't register a resolver. If a call throws DllNotFoundException, the plugin isn't present (or
isn't enabled) for your current platform.
Next: 02 — Your first runner, where you create a NetworkRunner and start
a host and a client.