GodsVictory

Multiplayer desync

Recommended Posts

What am I doing wrong here. Normal movement is fine, but when boost is applied, there is rubber banding at the end.

I'm using client/server model to implement movement.

 

pseudo code:

Client sends inputs to server

Client process inputs and displays locally

Server receives inputs and calculates where client should be

Server emit client coordinates

Client receives update and applies coordinates

Client reapply all inputs made after the last server update

 

Player class: https://github.com/GodsVictory/SuperOnRoad/blob/wip/public/js/player.js

Server code: https://github.com/GodsVictory/SuperOnRoad/blob/wip/server.js

Share this post


Link to post
Share on other sites

server.js line 55: You use for loop, but then use `inputs.shift()`, which manipulates the array in place. Maybe it's different in JS, but you probably want to use `while(inputs.length > 0)` instead of the for loop. Otherwise you might have issues once there's more than 1 input at a time.

I strongly recommend to refactor the code, so that game logic that's shared between the client and the server is separate and shared. You should use the same code to apply update on a player instance on both. This removes code duplication and down the road will save you lot of headaches (that code duplication almost always causes).

On the client side you cache all the inputs in `updates` array forever it seems. There's no reason to keep the confirmed inputs, they can be thrown away. I suggest using some big enough circular buffer instead.

As for the actual trouble you have: I'm not 100% sure, at first I thought you weren't properly syncing the `lastBoost` variable, but that one is part of the inputs (which might not be a good idea either, see below), so it should work properly. The only thing I noticed is that it seems you apply the last input twice on the client. First you push it to the `updates` and then you iterate all updates and then once again apply this latest `data` update.
Maybe this isn't the cause of the issue, but certainly something to check. I recommend inspecting values and trying to find out at what point the reconciliation result becomes different than expected.

Regarding sending `lastBoost` and `time` as part of the input data to server: If the server is supposed to be authoritative, all that should be sent are the inputs and the server should simulate it all. Otherwise what stops me from saying my `lastBoost` time is constantly 0 even though I am boosting? Even the delta time shouldn't really be sent, although that is a design decision that might be needed if you need perfect reconciliation results. I do in my game and I went about this in a slightly different way (constant timestep).

You can read about my approach on my blog: https://antriel.com/categories/multiplayer-platformer/. While it doesn't yet solve all the issues like time synchronization and entity interpolation, that article should come next week :)

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Recently Browsing   0 members

    No registered users viewing this page.