7 Example Project
Yuris Cakranegara edited this page 2026-08-22 20:59:01 +07:00

Example Project

dev/example-chat/ is a small, complete, openable Defold project, the on-ramp Roadmap named as missing. It is not the conformance harness. dev/example carries harness.project and is a test fixture; this is a real game.project you open with File ▸ Open Project and run.

What it is

  • game.project bootstraps main/main.collection, declares input/game.input_binding, and adds the extension-websocket 4.2.4 dependency the SDK needs.
  • main/main.gui and main/main.gui_script build a scrolling text log and a button. Clicking the button sends a canned chat message via call_reducer("send_message", ...), and every message row insert appends a line to the log.
  • main/chat_client.lua holds the SDK wiring (stdb.schema.fetch → stdb.connect → subscribe_query → on_insert → call_reducer), shared by the GUI script and a headless proof script so the two cannot drift apart.
  • main/headless.script, main/headless.collection and headless.project are a headless-only entry point reached through a settings overlay, the same pattern dev/example/harness.project uses for the conformance harness. It is not part of the openable example. It exists so the wiring can be proven in CI without a graphics adapter.

main/main.gui_script sets the server URL, database and sender (BASE_URL, DATABASE, SENDER). The STDB_URL, STDB_WS_URL and STDB_DB environment variables override them.

The module it talks to is the chat module under dev/server/, the same one the conformance harness and the fixture capture use. The Quickstart builds its example around a player table instead. That difference is deliberate. This project is pinned against the committed test fixture module, so the two are not meant to line up.

The conformance smoke test is a separate client. It lives at dev/example/main/smoke.script under the dev/example/ harness (which carries harness.project and no game.project of its own) and covers stdb/init.lua's websocket binding across eight phases. See Development.

dev/example-chat/stdb is a symlink to ../../stdb, the real SDK rather than a copy, so the example can never drift from what it exercises. That is also its one caveat. Git on Windows does not create symlinks by default. A clone on Windows without git config core.symlinks true (or Developer Mode plus that setting) leaves stdb as a text file containing a path instead of a working module, and require("stdb.init") fails.

The one-line alternative sidesteps the symlink entirely. Add this repo as a dependency in your own project's game.project, the same as any consumer does.

https://git.nokopia.com/yuris/spacetimedb-defold/archive/v4.0.2.zip
https://github.com/defold/extension-websocket/archive/refs/tags/4.2.4.zip

Then run Project ▸ Fetch Libraries. That resolves stdb/ from the archive Defold's own dependency fetcher downloads, with no symlink and no Windows-specific git configuration required. Use the cloned dev/example-chat/ as a reference for the wiring in chat_client.lua either way.

Running it

Start a local server and publish the chat database (see Quickstart).

dev/tools/dev-server.sh

Then open dev/example-chat/ in the Defold editor and press Build, or run it headless:

cd dev/example-chat
nix develop <repo>#conformance -c bob --settings headless.project \
  --variant headless --archive --platform x86_64-linux \
  resolve build bundle --bundle-output dist/headless
STDB_EXAMPLE_AUTOSEND=1 dist/headless/spacetimedb-defold-example-chat/spacetimedbdefoldexamplechat.x86_64

A headless run with STDB_EXAMPLE_AUTOSEND=1 sends one message on startup and prints PASS only once that same row comes back through message:on_insert. That proves a real round trip through the live server rather than only that the call was issued.