-
-
Notifications
You must be signed in to change notification settings - Fork 21.4k
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 is not deterministic when using time scale. #24334
Comments
Unless I'm wrong, changing time_scale does not affect the FPS, it only changes the delta passed to physics. If this is indeed the case, I wouldn't expect physics to behave the same at all because of errors inherent to any numerical computation. Essentially, the computer has to approximate curves using straight line segments and your delta controls the length of the segments. You run into trouble approximating the "true" curves (physical trajectories) with different segments. Only for very very small deltas (huge FPS) would I expect the physics to behave the same when changing the time_scale. edit: You're running into lots of trouble with collisions because impulses are huge. Stuff like jumping around should be relatively fine. |
Also, I'm not sure if using |
@isaacremnant Thanks for the response, It does change the delta. I can only imagine something like you suggest with FPS as a solution. Keeping the delta 1/60, but increasing to 120 FPS might give a double speed, but is that flexible enough or viable in performance demanding situations? I'm going to experiment with that sometime soon, at least maybe I can do simulations if it works. Assuming it works I imagine you have to round to the nearest frame for a desired scaling value. So something like @Calinou Was thinking about using it globally first, then for only the entities with reduced effect, cancel this out by adding counter scaling to their delta in their processing loop when the effect is active. Since it is mostly only the player that would have reduced effect, feels more convenient to only write a bit of code in one place, rather than every game object. |
Bumped FPS to 120, and timescale to 2.0 to get 16ms delta. It only sometimes works. Was thinking maybe because it needs some time to set |
What I meant by very small delta was way beyond that, nothing feasible in game code! This is a very complicated numerical analysis problem and it's probably a lost cause. By the way, you're seeing the same outcome at 60fps because your computer can handle it, so all computations are exactly the same. At 120fps, you probably have a few frames have a different delta and that can make the difference between a collision normal of 60 and 61 degrees. I would suggest only worrying about the parts of your code that the player would notice if they were not deterministic. Stuff like jump height should be fine since the computations aren't too sensitive. Physics wouldn't, but I doubt players would notice the different outcomes of messy collisions so you should be able to tolerate that. |
Deterministic physics require fixed timesteps (as well as deterministic math inside the physics engine). |
I just have been working on the physics stepping code (for fixed timestep interpolation) and noticed this independently as a possible bug / feature. The timescale indeed is just affecting the delta. Once the fixed timestep interpolation is working, I can potentially change this to dynamically change the physics tick rate, if this was desirable, which would give deterministic physics, and more of a 'bullet time' effect, which I'm guessing was the intention. For this to look good, it would be dependent on the fixed timestep interpolation however, because otherwise slowing the physics tick rate would just give slow juddering movement. Perhaps an optional switch in the engine between both methods? Anyway, just an idea. 😁 |
Just an update, I have fixed this. I'll be submitting it as part of a bigger PR with lots more timestep options, probably in the next couple of weeks. I've put an option in the project settings to toggle between this and the older behaviour, defaulting to the older version. 👍 It should make far more sense in most use cases. However you will probably need to either be using the new fixed timestep interpolation, or semi-fixed timestep, to avoid getting judder when slowing the timescale right down, as it completes fewer physics ticks to maintain identical physics behaviour with slower timescale.
This is an interesting point, I'll try and have a look at this next week. Maybe there is a need for some items not to be affected by timescale. |
@lawnjelly Looking forward to the PR. |
Fixes godotengine#24769 Fixes godotengine#24334 The main change in this PR is adding the option in project settings->physics to choose between the old fixed timestep and a new path for semi-fixed timestep. With semi-fixed timestep users can either choose a high physics fps and get the benefit of matching between physics and frame times, or low physics fps and have physics effectively driven by frame deltas. There is also a minor refactor to the main::iteration function, notably moving the physics tick into a separate function, as well as a major refactor to main_timer_sync, separating the common components of timing (timescaling, limiting max physics ticks) from the details of the timestep functionality themselves, which are separated into 2 classes, MainTimerSync_JitterFix (the old fixed timestep) and MainTimerSync_SemiFixed. There is also a modification to allow the existing global time_scale to change the speed of the game without affecting the physics tick rate (i.e. giving consistent physics at different timescales).
Is this still not in the current stable? I can't seem to find it. The default time_scale behavior is extremely unintuitive and renders the _physics_process function completely pointless with regards to a variable time scale. |
@swift502 The semi-fixed timestep pull request hasn't been merged yet (and there's no guarantee it will be merged as-is). Remember that you can change |
Win10 64bit d030c17
Demo Project (Timescale exposed as an export var in the scene root.): 3.1 Timescale Determinism Issue.zip
I have been experimenting with Engine.time_scale and noticed the results in the built-in physics can vary wildly.
It makes me a concerned about using time slowing effects in games, because the way the game will play will change. Maybe there might be points in the game where the character will now just barely never be able to reach a platform if they're using a time slowing powerup.
It would be very hard to identify problems like that and hack in work arounds in script.
I made a small test project. It's RigidBody2Ds with a KinematicBody2D arm, being animated with an AnimationPlayer on the physics process.
They stay deterministic from play to play until the timescale is modified. Below are some animations showing these results at different time scales.
Not clear at least if this is a bug, limitation, or requires a totally different approach.
1X Timescale
4X Timescale
The text was updated successfully, but these errors were encountered: