Group packetloss, unrecoverable state
by Wes Macdonald · in Torque Game Engine · 07/28/2010 (9:57 pm) · 0 replies
There is a bug in TGE 1.5.2, not sure about other versions, that if the internet connection drops too many client packets in a row but then stops dropping packets the client will remain stuck in the isBacklogged state when it could actually recover and continue working normally.
The fix is to change line 122 in gameProcess.cc from "return false;" to "return (tickCount);".
Patch:
The bug happens when $pref::Net::PacketRateToServer number of packets are dropped in a row. The higher this value the less likely in practice but still possible, max/default 32. When the client's move list fills because the server has not updated mLastMoveAck with any of its current moves it will stop sending packets waiting for the server to update mLastMoveAck. If it gets too far the server will not update the value because the packets never got to it and the client is no longer sending any. Although the server is still sending update packets to this client.
The client will not timeout because the ping packets will still be sending and receiving properly. This leaves the client stuck.
This fix works because it sill allows the client to send its last move packet repeatedly. Although returning true that the simulation ticked is not entirely true, because it returns before the tick begins processing, it is only used to handle the connection to server processing.
To reproduce this bug connect to a remote server, do not attempt when running client and server in a single executable. Then type into the console:
You will be stuck without this fix. I'm still testing this fix but so far appears to work. If anyone has anymore information or another fix I would like to hear about it.
The fix is to change line 122 in gameProcess.cc from "return false;" to "return (tickCount);".
Patch:
Index: engine/game/gameProcess.cc
===================================================================
--- engine/game/gameProcess.cc (revision 3740)
+++ engine/game/gameProcess.cc (working copy)
@@ -119,7 +119,7 @@
mLastTime = targetTime;
mLastTick = targetTick;
PROFILE_END();
- return false;
+ return (tickCount);
}
if (connection->areMovesPending())
control = connection->getControlObject();The bug happens when $pref::Net::PacketRateToServer number of packets are dropped in a row. The higher this value the less likely in practice but still possible, max/default 32. When the client's move list fills because the server has not updated mLastMoveAck with any of its current moves it will stop sending packets waiting for the server to update mLastMoveAck. If it gets too far the server will not update the value because the packets never got to it and the client is no longer sending any. Although the server is still sending update packets to this client.
The client will not timeout because the ping packets will still be sending and receiving properly. This leaves the client stuck.
This fix works because it sill allows the client to send its last move packet repeatedly. Although returning true that the simulation ticked is not entirely true, because it returns before the tick begins processing, it is only used to handle the connection to server processing.
To reproduce this bug connect to a remote server, do not attempt when running client and server in a single executable. Then type into the console:
ServerConnection.setSimulatedNetParams(1,0);Wait two seconds or so then:
ServerConnection.setSimulatedNetParams(0,0);
You will be stuck without this fix. I'm still testing this fix but so far appears to work. If anyone has anymore information or another fix I would like to hear about it.
About the author
Lead engineer at Onverse.