Networking can be quite confusing when we just get started. Same for me.
So yeah, rpc is a good way Godot provides that allows you to remote call a function, that's great. However, it needs both sides scenes structures to be exactly the same, including the names.
That may be okay, but sometimes we may prefer using two different scenes structures for the server and the client so it will be convenient. Keeping everything the same can restrict us a lot.
So, actually you don't have to keep the nodes the same, except the root node. For example, you have the node WORLD
as the root, keep the name the same on both sides, and put two functions like send_data_to(id, data)
and data_received(data)
. For function data_received(data)
remeber to add remote
, like this: remote function data_received(data)
You only need the keep the name "WORLD" the same, inside the sciripts, you can do whatever you want, But whenever we send or receive data, we go through the node WORLD
.
Without directly remote call a function inside the scene, this may seem to be a little bit inconvenient, but it's actually okay, it works quite well without needing to worry about keeping the scenes structures the same on both side and that kind of errors.
So to help to control how data comes and goes through just two functions, actually we can add data_received(data)
in different scenes too, except that these functions are not for remote calls. To send a data, you can do it like this: data = {"path": "/root/WORLD/Player", "Type": "Position Update", "Position": Player.position}
. Inside the function data_received(data)
you can do it like this: if data.has("path"): get_node(data.path).data_received(data)
so the data will be send to the scenes you want, and so we don't have to do everything within just one script that is attached to the node WORLD.
Also, here's how I set up networks of server and clients, it might help:
For server:
var ENET = NetworkedMultiplayerENet.new()
ENET.create_server(PORT, MAX_PLAYER_NUMBER)
get_tree().set_network_peer(ENET)
For client:
var ENET = NetworkedMultiplayerENet.new()
ENET.create_client(SERVER_IP, PORT)
get_tree().set_network_peer(ENET)
To send data, we need to use rpc function.
So:
function send_data_to(id, data):
rpc_id(id, "data_received", data)
For the same function on client side, you can just replace the id to 1, which means the server. Also, don't directly send data from client to client, try to go through the server first, because server is there to keep things under control and keep data flow in order.