When multiplayer misbehaves, SpawnWeaver can tell you exactly what happened — on the client (SDK logging, debug reports) and on the server (session timelines, aggregated errors). This guide is your toolbox, plus checklists for the three most common failures.

SDK logging

SpawnWeaver.set_debug_enabled(true)

With debug enabled, the SDK prints every message it sends and receives, and every error, to the Godot output:

[SpawnWeaver] → room.create
[SpawnWeaver] ← room.created
[SpawnWeaver] ← room.player_joined
[SpawnWeaver] error rate-limited: Sending faster than the allowed rate…

You can also switch it on without code by adding debug=true to the [spawnweaver] section of res://spawnweaver.cfg.

Debug reports and the Debug Bundle viewer

Every SDK client can produce a copyable diagnostic snapshot — SDK and Godot versions, connection status, server URL, player and room ids, latency, reconnect attempts, and ring buffers of the last 50 messages and last 10 errors:

print(SpawnWeaver.create_debug_report_string())   # pretty-printed JSON

Wire it to a debug key or a "Copy debug info" button in your bug-report UI:

func _input(event: InputEvent) -> void:
    if event.is_action_pressed("copy_debug_report"):
        DisplayServer.clipboard_set(SpawnWeaver.create_debug_report_string())

Paste the report into the dashboard's Debug Bundle viewer (/dashboard/debug) to inspect a player's state offline — perfect for playtester bug reports: "paste what the game copied to your clipboard".

The dashboard debugger

The Debugger hub in the dashboard explains why a session failed:

Tool Where What it shows
Session inspector /dashboard/sessions/{id} Per-connection timeline: connected → authenticated → every action → rejections → disconnected; plus IP, SDK + Godot versions, current room, auth status, disconnect reason
Error explorer /dashboard/errors Protocol errors aggregated by code, with counts, affected sessions, and a suggested fix for each
Room & matchmaking inspectors Debugger hub A room's members, host, and metadata; the matchmaking queue's contents
Debug bundle viewer /dashboard/debug Paste a client's create_debug_report_string() output
Live activity & logs Debugger hub Live connections/rooms and recent server logs

The SDK reports its sdkVersion and engine version on connect, so the session inspector can tell you a tester is on an old build.

The editor dock

The SpawnWeaver dock is the first stop for setup problems:

  • Test connection — performs a real end-to-end connect with your saved key and server URL, from inside the editor.
  • Live counts — shows your project's connected players and open rooms, refreshed every few seconds while the editor runs. If your game connects and the count rises, the pipeline works.

Simulating bad networks

SpawnWeaver.simulate_connection_loss()

Drops the socket as if the network blipped: auto-reconnect and room resume kick in exactly as they would in production. Use it to test your reconnecting, player_disconnected, and room_joined-resume handling without pulling cables.

Checklists

"Could not connect"

start() fails, or the dock's Test connection fails.

  1. Key: is project_key a pk_… value with no spaces? (Not the sk_… secret.)
  2. URL: hosted service → leave the Server field empty. Local server → ws://127.0.0.1:5159/connect (note ws://, not wss:// — local dev has no TLS; hosted/production is wss://).
  3. Server up? Local: is ./quickstart.ps1 (or your dotnet run) still running? Check http://localhost:5159/health.
  4. Project active? A deactivated project rejects the handshake with 401.
  5. Enable set_debug_enabled(true) and read the close reason in the output; check the session (or its absence) in the dashboard's session inspector.

"Join failed"

  1. room-not-found — the code is wrong, or the room expired (rooms with no connected members expire after ~60s; a server restart drops all rooms).
  2. room-fullmax_players reached; note players inside the disconnect grace window still hold seats.
  3. already-in-room — you're already in a room (one per connection); await SpawnWeaver.leave_room() first.
  4. not-connected — you called join_room() before start() succeeded.

"Movement is choppy"

  1. Remote copies should have interpolate = true on their SpawnSync (default). If you snap positions yourself in _process, you're fighting the interpolation.
  2. interpolation_speed: lower = smoother but laggier; try 10–16 for avatars.
  3. Check SpawnWeaver.latency_ms — with high ping, favor smoothness.
  4. Watch the output for rate-limited errors: if other traffic (events, manual state calls) eats the budget, SpawnSync updates get dropped. Keep send_rate at the default 8 and batch other messages.
  5. Only the local copy should have is_local = true — two senders for one entity produce state-forbidden errors and teleporting.

More symptom → fix tables in Troubleshooting.

Next

  • Troubleshooting — symptom → cause → fix, with exact error codes
  • Limits — the limit behind each limit error