Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Physics framerate independence #3957

Closed
okaybenji opened this issue Aug 20, 2018 · 17 comments
Closed

Physics framerate independence #3957

okaybenji opened this issue Aug 20, 2018 · 17 comments

Comments

@okaybenji
Copy link

okaybenji commented Aug 20, 2018

When the game's frame rate drops, the physics slow down as well (at least with Matter.js, but I would imagine with other physics engines as well).

Ideally, an entity's inertia would not be affected by the performance of the machine running the game. (For instance, a ship moving 100px/sec at 60 FPS should not move 50px/sec at 30 FPS. They should travel at the same speed, and at 30 FPS they should go twice as far each frame as at 60.)

Please either add a configuration option to enable frame rate independence (by internally passing delta time to the physics engine), or simply do so always if that makes more sense.

Thanks very much!

Demo of current frame-rate dependence: https://streamable.com/z6sbf
I run the simulation 3 times at normal speed, and then 3 times with 6x CPU throttling.

You can run this yourself here: https://codepen.io/anon/pen/KxKqOL

It is based on this Phaser 3 example, but I have simply added more bodies: https://labs.phaser.io/edit.html?src=src/physics/matterjs/body%20velocity.js

@hexus
Copy link
Contributor

hexus commented Aug 20, 2018

Frame rate independence for MatterJS was the default before Phaser 3.4.0, but it caused a lot of instability when used with Phaser's delta.

However, you can still provide your own function to step Matter's physics simulation. It's mentioned here in the change log:

https://github.com/photonstorm/phaser/blob/0eef6f1bb9a9cf3c12b162dd28f8afd080ea172f/CHANGELOG.md#version-340---miyako---12th-april-2018

If you find a good way to retain frame rate independence and stability with Matter in Phaser 3, please let me know! I'd be very interested to see it working. :)

@okcompewter
Copy link

I've noticed this using Arcade physics as well: on slower performing machines, character movement is also slowed. Not great for a real-time multiplayer game. Is it possible to address this while using Arcade physics?

@hexus
Copy link
Contributor

hexus commented Aug 20, 2018

I'm not certain when it comes to Arcade. That's always been stepped a fixed amount as far as I'm aware.

By the way, when I run your code pen, the bodies tumble at and angle and start flying everywhere, and eventually the browser tab crashes! 😄

@photonstorm
Copy link
Collaborator

photonstorm commented Aug 20, 2018

Arcade Physics was changed in 3.10 to purposely use a fixed time-step, ensuring the results are deterministic (which is far more important for a multiplayer game):

  • Arcade Physics now uses a fixed time-step for all internal calculations. There is a new fps config value and property (defaults to 60fps), which you can change at run-time using the setFPS method. The core update loop has been recoded so that it steps based entirely on the given frame rate, and not the wall-clock or game step delta. This fixed time step allows for a straightforward implementation of a deterministic game state. Meaning you can now set the fps rate to a high value such as 240, regardless of the browser update speed (it will simply perform more physics steps per game step). This is handy if you want to increase the accuracy of the simulation in certain cases.
  • You can also optionally call the step function directly, to manually advance the simulation.

Both Matter and AP allow you to change how the simulation steps to match your requirements to whatever is needed. Matter before using a fixed time-step was a mess (try it and see for yourself), so there's no way it's going to change back again. Define your own step for full control.

@okaybenji
Copy link
Author

okaybenji commented Aug 21, 2018

Deterministic results on the client are not more important for multiplayer games than a physics system's frame rate independence. In most real-time games the determinism should be on the server, not the client.

@photonstorm Can you explain what you mean by "Define your own step for full control"? Do you mean write our own physics simulation?
@hexus Would you mind telling me more about the instability you're talking about?

@hexus
Copy link
Contributor

hexus commented Aug 21, 2018

@okaybenji Any considerable hitches in performance between frames would cause a delta too large for Matter to handle in a stable way, causing bodies to start flying across the world with huge velocities from the lightest impulses.

Your code pen demonstrates this on my machine. I'll try to record a GIF.

@okaybenji
Copy link
Author

Ah, okay I see that. Thanks very much for the help!

@hexus
Copy link
Contributor

hexus commented Aug 21, 2018

manycam3

@okaybenji
Copy link
Author

okaybenji commented Aug 21, 2018

I wanted to point out one weird thing with this. I accidentally left the block from the original demo in place. (This line: var block = this.matter.add.image(400, 100, 'block');) If you take it out, the update method never gets called:

https://codepen.io/anon/pen/LJExXG

Should I open an issue for this?

@hexus
Copy link
Contributor

hexus commented Aug 21, 2018

If you check the console, you'll see that block is not defined.

Commenting out these lines gets your example running again, with the same issues:

block.setFriction(0.05);
block.setFrictionAir(0.0005);
block.setBounce(0.9);

@okaybenji
Copy link
Author

Ah, of course! 😅 Sorry about that. Thanks again for your help.

@bulboka
Copy link

bulboka commented Dec 19, 2018

Matter.js Body.update seems very strange to me.

The velocity is not multiplied by deltaTime, when changing the position.
The force is multiplied by deltaTime squared (why squared?), though it is reset to zero every frame after update. So strictly speaking it's not a force but something like an impulse and there's no reason to multiply it by time.

Maybe all of it was done in the name of performance optimization or for some other reasons, but the point is that Matter.js is not framerate independent in any way, no matter what timeDelta you're passing to it.

@photonstorm
Copy link
Collaborator

@bulboka you need to mention this on the Matter.js repo, it's outside of our control.

@nfernand
Copy link

nfernand commented Dec 28, 2018

I am currently stuggling with similar issues.
I have users who use a 144Hz monitor causing requestAnimationFrame() to be called more than once every 16ms or so.
With matter using fixed timestep, the simulation runs way too fast for those users and also runs too slow when throttling cpu for simulating slower computers.

I have also tried using custom timestep based on elapsed time since last frame broke down into smaller steps to avoid beforementioned issues if elapsed time is too big.
But as already discussed here, using matter without fixed timestep indeed is messy and I could not get results to be smooth and predictable using this technique.

Anyone has any advice for me if I want to use a physics engine combined with phaser 3 that manages polygonal bodies and also support 144Hz monitors ? I feel a bit stuck here.

@okaybenji
Copy link
Author

We fell back to using P2 with Phaser 3 instead of Matter... there are still some issues with 144Hz monitors even with P2, but it's better.

@epurban
Copy link

epurban commented May 7, 2024

Can't believe this is still an issue.

@photonstorm
Copy link
Collaborator

Can't believe this is still an issue.

Feel free to take it up on the matter repo. It's still not resolved there.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants