I'm having trouble getting my RPCs to work

Godot Version

4.3

Question

I’m having trouble finding out what I’m doing wrong regarding RPCs. I got a much better understanding from one of my previous posts:

(I'm trying to understand the logic and use cases of RPCs in relation to server-authoritative gameplay on a dedicated server)

However, when trying to synchronize my move and jump functions, it doesn’t work. This confuses me, because the multiplayer synchronizer works and that uses RPCs.

I could use the multiplayer sync node. However, I need more fine control of what is being replicated and when. Plus, I’ll need to be able to fine tune around additional network features like client prediction, rollback, etc.

So, here are my specific questions (The relevant code is below):

  1. Why doesn’t my jump.rpc() event work? I’d love some insight so I can implement RPCs properly.
  2. Can you use RPCs to sync player movement? I’d love to for the reasons above.
  3. A little unrelated, should I disable the _process() and _physics_process() nodes on the player if they aren’t the authority over their player character? Will this cause and potential issues?
  4. Very unrelated, do you guys have any other misc networking tips from your own experiences?

Main Script

Dedicated Server Creation (From the same project): [This Works]

Client Creation (It automatically connects to my own server instance): [This Works]

Server Signal Connections: [This Works]
image

Player Spawning Function (I’m not sure if the RPC does anything) [This Works]:

Player Despawning Function: (I’m not sure if the RPC does anything) [This Works]

Player Script

Give Client Control Over Their Player: [This Works]

_process(): [Not sure if this works over the network]
image

_physics_process(): [Not sure if this works over the network]
image

Jump RPC: [Does NOT work over the network]
image

Movement RPC: [Does NOT work over the network]

  1. Did you actually set the multiplayer authority somewhere?
  2. Yes you can, you probably want to use “unreliable” in this case, if you call the rpc every frame (As you mentioned above the synchronizer uses the same technology)
  3. You can disable process and physics-process if you dont need to run them on the other player. This will only cause issues if you have code that you want to run regardless of the authority
  4. I personally only synchronize the input and then every player on every peer calculates the results on that input, this means i dont need to call any rpcs for anything basically, but this depends on the game you are trying to make
1 Like

@herrspaten
When you say “multiplayer authority” it could mean one of two things.

  1. The dedicated server has authority over all clients.
  2. The client can only control their character.

Which one is it?

Also, I’m developing a MVP for a real-time third-person shooter with a dedicated server model.

I’ve done some tests with RPCs and learned a little more about them.

However, i think I’m optimising prematurely. I’ll use the Multiplayer Synchronizer until i need to do otherwise.

with authority i mean the person thats supposed to control the player

Yes, I did set that. Not to sound condescending, bid you not read the code I provided?

Yes sorry must have missed the enter_tree method. Can you put a print statement inside your jump-method to check if its being called?

if Input.is_action_just_pressed("jump"):
    print("Trying to Jump")
    Jump.rpc()

...
@rpc(...)
func Jump():
    print(name + " jumps")
    ...
1 Like

@herrspaten
I did a series of tests earlier today to reconfirm how RPCs work for a dedicated server model (Please read the whole thing)





image

Even with all this info, the jump RPC still didn’t replicate on all clients.

Moving the character works right? Because your move_and_slide-method is inside physics_process and you set it to false if its not the authority.
Thats the downside of disabling physics_process on the other characters :wink:

Nope. Movement doesn’t work either. I tested disabling and not disabling _process(): and _physics_process(): for good measure.

So you are sure “move_and_slide” is getting called?

To clarify. Have you tested the jump() rpc specifically like herrspaten suggested? From your screenshots it looks like you tested the Jump_Server() rpc which i’m guessing receives the jump input from clients. It might seem too basic to check a simple function like that but it really helps to be systematic because you’re trying to find your own blind-spot. Once you confirm that it’s not getting called you can go back one step to the server and confirm that the server makes the rpc. If that doesn’t work you can go back another step, etc. It’s a little tedious but you’re pretty much guaranteed to find the error if you go step by step.

I believe I have. I’m gonna figure this out myself.

Your jump and move have if statements that blocks the jump rpc from running on remote peers.

if not is_multiplayer_authority(): return

You need to remove these with RPC calls.

RPC authority can be dictated by the RPC definition @rpc('any_peer') and @rpc('authority')

Your intention is the player with authority should only be able to call the functions. Use the authority attribute. Is_multiplayer_authority() will only return true if peer’s multiplayer_id == node.authority

1 Like

I tried it. It didn’t work.

Try and get rid of the number at the end of the RPC declaration. You can let the transfer channel handle itself.

Or maybe just set it to 1?

I think it only matters if you use unreliable_ordered

1 Like

Nope. Didn’t work either when I leave the arg blank or set it to 1, 2, etc.

I reviewed your code again.

Your move RPC has no parameters. So it will be impossible to try and pull input on the remote end. It will most likely get your opponents input state. You should get the local input and send it via the RPC as a parameter. (Generally speaking it’s bad practice to pull input during the process function, use _unhandled_input instead)

The other issue is you set process to false on remote peers. This is fine but they will no longer update gravity, or move slide. This could be the culprit.

I would wrap some functions in the process to only be checked if they are the authority. But you should at least allow generic processing, like move and slide, on the remote peer.

(In most cases you would typically sync the position/velocity/rotation after everything has been updated by move_and_slide.)

1 Like

@pennyloafers
I changed up the script while trying out different solutions.

I can send you my entire project. It’s only 2 scripts and a few simple scenes. I’m really not sure what I’m doing wrong.

1 Like

Yeah, I can do that.

1 Like