Multiplayer authority - error passing the ID to instantiated objects? (SOLVED)

Godot Version

4.2.2

Question

I’m getting this error:

E 0:00:13:0939 on_replication_start: The MultiplayerSynchronizer at path “/root/NetworkTest/Units/PlayerUnit/MultiplayerSynchronizer” is unable to process the pending spawn since it has no network ID. This might happen when changing the multiplayer authority during the “_ready” callback. Make sure to only change the authority of multiplayer synchronizers during “_enter_tree” or the “_spawn_custom” callback of their multiplayer spawner.
<C++ Error> Condition “pending_sync_net_ids.is_empty()” is true. Returning: ERR_INVALID_DATA
<C++ Source> modules/multiplayer/scene_replication_interface.cpp:244 @ on_replication_start()

But I’m not setting anything related to multiplayer authority in _ready.

I just followed a tutorial, based on Multiplayer in Godot 4.0: Scene Replication, where I’m setting the multiplayer authority in the setter, like this:

UNIT.GD

@export var multiplayer_id:int = 1:
	set(id):
		multiplayer_id = id
		set_multiplayer_authority(id)

The unit is instantiated when the player joins a game, like this:

MULTIPLAY.GD

func add_player(id:int = 1) -> void:
	var unit:Unit
	
	if id == 1:
		unit = unit_red.instantiate()
		unit.set_global_position(Vector3(8.0, -0.1, -6.4))
	else:
		unit = unit_blue.instantiate()
		unit.set_global_position(Vector3(-8.0, -0.1, -6.4))
		
	unit.multiplayer_id = id
		
	units_path.add_child(unit, true)

Any idea what’s going wrong?

Note: I’ve also seen some tutorials where the ID is passed through the name of the player object, but that won’t cut it for me as players will have to control multiple units whom will need unique names.

Help is much appreciated, I’m completely stuck!

Try setting the multiplayer authority during _enter_tree as it recommends

@export var multiplayer_id:int = 1

func _enter_tree() -> void:
    set_multiplayer_authority(multiplayer_id)

Yes, I did so, but now I’m getting the following:

On the “host” instance I get the errors:

E 0:00:50:0240 on_spawn_receive: Method/function failed. Returning: ERR_INVALID_DATA

E 0:00:50:0256 on_delta_receive: Ignoring delta for non-authority or invalid synchronizer.
<C++ Error> Condition “true” is true. Continuing.
<C++ Source> modules/multiplayer/scene_replication_interface.cpp:783 @ on_delta_receive()

And on the “player 2 client” instance I get:

E 0:00:04:0395 network.gd:41 @ add_player(): Condition “!is_inside_tree()” is true. Returning: Transform3D()
<C++ Source> scene/3d/node_3d.cpp:343 @ get_global_transform()
network.gd:41 @ add_player()
network.gd:24 @ _start_server_pressed()

After some digging through the bug reports on GitHub, I found that this solution works for me:

func _on_ready():
	set_multiplayer_authority(multiplayer_id)

func _ready() -> void:
	self.ready.connect(_on_ready)

So basically a custom function “_on_ready()” that is called after a signal is emitted when the node is considered ready (which happens after _ready() is called.)

Conclusion after 15 hours of struggle is that Godot’s multiplayer needs some work, as this seems to be very hacky.

1 Like

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.