Revision Difference
GameLoop#560465
<cat>Code.Intro</cat>
<title>The Game Loop</title>
<deprecated>Entities and Pawns no longer exist in the new scene system</deprecated>⤶
⤶
# Every Tick⤶
⤶
## Simulate⤶
⤶
<upload src="aa125/8dad928c44339ac.png" size="12517" name="image.png" />⤶
⤶
**Reference:**⤶
- [BaseGameManager.Simulate( Client )](https://asset.party/api/Sandbox.BaseGameManager.Simulate(IClient))⤶
- [Entity.Simulate( Client )](https://asset.party/api/Sandbox.Entity.Simulate(IClient))⤶
⤶
Every Tick (60 times a second by default), the client will send a **Command** to the server. This command gets simulated. This means it takes the inputs from the command (ie, new `ViewAngles`) and applies them to the Pawn (ie, set rotation to `ViewAngles`)⤶
⤶
While that's being sent to the server the Client also runs the same command locally. This is called Prediction. This allows inputs like walking, shooting and jumping to feel instant, with no ping delay.⤶
⤶
After the client runs the command it stores all of the changed entity variables and when the result for that tick comes back from the server it compares them. If they're different then a prediction error happened.⤶
⤶
⤶
# Every Frame⤶
⤶
These things are called every frame on the client.⤶
⤶
## BuildInput⤶
⤶
<upload src="aa125/8dad9296cb9a25d.png" size="9975" name="image.png" />⤶
⤶
**Reference:**⤶
- [BaseGameManager.BuildInput()](https://asset.party/api/Sandbox.BaseGameManager.BuildInput())⤶
- [Entity.BuildInput()](https://asset.party/api/Sandbox.Entity.BuildInput())⤶
⤶
Every frame we build our input. This converts input from your mouse, keyboard and controller into a Command that can be sent to the server on the next tick.⤶
⤶
Within `BuildInput` you can use [Input](https://asset.party/api/Sandbox.Input) functions in order to manipulate input - for example, clearing actions using [Input.ClearActions()](https://asset.party/api/Sandbox.Input.ClearActions()) - and in order to assign values to properties marked with [[ClientInput]](https://asset.party/api/Sandbox.ClientInputAttribute).⤶
⤶
This is done by passing a `InputBuilder` class down to the gamemode - which then passes it to the current camera and pawn. These callbacks are generally used to do things like change mouse movement into view angles.⤶
⤶
You can override all of this behaviour in your Game class by overriding `BuildInput`.⤶
⤶
## Frame Simulate⤶
⤶
<upload src="aa125/8dad929a6454e87.png" size="13852" name="image.png" />⤶
⤶
**Reference:**⤶
- [BaseGameManager.FrameSimulate( Client )](https://asset.party/api/Sandbox.BaseGameManager.FrameSimulate(IClient))⤶
- [Entity.FrameSimulate( Client )](https://asset.party/api/Sandbox.Entity.FrameSimulate(IClient))⤶
⤶
Because `Simulate` only happens once every tick (60fps by default) and players may have monitors capable of showing framerates much higher than that, things like view direction are going to feel pretty choppy clientside. To get around that mismatch, `FrameSimulate` is called every clientside frame to give the game an opportunity to smooth out anything that would otherwise be stuttery or choppy.⤶
⤶
This is commonly used to update things based on view direction (such as [Pawn.AimRay](https://asset.party/api/Sandbox.Entity.AimRay)).⤶
⤶
It's important to realize that **this is clientside only**, so if you're setting something here then it needs to be updated in Simulate. If you can't comment out your `FrameSimulate` code and have the game work normally then you're doing something wrong.⤶
⤶
# Events⤶
⤶
You can also have your game code be triggered on [events](https://wiki.facepunch.com/sbox/EventSystem) such as the tick event, allowing you to run logic server side independent of clients.⤶
⤶
<note>⤶
Wiki editors: I re-made the images on this page in Figma so they should be pretty easy for other people to edit when necessary. Here's the exported Figma file:⤶
⤶
<upload src="aa125/8dad929e9751dae.fig" size="25727" name="GameLoop.fig" />⤶
⤶
Please keep this up to date if you change anything on this page.⤶
</note>⤶
<note>Page needs to be entirely rewritten for the scene system, old game loop has been removed entirely</note>