This is a Server-Autoritative PlayerController implementation for my unity game.
It works perfectly, but since its Server-Autoritative, clients need to send all movement to the server and wait until the position update is received. This makes movement on clients feel delayed, and is of course not how it should work.
How can I implement the standard practice where the client immediately updates himself and sends the movement to the server?
The server should then validate the movement and send the update to all players except the sender. If there’s something wrong with the movement, send the update to all clients to correct the sender.
There are numerous articles on that topic and not too hard to find.
For a start, make the player movement client authoritative. NetworkTransform will automatically sync the position updates to other players. This usually suffices anyway since NGO isn’t designed for competitive fast-paced multiplayer where you may need the server to validate. For instance, you also don’t get reconciliation that favors the shooter when determining hits (by simulating past game state).
This is going to be an issue. For online multiplayer, you practically cannot use a dynamic RigidBody to control your players. It’s got to use only kinematic physics.
For one, if the client directly controls the player, it will feel alright for the player but it will mess up the physics simulation for other clients due to the latency. If you let the server control dynamic physics, you end with the same issue as you have right now.
Avoid networked physics simulation in online multiplayer for anything but visual details (not affecting gameplay).
Any approach you take will be a compromise on something, depending on which person has authority over which thing. Broadly the three choices you have are:
Client-authoritative movement. This gives the player instant feedback and keeps their local movement snappy, but your server has to trust the player as technically someone could hack the client to cheat. It also means that you may see your character very slightly ahead of where other players see you, due to latency. Most action games use this approach and then do some server-side cheat detection.
Server-authoritative movement. This means all movement is sent to the server and executed there, and the player gets the updates on position from the server just like everyone else. The player will experience input delays as if playing on a remote computer, but they will see exactly the same thing as everyone else. This approach is suitable for low-input games where you issue small numbers of discrete orders to units such as an RTS.
Server-authoritative movement with client-side sync. This is the same as server-authoritative except that the player’s local client shows them the results of their input immediately. For example, you move your character and it seems to move instantly on your machine but also sends the command to the server and everyone gets updates on position based on where the server says it is. This has the problem that the server and your client can easily become desynced, where you see something happen one way but it happens differently on the server due to timing issues. This requires a complex system of resyncing and unwinding local actions, and players with bad desync will see a lot of rubber-banding. Unity doesn’t have a standard solution for any of this.
Ultimately, the most suitable form for an action game is to make the player client-authoritative using a ClientNetworkTransform and then if you’re worried about cheating you can handle it another way. When the player is client-authoritative their own rigidbody will be non-kinematic on their machine and kinematic to everyone else, so you can do rigidbody-based movement. The physics will be simulated only on the owner’s client, and then the other players will just see the results as the position updates due to the NetworkTransform.
Be aware that Unity has some visual oddness with NetworkTransform/ClientNetworkTransform, animation, and rigidbody physics not staying fully in sync, so other people may see your jump weirdly mis-timed, almost like it stalls for a fraction of a second. Unity suggests adding a NetworkRigidbody to help improve the sync in these cases, but it may still happen.
I personally went the route of server authoritative with client side prediction. It was not easy to get working and smooth but was well worth the time. Granted some things I had going for me was it is a 2D multiplayer game but are similar in 3D and I wrote the server/network layer. I have links to some articles in my main post that may help: