Simple state sync
Keep player positions aligned, and catch late joiners up with a snapshot.
1. Spawn & own an entity
Set an entity's state to create it — you become its owner. Key it by your player id.
var my_id := MultiplayerService.player_id
MultiplayerService.set_entity_state(my_id, { "x": 120, "y": 80 })
2. Patch as you move
Send partial updates; throttle them (e.g. ~15/sec) to stay under the rate limit.
MultiplayerService.patch_entity_state(my_id, { "x": new_x, "y": new_y })
MultiplayerService.entity_state_changed.connect(func(id, _patch, full):
move_dot(id, Vector2(full.x, full.y)))
3. Handle the late-join snapshot
When you join a room that already has state, you receive everything at once.
MultiplayerService.state_snapshot_received.connect(func(snap):
for e in snap.entities:
spawn_dot(e.entityId, e.state))
4. Room state & deletion
# Host-only shared state:
MultiplayerService.patch_room_state({ "round": 2, "phase": "combat" })
MultiplayerService.room_state_changed.connect(func(_patch, state): set_round(state.round))
# Remove your entity:
MultiplayerService.delete_entity_state(my_id)
MultiplayerService.entity_state_deleted.connect(func(id): remove_dot(id))
Rules & limits
- Only an entity's owner can update/delete it; only the host
can patch room state. Violations arrive on
state_update_rejected. - Defaults: 50 entities/room, 4 KB per entity, 16 KB room state, 10 updates/sec/client.
- v1 has no prediction or interpolation — interpolate on the client for smoothness.
Full version: the Simple State Sync Demo in
sdk/godot-gdscript/examples/state_sync/.