Jump to content

Client side prediction for multiplayer games


Recommended Posts

I'm trying to understand how to apply client side prediction to improve user input responsiveness when there is significant lag.  When there is lag, changes to every object in the game is lagged as well.  So I'm trying to understand how improving the responsiveness WRT user keypresses would work if everything else is not responsive.

 

Link to comment
Share on other sites

You effectively have 2 simulations running, one locally for the user and one on the server. Depends on how you set this up but often the authoritative one is the server, i.e. if there is a conflict then the server state wins, this is why games often jump into a different state when the lag is resolved.

User object prediction is easy as there is no prediction, you simply take the user input and update state. You'll still have to send all those inputs to the server, often this is not possible, the game is already lagging, so those packets often get discarded and when the simulation resumes the server state wins and your local version 'forgets' that input and resumes from the server state.

The prediction for other objects in your world is similar, during periods of lag your local copy makes guesses (predicts) movement and maybe other stuff to, when the lag is resolved you have to sync up the local state with the server state once more.

There are a few different ways that all this can happen.

If the server sends the state of the entire world with each update then things are super easy, you simply accept that state from the server and render the local world using that state. However, depending on your game this is likely unfeasible, the state object will likely be prohibitively large to send at regular quick intervals, plus, most of your state is redundant anyway, its not usual that everything in your world changes state from one tick to the next. Prediction is tricky here as the client is reliant on the server.

You could simplify the state model by only passing changes through the pipe, in this manner the client is effectively dumb, it does not run a simulation and it is only responsible for rendering the world and passing user inputs back to the server. This is a great way to go and strikes a good balance between packet weight and separation of concerns, you have no awkward syncing or state resolution and all your logic lives in one place. However, the packet weight can still get large if you have many changes happening each tick, usually this can be resolved by limiting the size of your world i.e. clients at one end of your world usually don't need to know about changes at the other so you can split them up. This does make prediction difficult though as the client is still totally reliant on the server.

A more complex architecture might only pass entity actions or behaviours between clients and server, for example, an entity could be facing a certain direction and moving at a certain speed. The client can run the same simulation as the server, when something happens, like a change of direction, only that change of behaviour is communicated and both client and server continue running the simulation. This requires that the simulation on client and server is the same and there will be syncing issues but this does let you predict what is going to happen i.e. if an entity is moving left (using cardinal directions as an example) then its probably going to continue moving left so in the absence of intention change thats exactly what the client simulation would do, when the client gets reconnected to the server, if the entity has indeed maintained direction and speed then all is good and the user will not have noticed any lag at all.

However, this last model does make things far more complicated, you'll still have to do state resolution as changes may have occurred and if the state is not eventually consistent between client and server then you are in for trouble.

In practise you'll probably want to do something between the two extremes i.e. you still resolve state based on the server state model which involves passing a fair amount of data about the world, but you'll likely also want to pass stuff regarding entity intentions/behaviours so that your client can also run a simulation.

Passing only what changes is usually required (dependent on the game) and declaratively passing actions can help to simplify i.e. tell the client to move entity X forward and let the client work out how vs tell the client to move entity X to position <X,Y,Z>.

Link to comment
Share on other sites

I understand how user object prediction is easy, since you're the one creating the events.  But for other objects, such as certain AI bots is instantiated on the server side, I'm not sure how client prediction can help.  Especially if their movement is not very predictable.

Link to comment
Share on other sites

  • 4 years later...
On 5/18/2016 at 6:04 PM, StrawberryJam said:

I understand how user object prediction is easy, since you're the one creating the events.  But for other objects, such as certain AI bots is instantiated on the server side, I'm not sure how client prediction can help.  Especially if their movement is not very predictable.

have you figured out how client side prediction works for AI bots

Link to comment
Share on other sites

  • 4 weeks later...

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...