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 was wondering if there is any possible harm when my game loop runs as fast as the system allows?

I currently have a loop, that, by measuring passed time in nanoseconds, runs the game logic and rendering logic at predefined speeds without a problem. In fact any logic I do in the loop is clocked to a certain amount of calls each second.

The loop itself though just runs about as fast as it likes to which comes up to around 11.7 million loops a second on my machine.

Loop (simple pseudocode):

while(!isGameOver){

 if(canPollInputs){
    pollInputs()
 }

 while(canStepLogic){
    stepLogic()
 }

 if(canRender){
    render()
 }
}

My question is basically if that simple loop, if its not running at a controlled speed, can do any harm to a system?

Edit: That means my logic is running 30 times a second (30 tps), my renderer is running at 60 fps, I'm polling inputs a 100 times a second and there's also some logic to cope with logic or rendering taking longer than expected. But the loop itself is not throttled.

Edit: Using Thread.sleep() to e.g. Throttle the main loop down to 250 loops per second leads to a reduction but the loops runs at around 570 loops per second instead of the desired 250 (will add code when I'm at my desktop machine..)

Edit: Here we go, a working java gameloop in order to clarify things. Also feel free to use it but don't claim it yours ;)

private void gameLoop() {

    // Time that must elapse before a new run
    double timePerPoll = 1000000000l / targetPPS;
    double timePerTick = 1000000000l / targetTPS;
    double timePerFrame = 1000000000l / targetFPS;
    int maxFrameSkip = (int) ( (1000000000l / MINIMUM_FPS) / timePerTick);

    int achievedPPS = 0;
    int achievedFPS = 0;
    int achievedTPS = 0;

    long timer = TimeUtils.getMillis();

    int loops = 0;

    int achievedLoops = 0;

    long currTime = 0l;
    long loopTime = 0l;

    long accumulatorPPS = 0l;
    long accumulatorTPS = 0l;
    long accumulatorFPS = 0l;

    long lastTime = TimeUtils.getNano();

    while(!isRequestedToStop) {
        currTime = TimeUtils.getNano();
        loopTime = currTime - lastTime;
        lastTime = currTime;

        loops = 0;

        accumulatorPPS += loopTime;
        accumulatorTPS += loopTime;
        accumulatorFPS += loopTime;

        if(accumulatorPPS >= timePerPoll) {
            pollInputs();
            playerLogic();
            achievedPPS++;
            accumulatorPPS -= timePerPoll;
        }

        while(accumulatorTPS >= timePerTick && loops < maxFrameSkip) {
            tick();
            achievedTPS++;
            accumulatorTPS -= timePerTick;
            loops++;
        }

        // Max 1 render per loop so player movement stays fluent
        if(accumulatorFPS >= timePerFrame) {
            render();
            achievedFPS++;
            accumulatorFPS -= timePerFrame;
        }

        if(TimeUtils.getDeltaMillis(timer) > 1000) {
            timer += 1000;
            logger.debug(achievedTPS + " TPS, " + achievedFPS + " FPS, "
                    + achievedPPS + " Polls, " + achievedLoops + " Loops");
            achievedTPS = 0;
            achievedFPS = 0;
            achievedLoops = 0;
        }

        achievedLoops++;
    }
}

As you can see there is almost no code run on each loop but always a certain selection based on how much real time has passed. The question is referring to that 'worker loop' and how it does influence the system.

share|improve this question
    
Thank you for formatting @Valkea –  dot_Sp0T Aug 12 at 11:09
1  
obligatory 'fix your timestep' link: gafferongames.com/game-physics/fix-your-timestep please read it. Also note that Thread.Sleep() cannot be used to throttle your timestep reliably as the OS does not guarantee to return control to your application after the requested amount of time. (It may vary). –  Roy T. Aug 12 at 11:59
    
Yeah, that's the problem with pseudocode. I did most of what gaffer writes about (currently working on a delta implementation that complements my loop structure). If I cannot use Thread.sleep() then what else is available within standard Java? –  dot_Sp0T Aug 12 at 12:10
1  
You usually use a busy loop with Thread.Sleep(0) and hope for the best. Gaffer talks about this a lot in a few articles. –  Roy T. Aug 12 at 12:22
    
Well that is basically what I've been doing, just without the thread.sleep(0), AND what originally provoked this question. Is there any harm in a busy (resp not busy as even that little repetitive logic is throttled down) loop for the system? –  dot_Sp0T Aug 12 at 13:10

3 Answers 3

up vote 30 down vote accepted

It will cause one CPU core to always run on 100%. This usually doesn't cause any harm to the system. CPUs are designed to run on 100% for hours. But on a mobile device it will drain the battery quickly and heat up the device, which will likely cost you about a stars in your store ratings. On a desktop computer this is less of a problem, but it will consume more of the users electricity, causes the CPU fan to spin faster which might cause some noise and waste CPU cycles which could otherwise be used by other processes. While these are not critical defects, they are still bad style, so you should avoid them when possible.

You didn't say anything about how your game logic loop works internally, but when you are using the delta-time approach (each calculation you are doing takes the time since the last call into account), you are dealing with very small delta-time values. This means you can run into problems with floating-point inaccuracy which can cause all kinds of strange behaviors. Also, the resolution of the system timer is often limited, so when your logic loop is too fast, you can get a delta-t value of zero, which then might cause a division by zero resulting in a crash.

To mitigate this problem, you should limit your framerate (graphic and logic) to the maximum of what the human eye can perceive. How much that is is disputed and depends on the kind of animation and on what kind of display it is shown, but estimations range from 40 FPS to 120 FPS. That means you need to set a minimum time of execution of each loop between 20ms and 8ms. Should a loop iteration finish faster, let the cpu thread sleep for the remaining timespan.

share|improve this answer
    
Thanks for the explanation Philipp. I actually did refer to the fact that I'm running at a certain fps and tps as well as do the polling only a certain amount of times a second. Will try to make it clearer though. –  dot_Sp0T Aug 12 at 10:42
    
@dot_Sp0T After your edit to your question, only the first paragraph and the last sentence are relevant to your case. However, I would like to retain the second and third paragraph of my answer because they might be helpful for others. –  Philipp Aug 12 at 13:41
    
I will presumably as well accept your answer as the first paragraph perfectly well gives an answer. Would you mind to somehow visually set it apart from the rest of the answer? –  dot_Sp0T Aug 12 at 18:14
    
Play an unpatched Civilization 2 on a desktop and you'll find it to be a problem. At least, I do. shrug –  corsiKa Aug 12 at 20:05
1  
In addition to battery and fan considerations, increased CPU usage can lead to excess heat which can be uncomfortable (e.g. laptop, esp my rMBP) and even lead to the PC shutting down (esp older PC's with dusty coolers). These factors are exasperated if you run all cores a 100%. –  NPSF3000 Aug 13 at 12:36

You shouldn't have jittery movement / gameplay

There are two ways that you can implement game logic - tied to a real time, or tied to the number of "turns"/processing steps. If some thingy in your game is moving leftwards, will it's motion be different if your stepLogic() was called 100 instead of 50 times?

If your code treats the elapsed time explicitly everywhere and does it correctly, then it might be okay; but if there's anything in your code that depends on the number of 'steps' then you'll get unwanted side-effects.

First, the speed of things that should be moving constantly will vary unpredictably (depending on processor usage), and this makes for very annoying controls - you can't make a precise punch or a jump if suddenly the game speeds up or slows down. Even for games with no 'twitch' at all, it looks annoying and jittery if things aren't moving smoothly.

Second, you might get problems with character abilities depending on the computer speed - a classic example is the old Quake issue where the maximum jumping range was unintentionally dependent on your fps.

These issues may appear even if you try to have the code to be fps-independent, accumulation of rounding errors can often cause such bugs.

share|improve this answer
1  
As much as I like your answer its not relevant to the question, as I'm not asking about jittery movement/gameplay but about the harm an uncontrolled loop (that does not control any logic or rendering or anything else) can do to the sys –  dot_Sp0T Aug 12 at 13:28

The only potential harm is to your power consumption, so don't do this on mobile devices. Conversely, quite a few embedded systems spend their entire lives in a loop waiting for things to happen.

It used to be entirely normal to simply render game frames as fast as possible, sometimes without even a timer to compensate gameplay for different CPU speeds. Bullfrog's racing game Hi-Octane was a particularly bad victim of this, and I suspect this is what the poster mentioning Civ2 is referring to.

I'd advise you to at least poll inputs on every pass if you're on a Windows system or similar, to ensure snappy input response.

share|improve this answer

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.