/multiplayer-sync
Use when synchronizing multiplayer state — MultiplayerSynchronizer, interpolation, prediction, and lag compensation
$ npx -y skills add jame581/GodotPrompter --skill multiplayer-sync --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
- You can call itInvoke it directly when you want it.
- Slash command
/multiplayer-sync
Context preview
The summary Claude sees to decide when to auto-load this skill.
Use when synchronizing multiplayer state — MultiplayerSynchronizer, interpolation, prediction, and lag compensation
SKILL.md
multiplayer-sync.SKILL.mdname: multiplayer-sync
description: Use when synchronizing multiplayer state — MultiplayerSynchronizer, interpolation, prediction, and lag compensation
Multiplayer Synchronization in Godot 4.3+
All examples target Godot 4.3+ with no deprecated APIs. GDScript is shown first, then C#.
> **Related skills:** **multiplayer-basics** for ENet setup, RPCs, and authority model, **dedicated-server** for headless export and deployment, **physics-system** for physics interpolation and RigidBody synchronization.
---
1. MultiplayerSynchronizer
`MultiplayerSynchronizer` is Godot's built-in node for replicating properties across the network. Add it as a child of the node whose state you want to share.
What It Does
- Sends property values from the **authority** peer to all others at a configured interval
- Supports both **delta sync** (only changed values) and **full sync** (all values every tick)
- Allows **visibility filters** to control which peers receive updates
Replication Config in the Editor
1. Select the `MultiplayerSynchronizer` node in the scene tree. 2. In the Inspector, open **Replication** and click **Add Property**. 3. Pick the parent node path and property name (e.g. `position`, `velocity`). 4. Set **Sync** (send every interval) or **Spawn** (send only on spawn) per property. 5. Set the **Replication Interval** (seconds). `0` means every physics frame.
Key Properties
| Property | Description | |---|---| | `replication_interval` | Seconds between full sync updates. `0` = every physics frame | | `delta_interval` | Seconds between delta sync updates. `0` = disabled | | `public_visibility` | When `true`, updates go to all peers (default) | | `visibility_filters` | Array of `Callable`s; each returns `true` if a peer should receive updates |
Delta vs Full Sync
| Mode | How It Works | Best For | |---|---|---| | **Full sync** | Sends all configured properties every `replication_interval` | Simple objects, low property count | | **Delta sync** | Sends only properties that changed since last sync, every `delta_interval` | Objects with many properties that change infrequently |
Use both together: set `replication_interval` for periodic full state and `delta_interval` for frequent change-only bursts.
Visibility Filters (GDScript)
# Only send updates to peers within 500 units of this object.
func _ready() -> void:
$MultiplayerSynchronizer.add_visibility_filter(_is_peer_in_range)
func _is_peer_in_range(peer_id: int) -> bool:
var peer_player := _get_player_node(peer_id)
if peer_player == null:
return false
return global_position.distance_to(peer_player.global_position) <= 500.0Visibility Filters (C#)
// Only send updates to peers within 500 units of this object.
public override void _Ready()
{
var sync = GetNode<MultiplayerSynchronizer>("MultiplayerSynchronizer");
sync.AddVisibilityFilter(Callable.From<int>(IsPeerInRange));
}
private bool IsPeerInRange(int peerId)
{
var peerPlayer = GetPlayerNode(peerId);
if (peerPlayer is null)
return false;
return GlobalPosition.DistanceTo(peerPlayer.GlobalPosition) <= 500.0f;
}---
2. Property Synchronization
What to Sync
Sync the minimal state needed to reconstruct the visual on remote peers. Typical properties:
| Property | Type | Notes | |---|---|---| | `position` | `Vector2` / `Vector3` | Core transform — sync every frame or use interpolation | | `velocity` | `Vector2` / `Vector3` | Helps remote prediction stay ahead of position snaps | | `health` | `int` / `float` | Sync reliably on change; delta sync is ideal | | `animation_state` | `String` / `int` | Sync on change; use an enum int to save bandwidth | | `is_crouching` | `bool` | Low-change boolean; delta sync or RPC on change |
Synced Player (GDScript)
# synced_player.gd
extends CharacterBody2D
## Sync interval in seconds — exposed so designers can tune per object type.
@export var sync_interval: float = 0.05 # 20 Hz
@export var speed: float = 200.0
# These properties are listed in the MultiplayerSynchronizer replication config.
var synced_position: Vector2 = Vector2.ZERO
var synced_velocity: Vector2 = Vector2.ZERO
var synced_health: int = 100
var synced_anim: int = 0 # 0 = idle, 1 = run, 2 = jump
@onready var _sync: MultiplayerSynchronizer = $MultiplayerSynchronizer
func _ready() -> void:
_sync.replication_interval = sync_interval
# Only the authority (owner) drives movement.
set_physics_process(is_multiplayer_authority())
func _physics_process(_delta: float) -> void:
# Authority: write canonical state so MultiplayerSynchronizer can replicate it.
synced_position = global_position
synced_velocity = velocity
synced_anim = _compute_anim_state()Synced Player (C#)
// SyncedPlayer.cs
using Godot;
public partial class SyncedPlayer : CharacterBody2D
{
/// <summary>Sync interval in seconds. Exposed so designers can tune per object type.</summary>
[Export] public float SyncInterval { get; set; } = 0.05f; // 20 Hz
[Export] public float Speed { get; set; } = 200.0f;
// These properties are listed in the MultiplayerSynchronizer replication config.
public Vector2 SyncedPosition { get; set; } = Vector2.Zero;
public Vector2 SyncedVelocity { get; set; } = Vector2.Zero;
public int SyncedHealth { get; set; } = 100;
public int SyncedAnim { get; set; } = 0; // 0=idle, 1=run, 2=jump
private MultiplayerSynchronizer _sync = null!;
public override void _Ready()
{
_sync = GetNode<MultiplayerSynchronizer>("MultiplayerSynchronizer");
_sync.ReplicationInterval = SyncInterval;
SetPhysicsProcess(IsMultiplayerAuthority());
}
public override void _PhysicsProcess(double delta)
{
// Authority: write canonical state for replication.
SyncedPosition = GlobalPosition;
SyncedVelocity = Velocity;
SynceRead more
name: multiplayer-sync description: Use when synchronizing multiplayer state — MultiplayerSynchronizer, interpolation, prediction, and lag compensation
Multiplayer Synchronization in Godot 4.3+
All examples target Godot 4.3+ with no deprecated APIs. GDScript is shown first, then C#.
> **Related skills:** **multiplayer-basics** for ENet setup, RPCs, and authority model, **dedicated-server** for headless export and deployment, **physics-system** for physics interpolation and RigidBody synchronization.
---
1. MultiplayerSynchronizer
`MultiplayerSynchronizer` is Godot's built-in node for replicating properties across the network. Add it as a child of the node whose state you want to share.
What It Does
- Sends property values from the **authority** peer to all others at a configured interval
- Supports both **delta sync** (only changed values) and **full sync** (all values every tick)
- Allows **visibility filters** to control which peers receive updates
Replication Config in the Editor
1. Select the `MultiplayerSynchronizer` node in the scene tree. 2. In the Inspector, open **Replication** and click **Add Property**. 3. Pick the parent node path and property name (e.g. `position`, `velocity`). 4. Set **Sync** (send every interval) or **Spawn** (send only on spawn) per property. 5. Set the **Replication Interval** (seconds). `0` means every physics frame.
Key Properties
| Property | Description | |---|---| | `replication_interval` | Seconds between full sync updates. `0` = every physics frame | | `delta_interval` | Seconds between delta sync updates. `0` = disabled | | `public_visibility` | When `true`, updates go to all peers (default) | | `visibility_filters` | Array of `Callable`s; each returns `true` if a peer should receive updates |
Delta vs Full Sync
| Mode | How It Works | Best For | |---|---|---| | **Full sync** | Sends all configured properties every `replication_interval` | Simple objects, low property count | | **Delta sync** | Sends only properties that changed since last sync, every `delta_interval` | Objects with many properties that change infrequently |
Use both together: set `replication_interval` for periodic full state and `delta_interval` for frequent change-only bursts.
Visibility Filters (GDScript)
# Only send updates to peers within 500 units of this object.
func _ready() -> void:
$MultiplayerSynchronizer.add_visibility_filter(_is_peer_in_range)
func _is_peer_in_range(peer_id: int) -> bool:
var peer_player := _get_player_node(peer_id)
if peer_player == null:
return false
return global_position.distance_to(peer_player.global_position) <= 500.0Visibility Filters (C#)
// Only send updates to peers within 500 units of this object.
public override void _Ready()
{
var sync = GetNode<MultiplayerSynchronizer>("MultiplayerSynchronizer");
sync.AddVisibilityFilter(Callable.From<int>(IsPeerInRange));
}
private bool IsPeerInRange(int peerId)
{
var peerPlayer = GetPlayerNode(peerId);
if (peerPlayer is null)
return false;
return GlobalPosition.DistanceTo(peerPlayer.GlobalPosition) <= 500.0f;
}---
2. Property Synchronization
What to Sync
Sync the minimal state needed to reconstruct the visual on remote peers. Typical properties:
| Property | Type | Notes | |---|---|---| | `position` | `Vector2` / `Vector3` | Core transform — sync every frame or use interpolation | | `velocity` | `Vector2` / `Vector3` | Helps remote prediction stay ahead of position snaps | | `health` | `int` / `float` | Sync reliably on change; delta sync is ideal | | `animation_state` | `String` / `int` | Sync on change; use an enum int to save bandwidth | | `is_crouching` | `bool` | Low-change boolean; delta sync or RPC on change |
Synced Player (GDScript)
# synced_player.gd
extends CharacterBody2D
## Sync interval in seconds — exposed so designers can tune per object type.
@export var sync_interval: float = 0.05 # 20 Hz
@export var speed: float = 200.0
# These properties are listed in the MultiplayerSynchronizer replication config.
var synced_position: Vector2 = Vector2.ZERO
var synced_velocity: Vector2 = Vector2.ZERO
var synced_health: int = 100
var synced_anim: int = 0 # 0 = idle, 1 = run, 2 = jump
@onready var _sync: MultiplayerSynchronizer = $MultiplayerSynchronizer
func _ready() -> void:
_sync.replication_interval = sync_interval
# Only the authority (owner) drives movement.
set_physics_process(is_multiplayer_authority())
func _physics_process(_delta: float) -> void:
# Authority: write canonical state so MultiplayerSynchronizer can replicate it.
synced_position = global_position
synced_velocity = velocity
synced_anim = _compute_anim_state()Synced Player (C#)
// SyncedPlayer.cs
using Godot;
public partial class SyncedPlayer : CharacterBody2D
{
/// <summary>Sync interval in seconds. Exposed so designers can tune per object type.</summary>
[Export] public float SyncInterval { get; set; } = 0.05f; // 20 Hz
[Export] public float Speed { get; set; } = 200.0f;
// These properties are listed in the MultiplayerSynchronizer replication config.
public Vector2 SyncedPosition { get; set; } = Vector2.Zero;
public Vector2 SyncedVelocity { get; set; } = Vector2.Zero;
public int SyncedHealth { get; set; } = 100;
public int SyncedAnim { get; set; } = 0; // 0=idle, 1=run, 2=jump
private MultiplayerSynchronizer _sync = null!;
public override void _Ready()
{
_sync = GetNode<MultiplayerSynchronizer>("MultiplayerSynchronizer");
_sync.ReplicationInterval = SyncInterval;
SetPhysicsProcess(IsMultiplayerAuthority());
}
public override void _PhysicsProcess(double delta)
{
// Authority: write canonical state for replication.
SyncedPosition = GlobalPosition;
SyncedVelocity = Velocity;
SynceAgentic skills framework for Godot 4.x game development. Gives AI coding agents domain-specific expertise for GDScript and C# projects.
Other skills on godot-prompter.
- /authoring-godot-prompter-skills
Use when writing or editing a SKILL.md or an agent definition in this repo — required frontmatter, section ordering, and the GDScript-then-C# example convention.
Open skill - /releasing-godot-prompter
Use when cutting a GodotPrompter release or bumping its version — the version-bump sequence, tag-triggered workflow, and the marketplace manifests that must follow.
Open skill - /2d-essentials
Use when working with 2D-specific systems — TileMaps, parallax scrolling, 2D lights and shadows, canvas layers, particles 2D, custom drawing, and 2D meshes in Godot 4.3+
Open skill - /3d-essentials
Use when working with 3D-specific systems — materials, lighting, shadows, environment, global illumination, fog, LOD, occlusion culling, and decals in Godot 4.3+
Open skill - /ability-system
Use when building character abilities — Resource-based abilities with cost/cooldown/cast, buffs/debuffs, stat modifiers, gameplay tags, and HUD binding
Open skill - /addon-development
Use when creating Godot editor plugins — EditorPlugin, @tool scripts, custom inspectors, and dock panels
Open skill

