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

C#: Add float delta overloads of _Process and _PhysicsProcess #74070

Closed
wants to merge 1 commit into from

Conversation

neikeq
Copy link
Contributor

@neikeq neikeq commented Feb 27, 2023

The bindings generator is hard-coded to replace the type of the parameter from double to real_t. This means it's no longer necessary to cast the delta in order to use it in float operations.

Math types like Vector3 use real_t, so going with real_t instead of float means the solution also works for project where real_t is 64-bit.

The double precision version of the delta is still available through the GetProcessDeltaTime() and GetPhysicsProcessDeltaTime(). I optimized the methods to return a cached value instead of going through an internal call. I also added two matching properties to reduce verbosity.

Fixes godotengine/godot-proposals#5403

@neikeq
Copy link
Contributor Author

neikeq commented Feb 27, 2023

Though this is late, I hope we can include it in 4.0. It's a breaking change, but it's something users complain a lot about.

core/object/script_language.h Outdated Show resolved Hide resolved
Copy link
Member

@RedworkDE RedworkDE left a comment

Choose a reason for hiding this comment

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

The CharacterBody & Node templates need adjusting (can you even have distinct templates for a double build?)
Also set_physics_process_delta_time and set_process_delta_time should be added to ScriptLanguageExtension

Looks ok to me, but

  • I would have left the Get(Physics)ProcessDeltaTime changes for 4.0.x
  • Tho probably a giant pain to implement, It should be possible to make this change in a backwards compatible way by emitting two overload for these methods, so that the users can implement it with either a float or a double argument.
  • IMO this change is unlikely to cause regressions, as long as everything still compiles

@akien-mga
Copy link
Member

We're sadly past the window of opportunity for such changes, this should have been at least a week ago. The stable release is in a couple of days, and the published RC6 should be the final "real" release candidate, so we're not making any compat breaking changes anymore.

@akien-mga akien-mga modified the milestones: 4.0, 4.1 Feb 27, 2023
@neikeq
Copy link
Contributor Author

neikeq commented Feb 27, 2023

I'm going to see if it's possible to go with the overload solution to not break compat.

@raulsntos
Copy link
Member

Despite breaking compat, I strongly prefer this PR (changing the delta parameter to real_t) over implementing overloads. I feel like the overload solution is confusing, especially when dealing with hierarchies.

class BaseNode : Node
{
    public override void _Process(float delta) { }
}

class DerivedNode : BaseNode
{
    public override void _Process(double delta) { }
}
  • What is the order of execution?
  • How do I call the base._Process method if the base class uses the other overload? Or how do I prevent its execution?
  • What if I have a multi-level hierarchy that mixes the overloads?

@neikeq neikeq force-pushed the csharp-delta-issue-5403 branch from 3180108 to f37c044 Compare February 27, 2023 19:59
@neikeq
Copy link
Contributor Author

neikeq commented Feb 27, 2023

I've updated the PR. The latest version shouldn't break compat.

  • What is the order of execution?

The double overload always executes first for the same node.

  • How do I call the base._Process method if the base class uses the other overload? Or how do I prevent its execution?

You shouldn't call the base of the other overload. Otherwise, it will be called twice (the float overload is called right after the double overload).

To prevent the execution of a base overload, override that particular overload (overriding both works) and skip the base call.

  • What if I have a multi-level hierarchy that mixes the overloads?

As long as you don't use casts to call a different overload on base, there shouldn't be issues. I do think it can be confusing, hence why I marked the double overload with the attribute that hides it from code-completion, to discourage its use (and in 5.0 we can go with the real_t solution).

@neikeq neikeq changed the title C#: Make _Process and _PhysicsProcess use real_t for delta C#: Add float delta overloads of _Process and _PhysicsProcess Feb 27, 2023
@raulsntos
Copy link
Member

You shouldn't call the base of the other overload.

Yes, but that wasn't my intention. I just want to call the base implementation which in the base class may happen to be the double overload while in my derived class I'm overriding the float overload and now I can't do this.

Hopefully this example illustrates my point better:

class BaseCharacter : Character3D
{
    public override void _Process(double delta)
    {
        MoveAndSlide();
    }
}

class DerivedCharacter : BaseCharacter
{
    public override void _Process(float delta)
    {
        Velocity = Vector3.Forward * delta;
        base._Process(delta);
    }
}

Because the double overload is executed first, I'm unable to set the Velocity before MoveAndSlide in my derived class. Using base._Process to control the order of execution is not possible. Although maybe I'm overthinking this.

To prevent the execution of a base overload, override that particular overload (overriding both works) and skip the base call.

You and I know this because we're familiar with the code. My concern is that for users this will be confusing.

I do think it can be confusing, hence why I marked the double overload with the attribute that hides it from code-completion, to discourage its use

Do you mean that the double overloads should never be used? In that case I'd prefer to also obsolete it.

@neikeq
Copy link
Contributor Author

neikeq commented Feb 27, 2023

Do you mean that the double overloads should never be used? In that case I'd prefer to also obsolete it.

Yes, we will keep it just to avoid breaking compat. I forgot to mark it as obsolete.

This overload reduces the need for casting the delta in order to use it
in `float` operations.

The `double` overload has been marked with `EditorBrowsableState.Never`
to discourage its use, as it can cause confusion. The plan is to replace
both with a single `real_t` version in Godot 5.

The `float` overload is called right after the `double` overload.
@paulloz
Copy link
Member

paulloz commented May 6, 2024

After discussing the PR, and the issue more broadly, we are closing this PR, since we are not planning to merge it.

We understand that changing the type of the delta parameter from a single to a double to match Godot's internal type came with adverse effects on usability. The solution proposed here is considered too brittle by all active .NET maintainers. We particularly fear the added complexity when dealing with complex class hierarchies that override one or the other method at several levels1. We also do not want this kind of solution to become a precedent on how to deal with method signature changes between GodotSharp and the core engine.

As such, we do not think the aforementioned effects on usability (namely, having to cast the delta parameter to a single) are important enough to risk the stability of the API over them.

Still, the community's opinion is important to us, and we are considering using the upcoming GDExtension-based API as an opportunity to switch those methods to using singles again.

Footnotes

  1. https://github.com/godotengine/godot/pull/74070#issuecomment-1447027651

@paulloz paulloz closed this May 6, 2024
@AThousandShips AThousandShips removed this from the 4.3 milestone May 7, 2024
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.

Reduce the amount of casting required for floating points in C#
7 participants