Godot: RPC call doesn't reach other clients on new connection

Created on 26 Apr 2018  路  12Comments  路  Source: godotengine/godot

Godot version:
3.0.2

OS/device including version:
Tested on Windows10 64 Bit, probably affects all platforms

Issue description:
when calling from the connected_to_server signal RPC calls to a function like remote func foo() are only called on the remote server, but not other clients.

This is probably due to the client not having established connections to the other clients yet.

This breaks sample code from the Documentation on Networking
It will not work properly when 2 or more clients connect to the server with older clients missing information on newer clients due to this bug

see: https://godot.readthedocs.io/en/latest/tutorials/networking/high_level_multiplayer.html#back-to-lobby

Steps to reproduce:

  1. Start up the reproduction project
  2. build it so that you can run it multiple times
  3. run the first instance and click on MakeServer
  4. run a second instance and click on MakeClient (...so far so good)
  5. run another instance with checkbox either ON or OFF, and click on MakeClient**
  6. observe the console log window of the other clients to see who gets the RPC call and who doesn't**
  7. repeat step 5 and 6

you will observe that without the 0.1 sec timer, only the server will get the rpc call, while with the timer all clients will get the rpc call.

Minimal reproduction project:
RPC_bug.zip

bug discussion documentation network

Most helpful comment

I guess that makes sense yes, but as @ThunderFD mentioned, the doc should be updated :)

This (is wrong)

func _connected_ok():
    # Only called on clients, not server. Send my ID and info to all the other peers
    rpc("register_player", get_tree().get_network_unique_id(), my_info)

should be something like

func _connected_ok():
    # Since _connected_ok is called by the signal connected_to_server, you can only send rpc to the server here
    rpc_id(1, "register_player", get_tree().get_network_unique_id(), my_info)

All 12 comments

This is still relevant in 3.0.6, any news?

CC @godotengine/network

This is mostly by design, and I don't think it can/should be fixed.
It should be better documented and the rationale explained.
I'll try to give a more in detail explanation on the why as soon as I get some time.
The very brief explanation is that, even if we wait for all the peers to be sent before firing the event, concurrency problems when 2 peers connect at the same time will still exists, somehow hiding the issue in the game network code design and causing even more surprising results.

PS. the solution is to either use peer_connected in those cases where you want p2p communication, or keep using connected_to_server but rpc_id(1, ...) and then have the server replicate to peers when using authoritative server.
Again, I'll try to give a more in-detail explanation as soon as I have some more time.

yeah when I ran into this I was wondering why this wasn't handled differently in the example project from the documentation.
just having something that's wrong in the docs is kinda bad^^

I guess that makes sense yes, but as @ThunderFD mentioned, the doc should be updated :)

This (is wrong)

func _connected_ok():
    # Only called on clients, not server. Send my ID and info to all the other peers
    rpc("register_player", get_tree().get_network_unique_id(), my_info)

should be something like

func _connected_ok():
    # Since _connected_ok is called by the signal connected_to_server, you can only send rpc to the server here
    rpc_id(1, "register_player", get_tree().get_network_unique_id(), my_info)

Indeed, this really needs to be fixed in the docs. :) Thanks for pointing it out.

@Faless Can you confirm my understanding. Basically the RPC calls do work, just fine executing on each peer, with the caller making a call to each peer 1 at a time. But there is some sync that must occur that takes a few seconds.
What I don't know is, if the calls are actually going peer to peer or are they peer> to server> to peer? Seems like this is the case since attempts to get a Peer's IP address from a Peer on a RPC call fails, although this could just be a security method that hides the information.

**ERROR**: Condition ' !is_server() && p_peer_id != 1 ' is true. returned: IP_Address()
10-27 12:05:31.324 21026 21039 E godot   :    At: modules/enet/networked_multiplayer_enet.cpp:761:get_peer_address() - Condition ' !is_server() && p_peer_id != 1 ' is true. returned: IP_Address()
10-27 12:05:31.324 21026 21039 I godot   : Test Peer IP = 
10-27 12:05:31.324 21026 21039 E godot   : **ERROR**: Condition ' !is_server() && p_peer_id != 1 ' is true. returned: 0
10-27 12:05:31.324 21026 21039 E godot   :    At: modules/enet/networked_multiplayer_enet.cpp:777:get_peer_port() - Condition ' !is_server() && p_peer_id != 1 ' is true. returned: 0
10-27 12:05:31.324 21026 21039 I godot   : Test Peer Port = 0

How long does this synchronization take, the likely answer how fast is your network, Ok good point. How big is the data, the likely answer how many peers are connected, OK. How big is the data with 1 peer and 1 server?
I think with this information I can update the docs.

@FeralBytes the architecture of NetworkedMultiplayerENet is client/server for now (even if the high level API itself could be P2P), so there is no real p2p connection with ENet, everything is relayed by the server.

How long does this synchronization take

Each peer is available when the signal peer_connected(id) (network_peer_connected in Tree).
The data is (8 bytes + ENet overhead) * peers. Each peer is sent in a separated packet, in a reliable way.
You really should not use a timer for waiting the peers to be available, but use peer_connected to know when they connect instead.

Ping @godotengine/network, IIUC the docs need an update?

@akien-mga imo definitely, the example code in the docs is broken and does not work. They need to be changed to get rid of the rpc call on _connected_ok

For me the reason was that I was accidentally using 2 different versions of Godot instances to test the game.

Was this page helpful?
0 / 5 - 0 ratings