SpawnWeaver has a small number of moving parts. This page gives you the mental model; each concept links to a guide with the details.

Project and keys

A project is one game. It has two keys:

Key Where it lives What it can do
Public key pk_… Inside your game client (spawnweaver.cfg) Open realtime connections; identify the project. Safe to ship.
Secret key sk_… Your own servers/tools only — never in the game Full HTTP access to every player's storage; shown once at creation.

Game clients only ever need the public key. If a secret key leaks, regenerate it from the dashboard.

Player identity

Players are anonymous-first: no accounts, no login screens. The first time a client connects, the server mints a new player id (player_…) and hands back a signed player token. The SDK persists that token in user:// and presents it on every later connect — so SpawnWeaver.player.id is stable across app restarts. A fresh token is issued on each successful connect (sliding expiration).

await SpawnWeaver.start()
print(SpawnWeaver.player.id)        # same id tomorrow, on this machine
SpawnWeaver.set_display_name("Ada") # what other players see

Identity is scoped per project (and per server URL), so one machine has an independent identity in each of your games. See Players & identity.

Connection and session

await SpawnWeaver.start() opens one WebSocket to the server and resolves when the session is welcomed. From then on the SDK:

  • keeps SpawnWeaver.status up to date (OFFLINE / CONNECTING / ONLINE),
  • heartbeats and measures SpawnWeaver.latency_ms,
  • reconnects forever after drops (exponential backoff, capped at 30s) until you call SpawnWeaver.stop().

Every request method is awaitable and returns an SWResultresult.ok, result.value (or a typed accessor like result.room), and result.error. You never need to connect a signal to learn a request's outcome.

Rooms

A room is where players meet: it has a short join code (e.g. 4V8772), a roster, a host, and optional attributes (name, max_players, metadata).

  • Visibility: "private" rooms are joinable by code only; "public" rooms also appear in list_rooms() and can be joined by id. A "lobby" is just a public room.
  • One room per connection — you are in at most one room at a time.
  • Host: the creator (or first matched player). Only the host can update_room() and write room-level state. If the host disconnects or leaves, the server promotes the earliest-joined connected player — host migration is automatic.
  • Disconnect grace: if a player's connection blips, their seat (and their entities) are kept for a grace window (default 60s). They resume exactly where they were.

SpawnWeaver.room is maintained for you: roster, host, code, metadata, and live state. See Rooms.

Matchmaking

Instead of sharing codes, players can queue: await SpawnWeaver.find_match("duel") resolves when the server has filled a bucket of players with the same mode, region, and size — the result is a normal room with a host. See Matchmaking.

Events vs. state sync

Two ways to communicate inside a room — use both, for different jobs:

Events State sync
Call send_event("fired", {...}) set_entity() / patch_entity() / set_room_state()
Nature Transient message, relayed once Persistent value, kept by the server
Who receives Other room members (not you) Everyone, including you (as the ack)
Late joiners Never see past events Get the full state snapshot on join
Good for Shots, chat, emotes, "round started" pings Positions, health, scores, game phase

Rule of thumb: if a player joining late needs to know it, it's state. If only players present right now care, it's an event.

State has two levels: room state (one shared object, host-writable) and entities (per-object state, writable only by the owning player). The SpawnSync node automates entity sync for transforms. See State sync and Events.

Player storage

Per-player key-value storage that persists across sessions — save games, unlocks, settings — with no server of your own:

await SpawnWeaver.storage_set("save", {"level": 3, "gold": 120})
var save := await SpawnWeaver.storage_get("save")

The same data is reachable over HTTP (with the secret key, or the player's own token) for tooling and dashboards. See Player storage.

The debugger

When something goes wrong, the dashboard explains why:

  • Session inspector — a per-connection timeline: connect, auth, every action, every rejection, the disconnect reason.
  • Error explorer — protocol errors aggregated by code, each with a suggested fix.
  • Debug bundle viewer — paste a client's SpawnWeaver.create_debug_report_string() output to inspect its state offline.

See Debugging.

Putting it together

A typical casual game uses: start() once at boot → a menu that calls create_room() / join_room() / find_match() → a level with a PlayerSpawner (avatars + movement sync, zero code) → send_event() for one-shot actions → set_room_state() from the host for the game phase → storage_set() for progression. That's the whole stack.