5
\$\begingroup\$

Skyrim (Creation Engine / Gamebryo) is a prime example of a game that has its physics tied to the framerate for which it has been heavily criticized, because if you disable vsync / have a > 60 HZ monitor the physics will glitch, characters will fly into the air, and the screen will flicker while you are put into a swimming position. This problem can be solved by using a framerate limiting mod. But I want my game to run at any framerate, any refresh rate, just fine. How can I do that? Sorry if this isn't a game development question necessarily, it's more of a game engine question.

I looked and saw similar questions asked but they were very old and new tech / new programming techniques might have allowed better ways to do it since 2008.

\$\endgroup\$
4
\$\begingroup\$

To do this, firstly you need to define a physics update time period (say, evry 16ms) and then you need to handle the case of when your game runs too fast, and when it runs too slow.

When the game runs too quickly (faster than your physics update period) you need to interpolate between the last physics frame data and the next physics frame data based on what percentage of time you are at between physics updates.

When the game runs too slowly, a common solution is to run it multiple times if needed, and if the game starts to fall too far behind, you can drop update calls.

The other important things here are that you always call your physics update code with a specific time step (again, like 16ms) and that you keep a variable that accumulates how much time has passed in the game, using that as a measurement to know how many physics simulations you need to do that frame (game loop) to catch up to real time.

Passing the constant frame update time to your physics system is what makes it not depend on actual frame time (fps)

\$\endgroup\$
4
\$\begingroup\$

For a really good and in-depth article on this subject, just read Fix Your Timestep. There's also a ton of existing questions about this subject, although addressing different angles.

But in really simple terms, this is how you get a fixed physics (or anything, really) frame rate despite the rendering frame rate being unpredictable:

loop
    check how long it's been since the last frame
    while we are overdue for a physics frame
        do one frame of physics
    render

Or diagrammatically:

ideal physics frames:     p1      p2      p3      p4

render (actual) frames: r1   r2            r3 r4 r5

what's actually run:    r1   p1            p2 r4 r5
                             r2            p3
                                           r3

At r2, we run physics for one frame (p1), at r3 we run two (p2, p3), at r4 and r5 we don't run any physics.

One key insight is that we don't have to run physics at an exact point in time. We just need to make sure the physics is up to date before we render everything. Some people get trapped into thinking they'll need some super-complex time-synchronised multi-threaded monstrosity to handle this, because of this misconception.

Usually this is implemented by taking the difference between the actual time and the expected time for the next physics update, accumulating that difference, and running physics frames as long as that difference is larger than the ideal physics frame time. So for example if ideally physics runs every 50ms, and it's been 120ms since the last frame, you run 2 physics frames (50 goes into 120 twice), and keep around the remainder 20ms. I think it's clearer if I just reproduce the code sample from the linked article:

double t = 0.0;
const double dt = 0.01;

double currentTime = hires_time_in_seconds();
double accumulator = 0.0;

while (!quit)
{
    double newTime = hires_time_in_seconds();
    double frameTime = newTime - currentTime;
    currentTime = newTime;

    accumulator += frameTime;

    while (accumulator >= dt)
    {
        integrate(state, t, dt);
        accumulator -= dt;
        t += dt;
    }

    render(state);
}
\$\endgroup\$
  • \$\begingroup\$ Great explanation.. I will implement this immediately. \$\endgroup\$ – Jane Jul 16 '15 at 4:23

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.