Layered Mutliplayer Spawners cause get_node: Node not found error

Godot Version

4.2.1

Question

Simple setup:

My main scene has a Node thats called containers and a MultiplayerSpawner node to spawn the childs of containers for every player that joins.

Now, the containers can contain items which are visually represented, so the container also has a multiplayerSpawner node.

What happens is, apparently when a player joins, the authority wants to synchronize the multiplayer spawner thats inside the container first, before synchronizing the container itself, which causes a get_node: Node not found error.

If i want to add an item to a container after the players joined, it works flawlessly, just synching the items that are inside a container before the player joins fails.

If get node is used for a node that is spawned. That ain’t the way to do it.

You should leverage the spawned callback, or child entered signal, to cache a reference somewhere who knows if the node exists or not.

At least check if the node exists first.

I do this with weapons of peers. Once the player spawns he has no weapon until the weapon is spawned and assigned to the player via the spawn signal. This also works for swapping weapons.

But thats the behaviour of the multiplayer spawner / multiplayer sync node, how can i prevent it from doing this. Or what exactly is your solution

Don’t use get_node for multiplayerspawned items. Or at least check if get node is null

Var node = get_node(path)
If node == null:
   Return
Else:
  Node.do_somethimg
 

Or use the MultiplayerSpawner to assign a node that is used.


Var my_node :MyCustomClass= null

Func _ready():
 $MultyplayerSpawner.spawned.connect(_on_multiplayerspawner_spawned)

Func _process(delta):
  If my_node:
     My_node.Do_something()


Func _on_multiplayerspawner_spawned(node)
  If node is MyCustomClass:
    My_node = node

I think i should add my scene tree to clarify some things. Im not accessing anything from the spawned item programatically (right now). I just want to sync the normal properties it has with the MultiplayerSync node.
Scene Tree of the client:
image
Errors late joining clients receive:

That error is on the client. What does the client tree look like?

That is the client tree

Your comment says “scene tree of host”

But anyways, the trees of host and client need to be the same form where ever the multiplayer API resides. (Which if you are doing a typical setup it’s at the scene root.)

So does the client and host both have a “Multiplayer/Level/MainGame/Containers/<…>”?

And when you add nodes only the host adds them, and are replicated via the spawners on the clients. And you use the readable names add_child parameter on the host every time a node is added.

Lastly the multiplayer spawner has the complete spawn list of all the scenes that will spawn under its watch

My bad, but its the scene tree of the client, not the host. Its exactly the same and exactly how you described it. The setup is correct, or else it wouldnt work whenever i do add something while a client is connected, the problem only occurs for late joiners.

Idk, I have a pretty complicated setup myself and I have worked all these kinds of issues out. And I can join a client any at any time.

Could it be you are modifying replication_configs on any of the MultiplayerSynchronizers via code?

Or you are not changing the names of nodes?

Im changing the name serverwise before i use add_child to add a node to the scene, similar of how i change the player node name into the authority id. Im not changing the replication_configs via code or anything.

image

Here a little video to demonstrate what i mean. Peer2 prints the errormessages i posted earlier after joining, if there is a bottle ontop of the white crate (Item inside of the container)

Did the demonstration help to illustrate the issue?

Did you re-child the bottles when they are placed on the box?

I don’t know what kind of magic you do to the box but it would make most sense if you are re-childing the bottles onto the box.

If that is the case then the box needs a spawner as well. So when the player joins it will spawn the items visually as expected.

I have heard that a spawner can also do nested children, but I some how doubt it, but if it did then the bottles on the box need to be under a spawner that is looking for them.

Im not rechilding, i instantiate a new entity. I’m keeping visual representation and physical representation seperated. So when a player puts a bottle on the box, i queue_free the one in his hand and instantiate another visual representation on the box. I want to pool this in the future if performance problems arise. In any case, the box has a spawner as well.

image

Thats how the container (box) looks like internally. The spawners path is stored items and it synchs the stored items aslong as the players are connected when storing

Okay… Wonder if it is related to when the authority is set. Or how marshaling the spawners work based on ownership when a peer joins. Because the host needs to spawn the containers and peer 1 needs to spawn the items?

It could be that there is a race condition to spawn the objects between the peers and host.

Thats what i suspect. But i don’t have many routes left to debug, i thought about adding a timer for the spawner. I will try to make a custom spawn function, to see if it works better

I couldn’t find anything.

About the custom spawn, it requires you to return a node that will automatically get placed in the tree. I think it will help to set authority as soon as possible. But if the authority hasn’t spawned the parent branch in the scene tree i yet, it will not matter.

I couldn’t find a way to guarantee order of operations. The only thing I could think of is if a peer connects you could set the tree root authority to server temporarily, on host and all peers so there is only one peer doing the spawning. Then when enough time has passed reconstruct the real authority graph. I don’t know if this will work and it will be a little cumbersome to reconstruct the authority… Maybe, maybe not.

The authority is on the sever anyways. The player only have authority over themselfes. The container (box) and the bottle always are on authority 1

Oh if the host should own those spawners then we shouldnt have this issue.

Why does it look like from the images that the box and bottles have multiplayer IDs?

Did you know that if you set the auth on a node all of its children will get authed as well? The set_multiplayer_authority defaults to recursive.