SpawnWeaver players are anonymous-first: no sign-up, no passwords. The first connect mints a stable player id; the SDK persists it so the same machine is the same player tomorrow.

How identity works

  1. On first connect, the server creates a new player id (player_…) and returns a signed player token in the welcome.
  2. The SDK stores that token on disk (user://spawnweaver/identity.cfg) and presents it on every later connect — same token, same player.id.
  3. Every successful connect issues a fresh token (sliding expiration); the SDK always stores the newest one. As long as the player keeps playing occasionally, the identity never expires.
await SpawnWeaver.start()
print(SpawnWeaver.player.id)   # "player_…" — stable across app restarts

There is nothing to build: no auth UI, no account database. If you later want real accounts, map your account ids to SpawnWeaver player ids in player storage.

Display names

Identity and display name are separate. Set the name other players see:

SpawnWeaver.set_display_name("Ada")

The name is applied on your next create/join/match — set it before entering a room (e.g. from a name field in your main menu). It is per-room, not stored server-side; to persist a chosen name across sessions, keep it in storage:

# Boot:
var saved := await SpawnWeaver.storage_get("display_name")
if saved.ok and saved.value != null:
    SpawnWeaver.set_display_name(str(saved.value))

# When the player edits their name:
SpawnWeaver.set_display_name(new_name)
await SpawnWeaver.storage_set("display_name", new_name)

SWPlayer fields

Roster entries (and your own SpawnWeaver.player) are SWPlayer objects:

Field / method Type Meaning
id String Stable player id — survives reconnects and app restarts
name String Display name given when creating/joining (may be empty)
connected bool false while briefly disconnected (inside the grace window)
is_local bool true when the entry is you
display_name() String The name to show in UIs: name, or a short id fallback
for p in SpawnWeaver.room.players:
    print("%s%s%s" % [
        p.display_name(),
        " (you)" if p.is_local else "",
        "" if p.connected else " — reconnecting…"])

Persistence across restarts

The token lives in Godot's user:// directory, so identity survives:

  • app restarts and updates of your game,
  • SDK upgrades,
  • reconnects and network changes.

It does not survive the player clearing the game's user data, or switching machines — that machine is then a brand-new player. There is no cross-device identity in the current release; treat the player id as "this install of the game".

Multiple projects (and servers)

Identity is scoped per server URL + project key combination. The identity file holds one token per scope, so:

  • Each of your games (different pk_…) gets an independent player identity, even on the same machine.
  • The same game pointed at a local dev server and at production has two independent identities.
  • Rotating your project's public key starts a new scope — existing installs get fresh identities.

For tools and tests that run several SDK clients in one process, the advanced identity_scope property isolates identity persistence per client instance. Leave it empty in games.

What resets identity

Cause Effect
Player clears user:// data (or a fresh install on a new machine) New anonymous player on next connect
Token expires after long inactivity Server rejects it; a new identity is needed
Project public key rotated New identity scope per install
SpawnWeaver.stop() / app quit No effect — identity persists

Identity and the disconnect grace window

Because identity is stable, reconnecting players are recognized: if your connection drops while in a room, the server keeps your seat for the grace window and the SDK's automatic reconnect resumes it — same player.id, same entities. Other players see player_disconnected then player_reconnected, not a leave/join. Details in Rooms.

Common mistakes

Mistake What happens Fix
Setting the display name after joining Others see an empty name this session Call set_display_name() before create/join/match
Using name as a unique key Names collide and can be empty Key everything by player.id
Expecting identity across devices Each install is its own player Layer your own account system on top if you need it, via storage
Testing "two players" with two rooms in one instance One connection = one player = one room Use Debug → Run Multiple Instances to run two clients side by side

Next