Hacker News new | ask | show | jobs
by strictfp 1416 days ago
How do you people feel about the Godot object and lifetime model? I found it hard to test my code because of how objects are tied to the tree, that emulating the tree isn't easy during testing, and that initialization during live use is different than if you instantiate manually, making it hard to rely on a constructor, since you might not be able to use it live.

I can't remember the exact details around this, since I only used Godot for a couple of jams and the last time was a year ago. But I was wondering if others have had the same reaction, perhaps this could be fixed? I love the engine in general, but this thing irked me.

3 comments

It’s something that’s pretty nice once you’ve implemented these lifecycles a bunch.

The tree turns out to be a great place to keep things, and you get several levels of control. Here’s how I think about it now.

`_init`: constructor. I usually use this to create dynamic child nodes

`_enter_tree`: now we have a parent; subscribe to signals, copy initial config, etc

`_ready`: I can be sure that all child nodes have called _ready, so anything I depend on there is… er, ready

`_exit_tree`: cleanup, especially anything we did with the parent and other ancestors. usually symmetric to `_enter_tree` if I’m using them

I just did a find all in my biggest recent project, and I never actually use `queue_free` or `free` for explicit memory management. Most of the times when I’ve thought I needed to, I actually was creating a bug

How do you remove objects if you don't queue free them? Just remove them from the tree?
Yes, or they are free’d automatically as the parent is free’d recursively. If you have called `add_child` on a node you created dynamically, godot will handle its lifecycle from there.

If you don’t add a dynamically-created node to the tree, you are responsible for `free`.

That almost never comes up, because I eventually figure out how to decompose everything into a tree Node, or! A Resource.

Resources are managed in a separate memory pool, and don’t need to be added to the tree for godot to take care of it. Go ahead, you just try and `free` a resource! ;)

In the docs for Node.remove_child(Node node)[1] it says

"Removes a child node. The node is NOT deleted and must be deleted manually."

Do you still have to queue_free the top node that was removed from the tree, or else how is it being deleted. Or is there a different method to call for removing it from the tree.

BTW: I really like the `_init` / `_enter_tree` / `_ready` / `_exit_tree` lifecycle as was described.

1:https://docs.godotengine.org/en/stable/classes/class_node.ht...

queue_free removes the node from the tree and frees it.

remove_child just deactivates it, but keeps it around in memory for later.

Damn, I didn't know that. Time to remove queue_free from my project :)
Thanks. Do you setup an artificial tree during testing? If so, how?
I’m not sure your mental model matches mine, but in my “real job” I deal with the shadow and virtual DOM. Maybe that’s the metaphor you’re looking for?

I’ll have to be a little practical and hope it makes sense. The tree in the editor is the same tree. Godot engine is written in Godot engine, so what is the distinction between being in the editor and being in the game?

The answer is that godot will ignore all project scripts by default while you are in the editor, but it offers mechanisms to enable them. The main way is a keyword in GDScript.

In Godot 3, you put `tool` as the first line of a script, and it will be loaded. Godot 4 has grown a pre-processy decorator syntax, so it’s the same, but `@tool`.

In your scripts, you can detect whether you are in the editor by checking `Engine.editor_hint`. You can do amazing things with this.

Then you can take it a step further, and convert your tool scripts into an addon. With an addon, which is just a directory structure for assets, your custom in-editor functionality becomes indistinguishable from native godot behavior.

https://docs.godotengine.org/en/stable/tutorials/plugins/run...

PS: I created a virtual node tree a few times to wrap UI components. Much like react. But honestly, I usually find a more idiomatic pattern later.

/sarcasm/ Why would game devs write tests?

On a more serious note, I do expect test-ability isn't a high customer priority for Godot. Godot is self-hosted, maybe check how they run their tests?

Probably not the most efficient way to do it, but I setup test scenes for just the functionalities I wanted to test and run those manually.