Issues with screen's FrameRates on different devices (Low-end and high-end)

I am developing a simple game, in which the player are just simple spherical balls which are moving in a particular direction with same velocity avoiding the obstacle. the user can control the movement of balls in left and right direction only, just like temple run to avoid obstacle. I’ve integrated cannon.js over three.js for physics. Issues i am getting are: -

  1. I have some obstacle that has animations, i’ve created physics world obstacle following the same animation and synced both. When the player Balls touches it, the screen stucks due to recieveing multiple callbacks of arround 400 and above and all balls gets destroyed. I want to destroy single-single balls.
  2. The Main issue is that, when running on different devices, On PC’s having framerates of 75fps, its working fine. But on mobile Phones having 60Fps or less. Its running very slow due to which the Gsap’s Duration is also not working good. The velocity of jumping am giving is not reached in low performance devices such as mobile phones.

Did anyone know how can i sync physics to work same on different devices also?

first i would not use cannon but something faster, cannon is probably the slowest physics engine out there and it has big problems with convex hull shapes. sync is usually handled automatically, rapier for instance has a fixed timestep. if your game then runs ok on mobile it’s probably enough.

the only way to make something work on everything is a performance monitor which would allow the application to adjust quality until a stable framerate is established. drei has one GitHub - pmndrs/drei: 🥉 useful helpers for react-three-fiber but i am not aware of something else that is open source.

1 Like

I am Developing it in THREE.JS and Not in R3F. I cannot monitor anything, still i’ve used GitHub - spite/rstats: rStats for monitoring. But Am getting unexpected results, I want to make it work the same on both mobile, mac, and windows.

Syncing on multiple devices is creating problem, help in that plzz.

performance monitoring has nothing to do with either threejs or react. you record your frames, normalize them and then make decisions based on the established framerate, this happens runtime — the app will degrade if it can’t establish at least 60fps.

it’s something that game engines do. the code that i posted would be applicable to your problem and imo that’s the only feasible way to make sure a demanding app runs everywhere, fast devices, mid devices to the slowest possible devices.

what you linked, rstats, that is something else. there is no point in measuring framerate on your computer, because someones device out there is 100 times as fast as yours, or 100 times as slow.

Can’t we simulate the Physics’s World’s Steps according to the frameRates and handle them accordingly ?
Moreover, i’ve been using gsap to change velocity so that it smoothly increase the velocity and on collision with the wall does’ not bounces back and sticks to wall, is that a good approach to do so ? As gsap is time based but velocity is different on different devices. Is there any alternative of updating the velocity.

physics should handle this by default. it’s just that cannon is very slow to begin with. rapier is probably a hundred times faster given that you’re colliding convex shapes. and i think there are engines now that are faster than rapier.

  1. You should set a boolean to determine if the ball has touched the wall (ex: isDestroyed = true). If the boolean is true, then stop performing the callback function until you reset the ball position.

  2. Modern games typically have 2 separate loop functions: Physics & Render. You should set a target “tick rate” for your physics engine for predictable results on different screens. Without defining limits, your world will perform expensive calculations every time the screen is refreshed.

Here is a basic example of performing your physics calculations on a lower interval (do not add this inside your render loop):

var fps = 60;
setInterval(function() {
    world.step(1 / fps);
}, 1000 / fps);