OpenFL + Nape. Physics acts different depending on FPS

Hello OpenFlashers! Sorry for another noob question. I’m using OpenFL with a conjuction of Nape and trying to force physics act equally on different fps. I’ve tried:

  1. pass deltaTime value to a step method -> napeWorld.step(deltaTime * 0.001); and use fixed values for impulses;
  2. napeWorld.step(1 / stage.frameRate); and use values for impules multiplied by deltaTime;
    But both methods doesn’t give desired result.
    My flash target works on 60fps and html5 30fps. And the more slower fps the more slower works physics.
    I would really appreciate if someone can give me a clue with that issue!

You want to be passing the exact same value each time you call step(). However, deltaTime * 0.001 varies unpredictably, and 1 / stage.frameRate varies depending on the framerate.

Start by declaring a constant step value. You’ll use this value - with no adjustments - every single time you call step().

public static inline var NAPE_STEP:Float = 0.01;

The trick is to call step() more than once per frame if a frame took too long. If a frame only takes 0.01 seconds, then you only need to call step() once. But if the frame takes 0.03 seconds (that’s around 30 fps), you’d call step() three times to keep the same overall rate.

That isn’t quite all. What if your frames take 0.015 seconds each? If you round down to 0.01, then you skip half a physics step every frame.

Instead of rounding, keep track of that “lost” time, and when it adds up to 0.01, run an extra step.

private var physicsTime:Float = 0;

public function onEnterFrame(e:Event):Void {
    deltaTime = /* calculate deltaTime here */;
    
    physicsTime += deltaTime;
    while(physicsTime >= NAPE_STEP) {
        napeWorld.step(NAPE_STEP);
        physicsTime -= NAPE_STEP;
    }
}

Thank you very much! I will try this method and tell you how it goes!

The only thing I’m worrying here is that, as I understand, each napeWorld.step() makes a lot of calculations and if I’ll repeat it a few times in the same frame it may cost some cpu usage and fps may drop down…

Fortunately, it’s easy to tweak. Change NAPE_STEP to 0.02, and you’ll run half as many steps. (The code I gave you will handle the details.)

EDIT: I’ve tested this method end it really shows a good result. If I need to apply an impulse during some period of time, I need to multiply it by deltaTime and if the result not perfect then at least it’s pretty close. So I’m happy enough with that approach. Thank you Player_03!
Also if there is some any ideas of how to handle it, please continue this thread…