Godot tutorial — build multiplayer with Lattice¶
A complete, hands-on guide to the Lattice Godot binding (bindings/lattice-godot/): a native
GDExtension that registers two Godot 4 nodes — LatticeRunner and LatticeSync — over the
Lattice C core (liblattice). You get a runner you drive from _physics_process, replicated objects,
RPCs, custom events, and authority checks — all from GDScript (and, on the Godot .NET build, from
C#).
This tutorial teaches the real API that actually runs, grounded in code you can read in the repository. Every method name, signal, 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 / local path (a player hosts a listen-server, others join) and a managed path (matchmaking via the control plane). This tutorial focuses on the Godot client and the local listen-server flow first — that is the path the working sample exercises — then shows the control-plane login and matchmaking flow and states exactly how far it is wired for Godot. 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 joins and plays O,
a replicated board object, host-validated moves, and a chat channel — all over the real
LatticeRunner / LatticeSync nodes.
The sample lives at samples/godot-tictactoe/. Its netcode is verified headlessly (no editor) by a
C++ harness that drives a full two-player match over the real native library — so the netcode you learn
here is proven, not hypothetical.
Verified against: samples/godot-tictactoe/README.md (project layout, "What is verified HEADLESSLY"),
samples/godot-tictactoe/harness/ttt_harness.cpp.
Chapters¶
| # | Chapter | What it covers |
|---|---|---|
| 00 | This page | Overview and orientation |
| 01 | Setup | Add the lattice GDExtension to a Godot 4 project; the native binaries per platform |
| 02 | Your first runner | LatticeRunner: host vs client, the _physics_process tick, the signals |
| 03 | Logging in | auth /login + /guest → an access token, called from Godot with HTTPRequest |
| 04 | Lobbies & matchmaking | director /matchmake → /resolve; verified wiring status (honest) |
| 05 | Networked objects | register_fields / replicate, spawn, replicated state, spawned/state_updated |
| 06 | RPCs | send_rpc + targets + reliability |
| 07 | Events & presence | send_event / the event signal, the object-less message channel |
| 08 | Authority | Host-authoritative validation; has_authority / request_authority |
| 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 node-and-signal netcode API, skim 02 and jump to 05.
This binding is snake_case + Godot signals — not the Unity C# names
If you have read the Unity tutorial, the concepts map across, but the names do
not. The Godot binding follows Godot conventions: methods are snake_case (start_game,
send_rpc, has_authority), and you subscribe to signals (connected, spawned,
state_updated), not C# events. There is no Fusion-compat layer in the Godot binding — every
method listed here is a real one.
Verified against: bindings/lattice-godot/src/lattice_runner.cpp:27-96,
bindings/lattice-godot/src/lattice_sync.cpp:59-94.
An honest note on what runs where¶
The binding is split into two layers, deliberately:
- The node layer (
LatticeRunner/LatticeSync, the GDExtension) needs godot-cpp + Godot 4.2+ to build. The Godot editor and godot-cpp are not installed in the reference environment, so these nodes are authored and documented but not run here. - The ABI glue layer (
src/lattice_glue.*) — everything that actually talks tolattice.h: schema build, spawn/dirty/tick, RPC and event pack/unpack, listen/connect, endpoint parsing, the stats snapshot — compiles with a plaing++/mingwand is compiled, linked against the real core, and run (native Linux and Windows via wine). The tic-tac-toe netcode is proven through this layer by the headless harness, and the compile-check stands up a host and a client that reachCONNECTEDthrough the same forwarders the nodes call.
So when a chapter says a feature is "verified," it means the harness drives it through the same glue the nodes route through. When a chapter says something "needs the editor," it means the node/scene side is authored but not executed here.
Verified against: bindings/lattice-godot/README.md ("What compiles where"),
samples/godot-tictactoe/README.md ("What is verified HEADLESSLY", "What needs the Godot editor").
Conventions¶
gdscriptblocks are real or faithfully-adapted binding/sample 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.
Next: 01 — Setup, where you add the GDExtension to a Godot 4 project.