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 defining custom node variables without scripts #661

Closed
ballerburg9005 opened this issue Apr 1, 2020 · 8 comments
Closed

Allow defining custom node variables without scripts #661

ballerburg9005 opened this issue Apr 1, 2020 · 8 comments
Milestone

Comments

@ballerburg9005
Copy link

ballerburg9005 commented Apr 1, 2020

Describe the project you are working on:
So imagine this: A primitive vertical scroller game spawns food items and there are literally hundreds of different ones (banana, apple, noodle, etc.).

Now you want to save dozens of individual facts about those objects (vitamin B1 = 1000mg, is_vegetable = true, watercontent = 0.8 and so forth).

If a collision happens those facts all are relevant to what happens next (banana + milk makes milkshake, milkshake + fire decreases moisture, dog + chocolate = poison, player + chocolate increases tryptophan). So they need to be read ad-hoc by any other object.

Or often times it are just single facts, not dozens. Nearly all objects in a game can have one or two of those facts attached to them for convenience.

Describe the problem or limitation you are having in your project:
I know you can achieve this in the following ways:

  1. Makeshift database inside main loop that polls and IDs objects. (unspeakably ugly)
  2. Attaching a new script to each of the hundreds of objects just for storing variables. (still pretty ugly)

But some objects already have scripts attached to them. And if, in this case the hundreds of objects all have already a single same script attached (via duplicate), you can't just attach a second script. You would have to copy and paste the old script into a new one just to add the "non-script data" as variables inside a new script hundreds of times, which means that the old scripts code becomes totally unmanagable.

As it would mean that as you perform just one tiny change in the old script (which is an actual true script as it contains algorithms not just data), you would have to perform it hundreds of times by hand in this data-as-scripts based solution.

A workaround to this would be to create new mock nodes where to attach new script to, then you would have to descent or ascent into the mock node to read the variables from.

Still this seems unneccessarily laborious and clunky, to create hundreds of mock nodes and mock scripts just to store some data. And as it is that elemental to store one or two facts about anything for convenience, this would result in the strangest practice to create a mock node and mock script for each and every object just as a precaution.

I am new to Godot, so I just don't see how this could be elegantly done in the editor or from the docs.

The spam-scripts-solution is not that bad to live with as in most cases you can work around it by shifting the old "true" script code into other scripts (like main loop). But it seems strange to me that such an easy to implement commonplace feature - one which I perceive to be very elemental - would only be supported in a kind of workaround manner that breaks all kinds of object oriented practice.

Describe the feature / enhancement and how it helps to overcome the problem or limitation:
As you can already define groups inside the GUI, a simple place to start with would be that you could define variables in the same place and manner.

To make this feature more elaborate, it could feature search functionality and other database-ish things. So I can for example display all objects in the GUI with water content > 0.8, or all vegetables.

Of course you could also do this with with scripts, by just iterating over all nodes with print(), but that is equally as clunky, as it is only a workaround and nothing useful is actually implemented in the first place.

Describe how your proposal will work, with code, pseudocode, mockups, and/or diagrams:
My proposal would work only if you can define custom variables for nodes in the GUI without defining them in scripts.

If this enhancement will not be used often, can it be worked around with a few lines of script?:
This feature offers in its basics almost exactly the same features as just defining variables in a script, except of course that you don't need a script.

Is there a reason why this should be core and not an add-on in the asset library?:
I don't understand how it can work as an add-on. And as described, this functionality is extremely elemental to all game development. It should not be hidden in some add-on.

@willnationsdev
Copy link
Contributor

willnationsdev commented Apr 3, 2020

One thing you may not know about: every Object instance has a pair of methods, get_meta(name) and set_meta(name, value) which enables you to use any string to store any Variant. It's kinda like every Object has a Dictionary attached to them (except the keys have to be strings; they can't be any Variant type).

If you created an EditorPlugin utility that enabled you to create and edit meta variables (perhaps in a bottom panel or in a new tab of the Node dock?), then you'd be able to configure these variables on specific instances of Nodes in your scene without ever having to add a script to them. These values are serialized to the scene file and will be present on the Node when the scene is instantiated. I believe this would solve your issue.

In fact, this topic was discussed before, and upon investigating, it seems there was already a merged pull request (godotengine/godot#22642) that exposes the Meta field to the Editor. If I were you, I might try investigating that. You may already be able to do exactly what you want without any work.

@Jummit
Copy link

Jummit commented Apr 4, 2020

godotengine/godot#22642 was reverted in godotengine/godot#30749 because of this:
godotengine/godot#22642 (comment)

I think OPs problem could be solved if the new PR (godotengine/godot#30765) gets merged.

@ballerburg9005
Copy link
Author

@willnationsdev:

Thank you for the tip. I am writing a plugin right now that exposes metadata and it is just like you said it isn't a dead end.

It might take a few days, because its rather complicated with possible recursion. I will come back when finished.

@Kequc
Copy link

Kequc commented Apr 8, 2020

I may be not understanding the task properly, but I'd make one script with all the variables I need, I'd attach it to one node save it as a scene. I'd make a Factory class that instances and populates those scenes from a database or whatever data source I want to use.

Not sure why I'd want to make a whole bunch of different scripts for that.

I could I suppose change the variables in the inspector and save different scenes for each type of thing I wanted. But that also seems needlessly arduous when a Factory could do the same thing much faster and more easily.

@willnationsdev
Copy link
Contributor

From the sound of it, all of these different ad-hoc property changes are really the result of one big database of rules and logic that results from combinations of other flags. If I were managing something like that, I would personally want to have a single system that handles all of the logic for that. I'd probably actually have some sort of database or other serialized data structure that keeps track of all the combinations that can occur and what they result in.

As for how to keep track of which entity has what, which is what OP really wants to resolve, you could use either meta properties to use a script-less approach, or you could keep all of the information in the centralized entity (much cleaner that way) whereby you pass an object reference to the singleton in order to identify what data is associated with the object. It keeps both the serialized data, deserialized data, and logic all together in a single system. It then abstracts away all that complexity by just exposing a simplified interface to the rest of the application.

@ballerburg9005
Copy link
Author

Kequc: The point is that in good OOP practice, you should have the data attached to the object to which it actually belongs to. This is not only more convenient, but also more clean and logical.

Godot already has all the functionality needed: The "script variables" inspector and the meta variable. It is just that they are not by default applied to each other, so the user has to do some kind of workaround-clunk.

Like: No one wants to create hundreds of same-ish single scripts just to store a couple of variables. But this would actually be the "cleanest" and "easiest" and "fastest" way in certain scenarios to deal with the issue, because the feature is missing.

What you described is just another workaround solution, that probably works better on smaller scales (like dozens of objects not hundreds, a couple of object categories and not dozens).

If it wasn't for engine limitation, it would always be cleaner and easier and faster to simply attach the object's data to the object.

Imho if you think this all through, this is just a tiny clunk at first glance, but it can grow really huge the more complex object interactions are in your game.

@ballerburg9005
Copy link
Author

For great justice: https://github.com/ballerburg9005/godot-metadata-inspector

@Calinou Calinou changed the title custom node variables without scripts Allow defining custom node variables without scripts Aug 13, 2021
@Calinou
Copy link
Member

Calinou commented Jan 26, 2023

Object metadata is now exposed and editable in the inspector in 4.0, closing.

@Calinou Calinou closed this as completed Jan 26, 2023
@Calinou Calinou added this to the 4.0 milestone Jan 26, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Implemented
Development

No branches or pull requests

5 participants