int iNextUpdateTick = SDL_GetTicks();
while( !g_bQuit) {
update();
render();
iNextUpdateTick += TICKS_TO_WAIT_FOR_NEXT_GAME_UPDATE;
iDelayTime = iNextUpdateTick - SDL_GetTicks();
if( iDelayTime >= 0 ) SDL_Delay( iDelayTime );
}
please help - inconsistent tick count values
I'm using SDL_GetTicks() and SDL_Delay() for my game loop timing. I'm trying to snap the game speed/frame rate at 50Hz but I'm getting inconsistent reading from SDL_GetTicks().
My game loop is as follows:
It seems when my game first starts for 5 seconds or so I get crazy readings, then after that they settle down a bit, but are still not consistent.
When my game first runs, the readings for about 5 seconds are as follows:
tick count elapsed fps/game speed
1407 57ms 17Hz
1513 106ms 9Hz
1866 353ms 2Hz
1879 13ms 76Hz
1893 14ms 71Hz
1957 64ms 15Hz
1970 13ms 76Hz
2264 294ms 3Hz
2278 14ms 71Hz
2290 12ms 83Hz
2304 14ms 71Hz
2317 13ms 76Hz
2472 155ms 6Hz
2479 7ms 142Hz
2492 13ms 76Hz
2505 13ms 76Hz
2518 13ms 76Hz
2619 101ms 9Hz
2626 7ms 142Hz
2639 13ms 76Hz
2652 13ms 76Hz
2658 6ms 166Hz
... etc ...
Then gradually they settle down to:
tick count elapsed fps/game speed
10415 24ms 41Hz
10431 16ms 62Hz
10455 24ms 41Hz
10471 16ms 62Hz
10495 24ms 41Hz
10511 16ms 62Hz
10535 24ms 41Hz
10551 16ms 62Hz
10580 29ms 34Hz
10592 12ms 83Hz
10611 19ms 52Hz
10631 20ms 50Hz
10651 20ms 50Hz
10671 20ms 50Hz
10691 20ms 50Hz
10711 20ms 50Hz
10737 26ms 38Hz
10751 14ms 71Hz
10771 20ms 50Hz
10792 21ms 47Hz
10811 19ms 52Hz
10831 20ms 50Hz
... etc ...
I'm running Vista Premium 32-bit but I had a similar problems with WinXPSP2. Is this tick reading behaviour normal? Is it the fault of SDL_GetTicks()? It seems I can't ever get a smooth consistent reading so my game animation/scrolling is always flickering/jumping/tearing in some way. I've even tried using a delta and updating the fps/game-speed as fast as possible (without using SDL_Delay(), but the same inconsistent tick readings occur. Any ideas? (I am writing to back buffer and using SDL_Flip() for rendering).
Many thanks
jimbogd
If you replace the
iNextUpdateTick += TICKS_TO_WAIT_FOR_NEXT_GAME_UPDATE;
iDelayTime = iNextUpdateTick - SDL_GetTicks();
if( iDelayTime >= 0 ) SDL_Delay( iDelayTime );
with sleep(0) or sleep(1) what happens?
iNextUpdateTick += TICKS_TO_WAIT_FOR_NEXT_GAME_UPDATE;
iDelayTime = iNextUpdateTick - SDL_GetTicks();
if( iDelayTime >= 0 ) SDL_Delay( iDelayTime );
with sleep(0) or sleep(1) what happens?
Quote:Original post by Jimmy Valavanis
If you replace the
iNextUpdateTick += TICKS_TO_WAIT_FOR_NEXT_GAME_UPDATE;
iDelayTime = iNextUpdateTick - SDL_GetTicks();
if( iDelayTime >= 0 ) SDL_Delay( iDelayTime );
with sleep(0) or sleep(1) what happens?
Both Sleep(0) and Sleep(1) both seem to have the same effect. Random jerkiness/jumpiness/speed and tearing. It might be quite smooth for a few seconds, then its all jumpy for a few. It looks awful! :(
jimbogd
I'd say this is to be expected when you're sharing the hardware with a load of other processes. You're pretty much guaranteed that the OS will sometimes put your game on hold to go and give everything else on the system a chance to run for a few milliseconds.
The solution is to design your game such that it doesn't require the loop to run at the exact update times. You could do something like this instead:
Key thing to note there is that update() may be called multiple times before render() gets called.
The solution is to design your game such that it doesn't require the loop to run at the exact update times. You could do something like this instead:
int iLastUpdate = SDL_GetTicks();while( !g_bQuit) { while(SDL_GetTicks() >= iLastUpdate + TICKS_TO_WAIT_FOR_NEXT_GAME_UPDATE) { update(); // update the game world by a fixed amount proportional to TICKS_TO_WAIT_FOR_NEXT_GAME_UPDATE iLastUpdate += TICKS_TO_WAIT_FOR_NEXT_GAME_UPDATE; } render(); // Do this with VSync turned on to avoid tearing}
Key thing to note there is that update() may be called multiple times before render() gets called.
OK I've changed my game loop to the way you suggested (thanks!) and in general its smoother (I also added an interpolation function for the rendering to smooth it out even more), but I'm still getting a degree of jerking/jumping at the start and sporadically after that. I guess then its because of all the other processes that windows is running. Just out of interest, how do the latest 3D FPS games avoid this problem, because they seem so smooth!? Do they give the game a higher priority over other tasks?
Also, turning on VSync in my ATI control center doesn't seem to do anything. I think this might be because it only affects 3D applications whereas I'm just using the simple SDL_BlitSurface(). Do you know if its possible to turn on VSync in this case?
Thanks again
jimbogd
Also, turning on VSync in my ATI control center doesn't seem to do anything. I think this might be because it only affects 3D applications whereas I'm just using the simple SDL_BlitSurface(). Do you know if its possible to turn on VSync in this case?
Thanks again
jimbogd
Quote:Original post by jimbogdAt this point I'd probably recommend writing or obtaining a profiling tool. Capture data about your game across a number of frames, and see how a non-jerky frame differs from a jerky one. It might be as simple as adding some SDL_GetTicks() calls at points throughout your code, and comparing the deltas between them from frame to frame.
OK I've changed my game loop to the way you suggested (thanks!) and in general its smoother (I also added an interpolation function for the rendering to smooth it out even more), but I'm still getting a degree of jerking/jumping at the start and sporadically after that. I guess then its because of all the other processes that windows is running.
Quote:Just out of interest, how do the latest 3D FPS games avoid this problem, because they seem so smooth!? Do they give the game a higher priority over other tasks?Messing with thread priorities is generally a bad plan. I can't really speak to how they do it because I'm not entirely sure why you're still seeing this jerkyness.
Quote:Also, turning on VSync in my ATI control center doesn't seem to do anything. I think this might be because it only affects 3D applications whereas I'm just using the simple SDL_BlitSurface(). Do you know if its possible to turn on VSync in this case?Hmm, SDL doesn't seem to have any direct support for VSync - if you were using full OpenGL then you could set it up (SDL_GL_SWAP_CONTROL), but I take it that you're not.
Oh, are you running in windowed or fullscreen mode?
Hi,
I'm running in fullscreen mode, and yeah I'm just using SDL for rendering, although I plan at some stage to switch to using OpenGL.
The program I'm writing is actually a comparison of different types of game loops, so when complete/working it should help beginners get to grips with game timing in general. I'll upload the whole source code when I get home. If anyone has the time to look at it, maybe it will help pinpoint the problem.
Thanks
jimbogd
I'm running in fullscreen mode, and yeah I'm just using SDL for rendering, although I plan at some stage to switch to using OpenGL.
The program I'm writing is actually a comparison of different types of game loops, so when complete/working it should help beginners get to grips with game timing in general. I'll upload the whole source code when I get home. If anyone has the time to look at it, maybe it will help pinpoint the problem.
Thanks
jimbogd
OK, I've uploaded the full program and source code here: -
http://www.bu22.com/files/timetest.zip
It's in one source file to keep things simple. Basically you press the space bar to switch game loops, and the timing info etc is written to the screen and more info is written to stdout.
If anyone could take the time to look over it I'd appreciate it. It would be great to get to the bottom of the inconsistent tick problem, and determine if its the code itself or my machine.
As I said, when finished I plan to release this for beginners to show some examples of popular game loops, so any ideas you have for improving it in any way will be gladly taken on board! :)
cheers
jimbogd
http://www.bu22.com/files/timetest.zip
It's in one source file to keep things simple. Basically you press the space bar to switch game loops, and the timing info etc is written to the screen and more info is written to stdout.
If anyone could take the time to look over it I'd appreciate it. It would be great to get to the bottom of the inconsistent tick problem, and determine if its the code itself or my machine.
As I said, when finished I plan to release this for beginners to show some examples of popular game loops, so any ideas you have for improving it in any way will be gladly taken on board! :)
cheers
jimbogd
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement