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

Physics delta never changes #23974

Closed
ForLoveOfCats opened this issue Nov 26, 2018 · 5 comments
Closed

Physics delta never changes #23974

ForLoveOfCats opened this issue Nov 26, 2018 · 5 comments

Comments

@ForLoveOfCats
Copy link
Contributor

Godot version:
815557c

OS/device including version:
Manjaro Linux w/KDE Plasma
Arch: x86_64

Issue description:
Physics delta does not change no matter what speed the physics engine is running at. It is stuck at what the delta should be at target physics tick rate. As a result when the physics engine starts chugging such functions as kinematic body's move_and_slide movement speed slow down drastically.

Steps to reproduce:
Stress physics engine and see that move_and_slide slows down

Minimal reproduction project:
I worked rather hard on this and it shows the issue concisely: PhysicsProcess.zip

I believe that the issue is that that physics_process_time in SceneTree is set once when instanced and then every call to get_physics_process_delta_time in Node reads that unchanging value. Line in question:

physics_process_time = p_time;

I would very much like to try to fix this with some assistance however I do not know where to start to being recalculating the correct physics delta on the fly.

@toger5
Copy link
Contributor

toger5 commented Nov 26, 2018

check Main::iteration() in mian.cpp

@ghost
Copy link

ghost commented Nov 27, 2018

It's possible I'm misunderstanding the issue, but I believe what you're running into as a problem in your project is that you're stacking 100s of colliders on top of each other. This would be exponentially overloading the collision-pair comparison.

I modified your project, only changing the static body collision size, and re-positioning them randomly. When you click away, no more lag:
PhysicsProcess.zip

Regarding the physics delta never changing. It shouldn't. The concept goes by another name, "fixed time steps". The fixed part means exactly that. It makes an attempt to measure the time, and provide identical time slices across 1 second of game time.

At 60 FPS it will try to slice a second into 1/60ths (0.0166...). That will be your delta. The delta only changes, when you change your frame rate. As far as I can tell, that is working, when you edit it in the project settings.

The rendering processing though can vary, and does. It will run as fast as it can, and report that delta. These are usually separated so hiccups in the rendering don't force the physics to slow down, and the graphical updates can be choppy, inconsistent, or dropped for a moment.

If your game is consistently not doing everything it needs to do in 1/60th of a second at 60fps in the physics end (rendering time is a different and more likely issue), you generally have these few options.

  1. Hopefully find ways to optimize your game or code.
  2. Remove things from the game.
  3. Lower the frame rate to get more time per frame.
  4. Increase the minimum hardware requirements of your game.

That's a just summary overview of it, there's plenty more worth looking into.

@ForLoveOfCats
Copy link
Contributor Author

ForLoveOfCats commented Nov 27, 2018

I am aware that placing many static bodies beneath a kinematic body overloads the physics engine. That is the point. This is not an actual project but instead was designed to exactly reproduced the issue in a viewable way.

The issue is that the delta never changes even when the physics engine is running below the target tick rate. Of course while preventing the physics engine from being overloaded is a good idea when building a game, that does not mean that when Godot misbehaves because of this it is okay. The concept of a delta is how much time has passed since the last step so this should change when the physics engine cannot maintain the target tick rate. The move_and_slide movement being slower is just one way to perceive this underlying issue and the static bodies a way to reproduce the issue by purposefully overloading the physics engine.

Cheers!

@ghost
Copy link

ghost commented Nov 27, 2018

I see.

I don't think there is a general solution to that though. The sorts of adjustments needed I think become very specific to the overload problem created by ones game.

If you change that delta you're also going to change the precision of the physics in general. That isn't desirable to have it fluctuate from frame to frame. A larger delta could introduce a situation where some things that would not have passed through a wall will start passing through walls, but only because of the state of your system resources during that moment of play.

Imagine your physics crawls to 1 FPS. Are you saying you want your physics delta to start returning 1.0?

In that kind of situation, if you had a box that moved 10 meters a second, the physics would move and test collisions for it at 0.16m at a time at 60fps. The delta being 0.016. Imagine then a 1 meter thick wall it will bump into up ahead. At a 1.0 delta, that step will go from 0 to 10 meters in one iteration. (velocity * delta) Never checking the collision.

The determinism and precision is lost if you vary this number based on moment to moment performance.

The physics frames have to be budgeted to your target frame rate.

Outside of that, there are situations where it is a temporary stress event you just have to allow for, and then it would be nice to introduce a recovery mechanism based on your needs. You game will run very poorly for a moment, but the code would have an algorithm to do some catching up when the congestion stops.

To keep the physics state preserved, it might iterate the processing loop multiple times a frame until the time is caught up. Looks and feels bad for a moment, but the game wouldn't unravel.

I'm curious if you have some sort of mechanism like this in mind? I have noticed there isn't anything explicit in the main game loop to customize how you'd like to handle such a freak event.

@ForLoveOfCats
Copy link
Contributor Author

I had not considered the physics precision 🤔 Very good point. If the delta starts getting to high then the physics objects will move in such large jumps that they could phase through other objects. Bullet does have continuous detection but that would be overkill and likely performance killing. I suppose I will leave this open a tad longer to see if anyone else has any ideas. If not I'll close it in a few days.

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