Jump to content

  • Log In with Google      Sign In   
  • Create Account

Awesome job so far everyone! Please give us your feedback on how our article efforts are going. We still need more finished articles for our May contest theme: Remake the Classics

#ActualSimonForsman

Posted 10 July 2012 - 12:18 AM

Hi,   

I'm coding a rhythm game and the game runs smoothly with uncapped fps. But when I try to cap it around 60 the game updates in little chunks, like hiccups, as if it was skipping frames or at a very low frame rate. The reason I need to cap frame rate is because in some computers I tested the fps varies a lot (from ~80 - ~250 fps) and those drops are noticeable and degrade response time. Since this is a rhythm game this is very important.
This issue is driving me crazy. I've spent a a whole week already and still can't figure out the problem. I hope someone more experienced than me could shed some light on it. I'll try to put here all the hints I've tried along with the code for my game loop, so I apologize with this post gets too lengthy.


1st GameLoop:

const uint UPDATE_SKIP = 1000 / 60;
uint nextGameTick = SDL_GetTicks();[/background][/background]
while(isNotDone)
{
	// only false when a QUIT event is generated!
	if (processEvents())
	{
		if (SDL_GetTicks() > nextGameTick)
		{
			update(UPDATE_SKIP);
			render();
			nextGameTick += UPDATE_SKIP;
		}
	}
}


2nd Game Loop:
	const uint UPDATE_SKIP = 1000 / 60;
	while (isNotDone)
	{
		   LARGE_INTEGER startTime;
		  QueryPerformanceCounter(&startTime);[/background][/color][/background][/background]
		  // process events will return false in case of a QUIT event processed
		  if (processEvents())
		  {
				update(frameTime);
				render();
		  }
		 LARGE_INTEGER endTime;
		do {
			   QueryPerformanceCounter(&endTime);
			   frameTime = static_cast<uint>((endTime.QuadPart - startTime.QuadPart) * 1000.0 / frequency.QuadPart);
		} while (frameTime < UPDATE_SKIP);
	}


[1] At first I thought is was a problem with timer resolution. I was using SDL_GetTicks, but even when I switched to QueryPerformanceCounter I saw no difference.


[2] Then I thought it could be an rounding error in my position computation and since game updates are smaller in high FPS that would be less noticeable. Indeed there is an small error, but from my tests I realized that is not enough to produce the position jumps I'm getting. Also, another intriguing factor is that if I enable vsync I'll get smooth updates @60fps regardless frame cap code. So why not rely on vsync? Because some computers can force a disable on gfx card config.

[3] I started printing the maximum and minimum frame time measured in 1sec span, in the hope that every a few frames one would take a long time and still not enough to drop my fps computation. With frame cap I get always min = 16ms and max = 18, and still, the game "does not moves like jagger".

[4] My process priority is set to HIGH (Windows doesn't allow me to set REALTIME for some reason). As far as I know there is only one thread running along with the game (sound callback, which I really don't have access to it). I'm using Audiere. I then disabled Audiere by removing it from the project and still got the issue. Maybe there are some others threads running and one of them is taking too long to come back right in between when I measured frame times, I don't know. Is there a way to know which threads are attached to my process?

[5] There are some dynamic data being created during game run. But It is a little bit hard to remove it to test. Maybe I'll have to harder this one.
Well, as I told you I really don't know what to try next. What bugs me more is why at 60fps & vsync enabled I get smooth results and with 60fps no vsync I don't. Is there a way to implement software vsync???


Thanks in advance. I appreciate the ones that got this far and yet again I apologize for the long post.


Try something like this instead


while(running) {
	processMessages();
    currentTime = getTimeFromOSSomehow();
	while (currentTime > nextGameTick) {
		update(timestep);
		nextGameTick+=timestep;
	}
	render();
}
This should let the game render as fast as possible while doing updates at a fixed rate and most importantly, it will keep the game running at the correct speed even if the render framerate drops below X fps (and you can set the gamestate updates to run at 300 fps if you wish), you could quite easily take it a step further and pass nextGameTick - currentTime to the render function and have it extrapolate the rendered scene to get smooth animations (i think extrapolating works better for games like guitar hero as things are moving at a fixed predictable pace and interpolating adds some latency(+ requires you to store an old state))

#2SimonForsman

Posted 09 July 2012 - 08:46 AM

Hi,   

I'm coding a rhythm game and the game runs smoothly with uncapped fps. But when I try to cap it around 60 the game updates in little chunks, like hiccups, as if it was skipping frames or at a very low frame rate. The reason I need to cap frame rate is because in some computers I tested the fps varies a lot (from ~80 - ~250 fps) and those drops are noticeable and degrade response time. Since this is a rhythm game this is very important.
This issue is driving me crazy. I've spent a a whole week already and still can't figure out the problem. I hope someone more experienced than me could shed some light on it. I'll try to put here all the hints I've tried along with the code for my game loop, so I apologize with this post gets too lengthy.


1st GameLoop:

const uint UPDATE_SKIP = 1000 / 60;
uint nextGameTick = SDL_GetTicks();[/background][/background]
while(isNotDone)
{
	// only false when a QUIT event is generated!
	if (processEvents())
	{
		if (SDL_GetTicks() > nextGameTick)
		{
			update(UPDATE_SKIP);
			render();
			nextGameTick += UPDATE_SKIP;
		}
	}
}


2nd Game Loop:
	const uint UPDATE_SKIP = 1000 / 60;
	while (isNotDone)
	{
		   LARGE_INTEGER startTime;
		  QueryPerformanceCounter(&startTime);[/background][/color][/background][/background]
		  // process events will return false in case of a QUIT event processed
		  if (processEvents())
		  {
				update(frameTime);
				render();
		  }
		 LARGE_INTEGER endTime;
		do {
			   QueryPerformanceCounter(&endTime);
			   frameTime = static_cast<uint>((endTime.QuadPart - startTime.QuadPart) * 1000.0 / frequency.QuadPart);
		} while (frameTime < UPDATE_SKIP);
	}


[1] At first I thought is was a problem with timer resolution. I was using SDL_GetTicks, but even when I switched to QueryPerformanceCounter I saw no difference.


[2] Then I thought it could be an rounding error in my position computation and since game updates are smaller in high FPS that would be less noticeable. Indeed there is an small error, but from my tests I realized that is not enough to produce the position jumps I'm getting. Also, another intriguing factor is that if I enable vsync I'll get smooth updates @60fps regardless frame cap code. So why not rely on vsync? Because some computers can force a disable on gfx card config.

[3] I started printing the maximum and minimum frame time measured in 1sec span, in the hope that every a few frames one would take a long time and still not enough to drop my fps computation. With frame cap I get always min = 16ms and max = 18, and still, the game "does not moves like jagger".

[4] My process priority is set to HIGH (Windows doesn't allow me to set REALTIME for some reason). As far as I know there is only one thread running along with the game (sound callback, which I really don't have access to it). I'm using Audiere. I then disabled Audiere by removing it from the project and still got the issue. Maybe there are some others threads running and one of them is taking too long to come back right in between when I measured frame times, I don't know. Is there a way to know which threads are attached to my process?

[5] There are some dynamic data being created during game run. But It is a little bit hard to remove it to test. Maybe I'll have to harder this one.
Well, as I told you I really don't know what to try next. What bugs me more is why at 60fps & vsync enabled I get smooth results and with 60fps no vsync I don't. Is there a way to implement software vsync???


Thanks in advance. I appreciate the ones that got this far and yet again I apologize for the long post.


Try something like this instead


while(running) {
	processMessages();
	while (currentTime > nextGameTick) {
		update(timestep);
		nextGameTick+=timestep;
	}
	render();
}
This should let the game render as fast as possible while doing updates at a fixed rate and most importantly, it will keep the game running at the correct speed even if the render framerate drops below X fps (and you can set the gamestate updates to run at 300 fps if you wish), you could quite easily take it a step further and pass nextGameTick - currentTime to the render function and have it extrapolate the rendered scene to get smooth animations (i think extrapolating works better for games like guitar hero as things are moving at a fixed predictable pace and interpolating adds some latency(+ requires you to store an old state))

#1SimonForsman

Posted 09 July 2012 - 08:45 AM

Hi,   

I'm coding a rhythm game and the game runs smoothly with uncapped fps. But when I try to cap it around 60 the game updates in little chunks, like hiccups, as if it was skipping frames or at a very low frame rate. The reason I need to cap frame rate is because in some computers I tested the fps varies a lot (from ~80 - ~250 fps) and those drops are noticeable and degrade response time. Since this is a rhythm game this is very important.
This issue is driving me crazy. I've spent a a whole week already and still can't figure out the problem. I hope someone more experienced than me could shed some light on it. I'll try to put here all the hints I've tried along with the code for my game loop, so I apologize with this post gets too lengthy.


1st GameLoop:

const uint UPDATE_SKIP = 1000 / 60;
uint nextGameTick = SDL_GetTicks();[/background][/background]
while(isNotDone)
{
	// only false when a QUIT event is generated!
	if (processEvents())
	{
		if (SDL_GetTicks() > nextGameTick)
		{
			update(UPDATE_SKIP);
			render();
			nextGameTick += UPDATE_SKIP;
		}
	}
}


2nd Game Loop:
	const uint UPDATE_SKIP = 1000 / 60;
	while (isNotDone)
	{
		   LARGE_INTEGER startTime;
		  QueryPerformanceCounter(&startTime);[/background][/color][/background][/background]
		  // process events will return false in case of a QUIT event processed
		  if (processEvents())
		  {
				update(frameTime);
				render();
		  }
		 LARGE_INTEGER endTime;
		do {
			   QueryPerformanceCounter(&endTime);
			   frameTime = static_cast<uint>((endTime.QuadPart - startTime.QuadPart) * 1000.0 / frequency.QuadPart);
		} while (frameTime < UPDATE_SKIP);
	}


[1] At first I thought is was a problem with timer resolution. I was using SDL_GetTicks, but even when I switched to QueryPerformanceCounter I saw no difference.


[2] Then I thought it could be an rounding error in my position computation and since game updates are smaller in high FPS that would be less noticeable. Indeed there is an small error, but from my tests I realized that is not enough to produce the position jumps I'm getting. Also, another intriguing factor is that if I enable vsync I'll get smooth updates @60fps regardless frame cap code. So why not rely on vsync? Because some computers can force a disable on gfx card config.

[3] I started printing the maximum and minimum frame time measured in 1sec span, in the hope that every a few frames one would take a long time and still not enough to drop my fps computation. With frame cap I get always min = 16ms and max = 18, and still, the game "does not moves like jagger".

[4] My process priority is set to HIGH (Windows doesn't allow me to set REALTIME for some reason). As far as I know there is only one thread running along with the game (sound callback, which I really don't have access to it). I'm using Audiere. I then disabled Audiere by removing it from the project and still got the issue. Maybe there are some others threads running and one of them is taking too long to come back right in between when I measured frame times, I don't know. Is there a way to know which threads are attached to my process?

[5] There are some dynamic data being created during game run. But It is a little bit hard to remove it to test. Maybe I'll have to harder this one.
Well, as I told you I really don't know what to try next. What bugs me more is why at 60fps & vsync enabled I get smooth results and with 60fps no vsync I don't. Is there a way to implement software vsync???


Thanks in advance. I appreciate the ones that got this far and yet again I apologize for the long post.


Try something like this instead

[code=auto:0]

while(running) {
    processMessages();
    while (currentTime > nextGameTick) {
        update(timestep);
        nextGameTick+=timestep;
    }
    render();
}

This should let the game render as fast as possible while doing updates at a fixed rate and most importantly, it will keep the game running at the correct speed even if the render framerate drops below X fps (and you can set the gamestate updates to run at 300 fps if you wish), you could quite easily take it a step further and pass nextGameTick - currentTime to the render function and have it extrapolate the rendered scene to get smooth animations (i think extrapolating works better for games like guitar hero as things are moving at a fixed predictable pace and interpolating adds some latency(+ requires you to store an old state))

PARTNERS