0 votes

i'm not sure how to retrieve data from server as a client, or rather send data from server to a certain client

on the server side, in script World.gd I have this function, here i spawn a player (and that works fine)

func spawn_player(spawn_pos, id):
  var player = Player.instance()
  player.position = spawn_pos
  player.name = String(id)
  player.set_network_master(id)
  $Players.add_child(player)

now in that function I want to send data from a global variable "player_list" to the player who just spawned

how would I approach this?

in Projects by (157 points)

alright I've done some research and now I'm even more confused
I can successfully send data from client to server, but I get error if i try to send from server to client
for example:
on my server I have function:

remote func test(t):
  print(t)

and from my client I send:

rpc_id(1, "test", "Hello")

and it works fine

but if I put my test function on client, and send:

rpc_id(id, "test", "Hello")

from the server, it gives me error:

ERROR: Node not found: World.
At: scene/main/node.cpp:1381
ERROR: _process_get_node: Failed to get path from RPC: World.
At: core/io/multiplayer_api.cpp:256
ERROR: Invalid packet received. Requested node was not found.
At: core/io/multiplayer_api.cpp:204

and yes I made sure both client and server have matching nodes

1 Answer

+1 vote

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.

by (754 points)
edited by
Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to webmaster@godotengine.org with your username.

Categories