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

Allow users to modify pre-existing classes (nodes) without recompiling the engine #7068

Open
Gamepro5 opened this issue Jun 12, 2023 · 6 comments

Comments

@Gamepro5
Copy link

Gamepro5 commented Jun 12, 2023

Describe the project you are working on

Trying to make UI for a game.

Describe the problem or limitation you are having in your project

I reached a point where I wanted to fill in the virtual function for a custom tooltip. I wanted this to apply to all control nodes. The only way I could do this is by extending control and filling it out, then only using my new extension version. Problem with that is I'd then need to recursively make a new node version for each and every node I wish to use that naturally extends Control. It would be so much easier if I could just change how the control node works.

Describe the feature / enhancement and how it helps to overcome the problem or limitation

This would give so much more freedom for the user to fix things they don't like:

  • You could apply a sound to be played on all button instances without searching through the entire tree and applying a signal to each and every button during runtime

  • You could fill out virtual functions that you want to have general behavior when you create the node.

  • You could fix small things you don't like with how a node is implemented out of the box, without cluttering the res by relegating the base nodes to never being used in favor of your extended version of said node.

...and much, much, more.

Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams

Add an attribute to the Object class called "overwrite" that is an input of code. Entering code in that box would add/overwrite methods. Under the hood, it could act exactly like an extension of the class, but the fact that it is an extension would be abstracted from the user. Instead of it needed a new class name, it would keep the class name of the node you wished to augment in this way, just with the added functionality of "technically" being this new extended node described by the overwrite box.

The language used in this code box doesn't matter, it could be C++ for all I care. The entire point is to allow small changes to pre-existing classes (not during runtime). I think that it being in GDscript shouldn't have much of a performance hit considering it is basically an abstracted extension of a class, which is already possible in GDscript. It's just instead of giving your extension a new name, it keeps the name of the class you extended. That way all other classes that inherit the class don't need to be changed.

If this enhancement will not be used often, can it be worked around with a few lines of script?

No, this cannot be done by script. You need to recompile the engine with your changes to these classes first.

Is there a reason why this should be core and not an add-on in the asset library?

It's too low level to find in the asset library.

@AThousandShips
Copy link
Member

AThousandShips commented Jun 12, 2023

Maybe add a box in a node's properties that allow you to write code that would add or overwrite the pre-existing functions, or just add a way to open a class and see how it's implemented.

What do you mean by this? This isn't really giving any details on how this functionality would work, and it's a pretty big question.

You're proposing allowing some form of overrides of built in classes, but how should it be accomplished? This needs details, I don't really see how this can be done without becoming a major performance issue, while still managing the functionality that must be in these nodes to function to begin with, so it can't be just a simple override

You really need to give more, or any really, detail on how this should be made possible

Edit: Do you mean GDScript code?

This isn't really any clearer, sorry

Where should this code be called? When? How? There's really no functionality for executing snippets of GDScript code in the engine right now, and that'd be the only code that could work for this.

@Gamepro5
Copy link
Author

Thanks for the reply, hopefully I made it more clear now.

@Gamepro5
Copy link
Author

@AThousandShips the functionality for extending a pre-existing class is already in the engine. This "modifying a class" would simply act exactly like extends under the hood, but would not require a new name and would affect all descendant nodes.

@AThousandShips
Copy link
Member

AThousandShips commented Jun 12, 2023

First of all, no need to tag me when there's no one else here

This seems like a performance mess, and I still don't see much in the way of real details on how to accomplish this, which is required here.

Proposal issues are required to explain in technical detail how the suggested change should be implemented. It is also preferred that the submitter of a proposal is ready to implement it if it was approved. If you have a more general idea for a feature but are not well versed in Godot's architecture or do not possess the necessary knowledge to implement it in the engine, feel free to open a discussion instead of an issue.

The idea of modifying a class, outside of recompiling, and having that affect direct inheriting classes is something I don't think I've ever seen, do you have any examples of this actually being done in any programming language or environment? To me it doesn't make any sense, and I don't see any way it could work from a C++ perspective without recompilation, at least not without a major performance overhead that affects everyone regardless if they use the feature.

@dalexeev
Copy link
Member

See also:

@Calinou
Copy link
Member

Calinou commented Jun 12, 2023

You could apply a sound to be played on all button instances without searching through the entire tree and applying a signal to each and every button during runtime

This does not require modifying core classes. See a solution I proposed in #1472.

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

4 participants