+1 vote

So, I've had a question that I've asked before yet never knew how to structure it. Now that I know more about the engine, I'd like to try asking the question in a much better way.

In a traditional programming environment (I've done this type of thing on a Discord bot using JavaScript) you can create one base class, and then create more derived classes. For example, you may have an Item base class with a use() function, and then derived from this class you may have HealthPotion and ManaPotion each with their own stats and use() functions. This is easy to create even in Godot, but in those other environments I can just instantiate any class that I want whenever I want.

In Godot, from what I've scene these class scripts need to be attached to a scene. I've thought of doing this two ways.

For one, I could have one sceen for each different item ... but if the game has 1000 items, isn't 1000 scenes too much?

I've also thought of having one scene, and like 1000 classes (one for each item). Then just instantiate the scene and attach a specific script to it when I need it... but I'm not sure how that would fair?

I've thought of using JSON but how do I make the JSON relevant when I still need a script for each item anyway. The json would have no information that each script would have anyway.

I'd like some thoughts please. Or if anything, would someone be able to explain how a system would be made anyway?


in Engine by (39 points)

I've thought about this as well. When I want dozens of different classes with slightly different parameters and methods, I've just been making that many scenes. I usually generate them with a script, but it's still dozens of files. I'd love to know a more elegant way to do it.

On the other hand, when I learned object oriented programming, I was generally told to make separate files for every class. So, maybe that's just the way it's meant to be.

Honestly you're probably right. I'm most likely just doing to do that unless someone comes here with a better proposal.

1 Answer

+1 vote
Best answer

you dont have to attach your objects to the scene. Attaching the object to the scenetree is just the way to be renderable and have access to the tree with get_tree() and beeing processed through _process(), _ready() .etc.

So to hold a reference and interact with your environment you basicly need one object attached to the scene. So you can make a myObjectInTheTree node and attach this to the sceneTree. This object can then hold any amount of referenced objects. Then you can use the objects as usual. But since the "subobject" dont have any reference to the sceneTree nor the "masterObject" they cant address anything by semself. But you can set them a variable with a reference to this objects.

Also any singleton is automaticly attached to the tree.

Its all about the holding references

Here a quote from the docs

Memory management
If a class inherits from Reference, then instances will be freed when no longer in use. No garbage collector exists, just simple reference counting. By default, all classes that don’t define inheritance extend Reference. If this is not desired, then a class must inherit Object manually and must call instance.free(). To avoid reference cycles that can’t be freed, a weakref function is provided for creating weak references.
by (3,116 points)
selected by

When you say "this object can hold multiple references" what do you mean exactly?

Do you mean I'd have an scene, Items for example, that will have a script containing an array of all items in the game?

Slightly confused, sorry lol

when you have objects that have to be
- proccessed with _ready, _process etc
- must be rendered
- must participate in physics

it has to be attached to the scenetree or else will not work.

All other objects must not been attached to the tree, you can hold a reference to them anywhere else. You need a reference or else they will be orphaned and cannot longer be addressed.

I get this. But by reference do you just mean instantiating a packed scene file like

var myScene = preload("res://path/to/scene.tscn").instance()

or is there another way to reference objects?

If you mean the way above, then this was what I was saying initially in my first post.

A reference is just a variable that points to an object.

Var myObject = myClass.new()
Var anotherReference = myObject

Those variables are both refering to the same object. They are both refereces.
As long as a variable points to an object this object is not lost. If the object is derifed from the reference class (wich all none extended classes are) it will be freed when no reference is pointing to them anymore.
The sceneTree is also only a class that holds the references to the scene nodes.

I was aware of how general OOP worked but wow I didn't know it was as simple as className.new(). Thank you VERY much. I can just load("res://path/to/classname").new() and it instantiates it!

I just didn't understand the syntax here.

Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to webmaster@godotengine.org with your username.