Slower physics movement with slower FPS

Godot Version

4.5

Question

TL;DR Rigidbody2D moves slower with lower FPS? Is this intended behavior, and how could I fix/workaround it?

I have a simple 2D physics-based multiplayer mobile game. The characters on the server are RigidBody2Ds while clients use CharacterBody2D. Currently I’m trying to work on improving performance on clients, there isn’t much help from Godot with client-side prediction with Rigidbodies, so I implemented a simple form of “prediction” by syncing rigidbody velocities as well as position/rotation.

Currently, the client game does become smoother from this, so I started testing this same functionality but with low performance from the server by setting the FPS to something extremely low (in the server only):

Engine.max_fps = 3

I looked at the client side and the velocities were definitely being synced, however they were much faster than they looked they should’ve been. The players were repeatedly widely cutting during each physics tick because of the high velocities compared to the actual position the body ended up in… (I can make a video if needed) then I noticed there was slight cutting even with normal FPS.

I later realized that it wasn’t the velocities that were too high, it was that the Rigidbody2ds on the server were actually just moving too slow. I noticed on the server that the players are moving less than half the speed they should be going. The velocities synced to the client are the correct velocities, as they move the speed that the player would normally go (on 60 FPS). I got the player velocities from RigidBody2D.linear_velocity and it’s interesting how it gets the correct intended velocity, even though it actually doesn’t move that fast in the server game on a lower FPS… I’m wondering if this is intended behavior and if there’s a way to improve my situation.

If you’re wondering, I use a constant apply_force in _physics_process() to move the Rigidbody2D player on the server. There is currently a lot of extra code so it would take a while to create a minimal example, I can give extra info when asked.

Could it be the way I set FPS? Is it not a good way to test slower devices?

I didn’t mean to write this much as I’m mainly sure that this is just a physics problem. I added as much info as I could just to make sure that it wasn’t actually a problem with the networking. I’m also wondering if there is a better way to implement client-side prediction with Rigidbodies as the conversations on this are quite old and unresultful, but this physics problem is my main priority so far.

Maybe its an issue with how often the sync up happens from client to server that is causing the cutting. A video would help with the problem described.

I think this talk from godot fest from the dome keeper dev teams has some really good multiplayer + godot information:

Thanks, that video was pretty helpful and informative for networking actually! It didn’t really answer my question though… the ‘sync’ between the client and server happens every update tick on the server, meaning the server is sending the game state to the client ~3 times per second. I’m trying to make it this slow to see how well I could implement client-side prediction only to realize how slow the physics was on the other side.

I’m becoming certain this is a physics problem because it’s really just the physics moving slower on the device with lower FPS and doesn’t really have to do with networking, but I still want to make sure.

I would guess this is related to max_physics_steps_per_frame.

Thanks for the response, I think this is exactly right:

However, the game will appear to slow down if the rendering FPS is less than 1 / max_physics_steps_per_frame of physics/common/physics_ticks_per_second. This occurs even if delta is consistently used in physics calculations. To avoid this, increase physics/common/max_physics_steps_per_frame if you have increased physics/common/physics_ticks_per_second significantly above its default value.

I just noticed that the physics speed is actually normal when the FPS is at least 8 but starts to drop when it goes lower (I don’t know how I didn’t notice this earlier). I realized physics_ticks_per_second is still 60 and according to the quote: physics_ticks_per_second (60) / max_physics_steps_per_frame (8) = 7.5 which fits this pattern exactly. So I guess its the way I just set FPS… there might more things I’m missing when trying to simulate really slow devices..?

I think this problem is OK for me for now, it works well even at 8 FPS, the game has very simple 2D physics so I probably don’t need to worry about slow physics as much as slow networking, I could probably increase max_physics_steps_per_frame when the framerate drops but I don’t know enough about Godot physics to do this properly. I’ll mark this as the answer for now!