Skip to content

Conversation

@slarticodefast
Copy link
Member

@slarticodefast slarticodefast commented Jan 6, 2026

Adds a guide to prediction, along with a few code examples and gifs showcasing the results.
I tried writing down everything that needs to be known, let me know if anything is wrong or unclear.

Draft until I had a few contributors and maintainers proofreading this and give feedback.
Especially the section on ApplyingState seems like it could be explained a little better, but it's a complicated topic.

ToDo in a future PR: Update the Basic Networking and you doc to include sections on field deltas, NetSerializableAttribute and how EntityUids are converted into NetEntities by the source generator.

@slarticodefast slarticodefast marked this pull request as draft January 7, 2026 00:10
@Pok27
Copy link

Pok27 commented Jan 7, 2026

Very cool job!

Copy link

@VerinSenpai VerinSenpai left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Partial review. Just some minor wording and grammar nitpicks. Its beautiful 🥺

@VerinSenpai
Copy link

Occurs to me that I reviewed this like a 500 word english essay that's due in 3 weeks. 😅

Copy link
Member

@SlamBamActionman SlamBamActionman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Baller guide. You're the GOAT.


With prediction each client runs its own game simulation of the game according to the local player's inputs and they will immediately see the results without having to wait for the server, hiding any latency. The server holds the authoritative game state, which is what all clients consider to be the "truth" in case they disagree on something.

During prediction the client will constantly time travel, reverting the game state repeatedly to the last known authoritative state sent by the server, and then reapplies the player's inputs, resimulating the game until the next server state comes in. This usually happens about 12 times per game tick.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"Time travel" is a correct description but it kinda comes in out of nowhere, and for a beginner may seem out of left field.

I think the entire line should be reworded. It explains the process but the process isn't intuitive enough on its own. What does it mean that the client is repeatedly reverting and resimulating, and why does it do it?

```
Don't forget the client-side system, even if it's empty. Otherwise the client won't be able to instanciate the system class and it will remain unpredicted.

Avoid shared abstract components. Some ancient code is still doing this, but nowadays we just instead put the entire component into `Content.Shared`, even if some datafields are only used on the server or client. This is minimally worse for performance, but makes the code much more readable, simplifies any API methods and makes it easier to use `TryComp` and `Resolve`.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good place to re-mention netSync and serverOnly here!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wait is serverOnly even mentioned? I think the only thing related to server-only datafields is when you imply not adding AutoNetworkedField to fields that shouldn't be networked.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To be honest I never used serverOnly so far, so no clue. Usually most components just keep the datafield on the client, even if it's only used on the server. Probably because it's just a microoptimization.

Copy link
Member

@Tayrtahn Tayrtahn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking great! Thanks for writing all of this up!


During prediction the client will constantly time travel, reverting the game state repeatedly to the last known authoritative state sent by the server, and then reapplies the player's inputs, resimulating the game until the next server state comes in. This usually happens about 12 times per game tick.

Once the authoritative server state arrives at the client it will be applied to the client's simulation, overwriting and correcting any disagreements the client may have in their predicted simulation (for example someone else killed you while you tried to interact with something, but you did not know about that yet due to latency).
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This and the previous sentence should perhaps be reworked to make it clear that the server state is applied to the client before resimulation. That might help explain the purpose of resimulation - redoing the prediction based on the new "true" state from the server. You might extend the example to say that, now that your client knows that you died before interacting, it needs to rewind back to before you died and resimulate the predicted state - but this time your character is dead, so your interaction fails.


Without prediction any input from the client (like keyboard presses or mouse clicks) will be networked to the server, which then simulates the game according to all players' inputs and networks the resulting game state back to each client. The client will only see the results with a noticable delay depending on their ping, which makes the game feel unresponsive and will cause a visual delay for UI elements.

With prediction each client runs its own game simulation of the game according to the local player's inputs and they will immediately see the results without having to wait for the server, hiding any latency. The server holds the authoritative game state, which is what all clients consider to be the "truth" in case they disagree on something.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might be worth adding something here about how the idea is to predict what the game state will be on the server by the time the player's input arrives there. In that sense, the player's game actually runs slightly ahead of the server.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants