Question about matter.js and it's update loop

Hey there!

I had a quite extensive look into phaser 3 with matter.js the last couple of weeks and am at a crossroads right now. The main issue lies within the game update loop and how matter.js works and updates with it.

I work on a 144hz monitor and was not able to get the physics simulation running at the same perceived speed on a 60hz monitor (or edge browser, which runs at 72fps on 144hz monitors). All of the matter.js examples on the phaser website run more than twice as fast at 144fps as they do at 60fps. So I guess that this is a known issue and nobody found a solution yet or it is plainly not possible.

As far as I know, it is currently not possible to limit RAF of browser to a specific framerate. Also Matter.js does not have it’s own fixed update loop, but updates together with the core game update loop, which is tied to RAF. I have no idea what matter.set60Hz; or matter.set30Hz really does other than internally changing the deltaTime of matter. It’s still updating 144 times a second, thinking it updates at a lower rate (meaning at set30Hz(), the physics update even faster!)

Even disabling autoUpdate and stepping the matter physics manually in the update loop and providing the game loops delta time does not lead to a consistent feel. It makes it behave even worse.

So my question is: Does anyone know if it’s even remotely possible to get a grip at this issue? Are there any examples out there providing a hint? If it’s not possible to get the physics simulation run consistent at a fps range of 60 to 144fps, then I have to look at a different engine.

Sorry for the long post, but I’m really lost at the moment. It seems like (almost) nobody is talking about this but it’s deal breaker for me.

Cheers!

Phaser v3.22 is going to have a variable-size delta for Matter by default.

Before Phaser v3.22, I believe you can pass getDelta in Matter’s config

{ getDelta: function (time, delta) { return delta; } }

or set the same property on the world

this.matter.world.getDelta = function (time, delta) { return delta; };
1 Like

Thanks for your quick response, I really appreciate it.

Your tip is on point and I have already tried this solution to fix the delta issues with matter (along lots of other ways) but it does not work as it should… at least not like I expected it to…

I just spend over an hour to really get behind the issue because in some cases it seemed to work and others it doesn’t and I was able to narrow it down a bit. I saw how the gravitational pull worked just as I wanted to, framerate independent, but my applied forces or manually set velocities did not. But I think I got my head around it now… I will try to fix up my prototype tomorrow and hopefully it will work framerate independent by then.

I thought that when you apply a force, it’s applied to the object as an framerate independent unit. But it seems like that the current delta is automatically taken into account. When manually setting velocities, it’s not the case and you have to integrate the delta into the velocity calculation yourself. At least it looks that way. In my debug workspace, I was able to get all the forces and velocities framerate independent with this (new found) knowledge

Thanks a lot for leading me in the right direction. Seems like I was just misunderstandig some crucial facts regarding forces and velocities.

I think I was a little to hasty with my optimism yesterday. While forces kinda work correctly and take delta times into account, objects without forces are moving completely without interferences of delta times.

Exmaple: An object without friction moving at a constant velocity (e.g in space or wahtever). The new position every update step is updated without a delta, therefore the object is moving faster on higher framerates.

I found this little thread talking about this exact issue (without any solutions, I’m afraid): https://github.com/photonstorm/phaser/issues/3957 (answer of bulboka from 19th december of 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
assing to it.

This is a real bummer. I don’t know if it’s really a matter.js issue or some problem with the implementation in phaser3 but I can’t really use it this way (and I’m kinda surprised that anyone can actually use it like that… >60hz monitors are not that of a niche, I would say)

I am facing the exact same problem right now ; physic is very different on a 144 Hz screen and a 60 Hz one.
I think it is a MatterJS issue https://github.com/liabru/matter-js/issues/851
The only solution I see is to use another physics engine like PlanckJS, which doesn’t have this problem.