I have seen a couple of threads with this issue, but none going into detail and none having a substantial solution.
My team and I are currently making a game that relies heavily on 3d physics for platforming. We noticed that on devices with different FPS the physics behaved very differently. The simplest example is our jump. On a 144hz device we’d see a super jump, while on 30fps we’d have half a jump.
This issue was initially caused by not setting fixedTimeStep to match the fps. We defaulted the game to a framerate of 60 and timestep of 1/60, but would change to a framerate of 30 if the device was struggling to reach 60.
The cocos team pointed the way that we must match framerate and fixedTimestep. For the most part this worked. However, we then discovered that setting the framerate to 60 (or even 30) would not actually cap the devices.
The engine code ran a conditional where values of 30 and 60 would just use the requestAnimationFrame of the browser while other values would use an internal function that combined with the rAF.
What this meant was that even though I would call game.setFrameRate(60) and PhysicsSystem.instance.fixedTimeStep = 1/60, our device with the 144hz monitor would still experience 144 fps and have a super jump. Likewise, devices that struggled to reach 60fps would have a shorter jump.
While we may need to specifically handle devices that are slower than our cap, our work is made much more complicated by the fact that we cannot rely on setFrameRate(60) to actually cap the device to 60 fps.
We tried the solution posted in another thread of use 59.9, but that resulted in wildly unpredictable behavior and broke the ability to use setFrameRate() again if we needed to downgrade the engine to support a slower model.
So, two issues that I would like to see addressed.
-
Should the physics engine not be able to handle a variation in the framerate by using the maxSubStep feature?
-
When I set a cap in setFrameRate() I expect it to be respected across all devices to guarantee a standard for all players. Even if I set it to 30 or 60 fps.
For additional context here is our default physics settings
"physicsEngine": "physics-ammo",
"allowSleep": true,
"sleepThreshold": 0.1,
"autoSimulation": true,
"fixedTimeStep": 0.0166667,
"maxSubSteps": 10,