Skip to content

Add optional delta parameter to move_and_slide#84665

Open
monitz87 wants to merge 10 commits intogodotengine:masterfrom
Skillcap-Studio:feat/move-and-slide-delta
Open

Add optional delta parameter to move_and_slide#84665
monitz87 wants to merge 10 commits intogodotengine:masterfrom
Skillcap-Studio:feat/move-and-slide-delta

Conversation

@monitz87
Copy link
Copy Markdown

@monitz87 monitz87 commented Nov 9, 2023

This overrides the implicit delta derived from context that is currently being used. If not passed, the method functions as it normally does. This change allows finer control over the method's behavior without sacrificing ease of use.

Explanation for why this is necessary here

This is my first contribution to the project, so I apologize in advance if I botched something. I read the contribution guidelines but there's a chance I missed something

This overrides the implicit delta derived from context that is currently being used. If not passed,
the method functions as it normally does. This change allows finer control over the method's behavior without
sacrificing ease of use.
@AThousandShips
Copy link
Copy Markdown
Member

Thank you for your contribution!

You need to add the new parameter to the documentation, use --doctool to generate this is the easiest way, see here

@monitz87
Copy link
Copy Markdown
Author

monitz87 commented Nov 9, 2023

Thank you for your contribution!

You need to add the new parameter to the documentation, use --doctool to generate this is the easiest way, see here

Done. My bad for missing that part 😅

@AThousandShips
Copy link
Copy Markdown
Member

What happens when delta is 0.0? This shouldn't happen with the current behaviour so feeding it 0.0 might break things, the check should probably be delta <= 0 instead

@monitz87
Copy link
Copy Markdown
Author

monitz87 commented Nov 9, 2023

Fair enough. Should I just make the default 0.0?

@AThousandShips
Copy link
Copy Markdown
Member

I think -1 is clearer so leave it as that

@monitz87
Copy link
Copy Markdown
Author

monitz87 commented Nov 9, 2023

Should probably document that passing non-positive delta leads to unexpected behavior

@AThousandShips
Copy link
Copy Markdown
Member

That it uses the default one yes, that it ignores it, not necessarily unexpected behaviour, should be clear what it does

Also add a note to the docs about the behavior when delta is <= 0
@AThousandShips
Copy link
Copy Markdown
Member

Might want to change the check to !(delta > 0) to catch NaN but not sure if needed

Will do more style and detail review later but will leave for testing for right now, can test and investigate when I have more time

@monitz87
Copy link
Copy Markdown
Author

monitz87 commented Nov 9, 2023

Edit: my bad should have been no trailing zero

Why is that? In the current docs I see examples of both

@AThousandShips
Copy link
Copy Markdown
Member

AThousandShips commented Nov 9, 2023

Unsure, it's stripped by the generator I think, which is an issue, can't find it right now though

Edit: might have updated since then, had it backwards in any case

@AThousandShips
Copy link
Copy Markdown
Member

The current thing that's failing is compatibility related, a bit of a complex thing to add so no rush with that right now, will guide you through it when reviewers have gone through the feature itself

@Calinou
Copy link
Copy Markdown
Member

Calinou commented Nov 9, 2023

This doesn't sound sufficient on its own to perform rollback. If you're catching up with server lag, performing move_and_slide() once with a really large delta is different from performing many physics steps at once (it will be much less precise). The original proposal is explicitly asking for the simulation of multiple physics frames at once.

@monitz87
Copy link
Copy Markdown
Author

monitz87 commented Nov 9, 2023

The current thing that's failing is compatibility related, a bit of a complex thing to add so no rush with that right now, will guide you through it when reviewers have gone through the feature itself

Thanks :D

@monitz87
Copy link
Copy Markdown
Author

monitz87 commented Nov 9, 2023

This doesn't sound sufficient on its own to perform rollback.

It's not sufficient on its own, but it's still a necessary step to be able to use move_and_slide together with rollbacks, and even if stepping the physics engine wasn't a thing, it still doesn't make much sense to not allow users to have control over the delta. This brings the API closer to move_and_collide and it makes it more intuitive to boot.

The original proposal is explicitly asking for the simulation of multiple physics frames at once.

Technically, this is a separate issue from being able to step the physics engine, even if they're related to the same use case, so it made sense to me to raise a separate PR for it.

If you're catching up with server lag, performing move_and_slide() once with a really large delta is different from performing many physics steps at once (it will be much less precise).

PS: just to be clear, the comment this PR refers to doesn't allude to performing move_and_slide once with a really large delta. It refers to performing it once per physics frame with a fixed delta, but having the engine tick faster, so that the client actually simulates the game faster and sends inputs to the server at a higher frequency when the server signals that it is being starved

@nicobatty
Copy link
Copy Markdown

nicobatty commented Dec 9, 2023

I was actually wondering if anyone suggested this change! I did run into this problem myself and noticed it was also mentioned as a caveat in a network library from @foxssake called netfox.

@WantToSignUp
Copy link
Copy Markdown

WantToSignUp commented Jan 1, 2024

This doesn't sound sufficient on its own to perform rollback. If you're catching up with server lag, performing move_and_slide() once with a really large delta is different from performing many physics steps at once (it will be much less precise). The original proposal is explicitly asking for the simulation of multiple physics frames at once.

With this PR, multiple simulation steps for character movement could be easily implemented by just calling move_and_slide() multiple times in a for loop, with smaller delta, no?
Multiplayer games may implement their own fixed timestep movement code outside the _physics_process(which has some quirks thanks to the way it keeps delta stable), so custom delta is much needed for move_and_slide().

@l3dotdev
Copy link
Copy Markdown

l3dotdev commented Jan 6, 2024

@monitz87 I thank you for this contribution, glad to see this feature is finally getting added after the over 2 years of discussion about it in issues! Been banging my head against a wall trying to figure out why I was getting constant desyncing in my netcode to find that move_and_slide was the culprit.

@Glitshy
Copy link
Copy Markdown

Glitshy commented Jun 19, 2025

I just stumbled accross this problem myself. What is holding this back from being merged?

Copy link
Copy Markdown
Contributor

@nongvantinh nongvantinh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please squash it into a single commit and resolve the conflict with the master branch.

Comment on lines +1111 to +1114
if (!(delta > 0)) {
// Hack in order to work with calling from _process as well as from _physics_process; calling from thread is risky.
delta = Engine::get_singleton()->is_in_physics_frame() ? get_physics_process_delta_time() : get_process_delta_time();
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (!(delta > 0)) {
// Hack in order to work with calling from _process as well as from _physics_process; calling from thread is risky.
delta = Engine::get_singleton()->is_in_physics_frame() ? get_physics_process_delta_time() : get_process_delta_time();
}
if (delta <= 0) {
// Hack in order to work with calling from _process as well as from _physics_process; calling from thread is risky.
delta = Engine::get_singleton()->is_in_physics_frame() ? get_physics_process_delta_time() : get_process_delta_time();
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is incorrect, see the comment above, this handles invalid values such as NaN

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting, I have never seen this way to catch NaN used before. The expression is really confusing, though it's valid.

Copy link
Copy Markdown
Contributor

@nongvantinh nongvantinh Jul 8, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@AThousandShips Shouldn't we use Math::is_finite(delta) to be more expressive?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is an established syntax used in several places, the comment is clear enough and there's no need to make a less efficient check IMO

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In my opinion, since the user wants to pass in their own delta, they are supposed to provide a valid value. If the provided value is invalid, the engine should report the error and stop executing the remaining code instead of enforcing a random choice from the engine to avoid unexpected surprises.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would be noisy and there's no random choice here it is perfectly reasonable IMO, but that should be discussed in the proposal instead as it's a design derail, not an implementation one

Comment on lines +1175 to +1178
if (!(delta > 0)) {
// Hack in order to work with calling from _process as well as from _physics_process; calling from thread is risky.
delta = Engine::get_singleton()->is_in_physics_frame() ? get_physics_process_delta_time() : get_process_delta_time();
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (!(delta > 0)) {
// Hack in order to work with calling from _process as well as from _physics_process; calling from thread is risky.
delta = Engine::get_singleton()->is_in_physics_frame() ? get_physics_process_delta_time() : get_process_delta_time();
}
if (delta <= 0) {
// Hack in order to work with calling from _process as well as from _physics_process; calling from thread is risky.
delta = Engine::get_singleton()->is_in_physics_frame() ? get_physics_process_delta_time() : get_process_delta_time();
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here

@monitz87 monitz87 requested a review from a team as a code owner August 17, 2025 16:29
lucacicada added a commit to lucacicada/voidine that referenced this pull request Oct 18, 2025
lucacicada added a commit to lucacicada/voidine that referenced this pull request Oct 18, 2025
@gordongu
Copy link
Copy Markdown

@monitz87 @AThousandShips I don't know if this PR is still being worked on but I'd like to push it across the finish line. I've added the missing compatibility functions which were causing the tests to fail but I'm not sure if I should create a new PR or push the changes onto this one.

@monitz87
Copy link
Copy Markdown
Author

@gordongu no complaints from me if you want to take over this PR

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.