Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

get_gravity yields different results from _process and _physics_process #87996

Open
mihe opened this issue Feb 5, 2024 · 2 comments
Open

get_gravity yields different results from _process and _physics_process #87996

mihe opened this issue Feb 5, 2024 · 2 comments

Comments

@mihe
Copy link
Contributor

mihe commented Feb 5, 2024

Tested versions

Reproducible in: Godot 4.3.dev [d335281]

System information

Windows 10 (10.0.22631)

Issue description

Related to #84640.

Due to the current implementation of PhysicsBody*D.get_gravity relying on body_get_direct_state you will end up with desync between the gravity reported by _physics_process and the gravity reported by _process, within the same physics frame.

This means that when a body enters/exits an area with some type of gravity override, _process will pick up on the change before _physics_process does, while they still report the same position in the world, which can potentially lead to subtle and hard-to-track-down bugs.

The reason for this is because of how a frame is laid out in Godot, which in very simplified terms goes something like this:

  • Maybe do the physics tick
    • Pull state from the physics server
    • Run _physics_process
    • Step the physics simulation/server
    • Maybe repeat
  • Do the idle tick
    • Run _process
  • Render, audio, input, etc.

The important thing to note here is that the physics simulation/server is stepped inbetween _physics_process and _process, which means that the physics simulation/server is always one tick ahead of _physics_process while _process is running.

This means that if you use something like body_get_direct_state, which as the name would suggest gives you direct access to the physics server, you will bypass the state synchronization that typically happens before _physics_process and access the most current (future) value in the physics simulation/server instead, leading to a desync with _physics_process.

Steps to reproduce

  • Run the MRP
  • Note the output logs when the CharacterBody3D enters the Area3D
  • Note the output logs when the CharacterBody3D exits the Area3D

Minimal reproduction project (MRP)

GravityDesync.zip

@Mickeon
Copy link
Contributor

Mickeon commented Feb 6, 2024

Can/should this even be fixed or should this quirk be noted down?

@mihe
Copy link
Contributor Author

mihe commented Feb 6, 2024

There are ongoing discussions in #84640 for how to potentially address this. I certainly think it should be fixed, but whether it can be fixed (in a good way) is a different story, unfortunately.

This new get_gravity method sort of "breaks new ground" in terms of accessing physics state in Godot, in that it's a state that affects all physics bodies (including static and kinematic ones) while also being a state that can change at every simulation step without any action from the body itself.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants