2025-07-18 18:07 CEST

View Revisions: Issue #4290

Summary 0004290: Fix stutter at lower frame rates - PATCH INCLUDED
Revision 2014-01-23 21:36 by Beherith
Description

So, I noticed how spring stutters alot at lower frame rates (CTO assert errors) and I found the bug and have solved it on my local mingw build.

Inside CGame::ClientReadNet(), there is a switch which handles packetCode. ClientReadNet will keep on reading netmessages until it either: 1, runs out of its time to do so (unlikely, msgProcTimeLeft is usually >10ms) 2. runs out of netpackets (at the current time) OR if it encounters a NETMSG_SYNCRESPONSE. The bug is that if the sync check is correct (any of the following return true):
if (playerNum == gu->myPlayerNum) { return; }
if (gs->frameNum != frameNum) { return; }
if (checkSum == ourCheckSum) { return; }

then ClientReadNet will return and not continue processing packets. If it has not found NETMSG_KEYFRAME or a NETMSG_NEWFRAME before returning, then a draw frame will commence (because no new frame was issued)!

If many NETMSG_SYNCRESPONSE follow each other, then each one will result in a new draw frame and no new simframe.

Note the log for more info:
NETMSG_SYNCRESPONSE = 33

Revision 2014-01-24 11:43 by abma
Description
So, I noticed how spring stutters alot at lower frame rates (CTO assert errors) and I found the bug and have solved it on my local mingw build.

Inside CGame::ClientReadNet(), there is a switch which handles packetCode. ClientReadNet will keep on reading netmessages until it either: 1, runs out of its time to do so (unlikely, msgProcTimeLeft is usually >10ms) 2. runs out of netpackets (at the current time) OR if it encounters a NETMSG_SYNCRESPONSE. The bug is that if the sync check is correct (any of the following return true):
if (playerNum == gu->myPlayerNum) { return; }
if (gs->frameNum != frameNum) { return; }
if (checkSum == ourCheckSum) { return; }

then ClientReadNet will return and not continue processing packets. If it has not found NETMSG_KEYFRAME or a NETMSG_NEWFRAME before returning, then a draw frame will commence (because no new frame was issued)!

If many NETMSG_SYNCRESPONSE follow each other, then each one will result in a new draw frame and no new simframe.

Note the log for more info:
NETMSG_SYNCRESPONSE = 33