Prediction refers to one of the systems Source (and Source 2) uses to smooth out the multiplayer experience, this system 'predicts' what effects a player's input will have on the world (by running the same calculations the server does multiple times and comparing them) and displays the result without having to wait for the server to both receive the player's input and send the result back.
Without prediction the game would be effectively unplayable for anyone with more than 50ms of ping, only getting worse as it increases further. Incorrectly setting up prediction can lead to all sorts of issues in multiplayer such as:
- Sluggish/slow responses to player input
- Duplicated effects/animations
- Broken hit registration
Prediction should be used for anything that is directly affected by a player's inputs, this includes:
- The player itself
- Any controllers or animators attached to the player
- The player's ActiveChild (Weapons and other
IPlayerControllableentities like vehicles)
Technically every entity with a player as it's owner is predictable, but those are the main ones you should be worried about.
If you've ever wondered why the Half-Life 2 vehicles don't handle well in multiplayer, this is why.
Prediction isn't something you can start yourself, it's a context that is set by the engine for certain methods (and any code that branches off from those methods) These methods are:
TimeSinceand check for completion in subsequent calls instead if you need to delay something
Player.Simulate( Client client )which calls
ActiveChild.Simulate( Client client )by default
PlayerController.Simulate( Client client )
PlayerAnimator.Simulate( Client client )
Adding prediction to an entity is fairly straightforward if you know what you're doing.
- Keep your code the same between client and server as much as possible
- Mark any networked properties that change during predicted hooks with
- Wrap clientside code that isn't supposed to be predicted (think notifications) in
using (Prediction.Off())to keep them from running multiple times
If you've done all of this the end result might look something like this example based on dm98: