Skip to content

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 to lattice.h: schema build, spawn/dirty/tick, RPC and event pack/unpack, listen/connect, endpoint parsing, the stats snapshot — compiles with a plain g++/mingw and 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 reach CONNECTED through 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

  • gdscript blocks 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.