Skip to content

GDScript: Allow overriding default values of base class variables#93787

Draft
dalexeev wants to merge 1 commit intogodotengine:masterfrom
dalexeev:gds-override-var
Draft

GDScript: Allow overriding default values of base class variables#93787
dalexeev wants to merge 1 commit intogodotengine:masterfrom
dalexeev:gds-override-var

Conversation

@dalexeev
Copy link
Copy Markdown
Member

@dalexeev dalexeev commented Jun 30, 2024

@override var script_var: int = f(2)
@onready @override var name: StringName = &"Test"

TODO: Implement proposal godotengine/godot-proposals#8045 (only possible for inline setters/getters).

@dalexeev dalexeev added this to the 4.x milestone Jun 30, 2024
@dalexeev dalexeev requested a review from a team as a code owner June 30, 2024 16:57
@dalexeev dalexeev marked this pull request as draft June 30, 2024 16:57
@Mickeon
Copy link
Copy Markdown
Member

Mickeon commented Jun 30, 2024

How far does the @override go? Would it actually let you override, say, export properties as well?

Also I see my PR to highlight overridden properties is being put to even better use now.

@dalexeev
Copy link
Copy Markdown
Member Author

How far does the @override go? Would it actually let you override, say, export properties as well?

Variable overriding is reasonably quite limited:

  • You cannot change the variable type.
  • You cannot override static variables because they belong to their classes, not to the instance.
  • You cannot change or remove setter/getter because GDScript is a fairly dynamic language and it would be weird to have different behavior depending on the type and casts inferred by the analyzer.

The only thing this feature is really intended for, is to change the default value of a variable in an inherited class, just like it is possible in native classes. This can be useful because the overriden default value is shown in the documentation and in the Inspector (the latter is not yet debugged). Also it shouldn't require @tool.

Note that the current implementation the default value is not replaced, just the inherited implicit initializer is executed after the base implicit initializer. That is, the variable will be assigned twice (or more, as many overrides). In all initializations the setter will not be called, since there is an exception for the initializer. I'm not sure if this is a good thing, but I don't see how we could implement it without complicating the compiler.

As for changing export info, it doesn't work correctly now, but I think it can be fixed:

So, I'm not sure about this feature yet, but I decided to check it out to see how feasible it is.

@Mickeon
Copy link
Copy Markdown
Member

Mickeon commented Jun 30, 2024

You cannot change the variable type.

Good, but in practice it would still be desirable to narrow it down with covariance like in #82477

That is, the variable will be assigned twice (or more, as many overrides). In all initializations the setter will not be called, since there is an exception for the initializer. I'm not sure if this is a good thing, but I don't see how we could implement it without complicating the compiler.

This may actually not be too much of a deal-breaker for most, but it is certainly a waste of processing time which would be nice to avoid.

JuanFdS added a commit to endlessm/threadbare that referenced this pull request Mar 27, 2025
This way, we have a scene that has the default configuration (collision layers and mask) of the interact area already setup.
I made it this way instead of by modifying the interact_area.gd because I'd like to let the contributors modify the collision layers of the nodes after they were created.

I think that this would not be needed anymore once we this pull request is merged into godot and default values for inherited properties can be overriden: godotengine/godot#93787 -- godotengine/godot-proposals#338
JuanFdS added a commit to endlessm/threadbare that referenced this pull request Apr 1, 2025
This way, we have a scene that has the default configuration (collision layers and mask) of the interact area already setup.
I made it this way instead of by modifying the interact_area.gd because I'd like to let the contributors modify the collision layers of the nodes after they were created.

I think that this would not be needed anymore once we this pull request is merged into godot and default values for inherited properties can be overriden: godotengine/godot#93787 -- godotengine/godot-proposals#338
wjt pushed a commit to endlessm/threadbare that referenced this pull request Apr 3, 2025
This way, we have a scene that has the default configuration (collision layers and mask) of the interact area already setup.
I made it this way instead of by modifying the interact_area.gd because I'd like to let the contributors modify the collision layers of the nodes after they were created.

I think that this would not be needed anymore once we this pull request is merged into godot and default values for inherited properties can be overriden: godotengine/godot#93787 -- godotengine/godot-proposals#338
JuanFdS added a commit to endlessm/threadbare that referenced this pull request Apr 3, 2025
This way, we have a scene that has the default configuration (collision layers and mask) of the interact area already setup.
I made it this way instead of by modifying the interact_area.gd because I'd like to let the contributors modify the collision layers of the nodes after they were created.

I think that this would not be needed anymore once we this pull request is merged into godot and default values for inherited properties can be overriden: godotengine/godot#93787 -- godotengine/godot-proposals#338
JuanFdS added a commit to endlessm/threadbare that referenced this pull request Apr 3, 2025
This way, we have a scene that has the default configuration (collision layers and mask) of the interact area already setup.
I made it this way instead of by modifying the interact_area.gd because I'd like to let the contributors modify the collision layers of the nodes after they were created.

I think that this would not be needed anymore once we this pull request is merged into godot and default values for inherited properties can be overriden: godotengine/godot#93787 -- godotengine/godot-proposals#338
JuanFdS added a commit to endlessm/threadbare that referenced this pull request Apr 3, 2025
This way, we have a scene that has the default configuration (collision layers and mask) of the interact area already setup.
I made it this way instead of by modifying the interact_area.gd because I'd like to let the contributors modify the collision layers of the nodes after they were created.

I think that this would not be needed anymore once we this pull request is merged into godot and default values for inherited properties can be overriden: godotengine/godot#93787 -- godotengine/godot-proposals#338
@hmturnbull
Copy link
Copy Markdown

hmturnbull commented Jun 4, 2025

  • You cannot change or remove setter/getter because GDScript is a fairly dynamic language and it would be weird to have different behavior depending on the type and casts inferred by the analyzer.

👍

Since you can override the content of the setter/getter function like any other function, changing the variable so it points to a different setter/getter entirely would be completely pointless and make everything needlessly confusing.

How messed up would it be if you called a setter function in code, only to find out it wasn't the correct setter in the specific object you were dealing with? 🥶

@Laskivi
Copy link
Copy Markdown

Laskivi commented Jul 21, 2025

Just chiming in to say this is an absolutely necessary feature for using inheritance with Resources and RefCounteds. Especially RefCounteds, since they cannot be exported to the inspector. I was going about my business making abstract Resource classes in my project, expecting being able to easily override their variables to be completely par for the course. I was very happy to find that abstract classes and methods will be added in 4.5, but a bit surprised that overriding parent variables wouldn’t also be part of the package just yet. These things go hand in hand. Would really appreciate this!

@FoxyFox909
Copy link
Copy Markdown

Just chiming in to say this is an absolutely necessary feature for using inheritance with Resources and RefCounteds. Especially RefCounteds, since they cannot be exported to the inspector. I was going about my business making abstract Resource classes in my project, expecting being able to easily override their variables to be completely par for the course. I was very happy to find that abstract classes and methods will be added in 4.5, but a bit surprised that overriding parent variables wouldn’t also be part of the package just yet. These things go hand in hand. Would really appreciate this!

Yeah, the only workaround is using _init method on the extended script, but that is cumbersome

@AThousandShips AThousandShips changed the title GDScript: Allow override default values of base class variables GDScript: Allow overriding default values of base class variables Jul 28, 2025
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.

Allow ability to override parent variables

5 participants