S&box Wiki

Revision Difference

Prediction#549155

# What is Prediction Prediction is a technique used in online games that allows for smoother gameplay by predicting what will happen next instead of waiting for the server to respond. The process involves running input logic locally while waiting for the server's response to the input. The client compares the server's response with its predictions, and if there is an error, it re-runs the commands to fix the problem. # Why use Prediction Without prediction, there is a delay between the player’s input and the game's response. For instance, in a first-person shooter game, when the player shoots a weapon, without prediction, there would be a delay between the player pressing the button, the server processing the command, and the player seeing the results. This delay can range anywhere from 30 milliseconds to half a second, depending on network latency. This delay would be very obvious to the player and would make the game seem unresponsive or laggy as a result. # What Should be Predicted Anything that involves direct input of the player interacting with networked entities should be predicted. For example, movement code should match on both client and server. In weapons, variables such as ammo count and animations can be predicted. Also see: [Input](https://wiki.facepunch.com/sbox/Input_System) Dynamic physics cannot be predicted as the physics engine is inherently non-deterministic. Only deterministic things, i.e. things that can be consistently calculated with the same end result on both client and server, can be predicted. Deterministic things like [Traces](https://wiki.facepunch.com/sbox/Traces), which will always produce the same results, can be used for prediction. # Prediction Errors A prediction error occurs when the client's prediction of an action differs from the server's actual response. This can result in jittery or inconsistent gameplay. Prediction errors can be caused by poor coding, lag spikes, dropped packets, and other factors. Prediction errors aren't inherently "bad". It just indicates that there was a difference between server and client, so the server corrected the value. **The server always has authority over networked values at the end of the day.** ## Fixing Prediction Errors To fix a prediction error, you should: 1. Identify the property that was mis-predicted. The prediction error should reference the property name. 2. Find all the code segments that alter the property, and ensure that they run consistently on both the client and server. 3. Check whether all the logic is predictable and running on both the client and server in a predictable context. # Prediction in Practise The main entry point for prediction is the `Simulate( IClient cl )` function in your GameManager class. By default, the client's pawn will have its Simulate function called, which is where the player's actions can be predicted. ``` public override void Simulate( IClient cl ) { cl.Pawn?.Simulate( cl ); } ``` Any entity that has the predicted client as its Owner can be Simulated this way. So, for example, you might Simulate an active weapon in your pawn's Simulate method to allow the weapons to fire in a predicted way. Predictable properties can be created by using the [Predicted] attribute: ``` [Net, Predicted] public float Stamina { get; set; } = 100; ``` Predicted properties can then be Predicted in any valid predictable context: ``` public override void Simulate( IClient client ) { if ( Input.Down( InputButton.Run ) ) Stamina -= Time.Delta * 10f; } ``` # Specific Behavior In the case of effects like sounds and particles being predicted, the client will simulate them locally, while the server will tell clients to play things such as a shot sound via RPCs. To prevent the local client from getting sound RPCs for sounds they've already heard, the RPCs get culled and won't be played again as a result. ## Disabling Prediction ⤶ Sometimes, however, you might want to force the client to hear a sound, for example, if you shot something and someone died; in these cases, you can turn prediction off like so:⤶ ⤶ For logic that branches off from the main simulation loop but cannot be predicted, you'd turn off prediction within a specific scope:⤶ ``` using ( Prediction.Off() ) { // Play sound here⤶ // Non-predictable logic⤶ } ``` ⤶ <validate>RPC culling should work fine if it's predicted right. Prediction.Off should only really be for things that cannot be predicted in the first place.</validate>⤶ ⤶ ## First Time Predicted ⤶ ⤶ ## First Time Predicted As mentioned at the beginning. The client may sometimes re-run predicted ticks to try and correct predicted properties. In this instance, client-side effects might be run multiple times. To prevent this behavior, you can use `Prediction.FirstTime` to check if the code is currently re-running prediction or not. ``` if ( Prediction.FirstTime ) { // Play client-side effects } ```