so it works by spawn_path property in MultiplayerSpawner, but how does it work without this node? Just through code and RPC. I have a player spawn system without a MultiplayerSpawner and I don’t understand how it works at all, I have the same system as in this blog
So since it seems like you are doing a peer-to-peer network you should have a mspawn class that is authed to the peer. This will grant the permission to spawn a remote grenade on all peers.
The Throw the grenade function will setup the position and velocity, then add child to a node location mspawn is watching. This will spawn the grenade in the origin of the watched node with default values with no velocity on each peer.
Each grenade scene should then have a multsync object that on spawn sets position and velocity.
Note: when you set auth to the grenade you should make it recursive to all child nodes in the scene so the grenade multsync is owned by the player who throws it.
You could do it with RPC but it will be a lot easier to use the mspawner. And if a you want to allow players to join mid game spawners already have the functionality to spawn nodes for the new client. Although it may require you to structure multiple mspawners for the tree replication.
But yea, for dynamic scenes where nodes are created and freed both types of multiplayer nodes are needed as each does a different job.
If you have a static scene RPC and multisync nodes are fine.
If you want to replicate a spawner in rpc to need to listen for two types of events. Peer connected and child added. All while keeping track of what children of depth 1 exist on the monitored node. But at this point you should just use the built in nodes.
I don’t fully understand how it works without the MultiplayerSynchronizer. By a global NodePath like /root/map/grenades/?
But how will it understand the path if, when adding an object, it is assigned an almost random name, for example /root/map/grenades/@grenade@31. It may be different for some clients.
Will it work if I send the tick argument with the Time.get_ticks_usec() value to the RPC and assign it to the name like grenade_45232141 so that everyone has the same name?
I would attach a MultiplayerSynchronizer in the scene of the grenade. It will look at its existence (it’s path) and send info to remote clients synchronizer in the same path. So for each new grenade they will each have their own synchronizer and path.
You shouldnt need to worry about timestamps I think synchronizers send “unreliable ordered”. So the will drop packets if they come out of order at least. (Spawners use reliable packets, so it is guaranteed to make sure each client gets the new node)
That is how the network arch works. Although new nodes typically defaults to the host for authority, IDK if that is going to cause issue, but since the spawner is owned by the peer maybe it will work out.
The MultiplayerSpawner will also sync the name there shouldn’t be a worry (but since you are peer-to-peer maybe should), and yes you can change it to whatever you like. It will have some funny characters in the name that is general godot add_child stuff to make it uniquely named. But if you don’t like that you can pass a parameter to add_child(new_node, true) to make it human readable.
If you are setting the name manually IDK if you need to worry about name collisions. But give it a try
I’m pretty confident it will avoid name collisions
If you want to save packet history to resolve conflicts, you may need to make a custom synchronizer with a script that pulls properties off of the synced object packs them with a time stamp in an array or dictionary, and send it off. For custom properties you need to export them in order to be added to the replication config.
Then When the remote synchronizer gets that array it unpacks it checks timestamps, or frame number, and puts the new data on the remote synched object. Then takes the array and saves it locally. You can trigger this event with the synchronized signal when the new data is received.