Godot Version
4.7.1
Question
Hello,
I have an issue with MultiplayerSynchronizer. It is not syncing my Input nodes, and it is not giving any errors.
The game should allow to join another game in progress (without needing a lobby).
The server flow:
- Host starts game
- Server networking is initialised
- World is loaded
PlayerMultiplayerSpawnerconnects toPeerConnectedevent.PlayerMultiplayerSpawnerrecieves event that player id: 1 (host has joined)- A new vehicle is spawned with the node name of
1 - The
Vehiclescript self-assigns the multiplayer authority based on it’s name when added to scene on_EnterTree()
When a new player joins, the server:
PlayerMultiplayerSynchronizergets aPeerConnectedevent.- A new vehicle is spawned with the node name of e.g.
1234 - The
Vehiclescript self-assigns the multiplayer authority based on it’s name when added to scene on_EnterTree()
The client flow is:
- Initialise networking as client
- Load world
- Vehicle Nodes are ‘automatically’ spawned using
PlayerMultiplayerSpawner - The
Vehiclescript self-assigns the multiplayer authority based on it’s name (does not depend on server) on_EnterTree()
My scene structure when two players have joined, on the host (the client is identical - and the authority is set correctly):
The node/synchronizer I am having issues with:
The inspector view of the node/synchronizer (in scene mode):
The node I want to sync (changing any field to public did not help):
public partial class VehicleInput : Node
{
[Export]
float _SteerInput;
[Export]
float _AccelerateInput;
[Export]
float _BrakeInput;
[Export]
bool _IsAccelerateInputPressed;
[Export]
bool _IsBrakeInputPressed;
//...
}
The spawn script - attached to the PlayerMultiplayerSpawner node:
public partial class PlayerMultiplayerSpawner : MultiplayerSpawner
{
// ...
public override void _Ready()
{
if (Context.Instance.Multiplayer.IsServer())
{
GetParent().SetMultiplayerAuthority(Context.Instance.Multiplayer.MultiplayerPeer.GetUniqueId(), false);
Context.Instance.Multiplayer.PeerConnected += OnPeerConnected;
Context.Instance.Multiplayer.PeerDisconnected += OnPeerDisconnected;
CallDeferred(nameof(AddPlayerToRoot), Context.Instance.Multiplayer.MultiplayerPeer.GetUniqueId());
}
}
private void OnPeerConnected(long id)
{
// only connected if server
CallDeferred(nameof(AddPlayerToRoot), (int)id);
// this.Spawn();
}
private void OnPeerDisconnected(long id)
{
// only connected if server
var playerToDelete = GetParent().GetNode(id.ToString());
playerToDelete?.QueueFree();
}
private void AddPlayerToRoot(int id)
{
var playerScene = ResourceLoader.Load<PackedScene>(CommonConstants.PATH_SCENE_VEHICLE);
var player = playerScene.Instantiate<Vehicle>();
player.Name = id.ToString();
GetParent().AddChild(player);
player.GlobalPosition = new Vector3(player.GlobalPosition.X, player.GlobalPosition.Y + 2.5f, player.GlobalPosition.Z);
}
}
Excerpt from Vehicle script (attached to nodes 1 and 2080699575) which assigns authority:
public partial class Vehicle : VehicleBody3D
{
//...
public override void _EnterTree()
{
// if (!Multiplayer.IsServer())
// return;
if (int.TryParse(this.Name, out int result))
{
this.SetMultiplayerAuthority(result);
}
else
{
Logger.LogErr<Vehicle>("Failed to set authority, as the node name does not translate into a multiplayer id (int).");
}
}
// Called when the node enters the scene tree for the first time.
public override void _Ready()
{
if (!IsMultiplayerAuthority())
this.GetNode("Camera3D").QueueFree();
}
//...
}
What have I done wrong? Is there anything else I can check?
Could this be to do with timing? I use CallDeferred in PlayerMultiplayerSpawner as otherwise I get an error that the tree is still initializing.
Please let me know if I can explain anything (such as the state system).



