Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I implemented my game-loop as described in deWiTTER's article, using the last approach with an unlimited FPS and a constant game-speed.

My problem is, that the unlimited FPS cranks up my CPU usage to nearly 100%. I understand that this is desired (as the hardware does as much as it can), but for my game, it's not really necessary (it's pretty simple). So I'd like to limit the FPS to some upper bound.

Consider my game-loop:

private static final int UPDATES_PER_SECOND = 25;
private static final int WAIT_TICKS = 1000 / UPDATES_PER_SECOND;
private static final int MAX_FRAMESKIP = 5;

long next_update = System.currentTimeMillis();
int frames_skipped;
float interpolation;

// Start the loop:
while (isRunning){
    // Update game:
    frames_skipped = 0;
    while (System.currentTimeMillis() > next_update
            && frames_skipped < MAX_FRAMESKIP){
        // Update input, move objects, do collision detection...
        // Schedule next update:
        next_update += WAIT_TICKS;
        frames_skipped++;
    }
    // Calculate interpolation for smooth animation between states:
    interpolation = ((float)(System.currentTimeMillis() + WAIT_TICKS - next_update)) / ((float)WAIT_TICKS);
    // Render-events:
    repaint(interpolation);
}

How would I implement a maximum FPS?

If i implement the repaint the way I implemented the update (or use a sleep instead of "do-nothing-cycles"), then the FPS is locked, right? That is not what I want. I want the game to be able to work with lower FPS (just as it does now), but limit the FPS to a maximum of, say 250.

share|improve this question
    
possible duplicate of CPU usage, game loop and sleep() –  Samaursa Dec 31 '13 at 17:54
    
@Samaursa This doesn't answer my question, since mine is about implementing the max FPS. What you linked is just a discussion about if and why. –  Lukas Knuth Dec 31 '13 at 18:15
    
One of the points in that question is "Running at 100% CPU is not necessarily bad.". But I see your point about it not directly answering your question. –  Samaursa Dec 31 '13 at 18:51
add comment

1 Answer 1

up vote 1 down vote accepted

Store the last time you rendered a frame, and if it hasn't been enough time, Sleep().

Note that Sleep() can sometimes result in your program not waking up when it should, giving you a framerate stutter - test it pretty carefully. In my experience most modern OSes will timeslice frequently enough that this won't be an issue except in fast-paced first-person-shooters.

private static final int UPDATES_PER_SECOND = 25;
private static final int WAIT_TICKS = 1000 / UPDATES_PER_SECOND;
private static final int MAX_FRAMESKIP = 5;

long next_update = System.currentTimeMillis();

/////// NEW CODE BEGIN
private static final int MAX_UPDATES_PER_SECOND = 60;
private static final int MIN_WAIT_TICKS = 1000 / MAX_UPDATES_PER_SECOND;

long last_update = System.currentTimeMillis();
/////// NEW CODE END

int frames_skipped;
float interpolation;

// Start the loop:
while (isRunning){
    /////// NEW CODE BEGIN
    // Delay if needed
    while (System.currentTimeMillis() < last_update + MIN_WAIT_TICKS){
        System.Sleep(0); // I don't know C# so this is a guess, but there will be some equivalent function somewhere
    }
    last_update = System.currentTimeMillis();
    /////// NEW CODE END

    // Update game:
    frames_skipped = 0;
    while (System.currentTimeMillis() > next_update
            && frames_skipped < MAX_FRAMESKIP){
        // Update input, move objects, do collision detection...
        // Schedule next update:
        next_update += WAIT_TICKS;
        frames_skipped++;
    }

    // Calculate interpolation for smooth animation between states:
    interpolation = ((float)(System.currentTimeMillis() + WAIT_TICKS - next_update)) /     ((float)WAIT_TICKS);

    // Render-events:
    repaint(interpolation);
}
share|improve this answer
    
Is that "busy-wait" with the sleep()-function? Thread.sleep( (last_update + MIN_WAIT_TICKS) - System.currentTimeMillis() ); would also work. Otherwise, this seems to work fine. –  Lukas Knuth Dec 31 '13 at 18:09
    
On Windows, at least, Sleep(0) means "give up whatever is left of my timeslice, but come back to me ASAP". There's no guarantee that the OS comes back instantly, and in my experience, it usually won't. The danger of giving a larger number is that the OS will not return until at least that much time has passed, and sometimes until significantly more than that much time has passed. In my empirical testing (years back), Sleep(0) provided almost the same CPU reduction that your suggestion did, with significantly better responsiveness. Of course YMMV :) –  ZorbaTHut Dec 31 '13 at 19:05
    
That makes sense. I'll test that out. –  Lukas Knuth Jan 1 at 13:57
    
For sleep(0) I get CPU usage of 50% - 100%. For sleeping longer, I get 25% - 50%. Seems significant to me. –  Lukas Knuth Jan 1 at 17:50
    
Huh. Perhaps things have changed since the last time I tested. Well, that's why we test :D That said, if your'e not outputting the actual updates as well, you should do that - it may be that the sleeping-longer solution is getting less than the target framerate. –  ZorbaTHut Jan 5 at 15:02
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.