jcornaz / heron

[DISCONTINUED] An ergonomic physics API for bevy games
MIT License
292 stars 44 forks source link

Implement Variable Timestep Mode for PhysicsSteps #123

Closed zicklag closed 3 years ago

zicklag commented 3 years ago

I'm not sure if I'm missing some caveats or something, but I like the variable timestep strategy because the simulation speed is stable regardless of the framerate. That way, even if some machines can only run at 30 fps, it won't cause a physics slowdown when the physics step is set to 58 fps to optimize for players who can run the game at 60 fps. Or even for players who's FPS might drop temporarily.

jcornaz commented 3 years ago

Hi, thanks for this new contribution :-)

I thought about this problem indeed, but let me suggest an alternative solution.

Before all, I just want to state a potential problem of allowing low frame rate without slowing done the physics simulation. The slower the frame rate, the more each objects will move at each frame. And (depending on the object's velocity and thickness) at some point they may pass through each others. That's why most physics engine by default (and sometime not even configurable) run at a fixed rate and are out-of-sync of the rendering updates. This is also why rapier has a CCD feature (Continus Collision Detection). But CCD isn't all panacea. It notably has a high performance cost and require users to explicitly enable it.

Taking this in account and trying to combine it with your suggestion, I'd like to propose a max_delta_time steping mode. The user would define what is the maximum delta time that should be used for reliable physics simulation (depending on game objects velocities and thiknesses). The physics step would run every frame (like in your suggestion) and the delta time would be the real elapsed time, but clamped to be at max the user-defined maximum delta time.

Here is a usage example:

fn main() {
  App::build()
     .add_plugins(DefaultPlugins)
     .add_plugin(PhysicsPlugin::default())

     // Runs physics step every frame.
     // If the frame rate drops bellow 30 FPS, then the physics simulation will slow down.
     .insert_plugin(PhysicsSteps::from_max_delta_time(Duration::from_seconds_f64(1.0 / 30.0)))
     // ....
     .run();
}

This mode could even become the new default with a max delta time of let's say 20 ms (50FPS)

Note that, in the specific case of using Duration::MAX for the max delta time this mode would be equivalent of the change you suggested ;-)

What do you think @zicklag?

zicklag commented 3 years ago

That sounds great! If you want, then, I can make those changes when I get the chance.

zicklag commented 3 years ago

I updated the PR with your recommended strategy. :rocket: Let me know if there's any other things to change.