godot-rapier-2d icon indicating copy to clipboard operation
godot-rapier-2d copied to clipboard

manually stepping the engine results in non-deterministic area overlap

Open bcolloran opened this issue 1 year ago • 1 comments

Describe the bug

I'm trying to get rollback + client prediction working using godot-rapier-physics, which requires manually stepping the engine.

The manual stepping itself works fine, but the results of the simulation are different, at least when checking for area overlaps with Area3D.has_overlapping_bodies() -- the simulation ticks on which bodies overlap depends on how the simulation is stepped, not on the simulation tick on which the overlap check is made.

(I wonder if this has to do with syncing of transforms that are defined on the Godot side with transforms needed for collision checks on the rapier side?)

To Reproduce run the main scene in this repo: https://github.com/bcolloran/godot_rapier_physics_rollback_test

with the "advance kind" enum set to each different value:

image

Expected behavior

The logging that prints out which ticks the areas have overlap should print an identical set of ticks no matter how the simulation is stepped.

Environment:

  • OS: linux mint
  • Version: latest
  • Godot Version: 4.3
  • Type:
[plugin]

name="Godot Rapier 3D"
description="A 2D and 3D drop-in replacement for the Godot engine that adds stability and fluids."
author="appsinacup"
version="0.8.8"
flavour="godot-rapier-3d-single-enhanced-determinism"
script=""

Example project here's a complete minimal repo: https://github.com/bcolloran/godot_rapier_physics_rollback_test

bcolloran avatar Nov 14 '24 20:11 bcolloran

This is a little subtle, so I thought it might hopefully help to include a screen recording explaining my experimental setup

https://github.com/user-attachments/assets/b5c63c7a-5b26-4391-86b6-521367af2e80

Feel free to ping me here or on discord. Also, if you have ideas about how this might be addressed, I don't mind trying to put together a PR if you can give me some pointers and orientation (though I know that explaining a project you've been building can take longer than just fixing things yourself :-) )

Thanks, amazing project!

bcolloran avatar Nov 14 '24 22:11 bcolloran

Hi, sorry took so long to take a look at this. This is a complicated issue, if you want also come on discord to discuss it. About this issue, determinism works, however overlap to be sent over by Godot I think takes 1 frame. Same can be seen here eg. where I:

  • run 1s, save, run 1 s (print final hash)
  • load, run 1s (print final hash) They match. However, the contact points that godot display are incorrect when loading. So the issue is sometimes Godot will display older values from the Physics Server, but the Physics Server itself (and its state) will be correct. If you really want to get correct states, you can access stuff from PhysicsServer API, not through the node.

https://github.com/user-attachments/assets/10b382fe-64fc-496f-af8d-f59759521f0a

Ughuuu avatar Nov 02 '25 17:11 Ughuuu

Again, not 100% sure if it's the exact same case, jsut wanted to ilustrate that this can happen, and right now it's outside of the PhysicsServer, but inside Godot (godot would need a patch for this, eg. like a reset function or something like that or update).

About this issue, I would want to know exactly what you want to test, and if possible I want first to focus on some kind of test suite for this library with determinism. So if you want to redo your repro or make a PR with an even simpler repro that reuses the rapier_state and uses just basic stuff from it, and a simple scene that prints the hash, so its easy to compare. The output being an area colliding or not is not from physics side, so that will always have issues (at least with current godot version)

Ughuuu avatar Nov 02 '25 17:11 Ughuuu

Also, one more thing to consider, are you doing logic based on the area colliding or not? Because if so, that might actually not be deterministic, which not sure if that is because of godot or not(rapier reports the collision, but godot handles it next frame, not current one)

Ughuuu avatar Nov 02 '25 17:11 Ughuuu

Will wait for you to respond for a few days, and if nothing will close the issue, and then you can reopen it with a new repro and new understanding of this. Ideally I am interested in a talk about this, to see what would be the best way to do it, on discord maybe best.

Ughuuu avatar Nov 02 '25 17:11 Ughuuu

Hi, feel free to close this if you wish. I needed to move forward, so I ended up building my own wrapper around just the pieces of rapier functionality that I needed. Thanks!

bcolloran avatar Nov 02 '25 18:11 bcolloran