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

move_and_slide() should not implement delta on its own #1192

Closed
Shadowblitz16 opened this issue Jul 13, 2020 · 21 comments
Closed

move_and_slide() should not implement delta on its own #1192

Shadowblitz16 opened this issue Jul 13, 2020 · 21 comments

Comments

@Shadowblitz16
Copy link

Describe the project you are working on:
Zelda 2 recreation game

Describe the problem or limitation you are having in your project:
I have documentation on zelda2 physics based in the NES's original 60 fps.

the move_and_slide function of KinematicBody2D implements delta time on its own making the values I use far too slow.
I tried dividing by delta before passing but that doesn't work either and makes my player fly off screen

I also tried doing move_and_collide but due to the zelda2 physics of applying gravity every frame regardless if I am on the ground or not makes the player unable to move on the x axis

Describe the feature / enhancement and how it helps to overcome the problem or limitation:
just remove the delta time implementation and have us multiply it ourselves
this makes code not only clearer but make it much more flexible for different types of games

Describe how your proposal will work, with code, pseudocode, mockups, and/or diagrams:
just remove the delta time multiplication from the move_and_slide function

If this enhancement will not be used often, can it be worked around with a few lines of script?:
it would certainly be used by me and any other person trying to recreate a beloved game

Is there a reason why this should be core and not an add-on in the asset library?:
its already in it just needs to be separated

@madmiraal
Copy link

@Shadowblitz16 Thank you for the suggestion. The delta is used to convert velocity into distance moved during that frame. It is implemented the way it is in the move_and_slide() function, because it needs to use it to also calculate the distance the platform the user is standing on moves and adjust the player's movement accordingly.

making the values I use far too slow.

I'm not sure what you mean, but move_and_slide() takes velocity as it's first parameter; so the speed of the body is controlled by changing the size of this vector not by adjusting delta.

I tried dividing by delta before passing but that doesn't work either and makes my player fly off screen

Dividing the velocity by delta is the same as multiplying the velocity by 60 (or whatever you've set the physics Fps to); so yes, the body will fly off the screen.

Finally, there is a lot of work planned for updating the physics interface in Godot 4, including changing move_and_slide() to make it more user friendly; so I'm closing this proposal for now.

@jonbonazza
Copy link

@madmiraal you are misunderstanding this. He's suggesting that move_and_slide should not automatically grab the physics delta, but should instead be left to the user to multiply the provided velocity by the physics delta themselves so that it is consistent with move_and_collide. I know that the physics system will be getting a revamp soon, but IMO, this is still a valid criticism and one that should absolutely be addressed in the redesign.

@Shadowblitz16
Copy link
Author

Shadowblitz16 commented Jul 15, 2020

@madmiraal jonbonazza is correct.
Not only is it inconsistent but it forces the user to use delta time to use kinematic body collisions.
Now most of the time delta time is a good thing and should be used.
However when trying to recreate the physics from a 90s system which wasn't frame rate independent its makes it impossible to simulate the exact physics.
not only that but framerate independence should be strongly encouraged not required.

@Shadowblitz16
Copy link
Author

Shadowblitz16 commented Jul 18, 2020

@madmiraal please reopen this.
this is a very big issue forcing us to use delta with kinematic bodies

@Shadowblitz16
Copy link
Author

@Calinou can you or one of the godot devs reopen this?
this is a valid suggestion and I feel it was closed for the wrong reasons

@Calinou Calinou reopened this Jul 29, 2020
@Calinou Calinou removed the archived label Jul 29, 2020
@Shadowblitz16
Copy link
Author

@Calinou Thankyou very much ♡

@Sslaxx
Copy link

Sslaxx commented Aug 4, 2020

On a related note: it seems odd that delta is not applied consistently to the move_and functions. Either they should both do so, or not.

@Shadowblitz16
Copy link
Author

I would prefer not as it allows more control over our own game's physics

@Calinou Calinou changed the title move_and_slide should not implement delta on its own move_and_slide() should not implement delta on its own Aug 14, 2021
@fabriceci
Copy link

@Sslaxx This will be harmonized in Godot 4, delta will (probably) be applied on both methods.

@Shadowblitz16 Could you please describe in detail why you need to set a custom delta? I understand those who wants to not pass a delta, but not to set a custom value instead. I'm curious on that.

As it was said, move and slide use the delta for other thing that multiply it with the velocity, so we can't remove the delta time multiplication . However we can add the ability to override the delta with an optional parameter.

@Calinou Calinou added this to the 4.0 milestone Aug 26, 2021
@Shadowblitz16
Copy link
Author

Shadowblitz16 commented Aug 26, 2021

@fabriceci delta is unpredictable and when trying to emulate a existing game's physics (for example nes games) you don't want to have that stuff.

I would be fine if delta was scaled so that movement was the same speed with or without it, but its not.

delta when applied slows the movement down because its multiplied by far less then 1.0

@pouleyKetchoupp
Copy link

@Shadowblitz16 Are you calling move_and_slide during _process(delta) function or _physics_process(delta) function?

At the moment there are two possibilities:
-If you call it in _process, the value of delta will be dependent on the rendering, and can have variations.
-If you call it in _physics_process, the value of delta will be fixed, and based on the project setting physics/common/physics_fps

The best way to achieve constant speed in physics is to use the second approach, physics calls in _physics_process.

The only case I see where you would need a custom delta is if you want to call move_and_slide in _process and still want a fixed delta time. That would cause the physics to go at an inconsistent speed though. Is it the effect you're trying to achieve?

@Shadowblitz16
Copy link
Author

Shadowblitz16 commented Aug 27, 2021

Not sure but the effect needs to seem frame rate dependent, even if its not. (aka same speed)

I just know when following this..
https://www.deviantart.com/jakeroo123/art/Legend-of-Zelda-The-Adventure-of-Link-physics-372868878

using move_and_slide vs manually incrementing position makes things move at extremely different speeds.

@pouleyKetchoupp
Copy link

Not sure but the effect needs to seem frame rate dependent, even if its not. (aka same speed)

I'm not sure if you mean that it should be frame rate dependent or not, it's an important detail.
Would you have a minimal project to share so we can have a look to what you are trying to achieve and the issue you're having?

@Shadowblitz16
Copy link
Author

@pouleyKetchoupp no I don't have that project anymore.
If you don't believe me then the best is to do the following if you have time...

  • Implement the zelda 2 physics with move and slide and that data sheet,
  • Rip a legal copy of a zelda 2 rom (meaning a copy you bought),
  • Compare the two side by side with a nes emulator.

This is what I did, and I couldn't get it to work, mainly because godot has no way to do collision checking without physics or delta time.

@pouleyKetchoupp
Copy link

@Shadowblitz16 I'd like to help find a solution to your problem, but you need to do your part as well to provide clear information. I'm not going to do the research for you or add a feature without confirming it's useful first.

What we need from you is:
-An example project that shows the problem you encountered
-A clear description of what you want to achieve. The best would be a script using position changes directly instead of move_and_slide (since it's working as intended this way if I understand your previous comments correctly).

Then we will be able to answer these questions before we implement the new feature:

  1. Is there an easy way to solve the problem with a simple script change?

You state in your proposal that you tried and had some issues with the character flying off screen, but there's no way to check if there's a simple bug to fix in the script in order to achieve what you're intending.

  1. Would it actually solve the problem you have?

Unless what you want is physics motion dependent on the framerate (which would cause heavy jittering when the framerate is not constant) I'm not sure what you're asking for is the right solution to your problem at this point, but that still needs to be confirmed.

@Shadowblitz16
Copy link
Author

@pouleyKetchoupp I don't have the project anymore and I don't have time to recreate it right now.
I guess I would be happy if delta time was scaled so velocities multiplied by it matched velocities not multiplied by it when the game is running at full speed.
Of course this would have to be a 4.0 change because it breaks compatibility.

@pouleyKetchoupp
Copy link

I guess I would be happy if delta time was scaled so velocities multiplied by it matched velocities not multiplied by it when the game is running at full speed.

@Shadowblitz16 I'm not sure to understand what you mean. Would you like delta time to be 1 when running at 60 FPS? Delta time is the time spent in seconds since the last tick, it's not a scale.

In practice, what happens is simple:
_process is called for each render tick, its delta can vary and represents the time since the last tick.
_physics_process is called for each physics tick at a constant rate (60 FPS by default) so the delta is always 1/60 in this case.
The recommended way to use move_and_slide is to call it in _physics_process so it goes at constant speed using a fixed physics tick. In this case you're ensured it's called 60 times per second with a fixed delta.
You can also use move_and_slide in _process and it uses the render delta internally. In this case it's called at the rate of rendering, so if the game goes slower you might end up with a longer motion in one frame.

Now if you want to try and implement framerate-dependent velocity, you can do a simple test by calling move_and_slide in _process but adjust the velocity so it will use a constant delta:

func _process(delta):
    var desired_delta = 1.0 / 60.0
    velocity = move_and_slide(velocity * desired_delta / delta)

This will cancel out the application of delta internally, and replace it with desired_delta (it won't work with moving platforms but it's fine for a simple test).
This way you can check what happens, but my guess is it's just going to cause some jitter.

I'm going to close this ticket again for now, but feel free to comment with an example project if you have time to get back to this project in the future and we'll re-open the discussion.

@igamigo
Copy link

igamigo commented Oct 20, 2023

@pouleyKetchoupp @Calinou move_and_slide() should definitely have at least an optional delta parameter. For networked games where you want to roll back some frames and re-simulate at your own pace, how can you achieve this currently?

@Calinou
Copy link
Member

Calinou commented Oct 20, 2023

Please continue the discussion in #2821 (which is what's needed for rollback).

@lokimckay
Copy link

lokimckay commented May 2, 2024

@Calinou

I posted #2821 and agree it's related but I think this issue should be reopened as a separate proposal

Here is an example use-case unrelated to #2821 that illustrates the problem of naively applying a single physics/render frame delta as the current move_and_slide in Godot 4 does (code)

  1. Project's physics frame rate is set at 60 FPS
  2. Certain objects use move_and_slide() as normal - no issues
  3. We desire other objects to run at a slower frame-rate for performance reasons - e.g. 30 physics FPS
  4. Implement a system that cumulates frame deltas in _physics_process and calls our slower objects movement function when it is their time to move (every second frame) - providing the summed delta
  5. Since move_and_slide multiplies by get_physics_process_delta_time() internally, it may be complicated to apply the desired summed delta to the characters velocity - particularly if other scripts are editing the character's velocity elsewhere

Ideally I think move_and_slide() should accept a velocity parameter the same way move_and_collide() does, and expect the user to multiply by their desired delta when passing it

Edit: found related articles:

@Calinou
Copy link
Member

Calinou commented May 2, 2024

I posted #2821 and agree it's related but I think this issue should be reopened as a separate proposal

I suggest opening a new proposal, since this proposal was rejected in its current form (it was about removing automatic delta behavior entirely from move_and_slide()).

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

9 participants