Best practise for FPS limiting?

Just curious, why do you want to limit your framerate? typically games will allow the framerate to be as fast as the host computer can handle...
 
You limit the framerate so the game runs the same speed on everyones computer (so long as they can get above the framerate you limit it too anyway).

This is very important for fairness and testability, among other things. Its useful for timing purposes if you know that any pc (above min spec) is going to run at exactly the same speed.

Pete
 
If you use time-based algorithms (animations, physics, AI, etc) then they will run at the exact same speed regardless of framerate. This is the way almost all modern games operate.
 
Does anyone know what the article is talking about here:

For flipping sprites you would do the same. You would have to declare a float variable that keeps track of the current frame. Also, you would limit the frames drawn per second.

sprite.fcurrentframe+=sprite.framespersecond*frametime;
if(sprite.fcurrentframe>sprite.totalframes)
{
int isoverby=sprite.fcurrentframe/sprite.totalframes;
sprite.fcurrentframe-=mesprite.totalframes*isoverby;
}
sprite.icurrentframe=(int)sprite.fcurrentframe;
sprite_draw(&sprite);


This skips frames if you have a slow PC, and on a fast PC it will run every frame but no more than sprite.framespersecond.

It seems to be missing something....

I want to be able to skip the rendering stage of my game loop when the FPS limit is reached - I understood the first part of the article about how to limit the movement of game objects, but this second half has me baffled.

Ideas?
 
i HAVE to agree with Optikal here. I have to spoil everyones fun here even if this IS an OK way to do it the current "state-of-the-art" way is to do a deterministic game-loop using "time-frames" or should i call it "time-step-based" game-loop that allows for unlimited fps but same speed on all computers.

you basically every time the loop goes around you update the game-state in loops of X milliseconds. so on a slow computer 42 milliseconds passed since last loop, and you have physics and everything on 10ms, you loop while 10*X<42 and save the last 2 fot next loop.

i have read an article on this on gamasutra (have no link sorry, and you have to register) and i HIGHLY recommend people that are intreseted in this to read up on it.

thanks :) i love this topic its very intreseting.
 
Problems

i copied your class, adding
Code:
Imports System.Runtime.InteropServices
to the top and i get exceptions:

An unhandled exception of type System.InvalidProgramException occurred in xfengine.dll

Additional information: Error: PInvoke item (field,method) must be Static.

The program [1588] XF2.exe has exited with code 0 (0x0).


xfengine.dll is my class library containing the high resolution timer and XF2.exe is the console app using xfengine.dll

any help much appreciated
Stephen
 
Like everyone else, I programmed my own Performance Timer class. I used this in a game loop to test it, and it works perfectly. I found the others that were provided a little disjointing to use, which is why I programmed my own.

Maybe itll help those who still dont fully understand how its working *shrug*

A few reminders about how this all comes together:
To base game movements off pixels per second multiplied by the current ticks per second, and for animation multiply frames per second by the current ticks per second.

If you add up the ticks per second for a full second, the total will come out to 1. This is because TicksPerSecond will give you a fractional time based off of 1 second.

The current frames per second is the inverse of the ticks per second (1.0/timer.TicksPerSecond)

C#:
using System;
using System.Runtime.InteropServices;

namespace DDUtil
{
	/// <summary>
	/// A high performance timer.
	/// </summary>
	public class PerfTimer 
	{
		#region Imported Methods

		/// <summary>
		/// The current system ticks (count).
		/// </summary>
		/// <param name="lpPerformanceCount">Current performance count of the system.</param>
		/// <returns>False on failure.</returns>
		[DllImport("Kernel32.dll")]
		private static extern bool QueryPerformanceCounter(out long lpPerformanceCount);

		/// <summary>
		/// Ticks per second (frequency) that the high performance counter performs.
		/// </summary>
		/// <param name="lpFrequency">Frequency the higher performance counter performs.</param>
		/// <returns>False if the high performance counter is not supported.</returns>
		[DllImport("Kernel32.dll")]
		private static extern bool QueryPerformanceFrequency(out long lpFrequency);

		#endregion

		#region Member Variables

		private long _startTime = 0;
		private long _recordTime = 0;
		private double _ticksPerSecond = 0;

		#endregion

		#region Constructor

		/// <summary>
		/// Creates a new PerfTimer.
		/// </summary>
		public PerfTimer() 
		{
			// No need to do anything.
		}

		#endregion

		#region Methods

		/// <summary>
		/// Records stop time and ticks per second from when this PerfTimer was started.
		/// </summary>
		public void Record() 
		{
			// Record when the timer was recorded and the ticks per second.
			_recordTime = PerfTimer.Counter;
			_ticksPerSecond = (double) (_recordTime - _startTime) / (double) PerfTimer.Frequency;
		}

		/// <summary>
		/// Starts this PerfTimer at the specified tick count.
		/// </summary>
		/// <param name="ticks">Tick count to start at.</param>
		public void Start(long ticks) 
		{
			// Record when the timer was started.
			_startTime = ticks;
		}

		#endregion

		#region Properties

		/// <summary>
		/// Gets the number of ticks per second based off the current start and record times.
		/// </summary>
		public double TicksPerSecond 
		{
			get {
				return _ticksPerSecond;
			}
		}

		/// <summary>
		/// Gets the tick count of when this PerfTimer was started.
		/// </summary>
		public long StartTime 
		{
			get {
				return _startTime;
			}
		}

		/// <summary>
		/// Gets the tick count of when this PerfTimer was last recorded.
		/// </summary>
		public long RecordTime 
		{
			get {
				return _recordTime;
			}
		}

		/// <summary>
		/// Gets the frequency that this PerfTimer performs at.
		/// </summary>
		public static long Frequency 
		{
			get {
				long freq = 0;
				QueryPerformanceFrequency(out freq);

				return freq;
			}
		}

		/// <summary>
		/// Gets the current system ticks.
		/// </summary>
		public static long Counter 
		{
			get {
				long ticks = 0;
				QueryPerformanceCounter(out ticks);

				return ticks;
			}
		}

		#endregion
	}
}

Sample on how to use it (its almost too simple);

C#:
PerfTimer timer = new PerfTimer();
timer.Start(PerfTimer.Counter)

while (_playGame) {
   timer.Record();

   // ... update game objects with object.Update(timer.TicksPerSecond).
   // ... display fps with 1.0/timer.TicksPerSecond.

   timer.Start(timer.RecordTime);
}
 
Last edited by a moderator:
Back
Top