Skip to content

Fix delayed heartbeat and host stats sending every frame#70

Closed
andy013 wants to merge 4 commits intoFacepunch:masterfrom
andy013:delayed_heartbeat_fix
Closed

Fix delayed heartbeat and host stats sending every frame#70
andy013 wants to merge 4 commits intoFacepunch:masterfrom
andy013:delayed_heartbeat_fix

Conversation

@andy013
Copy link
Copy Markdown
Contributor

@andy013 andy013 commented Nov 30, 2025

Fix delayed heartbeat and host stats sending every frame

This PR finishes up #709

Changes

  • Fixes heartbeat being delayed by 1 frame
  • Fixes host stats sending every frame rather than every second

Notes

Currently the heartbeat is sent after the frame has rendered but it uses the Time.Now value from the previous frame. This means if the frame takes a long time to render the heartbeat will be incorrect and cause unnecessary timing fluctuations on the client.

I tested this and this is what happens to Time.Now on the client after a 2 second delay on the server:

[Generic] Frame 185: Time.Now=16.0084 FixedUpdatesSinceLastLog=1 	
[Generic] Frame 186: Time.Now=16.01841 FixedUpdatesSinceLastLog=1 	
[Generic] Frame 187: Time.Now=16.028421 FixedUpdatesSinceLastLog=1 	
[Generic] Frame 188: Time.Now=16.038431 FixedUpdatesSinceLastLog=1 	
[Generic] Frame 189: Time.Now=14.047403 FixedUpdatesSinceLastLog=0 	<-- Heartbeat arrives with 2 second old Time.Now
[Generic] Frame 190: Time.Now=14.057407 FixedUpdatesSinceLastLog=1 	
[Generic] Frame 191: Time.Now=14.068408 FixedUpdatesSinceLastLog=1	

// A short time later

[Generic] Frame 219: Time.Now=14.352655 FixedUpdatesSinceLastLog=1	
[Generic] Frame 220: Time.Now=14.3626585 FixedUpdatesSinceLastLog=1 	
[Generic] Frame 221: Time.Now=16.374989 FixedUpdatesSinceLastLog=201  <-- Next heartbeat arrives, client now needs to skip forward, running lots of Fixed Updates
[Generic] Frame 222: Time.Now=16.384993 FixedUpdatesSinceLastLog=1	
[Generic] Frame 223: Time.Now=16.395042 FixedUpdatesSinceLastLog=1 	
[Generic] Frame 224: Time.Now=16.405169 FixedUpdatesSinceLastLog=1 	

With this fix the time keeps on running like it should and the client doesn't run any extra fixed updates when the server has a large frametime spike.

I also moved SendHostStats() to Networking.PreFrameTick() because it uses Time.Now from the previous frame too. There is no good reason to delay sending it until after the current frame has rendered. It doesn't matter much for host stats but this is more correct.

Comments

I feel like Networking.PostFrameTick() could be removed entirely. It now only has a call to SendTableUpdates() which is currently being called 3 times per frame in these places:

  • Networking.PreFrameTick()
  • GameInstanceDll.FinishLoadingAssemblies()
  • Networking.PostFrameTick()

I did a quick test and I only ever saw PreFrameTick() actually sending any changes. I haven't tested it extensively though and I don't feel confident enough to remove PostFrameTick() without breaking anything. I don't think it's a big deal to call it too many times but it just clutters up the code if it's not needed.

@garrynewman garrynewman added the triaged triaged pull-requests are replicated on the internal sbox repo label Nov 30, 2025
@handsomematt handsomematt added triaged triaged pull-requests are replicated on the internal sbox repo and removed triaged triaged pull-requests are replicated on the internal sbox repo labels Nov 30, 2025
@sboxbot
Copy link
Copy Markdown
Contributor

sboxbot commented Nov 30, 2025

This PR has been merged upstream.

@sboxbot sboxbot added the accepted this pull request was accepted, hurrah! label Nov 30, 2025
@sboxbot sboxbot closed this Nov 30, 2025
@andy013 andy013 deleted the delayed_heartbeat_fix branch December 19, 2025 19:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

accepted this pull request was accepted, hurrah! triaged triaged pull-requests are replicated on the internal sbox repo

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants