Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Build networked games with Godot 4.x high-level multiplayer: set up an ENetMultiplayerPeer server/client, define RPCs with the @rpc annotation (call via rpc()/rpc_id()), set per-node multiplayer authority, and replicate state with MultiplayerSpawner and MultiplayerSynchronizer. Use when adding multiplayer/networking to a Godot project, writing @rpc functions, or syncing player/world state across peers.
| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-10 | ✗→✓ | ▲ Improved | 2% | 0% |
| case-21 | ✓→✗ | ▼ Worse | 23% | 0% |
| case-02 | ✓→✓ | = Same ✓ | 40% | 0% |
| case-12 | ✓→✓ | = Same ✓ | 295% | 0% |
| case-17 | ✓→✓ | = Same ✓ | 297% | 0% |
Connect peers, call functions remotely with @rpc, assign authority, and replicate state with MultiplayerSpawner/MultiplayerSynchronizer. Targets Godot 4.3+ (ENet). Treat all client input as untrusted; keep the server authoritative.
assigning per-node authority, or auto-spawning/syncing nodes across peers.
When not to use: local split-screen (no networking); raw TCP/UDP/WebSocket protocol work (low-level PacketPeer); HTTP requests. For save/persistence → save-systems.
ENetMultiplayerPeer), call create_server(port, max) orcreate_client(ip, port), and assign it to multiplayer.multiplayer_peer. The server's unique ID is always 1; clients get random positive IDs.
multiplayer: peer_connected(id),peer_disconnected(id), connected_to_server, connection_failed, server_disconnected.
@rpc(...). Call them on a Callable via rpc() (all peers) orrpc_id(peer_id) (one peer). Inside, multiplayer.get_remote_sender_id() tells you who sent it.
all @rpc methods in a script; mismatches break silently.
set_multiplayer_authority(id); gate input/RPCs byis_multiplayer_authority().
MultiplayerSpawner (auto-instances scenes on clients) andMultiplayerSynchronizer (auto-syncs selected properties).
gdscriptconst PORT := 7000 const MAX_PLAYERS := 8 func host() -> void: var peer := ENetMultiplayerPeer.new() var err := peer.create_server(PORT, MAX_PLAYERS) if err != OK: push_error("Cannot host: %s" % err); return multiplayer.multiplayer_peer = peer multiplayer.peer_connected.connect(_on_peer_connected) func join(ip := "127.0.0.1") -> void: var peer := ENetMultiplayerPeer.new() peer.create_client(ip, PORT) multiplayer.multiplayer_peer = peer multiplayer.connected_to_server.connect(func(): print("connected")) func leave() -> void: multiplayer.multiplayer_peer = OfflineMultiplayerPeer.new()
gdscriptfunc _unhandled_input(event: InputEvent) -> void: if event.is_action_pressed("fire") and is_multiplayer_authority(): request_fire.rpc_id(1) # send only to the server (id 1) # Clients may call this; it runs on the server (and locally if server is a player). @rpc("any_peer", "call_local", "reliable") func request_fire() -> void: var sender := multiplayer.get_remote_sender_id() if not _can_fire(sender): # server-side validation return spawn_projectile.rpc(sender) # tell everyone to spawn it @rpc("authority", "call_local", "reliable") func spawn_projectile(owner_id: int) -> void: _do_spawn(owner_id)
gdscriptextends CharacterBody2D func _ready() -> void: # The node name is the owning peer's id; that peer is the authority. set_multiplayer_authority(name.to_int()) func _physics_process(delta: float) -> void: if not is_multiplayer_authority(): return # only the owner reads input & moves velocity = Input.get_vector("left", "right", "up", "down") * 200.0 move_and_slide()
gdscript# Add a MultiplayerSynchronizer child; in its Replication editor add the properties to # sync (e.g. position, velocity). Set "Sync"/"Spawn" flags per property. From code you # can scope visibility: @onready var sync: MultiplayerSynchronizer = $MultiplayerSynchronizer func _ready() -> void: # Only replicate this node to a specific peer (e.g. private info). sync.set_visibility_for(target_peer_id, true)
@rpc method in a script must exist with the samedeclaration on both client and server builds — even unused ones. A mismatch causes errors that may point at the wrong function. Argument names/count are not checked, but the set of RPCs and their annotations are.
@rpc is "authority". Clients calling it are ignored unless you set"any_peer". Use "call_local" so the host (also a player) runs it too.
with identical names on all peers (use MultiplayerSpawner or add_child(node, true) for readable, deterministic names).
hits) directly. Send intent, validate on the server, then broadcast results.
@rpc methods must be on Node-derived classes, notplain Resource/RefCounted.
dictionaries, PackedArrays).
multiplayer.multiplayer_peer = OfflineMultiplayerPeer.new().
MultiplayerSpawner setup, transfer modes/channels, SceneMultiplayerauthentication (auth_callback/complete_auth), a lobby skeleton, and dedicated-server export notes, read references/replication-and-rpc.md.
godot-nodes-scenes — instancing the scenes that get spawned/synced.godot-signals-groups — connection signals and event flow.godot-export — exporting a headless dedicated server build.Other measured skills in the registry, with their headline benchmark lift.