Framerate independence?

?? Tue, 27 Mar 2007 13:18:45 +0200
"Stefan Hendriks" ???:

Why does one need a ‘fixed’ fps anyway? Afaik you want a fixed
game-flow , independant of the fps.
It’s not fixed, it’s capped at maximum. You won’t have more than some
number of FPS. In particular, it doesn’t make any sense to have a
refresh rate higher than monitor’s refresh rate (60Hz usually on LCD
monitors) because you won’t see anyway more than 60FPS. But if the game
just can’t do 60FPS, your game logic still must account for the lower
FPS, thus the amount of time that has passed since last frame is passed
into the update_game() function.

void handle_logic() {
while (timer > 0) {
updatelogicbytickonsomeevent/unit. etc.
timer–;
}
This is exactly the kind of overkill I was mentioning. Instead of
calling your updatelogic function N times, call it just once and pass
it the amount of the time between previous frame and this frame. So you
can spend the extra time in a sleep, so that your game behaves nicely
in a multitasking environment.

In particular, on my GeForce 7600GT I can keep a 60FPS rate with just
1-2% CPU usage, so I can run the game and in parallel compile,
download, compute, encode audio or video and in general do any kind of
useful background stuff.–
Greetings,
Andrew
-------------- next part --------------
A non-text attachment was scrubbed…
Name: signature.asc
Type: application/pgp-signature
Size: 189 bytes
Desc: not available
URL: http://lists.libsdl.org/pipermail/sdl-libsdl.org/attachments/20070327/41af454a/attachment.pgp

Ah, now i see the light heh. I thought you really wnted to fix the fps on 60.

This is exactly the kind of overkill I was mentioning.
I also see what you mean with my approach being an overkill. But even
then you can reduce the amount of n by setting a global , and
executing it 1 time and multiply all your vars with n ofcourse. Then
you only need 1 cycle, and won’t need all these precalc stuff.

-Stefan

Truth be told, I hadn’t actually thought of the persistent framerate
with sub-frame interpolation idea! Nice, that one!

To be honest, I think that sub-frame interpolation is wasteful.
It is actually a requirement for many game physics algorithms.

And then there is always the cadillac of game loops: a dynamically
multi-threaded game engine. Not for the faint of heart! Check out this
article
http://delivery.acm.org/10.1145/1240000/1231896/p9-tulip.pdf?key1=1231896&key2=9458994711&coll=&dl=GUIDE&CFID=15151515&CFTOKEN=6184618

-------------- next part --------------
A non-text attachment was scrubbed…
Name: aschiffler.vcf
Type: text/x-vcard
Size: 135 bytes
Desc: not available
URL: http://lists.libsdl.org/pipermail/sdl-libsdl.org/attachments/20070327/917cf34a/attachment.vcf

Truth be told, I hadn’t actually thought of the persistent framerate
with sub-frame interpolation idea! Nice, that one!
To be honest, I think that sub-frame interpolation is wasteful. You
don’t really need to run game logic more than once per display
(because these extra computations won’t be visible anyway - user will
see only the end result), and don’t need to run it less than that
(because all objects will be redisplayed at the same position several
times - user won’t see this).

But what of situations where, say you have a platformer and the
designer wants to put in some wicked hard jumps that are timed
exactly to you have to do it JUST right in accordance to your
avatar’s jump height and timing. How would you accomplish this on a
system which cannot guarantee a given framerate? Or what if the OS
decides to be a process hog for the precious few milliseconds where
you would reach the summit of your jump, crest the platform, and
safely land on it? That’s the one that’s always bugged me. I’ve
compensated for it by always having the player jump higher than their
intended maximum jump, but never more than an extra block’s height.

It occurs to me, however, that running a logic process with a fixed
framerate would account for that sort of thing such that the designer
could say “the player reaches their crest after 50 logic loops”, and
the game would calculate positions one loop in advance and instead of
performing logic in between logic frames (I’m using the word frame
here not referring to the visual kind, which is probably some kind of
mistake, sorry) they would perform interpolation calculations so that
the game objects appear to MOVE each frame, just they don’t change
their logic at all.

If you have a better way of dealing with these inconsistencies,
PLEASE let me know! I would love very much to not have to get into
it that far with my next game! :slight_smile:

– Scott

If you have a better way of dealing with these inconsistencies,
PLEASE let me know! I would love very much to not have to get into
it that far with my next game! :slight_smile:

As I said before in a mail, you could implement a multi threaded
engine. It’s the way modern CPU are going.

In my game, to give you a simplistic schema, I have the rendering
thread, which goes freely inside a rendering loop, and I have the
animation thread. The animation thread runs at a certain rate. Let’s
say, 100 times per second (whith proper time management… It gives
you 10 ms max per computation, which is enough for a lot of math on
modern machines), this thread update some data, let’s say,
caracterPosition.

Then, the render thread simply read the current position and render
it. You can implement this in two ways:

  • The rendering thread lock the data, that mean the animation thread
    has to be prepared for this and adjust timers accordingly.
  • The rendering thread don’t lock the data, and simply read what’s
    here. In this case, the code is simpler, but you have a risk of
    rendering half one frame, half the other. We use that way, because we
    noticed no visual problem as render is faster than animation.

Best regardsOn Mar 27, 2007, at 5:51 PM, Scott Harper wrote:


Kuon

“Your computer requests another OS, deny or allow?”
“You should stop playing with that, or it will eventually works.”

Company website:
http://www.goyman.com/

Personal blog:
http://arkhi.goyman.com/blojsom/blog/default/

From Tue, 27 Mar 2007 09:51:25 -0600
Scott Harper wrote:

But what of situations where, say you have a platformer and the
designer wants to put in some wicked hard jumps that are timed
exactly to you have to do it JUST right in accordance to your
avatar’s jump height and timing.
What’s wrong with passing the delta time to all functions that
calculate the distance at which your sprite moves etc?

Yes, computing 3D physics is one of the places where precision is
required. But limiting the framerate actually helps the physics (and
not just the physics but most other computation algorithms) to be more
accurate: instead of doing 10 computations with 0.001sec interval
you’re doing just one computation with a 0.01sec interval.

There’s a catch here with the physics though: if you limit your FPS too
low (say 25FPS) an object could penetrate deep inside an obstacle if
it’s moving too fast (and perhaps even punch it through). So maximal
FPS should be adequate for the speed of the objects in the game.

How would you accomplish this on a system which cannot guarantee
a given framerate?
Yep, that’s why I’m passing the actual time between the previous and
current frame to the computation logic so that it can take that into
account.

Or what if the OS decides to be a process hog for the precious few
milliseconds where you would reach the summit of your jump, crest the
platform, and safely land on it?
This kind of errors could be compensated by not invoking the game logic
with deltas longer than some period. For example, if you set the
max FPS to 50 and min FPS to 10 your game logic will be never called
with time intervals larger than 100 milliseconds. If the delta between
two frames happens to be longer, game logic should be called twice.

By the way, I have reviewed the code I posted before and found some bad
bugs in it - sorry, I wrote it in a hurry. Here’s a fixed version,
with the MinFPS setting:

ulong CurrentTime = GetCurrentTime ();// in milliseconds
ulong PreviousTime = CurrentTime; // the time of the previous frame
ulong NextTime = CurrentTime; // the time of the next frame
ulong NextFrac = 0; // the fractional part of NextTime
int MaxFPS = 50; // top FPS limit
div_t MinFrameLen = div (1000, MaxFPS);// quotient and remainder
int MinFPS = 10; // bottom FPS limit
int MaxFrameLen = 1000 / MinFPS; // No need to have it too precise,
// so no fractional part

while (…)
{
long delta = CurrentTime - PreviousTime;
// Don’t allow update_game to be called with too long intervals
while (delta > MaxFrameLen)
update_game (MaxFrameLen), delta -= MaxFrameLen;
if (delta > 0)
update_game (delta);
// Now display whatever we computed
display_game ();

PreviousTime = CurrentTime;
CurrentTime = GetCurrentTime ();
NextTime += MinFrameLen.quot; // this is the integer part
NextFrac += MinFrameLen.rem;  // and accumulate the remainder

// carry the remainder overflow into the integer part
while (NextFrac > MaxFPS)
    NextTime++, NextFrac -= MaxFPS;

// have a good sleep if we're running too fast
delta = NextTime - CurrentTime;
if (delta > 0)
    Sleep (delta);
// drop frames if we're running too slow
else if (delta < -100)
    NextTime = CurrentTime, NextFrac = 0;

}

There’s a catch here that the MinFPS is limited somehow by the computer
speed: if the computer is SO slow that it cannot even run game logic
with MinFPS, the application will run slower then slower then slower and
will finally freeze. If you really want to take into account such slow
computers, there can be additional workarounds implemented.–
Andrew

“What’s wrong with passing the delta time to all functions that calculate
the distance at which your sprite moves etc?”

I started off doing this and let me tell you, it sucks for many reasons!
I’m not going to go into major details but check out the article at the end
of this message for some really good info.

#1 - at constant fps, your game will have slight random deviations in it.
You can’t reproduce skill jumps, or do play backs, or have consistent
results to things.

#2 - with high fps, your calculations can have precision errors (weak
argument but add it to the pile) and there are other problems at high fps
too.

#3 - with low fps, things are allllll out of wack in your physics stuff. It
is really not pretty.

Bottom line, read this article, it speaks the truth and gives great info!
http://dewitters.koonsolo.com/gameloop.html> ----- Original Message -----

From: sdl-bounces@lists.libsdl.org [mailto:sdl-bounces at lists.libsdl.org] On
Behalf Of Andrew Zabolotny
Sent: Wednesday, March 28, 2007 3:24 PM
To: sdl at lists.libsdl.org
Subject: Re: [SDL] Framerate independence?

From Tue, 27 Mar 2007 09:51:25 -0600
Scott Harper wrote:

But what of situations where, say you have a platformer and the
designer wants to put in some wicked hard jumps that are timed
exactly to you have to do it JUST right in accordance to your
avatar’s jump height and timing.
What’s wrong with passing the delta time to all functions that
calculate the distance at which your sprite moves etc?

Yes, computing 3D physics is one of the places where precision is
required. But limiting the framerate actually helps the physics (and
not just the physics but most other computation algorithms) to be more
accurate: instead of doing 10 computations with 0.001sec interval
you’re doing just one computation with a 0.01sec interval.

There’s a catch here with the physics though: if you limit your FPS too
low (say 25FPS) an object could penetrate deep inside an obstacle if
it’s moving too fast (and perhaps even punch it through). So maximal
FPS should be adequate for the speed of the objects in the game.

How would you accomplish this on a system which cannot guarantee
a given framerate?
Yep, that’s why I’m passing the actual time between the previous and
current frame to the computation logic so that it can take that into
account.

Or what if the OS decides to be a process hog for the precious few
milliseconds where you would reach the summit of your jump, crest the
platform, and safely land on it?
This kind of errors could be compensated by not invoking the game logic
with deltas longer than some period. For example, if you set the
max FPS to 50 and min FPS to 10 your game logic will be never called
with time intervals larger than 100 milliseconds. If the delta between
two frames happens to be longer, game logic should be called twice.

By the way, I have reviewed the code I posted before and found some bad
bugs in it - sorry, I wrote it in a hurry. Here’s a fixed version,
with the MinFPS setting:

ulong CurrentTime = GetCurrentTime ();// in milliseconds
ulong PreviousTime = CurrentTime; // the time of the previous frame
ulong NextTime = CurrentTime; // the time of the next frame
ulong NextFrac = 0; // the fractional part of NextTime
int MaxFPS = 50; // top FPS limit
div_t MinFrameLen = div (1000, MaxFPS);// quotient and remainder
int MinFPS = 10; // bottom FPS limit
int MaxFrameLen = 1000 / MinFPS; // No need to have it too precise,
// so no fractional part

while (…)
{
long delta = CurrentTime - PreviousTime;
// Don’t allow update_game to be called with too long intervals
while (delta > MaxFrameLen)
update_game (MaxFrameLen), delta -= MaxFrameLen;
if (delta > 0)
update_game (delta);
// Now display whatever we computed
display_game ();

PreviousTime = CurrentTime;
CurrentTime = GetCurrentTime ();
NextTime += MinFrameLen.quot; // this is the integer part
NextFrac += MinFrameLen.rem;  // and accumulate the remainder

// carry the remainder overflow into the integer part
while (NextFrac > MaxFPS)
    NextTime++, NextFrac -= MaxFPS;

// have a good sleep if we're running too fast
delta = NextTime - CurrentTime;
if (delta > 0)
    Sleep (delta);
// drop frames if we're running too slow
else if (delta < -100)
    NextTime = CurrentTime, NextFrac = 0;

}

There’s a catch here that the MinFPS is limited somehow by the computer
speed: if the computer is SO slow that it cannot even run game logic
with MinFPS, the application will run slower then slower then slower and
will finally freeze. If you really want to take into account such slow
computers, there can be additional workarounds implemented.


Andrew


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

Hi,

El Jueves, 29 de Marzo de 2007 00:24, Andrew Zabolotny escribi?:

Yes, computing 3D physics is one of the places where precision is
required. But limiting the framerate actually helps the physics (and
not just the physics but most other computation algorithms) to be more
accurate: instead of doing 10 computations with 0.001sec interval
you’re doing just one computation with a 0.01sec interval.

Many physic algorithms just don’t like that. Most of them use some kind of
integration over time, (as ODE for example), so incrementing arbitrarily the
time step size will break the simulation. This also happens if the delta time
is very high (=poor precision, unrealistic results).

Alberto

Hi Guys
Why are you all worrying about deltas and how far your sprites will
move relative to the frame rate?, as i said in one of my previous posts,
just use a timer. The main loop can run flat out and draw everything. The
timer will run at a set interval (30fps) on slow or fast or blindingly fast
machines. This system works for me on dog slow machines the game runs at the
same speed, but the screen update in obviously much slower but even with
tricky sprite deltas that can not be fixed. Some of my games i use more than
one timer running at different speeds like one for animation, one for moving
one for game time count down etc…

// main loop
while(1)
{
DrawStuff
Draw More Stuff
Flip()
WaitFrameRate.
}
// some timer
Timer()
{
MoveStuff
MoveMoreStuff
CheckCollisions // do this here because thats where you moved it
AnimateStuff
}

Trish

From Thu, 29 Mar 2007 09:40:37 +0200
Alberto Luaces wrote:

not just the physics but most other computation algorithms) to be
more accurate: instead of doing 10 computations with 0.001sec
interval you’re doing just one computation with a 0.01sec interval.
Many physic algorithms just don’t like that. Most of them use some
kind of integration over time, (as ODE for example), so incrementing
arbitrarily the time step size will break the simulation.
I understand that, I don’t mean setting the time step to an arbitrary
value. I just have shown a mean to keep this time step within
reasonable bounds, e.g. you can set a minimum and maximum timestep, and
then call dWorldStep() from within your update_game() routine. What are
the actual “reasonable bounds” is mostly game-dependent, but generally
speaking ODE does not require all frames have the same length in time,
just that it wouldn’t be way off the “adequate” value.

This also happens if the delta time is very high (=poor precision,
unrealistic results).
Exactly, that’s why I have both MaxFPS and MinFPS.–
Andrew

El Viernes, 30 de Marzo de 2007 01:10, Andrew Zabolotny escribi?:

generally
speaking ODE does not require all frames have the same length in time,
just that it wouldn’t be way off the “adequate” value.

Keep in mind that the fact that ODE lets you advance a different amount of
time in every step doesn’t mean that the computations are still right. Using
a delta that can be from 1 time to 10 times its value can be catastrophic in
all but the simpler simulations. Think that it is not the same to apply a
force during a millisecond that doing the same during 10ms. Going back in
time is not an option IMHO – it is generally a wate of resources and can
lead to a large combinational problem to solve (think of multiple
collisions) --.

Exactly, that’s why I have both MaxFPS and MinFPS.

For the reasons above, I think you must decouple completely FPS from physical
computation.

Regards,

Alberto