Nebula

Running locally

Build the player, run the whole mesh on one machine, watch it on the dashboard, and stop it.

Everything below goes through the nebula CLI, run from inside a project that has had nebula init (the Nebula repository is itself such a project). The Editor menu Nebula offers the same operations for people who prefer buttons.

Build

nebula build
nebula build --linux

nebula build runs Nebula.Editor.NebulaBuild in Unity batchmode, using the Unity version from ProjectSettings/ProjectVersion.txt found through Unity Hub's install folders, NEBULA_UNITY, or nebula config unity. It produces the executable every role runs: Builds/Win64/Nebula.exe on Windows (the base name comes from executable in nebula.json). --linux builds the Linux dedicated server into Builds/Linux64 and packs Builds/nebula-linux.tar.gz for deployment.

If the Editor has the project open it holds an exclusive lock, so the build automatically runs from a mirrored copy under ~/.nebula-cli/scratch/<project> and the result is copied back into Builds/. Lines tagged [nebula] and compiler errors are echoed while it runs; the full log is Builds/unity-build.log. A running mesh holds the previous build open; nebula build --stop-mesh stops it first.

Start

nebula start --open-ui
nebula start --workers 2 --bots 2
nebula start --workers 4 --npcs 128

start does, in order:

  1. Starts a local SpacetimeDB if none answers on mesh.spacetimeUri from nebula.json (logs to Builds/<platform>/Logs/spacetimedb.log).
  2. Publishes the control-plane module with fresh data (--skip-publish to keep the tables).
  3. Launches the orchestrator from the last build. The orchestrator launches the gateway and --workers worker processes, writes one lease per container, and deals containers across the workers.
  4. Launches --bots bot clients.
  5. Waits for the dashboard and prints how to join.

Defaults come from the mesh section of nebula.json. --build builds first.

Joining

Press Play in the Editor (NebulaBootstrap.EditorRole is Client by default), or run the build as a client:

Builds\Win64\Nebula.exe -nebula-role client -nebula-name jesse

Either way a title screen asks for the gateway (Local = 127.0.0.1:7000, Hetzner = the last remote address you used, or anything typed in) and a name. Escape in game brings it back to disconnect or switch. Clients started with -nebula-gateway <addr:port> or -nebula-connect, and bots, skip the title screen and connect at once.

Bots and NPCs

Two different things drive a pawn without a human, and they cost very different amounts:

Bot (--bots N)NPC (--npcs N)
What it isA full client process (-nebula-role client -nebula-bot) that connects through the gateway, predicts and reconciles like a real player, with a bot brain in place of the keyboardA server-driven entity: an ordinary entity with no owning client, driven by whichever worker owns it
CostOne headless Unity player eachOne entity
Use it forExercising the client pathLoad
How manyA handful. 128 of them on one machine starve the workersHundreds. 128 NPCs on 4 workers ran for 7 minutes at 0.25 to 0.35 ms per tick

The NPC total is a live mesh setting: change it on the dashboard, or type npcs 300 in the in-game console (backquote key). The policy of who spawns which NPC is game code, described in Spawning.

Watch

nebula status
nebula logs w1 --follow
nebula logs gateway -n 200

status prints the workers with the containers they own, how many players, bots and NPCs each simulates, and the orchestrator's recent events. logs reads a role's log: orchestrator, gateway, w1..wN or bot1... Logs live next to the build in Logs/.

The dashboard at http://localhost:7080/ shows the same and more: every worker with its authoritative and ghost entity counts, tick time and heartbeat age; the container-to-worker table with lease epochs; the gateway; mesh settings; and the event log. Its buttons add a worker, remove one gracefully, kill one (a simulated crash; it is relaunched) and force a rebalance. The same operations are an HTTP API, described in Orchestrator and dashboard.

In game, F3 toggles the technical overlay: tick, RTT and input lead, your container and its worker, handovers observed, and the container-to-worker table.

Stop

nebula stop
nebula stop --spacetime

stop kills every process of the build and the SpacetimeDB the CLI started. --spacetime also stops one that was already running before nebula start.

Unattended runs

Tools/smoke-test.ps1 drives the mesh through the CLI with bot clients that roam between quadrants and shoot at each other, then reads the logs and reports handovers, cross-worker hits, kills, errors and warnings:

pwsh Tools/smoke-test.ps1
pwsh Tools/smoke-test.ps1 -KillWorker w2 -KillAfter 30
pwsh Tools/smoke-test.ps1 -ScaleTo 2 -ScaleAfter 25

-KillWorker kills a worker mid-run to check reassignment and relaunch; -ScaleTo shrinks the mesh through the dashboard API to check graceful drain. Tools/typecheck.ps1 is a compile check without the Editor. Both are described in Debugging.

From the Editor

The Nebula menu has Control Plane (start and stop a local SpacetimeDB, publish the module, regenerate the C# bindings), Mesh (start and stop a local mesh from the last build, open the dashboard, launch an extra client window) and Build (Windows player, Linux dedicated server). A game adds its own menus next to it; the ShooterGame demo, for example, has ShooterGame > Generate Arena Scene + Prefabs, which regenerates its scene, prefabs and config from code.

On this page