flame icon indicating copy to clipboard operation
flame copied to clipboard

Different behaviour function applyLinearVelocity in windows (120 fps) and android (60 fps)

Open drakkonne007 opened this issue 1 year ago • 4 comments

What happened?

When I was testing my game on multiple platforms, I noticed that once the applyLinearImpulse(Vector2(3000, 0)) gives different results on the windows platform (120fps) and on my Android (60fps). In Windows, the distance the object traveled was noticeably greater than on the phone. The code is written in such a way as to guarantee acceleration once and compare different platforms

What do you expect?

I expect the distance to be the same for all platforms

How can we reproduce this?

class OrthoPlayer extends SpriteAnimationComponent with KeyboardHandler
{
Body? groundBody;
bool isNeedImpulse = true;

@override
  Future<void> onLoad() async
  {
    position = Vector2(100,100);
    FixtureDef fix = FixtureDef(PolygonShape()..set([Vector2(-10,-10),Vector2(-10,10),Vector2(10,10),Vector2(10,-10)]), friction: 
    0.1, density: 0.1);
   groundBody = BodyDef(type: BodyType.dynamic, position: position, fixedRotation: true),
      gameRef.world.physicsWorld);

  @override
  bool onKeyEvent(KeyEvent event, Set<LogicalKeyboardKey> keysPressed)
 {
       if(keysPressed.contains(LogicalKeyboardKey.keyE) && isNeedImpulse ){
           isNeedImpulse = false;
          groundBody?.applyLinearImpulse(Vector2(3000, 0));
       }
 }

  @override
  void update(double dt) 
     {
           super.update(dt);
           position = groundRigidBody?.position ?? position;
           //after the body stops, the distance is different
     }
}

What steps should take to fix this?

No response

Do have an example of where the bug occurs?

No response

Relevant log output

No response

Execute in a terminal and put output into the code block below

Output of: flutter doctor -v

PS C:\kyrgyz_epos_game> flutter doctor -v [√] Flutter (Channel beta, 3.22.0-0.3.pre, on Microsoft Windows [Version 10.0.22631.3593], locale ru-RU) • Flutter version 3.22.0-0.3.pre on channel beta at c:\flutter • Upstream repository https://github.com/flutter/flutter.git • Framework revision 87b652410d (3 weeks ago), 2024-04-23 21:41:18 -0500 • Engine revision b4bfd45986 • Dart version 3.4.0 (build 3.4.0-282.3.beta) • DevTools version 2.34.3

[√] Windows Version (Installed version of Windows is version 10 or higher)

[√] Android toolchain - develop for Android devices (Android SDK version 34.0.0) • Android SDK at C:\Users\gagin\AppData\Local\Android\sdk • Platform android-34, build-tools 34.0.0 • Java binary at: C:\Program Files\Android\Android Studio\jbr\bin\java • Java version OpenJDK Runtime Environment (build 17.0.9+0--11185874) • All Android licenses accepted.

[√] Chrome - develop for the web • Chrome at C:\Users\gagin\AppData\Local\Google\Chrome\Application\chrome.exe

[√] Visual Studio - develop Windows apps (Visual Studio Community 2022 17.7.5) • Visual Studio at C:\Program Files\Microsoft Visual Studio\2022\Community • Visual Studio Community 2022 version 17.7.34202.233 • Windows 10 SDK version 10.0.22621.0

[√] Android Studio (version 2023.2) • Android Studio at C:\Program Files\Android\Android Studio • Flutter plugin can be installed from: https://plugins.jetbrains.com/plugin/9212-flutter • Dart plugin can be installed from: https://plugins.jetbrains.com/plugin/6351-dart • Java version OpenJDK Runtime Environment (build 17.0.9+0--11185874)

[√] VS Code (version 1.82.3) • VS Code at C:\Users\gagin\AppData\Local\Programs\Microsoft VS Code • Flutter extension can be installed from: https://marketplace.visualstudio.com/items?itemName=Dart-Code.flutter

[√] Connected device (3 available) • Windows (desktop) • windows • windows-x64 • Microsoft Windows [Version 10.0.22631.3593] • Chrome (web) • chrome • web-javascript • Google Chrome 124.0.6367.208 • Edge (web) • edge • web-javascript • Microsoft Edge 124.0.2478.97

[√] Network resources • All expected network resources are available.

Affected platforms

Android, Windows

Other information

Version of my libraries:

flame-1.17.0 flame_forge2d-0.18.0 forge2d-0.13.0

Are you interested in working on a PR for this?

  • [X] I want to work on this

drakkonne007 avatar May 17 '24 08:05 drakkonne007

image image

First - on windows Second - on Android.

In this example I once for all time call function applyLinearImpulse(Vector2(0, -5000));

But еhe player does not move up the same level

drakkonne007 avatar May 17 '24 09:05 drakkonne007

I'm guessing that you're hitting the max force per tick. What is your zoom level, have you kept the default 10?

spydon avatar May 27 '24 17:05 spydon

Yes, but on the contrary I multiply the rigid body position by 10, because I learned about Forge2d much later than I made the game. I tried it with completely different values, and the speed is always completely different on the computer and on the phone. I have a sprint in the game, when I run without it, the speed on the computer and on the phone is also completely different. Although when I press sprint, the player on both devices starts running faster, i.e. this is not the maximum speed

drakkonne007 avatar May 28 '24 04:05 drakkonne007

https://github.com/flame-engine/flame/assets/90832165/54f1a32a-0b60-45ce-9f86-3939fc80d5e4

drakkonne007 avatar May 28 '24 04:05 drakkonne007

If you try a simpler example like https://examples.flame-engine.org/#/flame_forge2d_Tappable_Body, do you get the same behavior?

spydon avatar May 28 '24 09:05 spydon

Absolutly yes. I just copied this example (https://github.com/flame-engine/flame/blob/main/packages/flame_forge2d/example/lib/main.dart) into clean new project and replace body.applyLinearImpulse(Vector2.random() * 5000); on body.applyLinearImpulse(Vector2(3000,0)); And on the phone the speed of the ball is half as much. Maybe the DPI of the device matters?

drakkonne007 avatar May 28 '24 09:05 drakkonne007

DevKage had a look at it too and he found this from Box2D: image

So I'm guessing the dt for forge2d should be set to a constant (or close to constant) and then that the rendering should interpolate between the results for this to be able to work more deterministically between different framerates.

spydon avatar May 28 '24 11:05 spydon

So, I must override update() in my root game element about like this:

double currentDeltaTime = 0;
const double tickLimit = 1.0 / 30;

@override
void update(double dt)
{
    if(dt > tickLimit){ //to skip lags frame
       return;
    }
    currentDeltaTime  += dt;
    if(currentDeltaTime >= tickLimit){
       super.update(currentDeltaTime);
       currentDeltaTime = 0;
    }
}

drakkonne007 avatar May 28 '24 16:05 drakkonne007

That would probably work, but if I were you I would only set the physics engine to a fixed dt meanwhile the rest runs with a variable dt, so then you'd need to override update in the Forge2DWorld instead: https://github.com/flame-engine/flame/blob/main/packages/flame_forge2d/lib/forge2d_world.dart#L22-L24

spydon avatar May 28 '24 18:05 spydon

Yes, I tested several accelerations using a simple example and indeed - the speed is now the same on the phone and on the computer. Thank you!

drakkonne007 avatar May 29 '24 05:05 drakkonne007

So, most staibility with this code:

static const double tickLimit = 1.0 / 45;
double currentDt = 0;

void update(double dt)
  {
    currentDt += dt;
    int cycles = currentDt ~/ tickLimit;
    for(int i = 0; i < cycles; i++){
      physicsWorld.stepDt(tickLimit);
    }
    currentDt -= cycles * tickLimit;
  }

drakkonne007 avatar May 29 '24 07:05 drakkonne007