0
\$\begingroup\$
public static void main(String[] args) {

        long newTime, delta, timeSince1Second, startTime, oldTime;
        long ticks = 0;
        double frameCap = 1000/60;
        double time_passed = 0;

        startTime = System.currentTimeMillis();
        oldTime = System.currentTimeMillis();
        while(true)
        {
            newTime = System.currentTimeMillis();
            delta = newTime - oldTime; 
            timeSince1Second = newTime - startTime;
            currentTime = newTime;

            //update game based on dynamic time step here (if needed)

            //update loop (fixed time step) 
            while(time_passed >= frameCap)
            {
                //update game logic (fixed time step update)
                time_passed = time_passed - frameCap; //resetting time_passed essentially to 0
                ticks++; 
            }


            time_passed = time_passed + (double) delta; //time passed since start of loop

            //render here

            //frame rate counter
            if((timeSince1Second/1000) >= 1)
            {
                System.out.println(ticks+" frames per second");
                startTime = System.currentTimeMillis();
                ticks = 0;
            }
        }
} //end main function

This code has been written in java. I'd like to know if i'm missing anything here, because in the fixed time step update loop, if i display for example a window, and move the window around, the framerate will sometimes change until i stop moving the window around, which is kind of confusing to me. Is that normal? Or perhaps I might be missing something Guidance will be appreciated

\$\endgroup\$
  • \$\begingroup\$ Is it safe to assume your one reference to currentTime is actually meant to be oldTime? I don't see currentTime defined anywhere. \$\endgroup\$ – DMGregory Jun 17 '17 at 13:06
  • \$\begingroup\$ What if you don't move the window around? Typical game play rarerely occurs at the same time that the window is moved around.... \$\endgroup\$ – Vaillancourt Jun 18 '17 at 3:04
1
\$\begingroup\$

Short answer: no, this is not correct.

  1. time_passed = time_passed + (double) delta; should come before your fixed update loop. It's updating your store of time that needs to be simulated.

    Imagine our game lagged for whatever reason, and it's been 30 ms since the last frame we displayed. That's enough to do two fixed update loops. But if we don't add that time before checking how many fixed update loops to do, then we don't react to the longer frame duration. Our game visually slows down because not enough simulation steps have occurred to keep up with the time that's passed. Then, in the next frame, that extra time is now present in time_passed, so all our catch-up steps are done then - even if the frame time delta for this next frame was much smaller. So now our game runs too fast for a frame. Overall we're keeping pace with real time, but we're doing it in a stutter-and-race-ahead way that does not maintain a smooth update rate under varying frame times.

  2. You want to do your dynamic frame rate updates after your fixed updates.

    These dynamic updates are often for visual and audio feedback that needs to be presented to the player "just in time" to reflect the state of the game. When you do these updates before your fixed simulation steps, you allow the game state to get ahead of this feedback state before it's rendered to the screen.

    So, for example, imagine we have a spider character that uses inverse kinematics to match its legs to the ground it's clambering along. The movement of the character is handled in the fixed update step for consistency, but we don't need to do the IK for every step along the way - we just need to snap the legs to the terrain at the end, before we render the frame to present to the player. If we did this dynamic IK step before the fixed update step, then the spider could continue to move after we've tried to position the legs, leading to a mismatch by the time the frame is rendered.

  3. Your section labelled //frame rate counter is not measuring frame rate (as in, number of cycles per second).

    It's measuring the number of fixed update steps per frame. This is expected to fluctuate, due to variable frame rate and mismatches between your rendering frame rate and the frameCap you've set. (eg. If you're rendering at 90 FPS, you'd expect to bounce between 0 & 1 fixed steps per frame, in a 1:2 ratio overall, so that the game's fixed update steps 60 times per second)

    To measure whether your fixed update loop is keeping up correctly, you'd want to compare your total fixed step count since the start of the game versus your total time since the start of the game, divided by frameCap. Your fixed step count should be the same as the floor of your time divided by the framerate. If it drops behind by 1.0 or more and catches back up, then it's not correctly maintaining a fixed frequency of updates relative to real time.

    (Similarly, your timeSince1Second is not really measuring a time since 1 second into the game - it's a time since game start. Watch out for these comments and variable names - they're your reminders later about what the code is doing. If you leave yourself misleading notes, then you're liable to make mistakes the next time you come back to this code to reason about it or alter it.)

|improve this answer|||||
\$\endgroup\$
  • \$\begingroup\$ Thanks for your suggestions and observations. Designing a proper game loop is a lot more complex than I had previously thought. Could you post some sort of pseudocode/template that could be generically followed? The one I currently 'implemented' had been bits and pieces from all over the web, hence the reason why I didn't get it right. Conceptually, I may be a little far off as well. \$\endgroup\$ – Shayan Niazi Jun 18 '17 at 11:58
  • \$\begingroup\$ Gaffer on Games "Fix Your Timestep!" is generally the go-to. Game Programming Patterns develops a similar loop from a slightly different angle. Neither shows a hybrid loop with both fixed and variable update steps like eg. Unity uses, but it's easy enough to insert a variable step after the fixed steps & interpolation but before rendering, if that's how you want to go. \$\endgroup\$ – DMGregory Jun 18 '17 at 12:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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