#How to deal with unloading scenes that include a puppet

2 messages · Page 1 of 1 (latest)

mental nest
#

In my game there are loading zones where you walk into a trigger and that unloads the current scene while moving the player to the new scene. That works something like this:

player.get_parent().remove_child(player)
current_scene.free()
current_scene = load_scene(scene_path)
get_tree().get_root().add_child(current_scene)
current_scene.add_child(player)
get_tree().set_current_scene(current_scene)

This works fine in single player, but in multiplayer there is a problem. The puppet that is managed by the connected player is inside the scene we just free()ed, but is still sending us updates on their position and such. This results in a constant stream of errors

E 0:00:08.216   get_node: (Node not found: "World/353709412" (relative to "/root").)
  <C++ Error>   Method failed. Returning: nullptr
  <C++ Source>  scene/main/node.cpp:1465 @ get_node()
E 0:00:08.216   _process_get_node: Failed to get cached path from RPC: World/353709412.
  <C++ Source>  core/io/multiplayer_api.cpp:267 @ _process_get_node()
E 0:00:08.216   _process_packet: Invalid packet received. Requested node was not found.
  <C++ Error>   Condition "node == nullptr" is true.
  <C++ Source>  core/io/multiplayer_api.cpp:203 @ _process_packet()

So, how am I supposed to deal with this? Is each user supposed to keep track of all the other users that are in the same scene as them and only send updates to those users? This seems like it might have some race conditions where if we change scenes then we have to tell the other users that we changed scenes, so they know to stop sending us updates, but until they get that message they'll keep sending us updates, causing us to get errors.

What are some good solutions to the problem of unloading network puppets?

vernal raven
#

sup @mental nest I know this is from literally forever ago but I was searching online for how to fix this exact issue and ended up finding the solution thru a reddit post, but basically what you have to do is:
Tell the server to queue_free() itself first, and then follow up with your local call. Basically like shown in this screenshot (ignore the spaghetti code)

(just in the unlikely case you've been struggling over this for half a year)