Skip to content
Development
Skill

/multiplayer-sync

Use when synchronizing multiplayer state — MultiplayerSynchronizer, interpolation, prediction, and lag compensation

From plugin
godot-prompter
90361 skills9 agents1 hook

Claude Code

$ npx -y skills add jame581/GodotPrompter --skill multiplayer-sync --agent claude-code

SKILL.md

multiplayer-sync.SKILL.md
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** ("On Change" properties, sent reliably when changed) and **full sync** ("Always" properties, sent unreliably every interval)
  • 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 network process frame (the multiplayer API polls once per process frame, not per physics tick).

Key Properties

| Property | Description | |---|---| | `replication_interval` | Seconds between full sync updates. `0` (default) = every network process frame | | `delta_interval` | Seconds between delta sync updates. `0` (default) = every network process frame | | `public_visibility` | When `true`, updates go to all peers (default) | | `add_visibility_filter(callable)` | Method, not a property: adds a `Callable` that takes a peer ID and returns `true` if that peer should receive updates |

Delta vs Full Sync

| Mode | How It Works | Best For | |---|---|---| | **Full sync** | Sends every "Always" property every `replication_interval`, unreliably | Continuously changing values (position, velocity) | | **Delta sync** | Sends the "On Change" properties that changed, every `delta_interval`, reliably | Values that change rarely but must arrive (health, state) |

Each property uses one mode, so the two intervals govern different property sets — `replication_interval` is not a full-state refresh of the "On Change" properties.

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.0

Visibility 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, bool>(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>("MultiplayerSynchronize
Read more
@jame581
Ships withgodot-prompter

Agentic skills framework for Godot 4.x game development. Gives AI coding agents domain-specific expertise for GDScript and C# projects.

90361 skills9 agents
Get the whole plugin

Stars on GitHub

Momentum

stars in total
903
Star history of jame581/GodotPrompter on GitHub, a chart by star-history.com

Other skills on godot-prompter.

2d-essentials

2d-essentials

Use when working with 2D-specific systems — TileMaps, parallax scrolling, 2D lights and shadows, canvas layers, particles 2D,…

3d-essentials

3d-essentials

Use when working with 3D-specific systems — materials, lighting, shadows, environment, global illumination, fog, LOD, occlusion…

ability-system

ability-system

Use when building character abilities — Resource-based abilities with cost/cooldown/cast, buffs/debuffs, stat modifiers, gameplay…

More skills from other plugins.

brainstorming
Auto-invoked

brainstorming

You MUST use this before any creative work - creating features, building components, adding functionality, modifying behavior, or…

@obra@obraInstall Skill
ask-matt

ask-matt

Ask which skill or flow fits your situation. A router over the skills in this repo.

skills10d309k
@mattpocock@mattpocockInstall Skill
accessibility
Auto-invoked

accessibility

Design, implement, and audit accessible UI to WCAG 2.2 Level AA across Web, iOS, and Android — semantic ARIA roles and labels,…

ecc11d293k
@affaan-m@affaan-mInstall Skill
compiler-commit

compiler-commit

Use when you want to verify compiler changes and commit with the correct convention. Runs tests, lint, and format, then commits…

react1d252k
@facebook@facebookInstall Skill

Questions about multiplayer-sync.

Which coding agents can use multiplayer-sync?
multiplayer-sync installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.