Mapping tables from the three systems people most often arrive from. The short version: rooms, spawning, and transform sync map cleanly; RPCs become events; server authority does not map — SpawnWeaver has no server-side game code.
From Godot's built-in High-Level Multiplayer API
Godot's HLMP (ENet peers, MultiplayerSpawner, MultiplayerSynchronizer, RPCs) is
peer-hosted: one player is the server, everyone needs connectivity to them (port
forwarding/NAT), and the session dies with the host. SpawnWeaver replaces the
transport and hosting with a service — no ports, no host machine, codes instead of IPs.
| Godot HLMP | SpawnWeaver equivalent |
|---|---|
ENetMultiplayerPeer.create_server(port) |
await SpawnWeaver.create_room() — no ports, share room.code |
ENetMultiplayerPeer.create_client(ip, port) |
await SpawnWeaver.join_room(code) |
multiplayer.peer_connected / peer_disconnected |
player_joined(p) / player_left(p, reason) signals |
multiplayer.get_unique_id() (peer int) |
SpawnWeaver.player.id (stable string, survives restarts) |
multiplayer.is_server() |
SpawnWeaver.is_host (host can change — watch host_changed) |
MultiplayerSpawner + spawn function |
PlayerSpawner node (player avatars, automatic) |
MultiplayerSynchronizer + replication config |
SpawnSync node (transform + synced_properties) |
@rpc methods / rpc() calls |
send_event(name, data) + event_received — data, not remote calls |
@rpc("authority") server-side decisions |
Host-authoritative pattern via room state (Best practices) |
| Scene tree replication of arbitrary nodes | Entities (set_entity/patch_entity) — state dictionaries, not node trees |
| Host quits → session dies | Host migration — the room continues with a new host |
What doesn't map:
- RPCs. There is no "call a function on another peer". Send an event carrying data; the receiver decides what to do. This is a design improvement in disguise — events are inspectable, queueable, and can't call arbitrary code.
- Tick-level physics sync / rollback. SpawnSync interpolates at up to 10 updates/s. Fighting-game-grade netcode is out of scope.
multiplayer.multiplayer_peerecosystem (e.g. WebRTC mesh) — SpawnWeaver is its own client, not aMultiplayerPeerimplementation.
From Photon (PUN / Realtime / Fusion)
Photon's room model translates almost one-to-one; the main mental shift is that SpawnWeaver has no Unity-style magic components — sync is explicit nodes and calls.
| Photon | SpawnWeaver equivalent |
|---|---|
PhotonNetwork.ConnectUsingSettings() |
await SpawnWeaver.start() |
| App id | Project public key (pk_…) |
CreateRoom / JoinRoom(name) |
create_room() / join_room(code) |
JoinRandomRoom / lobbies |
find_match(mode) — or list_rooms() for a browser UI |
| Lobby / room listing | Public rooms + list_rooms() (a lobby is just a public room) |
| Room custom properties | Room metadata (static facts) + room state (live values) |
| Player custom properties | Your player's entity state, or per-player keys in room state |
| Master client | Host (SpawnWeaver.is_host) with automatic migration |
RaiseEvent / OnEvent |
send_event() / event_received (sender-excluded, like default Photon) |
PhotonView + PhotonTransformView |
SpawnSync node |
| Instantiate over network | PlayerSpawner for avatars; set_entity() + a spawn-on-entity_changed listener for other objects |
RPCs (photonView.RPC) |
Events — data messages, not method calls |
What doesn't map: Photon's regions/cloud tiers, interest groups, and Fusion's server-authoritative simulation. SpawnWeaver rooms are small and fully-broadcast — no interest management yet.
From Nakama
Nakama is a self-hosted server you extend with Lua/Go/TS server modules; SpawnWeaver deliberately has no server-side scripting. The client-facing features map like this:
| Nakama | SpawnWeaver equivalent |
|---|---|
| Device / anonymous authentication | Automatic — first connect mints an identity, token persisted by the SDK |
| Sessions & refresh tokens | Handled inside the SDK (fresh token per connect, sliding expiration) |
| Match (relayed multiplayer) | Room |
| Match join code / match listing | Room code / list_rooms() |
Matchmaker (AddMatchmakerAsync) |
find_match(mode, {region, size}) — exact-match buckets, no skill query language |
| Match state messages (op codes) | Events (send_event with a name instead of an op code) |
| Match presence events | player_joined / player_left / player_disconnected signals |
| Storage engine (collections/keys) | Player storage (storage_get/set/delete/list) — per-player only, no shared collections |
| Server runtime modules (authoritative matches, hooks) | No equivalent — use the host-authoritative pattern |
| Leaderboards, groups, chat channels, notifications | No built-ins — chat is a trivial event; leaderboards need your own service over the HTTP storage API |
Honest summary
Choose SpawnWeaver when you want rooms, matchmaking, transform sync, and saves with near-zero integration cost in Godot. Stay with (or choose) the alternatives when you need server-authoritative simulation, competitive anti-cheat, interest management for big worlds, or built-in social systems — SpawnWeaver doesn't pretend to have them today.
Migration order that works well:
- Replace connection/room plumbing (
start,create_room/join_room) — one afternoon. - Swap synchronizers for
SpawnSync/PlayerSpawnerand delete your interpolation code. - Re-express RPCs as events; move authoritative decisions into host-written room state.
- Port saves to player storage.
Then delete your port-forwarding docs, relay servers, and connection-failure FAQ — that's the payoff.