Let’s say I have a Player scene that has a MultiplayerSynchronizer node which is configured with client-controlled properties such as position and rotation. For those properties to be effectively controlled by the user whose avatar is this scene, it needs to be set its multiplayer authority to the peer id of his or her game instance. However, if doing so, no RPC can be called from the server to that player’s script, unless the function being called is annotated with “any_peer”, but this is a major security issue as anyone could call critical functiouns that normally only the server would be allowed to call
I’ve read tutorials and posts where people solve this by setting only the multiplayer authority of the Synchronizer that holds the client-controlled properties to the client id, and letting the rest be possessed by default id 1. But in my experience trying to replicate this, it doesnt work. Authority of the parent of the client-side properties’ Synchronizer must be set to the client peer_id, and it seems to not matter what the authority of the Synchronizer itself is. How is this usually solved? Thanks in advance
I haven’t tested this myself, but a thing or two to try for the split setup. What if you set the Synchronizer’s authority in _enter_tree instead of _ready? From what I read, doing it after the node is in the tree can fail to take effect since the Synchronizer starts its replication during tree entry.
Something like naming the player node after the peer id and then:
Also make sure that call runs on every peer, authority changes don’t replicate automatically. The _enter_tree approach should cover that since the scene enters the tree on everyone.
If that works, the root keeps authority 1 and the server should be able to call plain authority RPCs on the player script without any_peer.
Of course, I did just that in _enter_tree, as shown in most tutorials, and thats when the things didnt worked as expected; that’s why Im asking.
In the inspector, while running the game, authority of synchronizers on all player scenes (and in all sessions) appear as correct: only the synchronizer that manages client-controlled properties is set its authority to the peer_id of its owner; the rest, including the root node of the Player scene itself, is set authority 1. And thats precisely when the error occurs. Only the server player can be controlled: the other players shackles as if they try to respond to input, but the synchronizers seems to mantain them in their place. In the other instances, however, input does nothing, and they stay quiet in their place. Notice that it all gets fixed if I do set_multiplayer_authority(name.to_int()) in the _enter_tree after calling it for synchronizer. Thats why I think Im missing something about the multiplayer system
Gotcha, mb. So what does the movement gate in your player script look like? If it’s something like if not is_multiplayer_authority(): return called on the player root, that check reads the root’s authority, which is 1 everywhere in the split setup. So the server would try to simulate every player with its own input while the client owned Synchronizer keeps snapping the position back, and the clients would never run their own movement code at all. I think that could explain both the jitter on the server side and the dead input on the clients, and why handing the root to the peer fixes everything at once.
If that’s the case, might be worth trying to gate the movement on the Synchronizer’s authority instead of the root’s:
func _physics_process(delta):
if not $MultiplayerSynchronizer.is_multiplayer_authority():
return
That way the root stays at authority 1 so the server can call plain authority RPCs on the script, and the movement only runs on the peer that owns the synced properties.