Godot Version
4.4.1 .NET (.NET is needed only for compatibility with some external libraries. This question is all gdscript)
Question
I’m trying to do multiplayer in Godot for the first time. I’m a little confused about the rpc method tag. I have this function at a scene root that I run with 2 instances:
@rpc("any_peer", "call_remote")
func relay_make_choice_remote(data:Dictionary, actor):
print("relaying choice from ", multiplayer.get_remote_sender_id(), " to ", multiplayer.get_unique_id())
make_choice_remote.emit(data, actor)
It is called by a signal from lower in the scene.
In the same script, I have a very brief multiplayer setup (courtesy of this yt tutorial):
#Called when the "Host" button is pressed.
func _on_host_pressed() -> void:
peer.create_server(port)
multiplayer.multiplayer_peer = peer
#pass the id of connecting players to a player constructor
multiplayer.peer_connected.connect(_add_player)
#create a player for the host to use
var player = _add_player(1)
print("created server on port ", port)
#The "player" is not relevant as of yet. Just the existence of the host and client.
func _add_player(id:int) -> Node:
if !player_scene: return null
var player = player_scene.instantiate()
player.name = str(id)
#add the player to the tree
add_child.call_deferred(player)
print("Created player ", player)
return player
#Called when the "Join" button is pressed.
func _on_join_pressed() -> void:
peer.create_client("localhost", port)
multiplayer.multiplayer_peer = peer
print("connected to server ", peer)
Since the default host id is “1”, I would expect the result when triggering the signal connected to relay_make_choice_remote
to be something like “relaying choice from 1 to 2”, and the result of the same signal in the second instance “relaying choice from 2 to 1.” However, the results are “relaying choice from 0 to 1” (host instance) and “relaying choice from 0 to 745385639” (client instance). That’s not what I expected at all!
Next, I added a Label to my scene displaying the number of times the make_choice_remote
signal had been received. I kind of expected this, but it’s still disappointing that each instance was basically sending the signal to themselves. This was the case whether or not I used “call_remote” or “call_local” in the @rpc
tags.
My question is: What am I doing wrong? Is it possible to send a call between peers using a signal?
Context
I have a dialogue system that I’m trying to port to multiplayer. After looking at some tutorials, I feel I know the easiest way to approach this. I’m not sure how relevant the exact approach is to my problem. But, if you’re willing, brace yourself for a slightly abstract explanation:
All clients have a copy of the dialogue tree, which is loaded from a file. Each copy of the dialogue tree can tell who is trying to access it by a character name (actor
in the code above), and is able to display available choices, and process incoming choices using that character as context. This part of the code is finished, and works quite well.
Then, the different clients can send choices to each other over the internet… Just the local network would be good for now. Then, each local copy of the dialogue processes the choices coming in over the network to allow for progress through the dialogue tree in all instances.
In theory, this is as simple to implement as completing that relay_make_choice_remote
method above!