Game loop and capping fps

Hi, I currently have a game loop that has a fixed fps because the updates and the rendering are coupled together. I plan on separating the updates and rendering by changing the current loop into something like the following:


private void runGameLoop()
{
    long nextUpdate = System.nanoTime();

    while (isRunning)
    {
        int skipped = 0;

        while (System.nanoTime() > nextUpdate && skipped++ < MAX_FRAME_SKIPS)
        {
            updateState();
            nextUpdate += UPDATE_INTERVAL;
        }

        float offset = (float)(UPDATE_INTERVAL - (nextUpdate - System.nanoTime())) / UPDATE_INTERVAL;
        updateDisplay(offset);
    }
}

My problem with that method is it renders as many frames as possible. I want to be able to control the fps and cap it when I want to, so I’m thinking of changing it further to this:


private void runGameLoop()
{
    long nextStateUpdate = System.nanoTime();
    long nextFrameUpdate = System.nanoTime();

    while (isRunning)
    {
        int skipped = 0;
        long currentTime = System.nanoTime();

        while (currentTime > nextStateUpdate && skipped++ < MAX_FRAME_SKIPS)
        {
            updateState();
            nextStateUpdate += STATE_UPDATE_INTERVAL;
        }

        currentTime = System.nanoTime();

        if (currentTime > nextFrameUpdate)
        {
            float offset = (float)(frameUpdateInterval - (nextFrameUpdate - currentTime)) / frameUpdateInterval;
            updateDisplay(offset);
            nextFrameUpdate += frameUpdateInterval; // i'll be able to control the fps on the fly by changing frameUpdateInterval
        }
    }
}

I like that I’ll be able to control the fps, but the game would constantly be running the loop even when there’s nothing to do. Plus, I feel like I’m overlooking something. My main question is are there better ways to do this? Also, is there a better term for the float (offset) passed in updateDisplay?


public void run() {
		requestFocus();
		long lastTime = System.nanoTime();
		final double ns = 1000000000.0 / 60.0;
		double delta = 0;
		long timer = System.currentTimeMillis();
		int frames = 0;
		int updates = 0;
		while (running) {
			long now = System.nanoTime();
			delta += (now - lastTime) / ns;
			lastTime = now;
			while (delta >= 1) {
				update();
				delta--;
				updates++;
            render();
            frames++;
			}
			if (System.currentTimeMillis() - timer > 1000) {
				timer += 1000;
				frame.setTitle(title + " | " + updates + " ups, " + frames + " fps");
				updates = 0;
				frames = 0;
			}
		}
	}

This will update and render the game at a rate of 60 times per second, you can easily change it according to your needs.

Sorry if I wasn’t clear enough in my original post. As I said, my current loop does the updates and rendering together, but that’s why I’m changing it. I want a fixed timestep with variable rendering. I can’t use the code you posted since it pretty much still has a fixed rendering interval and it’s done with the game updates. I edited my original post to make it clearer. Thanks though!

Your question is still not clear, you’re contradicting yourself.

Anyways, whether you want fixed or not, you can do it with this code, see the comments.


public void run() {
      requestFocus();
      long lastTime = System.nanoTime();
      final double ns = 1000000000.0 / 60.0;              // Here you can change the rate
      double delta = 0;
      long timer = System.currentTimeMillis();
      int frames = 0;
      int updates = 0;
      while (running) {
         long now = System.nanoTime();
         delta += (now - lastTime) / ns;
         lastTime = now;
         while (delta >= 1) {
            update();
            delta--;
            updates++;                // Anything put inside this while loop will be executed 60 times per second
         }
         render();                      // By having the render() method outside of this while loop, it renders as many times it can
         frames++;
         
         if (System.currentTimeMillis() - timer > 1000) {
            timer += 1000;
            frame.setTitle(title + " | " + updates + " ups, " + frames + " fps");
            updates = 0;
            frames = 0;
         }
      }
   }

I believe I made it quite clear already.

I’m not. I appreciate that you’re trying to help, but please read the post carefully before saying I’m contradicting myself. Even if I wasn’t clear, I believe my code was. It does exactly the same thing as what you just posted. I’ll edit the post again to be even clearer.

you dont have to do this yourself. which library or framework or whatever are you using?

So much misinformation…

If the computer can’t render fast enough, your game starts slowin down. The solution that lots of people posted involves skipping the rendering of some updates to catch up and prevent a slowdown. However, if the computer can’t even keep up with updating, the game will inevitably slow down, or like many of the examples posted here seemingly freeze the game by falling further and further behind and doing more and more updates.

A solution is to reduce the update rate, but that gives you fewer unique frames to render, capping your FPS to a value even lower than 60 FPS. The somution is to add interpolation to generate frames inbetween updates. Almost all commercial games do this.

I know I don’t :slight_smile: Currently, I’m using only Java2D. I explain why here. Specifically, the second paragraph

Wouldn’t that pretty much behave the same way as my above code does when a computer falls behind?

If you look at the code I posted, it includes interpolation. One of the reasons why I want to change the game loop is to add interpolation actually, but I didn’t mention it since it’s not my issue.

Look at the code of the LWJGL Display class which has a great sync() function which caps the FPS to a certain value.

Thank you! will do :slight_smile:

edit: it looks promising. again, thank you!

[quote]Hi, I’m currently rewriting the game engine
[/quote]
Stopped reading there. Sorry.
I will assume you are pretty young and wont listen, but dont write an engine yourself unless you have like 10 years of experience and a team. Just dont.
Especially not one that uses Java2D… that shit was outdated in… well actually always.

Hahah. “Young” is a relative term. But I can tell you I’m well past puberty at least :P. Anyway, why do you say I shouldn’t make one by myself? Lots of people do it. I’m not aiming for anything fancy/professional anyway; just something clean and functional with enough challenge to be fun.

Also, since you didn’t read the rest of the post, I mentioned I actually plan to use a library (LWJGL most likely) once I get bored of Java2D (which may be soon).

I’ve seen some impressive stuff done with Java2d… Have a look here:

http://www.java-gaming.org/index.php?topic=30371.0

Just a thought: Java2D was too slow for a certain level of graphical fidelity in 2010. Since then the API has been improved at least a little bit. And graphics hardware has vastly increased in power since 2010. On the other hand, the graphical level of the average Java2d game has not increased much over the past few years. So I conclude that java2d has never been a better choice for game development!

@ags1
Really?
Performance wasn’t even my main concern…
You’ll end up with a codebase you cant port to anything, different from OpenGL code.
Why build expertise in an API no one uses?
There are literally zero advantages to handicapping yourself like that, EXCEPT “java2D is easier”. But compared to libgdx this isn’t even true, especially considering super hacks you have to do in java2D to get performance.

There is no point.

@pelep
We have discussed this over the years in this forum countless times.
Basically, since this is a gaming forum one would assume you want to make a GAME. You will either do a game or an engine, not both. And to be perfectly realistic you wont do an engine. At least a GOOD one. Now whats the point of making an inferior weak lackluster maybe unstable engine? Fun. I guess If its fun to you I can’t really argue… If you want to be productive though, this is certainly the wrong approach.

Well, that’s a lot more convincing than “just don’t” :slight_smile:

[quote]If you want to be productive though, this is certainly the wrong approach.
[/quote]
I’ll take your word for it. I guess it’s on to libraries for me. Thanks for the advice!

@Cero, I’m not really arguing with you, I’m fully aware that java2d is just about the worst possible choice for game development. My focus was more on the “super hacks to get performance” part. I can understand these were necessary 5-6 years ago, but surely less so today given the dramatic increase in rendering performance we have seen over the past half decade. My budget Android phone has better graphics than my above-average 2008 laptop… (yes, I know my android phone cannot run java2d, I’m only using it as an example of the preformance differential we see in the recent past). I don’t really know as I have not used java2d very much myself. From the little I have seen it seems very similar to OpenGL direct mode rendering.

Regarding porting, I don’t think that is such a big issue. It’s a luxury problem for the average java2d game. In general you should isolate third-party libraries so you have the minimum dependencies on them, regardless of how similar that library may be to other libraries. And porting is always possible - consider princec’s ports from Java to C++ for example.

Also, pelep has another thread where princec mentioned that anyone looking at java2d should really be looking at javafx8 today.

@ags1

I’m not really arguing that performance available was never better and the codebase of java2D was probably never better. Sure. Nevertheless I see no point why anyone would start getting into Java2D… there is just no point. I dont really see a OpenGL binding as a “dependency” because, I mean, we all use some sort of codebase to build a game with, you never start with zero, so whats the difference. And a OpenGL binding is really the basis of any game development framework.

I remember getting hardware acceleration in java2D was a nightmare… A) There was no real dependable way to get the information on IF we are hardware accelerated or not
and B) The rules for getting and worse the rules for losing hardware acceleration were completely arbitrary.

yeah but cas uses opengl and those instructions are easily ported, let alone to other opengl systems.

I mean by porting I kinda also mean your knowledge… knowing java2D is not beneficial when you could know OpenGL. Better that nothing obviously, but many of the concepts are actually complete Java2D’s own bullshit…

tl;dr
Yeah I also dont argue with you. If you do want to do Java2D it probably has never been easier performance-wise and codebase-wise.
However that being said, I dont see why anyone would ever do Java2D to begin with.