Understanding Active Rendering game loops

Hey everyone, I have been programming my past games using the “traditional” method of just having the run method sleep for a certain amount of time and then repainting, however want to switch to the Active Rendering method.

I am having trouble finding articles, tutorials, etc. on this topic and am having trouble figuring out how to implement it. Looking at the source code for Metagun by notch I was able to implement his loop into my game, however do not understand certain parts.

Why does the code sleep for 500 seconds beforehand? If i take this piece of code out, I get a NullPointer error when trying to render the screen, not sure why this is happening.

But my main questions is what does the while(unprocessedTime > 0) loop does.

lastly, how would I implement an FPS counter in this type of loop?

public void run() {
        requestFocus();
        Image image = new BufferedImage(320, 240, BufferedImage.TYPE_INT_RGB);
        setScreen(new TitleScreen(this));

        long lastTime = System.nanoTime();
        long unprocessedTime = 0;
        
       [b] try {
            Thread.sleep(500);
        } catch (InterruptedException e1) {
            e1.printStackTrace();
        }[/b]
    
        while (running) {
            Graphics g = image.getGraphics();

            long now = System.nanoTime();
            unprocessedTime += now - lastTime;
            lastTime = now;

            int max = 10;
            [b]while (unprocessedTime > 0) {
                unprocessedTime -= 1000000000 / 60;
                fps = unprocessedTime;
                screen.update(input);
                input.update();
                if (max-- == 0) {
                    unprocessedTime = 0;
                    break;
                }
            }[/b]
            screen.render(g);
            g.dispose();

            try {
                started = true;
                g = getGraphics();
                g.drawImage(image, 0, 0, GAME_WIDTH * SCREEN_SCALE, GAME_HEIGHT * SCREEN_SCALE, 0, 0, GAME_WIDTH, GAME_HEIGHT, null);
                g.dispose();
            } catch (Throwable e) {
            }
            try {
                Thread.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

Thanks guys, any resources, links or anything at all will help, I really want to learn what is happening rather then just get it working.

The first bold area, sleeping for 500 (millisecs ), half a second sleeping? The objective is to stacktrace and catch unexpected exceptions. Anyhow this only done once at start. Perhaps there is system where you have to wait to load some images/sounds before execution, and this half second gives it time to do so. Java is a bit ugly in this territory, I remember j2me not being at all nice in this. If you load something, it does it in the background or something? And if you try to start immediately it gives the Nullpointer. You have to make your own clean loaders perhaps.

Next boldness, i think here the idea is to go through updates depending on performance, if necessary go through many updates. So if unprocessed time is large, it will do multiple screen/logic updates before reaching render. In this case, the screen.update probably contains stuff that makes things move around on screen, so it has to be done to maintain overall logic.

So, an excellent example of a not-so-readable main loop. Optimally the sleeper would be explained, and the fps=unprocessedtime line would perhaps be chucked, since it is unlikely to give correct values - or does it?

Ahh yes, I guess that does make sense about the loading the resources, I guess it gives it time to load up before actually using them. I should just make it into a nicer loading method or something. (this was taken from a contest entry so I dont believe the intention of the code was to be presentable, but I actually enjoy going through it)

I see so what this loop is doing is making sure that if there was too much of a delay(?) it will keep the game logic going because a mis-step in this could change things, but once its caught up, render it all?

Lol sorry, the fps = unprocessedTime; was something I did just to see what the value for that was, somehow it got left in there.

But what I am not understanding is, this loop is updating at what FPS? because it seems to be tick based in the original code, how would I make movement, shooting and all of that uniform. For example I have seen some games that use Active Rendering run at 500 FPS, I would not want my character to update x+=5; at that rate correct?

Also if someone has a more readable game loop, i would really appreciate seeing that.

In regards to the FPS, what you are talking about is something different called ‘delta time’. It is a little similar, in that it is based on the speed of the game, but it’s aim is to generate a multiplier that you use for multiplying against all changing values. So rather then x += 5, it becomes x += 5*delta.

If the game is running at 500fps (which IMHO is waaaaaaaaaaay too fast and should be capped to a much lower value), then delta time will be a very small number (so you only move a small amount). If the game is running at 10fps, delta time should be large number (so you move much further then normal). Normally the expected speed for delta time to be based on is 60fps. So if your game is running at 60fps, delta time is 1, and at 30fps delta time becomes 2 (because your at half the speed).

I believe the algorithm is something along the lines of:


// how long a frame should take, which is around 16.6 milli seconds
double idealTime = 1000.0 / 60.0;

long lastTime = time();

while ( true ) {
    long now = time();
    long diff = now - lastTime;
    double delta = diff / idealTime ;
    
    // update your game here
    
    lastTime = now;
}

Note that the above is just psudo-code. The ‘1000’ in ‘1000 / 60’ is 1 second in milliseconds, and if your using nano or micro seconds instead then you will need to change this value accordingly. You should also cap your maximum and minimum delta time values (and your maximum fps too), as any odd pauses can cause delta time to become very large to the point that it just messes up your game.

I’d also personally be interested in any better algorithms then the above; I’ve heard of people smoothing delta time over several frames and things like that, but it always just looks buggy when I’ve tried implementing this.

As for your mainloop, where is the null pointer occurring? It’s been a while since I’ve written a mainloop in Java, but I don’t remember having to sleep for half a second first. AFAIK there should be no real reason why you need to sleep for half a second, and if you do have to wait for something to get ready first then that seems like a very hacky way of checking (it would be better to check if it is safe to start or not).

My game loop:


final int FPS = 60;
final long ONE_SECOND = (long)1e9;
int maxUpdates = /*user specified*/
int frames = 0;
int currentFPS = 0;
long time = System.nanoTime();
long lastTime = System.nanoTime();

isActive = true;

while(isActive()) {
	long diffTime = System.nanoTime()-lastTime;
	lastTime += diffTime;
	
	int updateCount = 0;
	
	while(diffTime > 0 && (maxUpdates <= 0 || updateCount < maxUpdates)) {
		long deltaTime = FPS > 0 ? deltaTime = Math.min(diffTime,ONE_SECOND/FPS) : diffTime;
		
		try{
			update(deltaTime);
		}
		catch(Exception exc) {
			exc.printStackTrace();
		}
		
		diffTime -= deltaTime;
		
		updateCount++;
	}
	
	try{
		do{
			do{
				Graphics2D g = (Graphics2D)strategy.getDrawGraphics();
				g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,quality);
				
				try{
					paint(g);
				}
				catch(Exception exc) {
					exc.printStackTrace();
				}
				
				if(showFPS) {
					g.setColor(Color.black);
					g.setFont(new Font(Font.SANS_SERIF,Font.TRUETYPE_FONT,10));
					g.drawString(currentFPS + " FPS",2,getHeight()-2);
				}
				
				g.dispose();
			}while(strategy.contentsRestored());
			
			strategy.show();
		}while(strategy.contentsLost());
	}
	catch(Exception exc) {
		exc.printStackTrace();
	}
	
	frames++;
	
	if(System.nanoTime()-time >= ONE_SECOND) {
		time = System.nanoTime();
		currentFPS = frames;
		frames = 0;
	}
	
	try{
		if(FPS > 0) {
			long sleepTime = Math.round((ONE_SECOND/FPS)-(System.nanoTime()-lastTime));
			if(sleepTime <= 0)
				continue;
			
			long prevTime = System.nanoTime();
			while(System.nanoTime()-prevTime < sleepTime) {
				if(useYield)
					Thread.yield(); //Smoother game loop, more CPU usage
				else
					Thread.sleep(1); //Less CPU usage but not as smooth as yield()
			}
		}
	}
	catch(Exception exc) {
		exc.printStackTrace();
	}
}

EDIT: If not waiting for 500ms causes a NPE, then that means there is a second thread loading resources.

@JL235 Thanks, that explanation helps me understand how to calculate the FPS, although I was curious as to how to implement that within the game loop that I posted, because that while loop within the while(running) throws me off completely as to what is happening. Also that sleep 500 was definitely a hack of getting it to work, it was written for a competition so I assume the author just wanted to get things working.

@R4KING, thanks for that, however I am curious as to the loops that use Thread.sleep(1), I have seen it used quite a bit but cant seem to grasp it. I will definitely think about implementing something like your code though.

Actually I think I got it working for the most part, (not sure yet so wont post anything) but thanks guys for the help, R4KING your example helped a lot so thanks again. Also here is a helpful link for people in the future who see this thread

http://www.koonsolo.com/news/dewitters-gameloop/

Thread.sleep(int) is unreliable so I use yield() or sleep(1) in a while loop.
yield() produces a smoother game loop but hogs the CPU.
sleep(1) uses very little CPU time but the game loop is not as smooth.

While in debug mode I use sleep(), and on single core machines I use sleep() as well by default; in dual core or release code I use yield(). And I provide a commandline switch to force it one way or the other. Cover all your bases :slight_smile:

Cas :slight_smile:

All your sleep are belong to us!

Hey guys, I have my loop updating at a constant 60 FPS, and then the rendering has no limit. However, if I have a block (just one block) moving left and right on the screen it twitches a bit from time to time.It isnt a constant twitch where I can predict where it will stutter, but just randomly it stutters. The time is still updating at the correct rate however it stutters.

I am not sure what could be causing this because the rendering is at its own rater (higher than 60 FPS).

Some ideas I have are that the code to keep updating at a constant rate is in a while loop and after that is rendering code. So if the loop some how falls behind, while it is catching up it is not rendering and therefore when it finally catches up the block jumps to the new position?

here is my loop, please dont be too harsh its roughly put together

public void run()
    {
        Image image = new BufferedImage(GAME_WIDTH,GAME_HEIGHT, BufferedImage.TYPE_INT_RGB);
        setScreen(new TitleScreen(this));

        int TICKS_PER_SECOND = 60;
        int ONE_SECOND = 1000000000;
        int SKIP_TICKS = ONE_SECOND / TICKS_PER_SECOND;
        int MAX_FRAMES_SKIP = 10;

        int currentFPS = 0;
        int frames = 0;
        long timePast = System.nanoTime();
        long time = System.nanoTime();

        int loops;

        while (running)
        {
            Graphics g = image.getGraphics();

            loops = 0;
            while (System.nanoTime() > time && loops < MAX_FRAMES_SKIP)
            {
                screen.update(input);
                input.update();
                time += SKIP_TICKS;
                loops++;
            }

            screen.render(g);
            if(!hasFocus())
            {
                g.setColor(Color.red);
                g.drawString("CLICK FOR FOCUS", Game.GAME_WIDTH/2-80,Game.GAME_HEIGHT/2);
            }
            g.dispose();

            frames++;

            if (System.nanoTime() - timePast >= ONE_SECOND)
            {
                timePast = System.nanoTime();
                currentFPS = frames;
                frames = 0;
            }

            try
            {
                g = getGraphics();
                g.drawImage(image, 0, 0, GAME_WIDTH * SCREEN_SCALE, GAME_HEIGHT * SCREEN_SCALE, 0, 0, GAME_WIDTH, GAME_HEIGHT, null);
                g.dispose();
            } catch (Throwable e)
            {
            }
            try
            {
                Thread.yield();
            } catch (Exception e)
            {
                e.printStackTrace();
            }

        }

    }

Hi -

You might find this neighboring thread interesting:

http://www.java-gaming.org/index.php/topic,24311.0.html

Ostensibly that thread is about using a game loop in a passive rendering situation (and in my case, via a “scheduled” game loop algorithm), but the timing aspects dealt with could be pertinent just the same.

As a result of the investigations there, I was able to both get a better idea of what is going on with the various time-related objects and how they interact with the time info provided by the OS. If you have WindowsXP, for instance, there are many ways to run afoul of its 15msec system clock interrupt.

Pretty amazing, though, that one can run a long sleep thread in the background, from the start of the program, and this prompts the OS to use a more precise (though slightly costlier) means of getting the time. Doing so might clear up some of your timing problems.

In particular, check out post #16.

My programs are definitely running smoother now. I posted there a simple tool for timing durations between game loops that might help in diagnosing the problem. (#11)

Hey thanks for the reply, I did try adding that long sleep thread in the beginning of my program but the same stuttering occurs, still have no idea what could be causing it but thanks for the link, ill continue to read up and see if i can figure it out, but any help is appreciated.

Specifically, is there anyone here that has a basic gameloop that doesnt stutter (similar to this active rendering approach)?

Scroll up and check out my post (Post #4) on this thread.

Just 2p more to throw in here - on Vista and Win 7 the desktop compositor runs unfortunately independently of the refresh rate in your windows and sometimes it doesn’t actually update every frame for whatever reason. End result is: I get a display which claims to be updating at 60Hz and even has data to prove it but Windows manages to make it glitch and drop a frame here and there now and again.

Doesn’t happen in fullscreen, and not sure if this is purely OpenGL related or happens with Direct3D rendered windows, but just something I have observed. The slower the machine is the more likely the display update glitches are.

Cas :slight_smile:

Hey guys, i have done some further test and see that the stuttering seems to happen completely randomly, even when the update loop is not catching up it just happens to stutter. I have a plain java2D block going left and right on the screen and it appears to jump forward and then jump back. I have no idea what could be causing it because the game is running at a constant 60 FPS, the rendering is much higher than that and the code is not putting a burden on the update loop causing it to catch up.

Sorry if any of you have mentioned something that would be a solution to this, I am just trying to understand this all and may not have understood what you meant, but from what I have been trying. I am yet to figure it out.

Try using Canvas + BufferStrategy.

I converted it to Canvas and used the bufferstrategy, as followed by this tutorial

http://www.gamedev.net/page/resources/_/reference/programming/languages/java/java-games-active-rendering-r2418

although the result seems to be a bit better, still see a quit stutter here and there

edit I even ripped the drawing code from your loop posted and it still stutters… does anyone have a full example of just a simple block going left and right at speed 5 pixels without stuttering? that is all I am trying to achieve and its insane to me that nothing seems to be solving such a small problem.

have any runnable code? an example application that stutters for you?

Here is a link to a quick example that I just wrote that shows the stuttering. I am not sure where I could upload the zip file of the source though.

link to the example
http://dl.dropbox.com/u/30070606/Example/example.jar

**edit, heres the http://cksgames.com/stutter/src.zip

OK I notice the stutter, isn’t the app small enough to just post the code here?