Re: [pygame] frame independant movement
> In other words, use a small enough time step that the difference > is not big enough to be a problem. But if you're doing that, you > might as well pick one sufficiently small time step and use a > variable number of them per frame, so that the physics is > always predictable whatever the frame rate. While we're on the time topic, is there an easy way to do slo-mo, a la Peggle Extreme Fever or a Burnout multi-car pileup? Alan
Re: [pygame] frame independant movement
Christopher Night wrote: But of course, it's extremely easy to do constant-acceleration motion as well: x += vx * dt + 0.5 * g * dt ** 2 vx += g * dt Yes, you can do this kind of thing if the differential equations governing your physics have an exact closed-form solution. But that's not always the case -- simulating an object orbiting a planet is one example. dt = max(clock.tick() * 0.001, 0.1) for j in range(5): for sprite in sprites: sprite.think(dt/5.) In other words, use a small enough time step that the difference is not big enough to be a problem. But if you're doing that, you might as well pick one sufficiently small time step and use a variable number of them per frame, so that the physics is always predictable whatever the frame rate. Although... you probably *do* want the physics to slow down if the frame rate gets too low, otherwise the game becomes unplayable due to the player not getting enough feedback. Anyway, it's fine to have a library to do this, but there are some simple things that have always worked for me. Even in the simple cases, there is benefit in having a library that you can rely on to do it all right, instead of having to think about whether the assumptions behind the particular shortcuts you're using are valid in the circumstances. -- Greg
Re: [pygame] frame independant movement
On Aug 27, 2010, at 9:06 AM, James Paige wrote: > On Fri, Aug 27, 2010 at 08:43:59AM -0700, Brian Fisher wrote: >> So you asked "what else do you need?" well the answer is if you want >> consistent non-linear physics (like say you want the players to jump the >> same all the time), then the "else" you need is fixed size timesteps for >> your physical simulation. > > I seem to remember that one of the Quake games (or was it all of them?) > did this /wrong/. The distance your character could jump was affected by > your frame rate, making certain hard jumps impossible at certain frame > rates. This page explains that issue nicely: http://www.niksula.cs.hut.fi/~hkankaan/Homepages/gravity.html -Casey
Re: [pygame] frame independant movement
Yes, a high-quality physics engine would aim for consistency. However, you can do drag with variable timesteps pretty easily as well, if not exactly correct, then good to second order in dt. Complicated things like orbital motion are difficult, and I can definitely see using a fixed timestep when you need good simulations. On the other hand, despite having programmed plenty of physics simulations, I've never needed to use it in a game. Of course it depends on the type of game, but I certainly would not jump to a fixed timestep as my first solution. I also find it very annoying when a game prohibits me from running it faster than 20fps, no matter how fast my computer is capable of running it. Just my opinion, though. -Christopher On Fri, Aug 27, 2010 at 12:22 PM, Brian Fisher wrote: > On Fri, Aug 27, 2010 at 9:10 AM, Christopher Night > wrote: > >> Sure. But of course, it's extremely easy to do constant-acceleration >> motion as well: >> >> y += vy * dt + 0.5 * g * dt ** 2 >> vy += g * dt >> >> Sure, that explicit integration technique works fine if you can write an > explicit integration function - I've used that same technique even with > fixed time-steps because it's more accurate. But now how about if you have > acceleration and friction for a car driving on a surface - can you write a > single dt based function for that? now how about something that is > accelerating away with a spring on it? or maybe something falling while > accelerating off axis with a spring attached? It very quickly gets beyond > your ability to write such functions if you try and do really interesting > stuff. > > While consistent timesteps on the other hand, make it so the thing is > always consistent and repeatable, even with simple update functions. Don't > you want your game to behave the same regardless of frame rate? If you do, > then fixed timestep simulation loops is a simple elegant widely used > solution. >
Re: [pygame] frame independant movement
On Fri, Aug 27, 2010 at 9:10 AM, Christopher Night wrote: > Sure. But of course, it's extremely easy to do constant-acceleration motion > as well: > > y += vy * dt + 0.5 * g * dt ** 2 > vy += g * dt > > Sure, that explicit integration technique works fine if you can write an explicit integration function - I've used that same technique even with fixed time-steps because it's more accurate. But now how about if you have acceleration and friction for a car driving on a surface - can you write a single dt based function for that? now how about something that is accelerating away with a spring on it? or maybe something falling while accelerating off axis with a spring attached? It very quickly gets beyond your ability to write such functions if you try and do really interesting stuff. While consistent timesteps on the other hand, make it so the thing is always consistent and repeatable, even with simple update functions. Don't you want your game to behave the same regardless of frame rate? If you do, then fixed timestep simulation loops is a simple elegant widely used solution.
Re: [pygame] frame independant movement
Here's what I always do: dt = clock.tick() * 0.001 x += vx * dt y += vy * dt And all the sprites have a think(dt) method that updates them as if dt seconds have passed. What else do you need? -Christopher On Fri, Aug 27, 2010 at 11:19 AM, James Paige wrote: > On Fri, Aug 27, 2010 at 10:59:09AM -0400, Kris Schnee wrote: > > On 2010.8.27 10:36 AM, B W wrote: > >> Howdy, > >> > >> Reviving this old thread. The comments by Patrick and Brian really > >> intrigued me, so I pursued the topic. Found a few interesting articles > >> and one great article. My study has resulted in a recipe for those of us > >> continually nagged by the question, "how can I get constant game speed > >> independent of frame rate?". The demo requires Pygame, but the clock > >> module only requires Python. > > > > Isn't it simply a matter of creating a Pygame Clock object and calling > > clock.tick() to delay until the appropriate time to maintain some max > > framerate? > > That only caps a max framerate. What Gumm is talking about is when your > framerate and your game simulation rate can be adjusted independantly > > --- > James Paige >
Re: [pygame] frame independant movement
Sure. But of course, it's extremely easy to do constant-acceleration motion as well: x += vx * dt + 0.5 * g * dt ** 2 vx += g * dt These results will be exactly correct. I did run into the issue with collision detection at one point. In my case, I needed at least, say, 10fps for the collision detection to work, and I decided that if the computer couldn't handle that, I would accept some slowdown so that the game at least worked. All I had to do was: dt = max(clock.tick() * 0.001, 0.1) In another case, I needed higher framerate for collision detection (say 50fps), and I was render-limited, not physics-limited. In that case I did: dt = max(clock.tick() * 0.001, 0.1) for j in range(5): for sprite in sprites: sprite.think(dt/5.) So I only got slowdown when the framerate dropped below 10. Anyway, it's fine to have a library to do this, but there are some simple things that have always worked for me. -Christopher On Fri, Aug 27, 2010 at 11:43 AM, Brian Fisher wrote: > That approach is perfectly fine with linear movement - because the linear > calculations aren't affected significantly by how large dt is (or put > another way: x += vx*2 is nearly identical to x += vx*1, x += vx*1 on your > computer) > > However, with any nonlinear physics (like say, gravity's relationship to > position, or an accelerating object) or with discrete actions that happen > once per frame (like say the artificial intelligence for an enemy that > decides what to do once every frame), then your game behavior can change > quite significantly depending on what values of dt you get. > > --- > For example, lets say you do gravity like this: > vy = vy + gravity*dt > y = y + vy*dt > > with a dt of 2, from vy = 0, y = 0, the result is: > vy = vy + gravity*2 = gravity*2 > y = y + (gravity*2)*2 = gravity*4 > > however if you get a dt of 1 twice, from the same starting point, the > result is: > vy = vy + gravity*1 = gravity > y = y + (gravity)*1 = gravity > ... > vy = vy + gravity*1 = gravity + gravity = gravity*2 > y = y + (gravity*2)*1 = gravity + gravity*2 = gravity*3 > --- > > so you've only moved 3/4 of the distance (3 vs. 4 gravitys) down with a > frame rate that is twice as fast, even though you are parameterizing > everything on dt. Note the acceleration component (which is linear with > time) is consistent and accurate with both timestep sizes. > > So you asked "what else do you need?" well the answer is if you want > consistent non-linear physics (like say you want the players to jump the > same all the time), then the "else" you need is fixed size timesteps for > your physical simulation. > > > > On Fri, Aug 27, 2010 at 8:27 AM, Christopher Night > wrote: > >> Here's what I always do: >> >> dt = clock.tick() * 0.001 >> x += vx * dt >> y += vy * dt >> >> And all the sprites have a think(dt) method that updates them as if dt >> seconds have passed. What else do you need? >> >> -Christopher >> >> >> On Fri, Aug 27, 2010 at 11:19 AM, James Paige >> wrote: >> >>> On Fri, Aug 27, 2010 at 10:59:09AM -0400, Kris Schnee wrote: >>> > On 2010.8.27 10:36 AM, B W wrote: >>> >> Howdy, >>> >> >>> >> Reviving this old thread. The comments by Patrick and Brian really >>> >> intrigued me, so I pursued the topic. Found a few interesting articles >>> >> and one great article. My study has resulted in a recipe for those of >>> us >>> >> continually nagged by the question, "how can I get constant game speed >>> >> independent of frame rate?". The demo requires Pygame, but the clock >>> >> module only requires Python. >>> > >>> > Isn't it simply a matter of creating a Pygame Clock object and calling >>> > clock.tick() to delay until the appropriate time to maintain some max >>> > framerate? >>> >>> That only caps a max framerate. What Gumm is talking about is when your >>> framerate and your game simulation rate can be adjusted independantly >>> >>> --- >>> James Paige >>> >> >> >
Re: [pygame] frame independant movement
On 2010.8.27 11:43 AM, Brian Fisher wrote: That approach is perfectly fine with linear movement - because the linear calculations aren't affected significantly by how large dt is (or put another way: x += vx*2 is nearly identical to x += vx*1, x += vx*1 on your computer) However, with any nonlinear physics (like say, gravity's relationship to position, or an accelerating object) or with discrete actions that happen once per frame (like say the artificial intelligence for an enemy that decides what to do once every frame), then your game behavior can change quite significantly depending on what values of dt you get. So you asked "what else do you need?" well the answer is if you want consistent non-linear physics (like say you want the players to jump the same all the time), then the "else" you need is fixed size timesteps for your physical simulation. Makes sense. Another example would be collision detection. If you've got a platform .1 unit thick and your 1-unit-tall character falls 2 units in one frame due to low framerate, then they'll fall through the platform.
Re: [pygame] frame independant movement
On Fri, Aug 27, 2010 at 08:43:59AM -0700, Brian Fisher wrote: >So you asked "what else do you need?" well the answer is if you want >consistent non-linear physics (like say you want the players to jump the >same all the time), then the "else" you need is fixed size timesteps for >your physical simulation. I seem to remember that one of the Quake games (or was it all of them?) did this /wrong/. The distance your character could jump was affected by your frame rate, making certain hard jumps impossible at certain frame rates. --- James Paige
Re: [pygame] frame independant movement
That approach is perfectly fine with linear movement - because the linear calculations aren't affected significantly by how large dt is (or put another way: x += vx*2 is nearly identical to x += vx*1, x += vx*1 on your computer) However, with any nonlinear physics (like say, gravity's relationship to position, or an accelerating object) or with discrete actions that happen once per frame (like say the artificial intelligence for an enemy that decides what to do once every frame), then your game behavior can change quite significantly depending on what values of dt you get. --- For example, lets say you do gravity like this: vy = vy + gravity*dt y = y + vy*dt with a dt of 2, from vy = 0, y = 0, the result is: vy = vy + gravity*2 = gravity*2 y = y + (gravity*2)*2 = gravity*4 however if you get a dt of 1 twice, from the same starting point, the result is: vy = vy + gravity*1 = gravity y = y + (gravity)*1 = gravity ... vy = vy + gravity*1 = gravity + gravity = gravity*2 y = y + (gravity*2)*1 = gravity + gravity*2 = gravity*3 --- so you've only moved 3/4 of the distance (3 vs. 4 gravitys) down with a frame rate that is twice as fast, even though you are parameterizing everything on dt. Note the acceleration component (which is linear with time) is consistent and accurate with both timestep sizes. So you asked "what else do you need?" well the answer is if you want consistent non-linear physics (like say you want the players to jump the same all the time), then the "else" you need is fixed size timesteps for your physical simulation. On Fri, Aug 27, 2010 at 8:27 AM, Christopher Night wrote: > Here's what I always do: > > dt = clock.tick() * 0.001 > x += vx * dt > y += vy * dt > > And all the sprites have a think(dt) method that updates them as if dt > seconds have passed. What else do you need? > > -Christopher > > > On Fri, Aug 27, 2010 at 11:19 AM, James Paige wrote: > >> On Fri, Aug 27, 2010 at 10:59:09AM -0400, Kris Schnee wrote: >> > On 2010.8.27 10:36 AM, B W wrote: >> >> Howdy, >> >> >> >> Reviving this old thread. The comments by Patrick and Brian really >> >> intrigued me, so I pursued the topic. Found a few interesting articles >> >> and one great article. My study has resulted in a recipe for those of >> us >> >> continually nagged by the question, "how can I get constant game speed >> >> independent of frame rate?". The demo requires Pygame, but the clock >> >> module only requires Python. >> > >> > Isn't it simply a matter of creating a Pygame Clock object and calling >> > clock.tick() to delay until the appropriate time to maintain some max >> > framerate? >> >> That only caps a max framerate. What Gumm is talking about is when your >> framerate and your game simulation rate can be adjusted independantly >> >> --- >> James Paige >> > >
Re: [pygame] frame independant movement
On Fri, Aug 27, 2010 at 10:59:09AM -0400, Kris Schnee wrote: > On 2010.8.27 10:36 AM, B W wrote: >> Howdy, >> >> Reviving this old thread. The comments by Patrick and Brian really >> intrigued me, so I pursued the topic. Found a few interesting articles >> and one great article. My study has resulted in a recipe for those of us >> continually nagged by the question, "how can I get constant game speed >> independent of frame rate?". The demo requires Pygame, but the clock >> module only requires Python. > > Isn't it simply a matter of creating a Pygame Clock object and calling > clock.tick() to delay until the appropriate time to maintain some max > framerate? That only caps a max framerate. What Gumm is talking about is when your framerate and your game simulation rate can be adjusted independantly --- James Paige
Re: [pygame] frame independant movement
On 2010.8.27 10:36 AM, B W wrote: Howdy, Reviving this old thread. The comments by Patrick and Brian really intrigued me, so I pursued the topic. Found a few interesting articles and one great article. My study has resulted in a recipe for those of us continually nagged by the question, "how can I get constant game speed independent of frame rate?". The demo requires Pygame, but the clock module only requires Python. Isn't it simply a matter of creating a Pygame Clock object and calling clock.tick() to delay until the appropriate time to maintain some max framerate?
Re: [pygame] frame independant movement
Howdy, Reviving this old thread. The comments by Patrick and Brian really intrigued me, so I pursued the topic. Found a few interesting articles and one great article. My study has resulted in a recipe for those of us continually nagged by the question, "how can I get constant game speed independent of frame rate?". The demo requires Pygame, but the clock module only requires Python. GameClock (http://www.pygame.org/wiki/ConstantGameSpeed) derived from "deWiTTERS Game Loop" (http://www.koonsolo.com/news/dewitters-gameloop/). Cheers, Gumm