Why is the multiplayer the way it is?

First of all, I never worked with networking until now, and maybe it’s just a standard practice when doing networking stuff, but I keep asking myself why Godot uses these “RPC” methods.
Why not just have one method to send things, with arguments for the client ID and data that should be send, and then have a in-build method like _event() or _process() that gets called when some data arrives.
With the current method, I can’t have (by default) the client-side scene and the server-side scene be different, because then the node paths would get messed up.
The reason I’m asking this is because

  1. I want to understand Godots design better
  2. I want to make a singleton that will provide the same behavior that I described earlier (global send method, overwritable receive method) and want to know if there are any problems with this approach.

I’m working on a network game myself.

I’m wondering if you have checked out the multiplayer nodes?

For tree matching it reduces the need for the developer to specify where the data should go, and you can have rpc calls independent for each node that wants to transfer data to it’s remote instances. “Node to node” talking. It isn’t direct talking because the data is packetized by the server.

A benefit of RPC annotations to add network functionality is that it makes it easier to port existing code with no change to current functionality.

They can technically be different just as long as the tree shape and node names are the same and the RPC api exists within the node.

I think you want to have node to Singleton to remote Singleton to remote node. This to me is makes little sense because the network server architecture is already doing this by abstracting the data path with the rpc functions. The RPC annotations add hidden functionality to scripts so the network code can collect all the data to send to remote clients, unpack and distribute to the correct nodes.

Also having a master function that you can express many outcomes via parameters is technically a bad coding practice. And to my knowledge there are only two RPC functions? The annotations have taken over the most complexity of the setup.

I think that the RPC design comes from the fact that when you start writing code to send and receive packets, you end up with a lot of glue code that just goes “if this is the packet type, call this other method”. RPCs do the exact same, without you needing to write all that glue code. This pattern exists in a lot of Unity frameworks as well ( Mirror, Fish, their own ).

Even if you look at backend development, like Spring, you have a very similar thing - you annotate your methods and the framework manages the glue code for you.

And don’t worry, to my understanding, you don’t need to have the same scene on both sides. All you need is to have the nodes on the same path that are actually using RPCs. For example if you have an autoload, its path will always be the same on all game instances.

1 Like

You should look at the dev blogs for Godot 4 there are 2 or 3, I think they could help on understanding the purpose and architecture to a degree.