I have been implementing my own networking for a third person multiplayer game, but controls and physics will be ala old school FPSs. I'm using Unity's transport layer, which allows me to send and recieve raw data between server and client.

I used this model as reference, in order to implement better client response: http://www.gabrielgambetta.com/client-server-game-architecture.html

Implementing prediction, and interpolation was no problem, but I'm having a problem implementing reconciliation, even though I successfully implemented for normal ground movement.

I do the following each tick:

  • Client: The client sends the server the delta updates on the player position, and the server validates this movement and updates the player accordingly on the server.
  • Server: I send a snapshot to all clients with all players' positions. Each client interpolates the rest of the players, and reconciliates it's own position.


Ground movement seems easy, because each frame the player input determines how the player moves: Each FixedUpdate, the player moves a certain distance. This makes reconciliation really easy, since knowing which was the last input the server has received, your client just needs to consider the rest of the inputs yet to be processed.

Reconciliating jumping

But I don't know how to deal with jumping. Jumping is an input that has an impact on the player's position over several frames: while it's airborne (and for a few frames, as the placer decelerates in case his air speed was high).

This means I can't just rely on the input "jump" to recalculate my client's position, since depending on the moment I'm present, I could be ascending, or descending. Even more, if I jump and collide with the roof, killing all my vertical speed, the movement would be completelly different.

This lead me to think I should be sending to the server each update on the player's position: Instead of sending "hey, im jumping here", I could send "I'm moving up 1 unit"..."I'm moving up 0.9 units".... describing the players parabole. But I feel this method is not enterily secure, since the client could be sending "I'm moving up 1" ever single time, allowing the player to just fly away. So the server has to be the one handling the physics on the jump.

Other scenerios

This problem is also present in anything physics related: When the player is pushed away by an external force set up by the server or the client itself. If the client recieves a message saying has been affected by an explosion, I could set the client's speed accordingly, but: - If I have any kind of air control (which I want to have), I need to tell the server the change on air speed - If the server makes a correction on the physics made, I need to be able to predict and reconciliate the position AND speed. For example: If I collide against a wall in the server, which for some reason, is not present in the client, I also need to kill the player speed or it will keep slamming into an invisible wall.

Posible solutions

There are several solutions I was thinking about, but I'm not really satisfied with any of them:

  • As said earlier, I could could let the client handle the air movement by sending the position update back to the server, but this feels insecure since th client could technically make himself fly around, and make himself immune to being pushed away.
  • Besides sending the player positions, I could also send the players' speed, storing this information could make reconciliation easier and more reliable, but it will also increase the size of snapshots and network usage.

Maybe I'm missing a clever alternative, but I don't really see any other option. Any ideas?

  • \$\begingroup\$ "This means I can't just rely on the input "jump" to recalculate my client's position" I'm not sure if I follow this reasoning. Knowing the position and velocity of the player when they hit jump (or applied mid-air control), we can use a ballistic equation to predict where they'll be at some arbitrary time t, and we can check for collisions that would change the velocity and break the curve using physics casts. \$\endgroup\$ – DMGregory Jun 2 '18 at 12:12
  • \$\begingroup\$ Maybe the issue is how my setup is built. For ground movement, if i move forward one FixedUpdate, and then right in the next FixedUpdate i move right, when the next client tick is processed, I just process a diagonal movement (forward + right). But in the case of moving forward and then jumping, I'd be sending a jump + forward command, which would be the same tick as jumping and then moving forward, which is not the same as air control is much slower. Maybe I should lower my fixed update to match the clint tick, and send each update through the network, to avoid this issue altogether? \$\endgroup\$ – Leo Jun 2 '18 at 12:31
  • \$\begingroup\$ Or you can send your updates with sequence information, so the server can distinguish jump + forward from forward + jump and simulate each accordingly. That will probably give smoother behaviour and less noticeable glitches than lowering your fixed update tick. \$\endgroup\$ – DMGregory Jun 2 '18 at 12:38
  • \$\begingroup\$ That would be fixed, yes. But in this case: if I'm mid-air, and I get corrected by the server mid-air, in order to reconciliate my position, I don't really know what the next position will be even if I have my old input, because the height change would depen on at wichi point of the jump I'm in. Unless, of couse, I send back to the client the position AND the speed (that would be my second posible solution in the question), since currently I'm only sending back to the player it's position. \$\endgroup\$ – Leo Jun 2 '18 at 13:14
  • \$\begingroup\$ I have read how Q3 handles networking, how it manages snapshots and messages, but I never seen what actually is sent back to the client, and how the client reconciliates, so I don't relly know how much data would be considered too much. \$\endgroup\$ – Leo Jun 2 '18 at 13:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.