[solved] FPS Counter not calculating FPS correctly

Hello JGO, yesterday I revised my game loop thanks to BurntPizza :slight_smile:

I added a FPS Counter and it seems to be returning the wrong FPS?
It’s returning 59 fps when I set my desired fps to 60, although I’m not worried about my frame-rate I’m worried that my calculations aren’t returning the right number.

Here’s my game loop:


	protected static void startGameThread() {
		gameThreadRunning = true;
		gameThread = new Thread() {
			@Override
			public void run() {
				super.run();

				// Initialize our frameStart time outside of the loop :D
				frameStartTime = System.nanoTime();

				while (gameThreadRunning) {
					final long startTime = System.nanoTime();

					if ((System.nanoTime() - frameStartTime) / 1000000 >= 1000) {
						fps = frames;
						frames = 0;
						System.out.println("FPS: " + fps);
						frameStartTime = System.nanoTime();
					}

					// Update
					update();

					// Render
					render();
					frames++;

					while (System.nanoTime() < startTime + nanosToSleep) {
						try {
							Thread.sleep(1);
						} catch (final InterruptedException e) { }
					}
					// End while loop
				}
			}
		};
		gameThread.setName("GameThread01");
		gameThread.start();
	}

Thanks for any help guys :slight_smile:

You start your frame count at zero instead of one. The other way to look at this is you don’t increment your frame count for the last frame before printing it out.

Either way, the result is you only count from 0 to 59 instead of from 1 to 60.

You could just put your if statement below the increment.

But I really wouldn’t worry about it. 59 vs 60 FPS is not something that anybody will notice.

Thanks Kevin, I actually tried both of the things you said prior to posting :confused:

Feedback is appreciated though :slight_smile:

EDIT:
I know 59vs60 fps isn’t something to worry about graphically/visually to the user, but why are my calculations wrong? o.O
I was taught to update the fps @ the beginning of the loop, correct?

Can you post an MCVE that we can play with? Right now you’ve left out quite a bit of your logic, which makes this pretty hard to debug.

Note that this shouldn’t include any actual graphics or game logic, just enough to show us what you’re doing.

For example, here is one I started trying to build for you, all you have to do is fill in your thread sleeping logic:

public class Test{

	public static void main(String[] args) throws InterruptedException {
		MyThread myThread = new MyThread();
		myThread.start();
		
		myThread.join();
	}

	private static class MyThread extends Thread {
		
		long totalFrames = 0;
		public void update(){
			totalFrames++;
		}
		
		@Override
		public void run() {
			
			//your logic here
			
			update();
		}
	}
}

Thanks, I’ll make a test case and try building off of the example you posted.

Here’s everything for my game loop (MCVE):


	private static Thread gameThread;
	static double desiredFPS = 60;
	static double nanosToSleep = 1000000000L / desiredFPS;
	static double fps;
	static double frames;
	static long frameStartTime;

	public static void main(final String[] args) {
		startGameThread();
	}

	protected static void startGameThread() {
		gameThreadRunning = true;
		gameThread = new Thread() {
			@Override
			public void run() {
				super.run();
				frameStartTime = System.nanoTime();
				while (gameThreadRunning) {
					final long startTime = System.nanoTime();

					if ((System.nanoTime() - frameStartTime) / 1000000 >= 1000) {
						fps = frames;
						frames = 0;
						System.out.println("FPS: " + fps);
						frameStartTime = System.nanoTime();
					}

					// Update
					update();

					// Render
					render();
					frames++;

					while (System.nanoTime() < startTime + nanosToSleep) {
						try {
							Thread.sleep(1);
						} catch (final InterruptedException e) {
						}
					}
				}
			}
		};
		gameThread.setName("GameThread01");
		gameThread.start();
	}

	protected static void render() { /* Blank */ }

	protected static void update() { /* Blank */ }

Thanks for your help :slight_smile:

Your math seems fine. Here is something I put together:


public class Test{

	static long programStart = System.currentTimeMillis();
	static double totalFrames = 0;

	private static Thread gameThread;
	static double desiredFPS = 30;
	static double nanosToSleep = 1000000000L / desiredFPS;
	static double fps;
	static double frames;
	static long frameStartTime;

	public static void main(final String[] args) {
		startGameThread();
	}

	protected static void startGameThread() {

		gameThread = new Thread() {
			@Override
			public void run() {
				super.run();
				frameStartTime = System.nanoTime();
				while (true) {

					// Update
					update();

					// Render
					render();
					frames++;

					final long startTime = System.nanoTime();

					if ((System.nanoTime() - frameStartTime) / 1000000 >= 1000) {
						fps = frames;
						frames = 0;
						System.out.println("FPS: " + fps);
						frameStartTime = System.nanoTime();
					}



					while (System.nanoTime() < startTime + nanosToSleep) {
						try {
							Thread.sleep(1);
						} 
						catch (final InterruptedException e) {
						}
					}
				}
			}
		};
		gameThread.setName("GameThread01");
		gameThread.start();
	}

	protected static void render() { /* Blank */ }

	protected static void update() { 
		totalFrames++;

		double totalFPS = totalFrames/(System.currentTimeMillis()-programStart) * 1000;
		System.out.println("Total FPS: " + totalFPS);
	}
}

This measures the total FPS over the lifetime of the program, and that matches up pretty closely to the goal FPS.

However, it looks like I was wrong in my initial answer of it being the placement of your frame logic, since I too am getting 59 FPS.

And that’s because timing in Java (or in computers in general) isn’t 100% accurate. Thread.sleep(1) does not actually sleep for 1 MS every time, and even the various timing functions are only accurate down to a few MS. This is dependent on the OS internal clock. From the API for System.nanoTime():

[quote]This method provides nanosecond precision, but not necessarily nanosecond resolution (that is, how frequently the value changes) - no guarantees are made except that the resolution is at least as good as that of currentTimeMillis().
[/quote]
All this means is that there’s going to be some wiggle room in the different timing functions you’re using. And that means that with a goal of 60 FPS, sometimes you’ll get 59 FPS, sometimes you’ll get 61 FPS, etc.

No idea what you did mate.

NOTE: Snippets below are from your code example.

Here’s the output now (Converted to Integer):
(Max FPS reached now: 57)


Total FPS: 1000
Total FPS: 105
Total FPS: 83
Total FPS: 75
Total FPS: 70
Total FPS: 68
Total FPS: 66
Total FPS: 65
Total FPS: 64
Total FPS: 62
Total FPS: 61
Total FPS: 60
Total FPS: 59
Total FPS: 58
Total FPS: 57
Total FPS: 56
// FPS: 57 outprints begin soon and stay steady @ 57

Here’s the output now (Converted to Double):
NOTE: Rather long so i used pastebin, you can see what’s happening here.
http://pastebin.java-gaming.org/7d1db036c0a1c

It seems to just slowly increment the FPS until it caps out @ 57, appreciate your help though.

What I posted wasn’t meant to be a fix, just a confirmation that your algorithm is working.

The total FPS is measured over the entire lifetime of the program. The FPS will be pretty low at the very beginning as everything gets started, but it increases to ~60 after a few seconds.

But since the FPS is measured over the whole lifetime, the average still includes that first second or so of low FPS, which is why the total average looks like it slowly rises and levels off.

The only point of what I posted was to confirm that you get around 60 FPS (or whatever FPS you specify), which is the only thing you should really care about.

Great, thanks for your help.

Not going to bug over a 1fps diff in my calculations ha.

Thread closed :slight_smile: