Timing issues (game/platform time advances slower than systime)
by Andreas Kirsch · in Torque Game Builder · 02/13/2006 (6:05 am) · 2 replies
While I was migrating some code to the new 1.1 beta, I've found out that my game is suddenly running slower. Using this code:
I found out that every sim second takes ~240 ms more in realtime with ~280 FPS.
After reading the engine source for some time I discovered that $pref::timeManagerProcessInterval does exactly what I need to solve my problem.
Setting it to e.g. 10 makes it only update the platform timer every 10 ms, thus it loses less ms fractions and works more precisely. It limits the effective FPS to 100 on the other hand.
This has cured my problem and the game runs normally again.
It would be nice if someone with more Torque experience could look at the engine code (the time stuff is in winWindow.cc) and change it in such a way that it wont lose so much precision so fast at high FPS.
My guess is that WinTimer needs to be changed to accumulate the subms fractions, too and add them back as soon as they reach the 1 ms "barrier". Sorry for my bad English.
Andreas Kirsch
$_oldRealTime = getRealTime();
$_oldSimTime = getSimTime();
$_maxDeltaTimeDiff = 50;
function checkTime() {
%newRealTime = getRealTime();
%newSimTime = getSimTime();
%deltaReal = %newRealTime - $_oldRealTime;
%deltaSim = %newSimTime - $_oldSimTime;
if( mAbs( %deltaReal - %deltaSim ) > $_maxDeltaTimeDiff ) {
echo( "Timer's running away: real:" SPC %deltaReal SPC "sim:" SPC %deltaSim SPC "delta:" SPC (%deltaReal - %deltaSim) );
}
$_oldRealTime = %newRealTime;
$_oldSimTime = %newSimTime;
schedule( 1000, 0, checkTime );
}
checkTime();'I found out that every sim second takes ~240 ms more in realtime with ~280 FPS.
After reading the engine source for some time I discovered that $pref::timeManagerProcessInterval does exactly what I need to solve my problem.
Setting it to e.g. 10 makes it only update the platform timer every 10 ms, thus it loses less ms fractions and works more precisely. It limits the effective FPS to 100 on the other hand.
This has cured my problem and the game runs normally again.
It would be nice if someone with more Torque experience could look at the engine code (the time stuff is in winWindow.cc) and change it in such a way that it wont lose so much precision so fast at high FPS.
My guess is that WinTimer needs to be changed to accumulate the subms fractions, too and add them back as soon as they reach the 1 ms "barrier". Sorry for my bad English.
Andreas Kirsch
#2
Apply it to winWindow.cc in platformWin32. I can also upload/post a unified diff if necessary/wanted, just ask for it.
The fix simply accumulates the subms fractions and adds them back as soon as they sum up to 1 ms.
Andreas Kirsch
03/03/2006 (4:47 pm)
Here's a bugfix that doesn't limit the maximum FPS.Apply it to winWindow.cc in platformWin32. I can also upload/post a unified diff if necessary/wanted, just ask for it.
The fix simply accumulates the subms fractions and adds them back as soon as they sum up to 1 ms.
Andreas Kirsch
Index: winWindow.cc
===================================================================
--- winWindow.cc (revision 72)
+++ winWindow.cc (working copy)
@@ -1291,6 +1291,7 @@
S64 mPerfCountNext;
S64 mFrequency;
bool mUsingPerfCounter;
+ F64 mMilliFractions;
public:
WinTimer()
{
@@ -1299,13 +1300,17 @@
mUsingPerfCounter = QueryPerformanceCounter((LARGE_INTEGER *) &mPerfCountCurrent);
if(!mUsingPerfCounter)
mTickCountCurrent = GetTickCount();
+
+ mMilliFractions = 0.0;
}
U32 getElapsedMS()
{
if(mUsingPerfCounter)
{
QueryPerformanceCounter( (LARGE_INTEGER *) &mPerfCountNext);
- U32 elapsed = (U32) (1000.0f * F64(mPerfCountNext - mPerfCountCurrent) / F64(mFrequency));
+ U32 elapsed = (U32) (1000.0 * F64(mPerfCountNext - mPerfCountCurrent) / F64(mFrequency));
+ elapsed += (U32) mMilliFractions;
+
return elapsed;
}
else
@@ -1316,8 +1321,12 @@
}
void advance()
{
- mTickCountCurrent = mTickCountNext;
- mPerfCountCurrent = mPerfCountNext;
+ mTickCountCurrent = mTickCountNext;
+
+ mMilliFractions -= (U32) mMilliFractions;
+ F64 realElapsed = (1000.0 * F64(mPerfCountNext - mPerfCountCurrent) / F64(mFrequency));
+ mMilliFractions += realElapsed - (U32) realElapsed;
+ mPerfCountCurrent = mPerfCountNext;
}
};
Associate Paul Dana