2
\$\begingroup\$

tl;dr = When/Where/Why use 'Node2d' as the parent vs going straight to 'Other Node'?

I have just started diving into using Godot for the first time. I completed the Your First Game official tutorial (Dodge The Creeps) and have a question my searchengine-fu hasn't yet been able to find an answer for. Links to this question being asked already and/or where I completely missed this in the docs are appreciated.

I would like to attempt my own game now and learn during the process. Something I can't seem to find an answer for is when it is appropriate to select "Node2d" when creating a new scene, versus clicking on "Other Node" and selecting what is required from there.

If I want to make a tower defense game I will need a scene to hold the 'world/map' that I make using a TileMap. The Turrets I place and the Mobs that follow the path will be their own scenes - presumably something like Sprite2D or AnimatedSprite2D

When I create these scenes (ie world.tscn, missile_turret.tscn etc), when/where/why is it appropriate to select Node2D as the parent and then add TileMap or Sprite2D as a child, versus when should I just go straight for "Other Node" then select either TileMap or Sprite2D from the list of all nodes that comes up?

Which Node to use for certain features is part of the journey of discovery I'm looking forward to, but currently I'm mentally stunlocked with the concept of using the correct parent node.

Questions rattling in my mind currently sound like: "Do I make everything Node2D and then add the appropriate child nodes every time? That didn't seem to be the case in the tutorial" / "Do I make a "main.tscn" that uses the Node2D option as the parent and then all of my other scenes skip straight to "Other Node > [correct node like TileMap]" as the parent which I then add to main.tscn?"

\$\endgroup\$

2 Answers 2

2
\$\begingroup\$

tl;dr: Use the generic Node2D, Node3D, Control or Node as root, and worry about it later.


I should clarify that scenes in Godot are bundles of Nodes you reuse. Which includes what you might call props, prefabs, and so on. For example, an enemy unit might be an scene.


When you are creating a new scene Godot will ask you if you want to use Node2D, Node3D, Control (user interface), or "Other" (which lets you pick, but defaults to Node).

By the way, there is another way to make an scene worth noting: you can pick a child and then use the option "Save Branch as Scene" from the context menu of the Scene dock. The option will allow you to create a new scene with that node as root and with its children, and in your current scene you will end up with an instance of the new scene.

Please be aware that what you pick as root of the scene is not final. You can use the "Change Type..." option you find in the context menu on the Scene dock to change it. Or you can use the "Make Scene Root" option from the same menu to promote a child to root of the scene.

Thus: you don't need to overthink this ahead of time.

Having a generic Node2D, Node3D, Control as root and then having more specific child might be a little overhead but usually not something to worry about.

The stronger argument is how you will use the instances of the scene. As Godot is not very good it easing access to scene internals. Note: the "Editable Children" option from the context menu in the Scene dock will allow you to see, add and edit the children of the instantiated scene.

You might find that as your scenes become complex it might not be clear which node should be root, but regardless of which you pick you need code to reach other nodes. In that situation it makes sense to use a generic root and give it an script that eases access to what you need where you instantiate it.


What I do is start with the generic Node2D, Node3D, Control, or just Node if none of those make sense. Then add children of specific types. And if it makes sense to make any of them the root, I'll use the "Make Scene Root" option. Of if it makes sense to make some of them a new scene I'll use the "Save Branch as Scene" option.


I'll describe something more advanced here...

As you know, you can change the scenes with scene tree methods (e.g get_tree().change_scene_to_file(…))… I don't do that at all. Using those requires using autoloads to keep data from one scene to the other, and it is an obstacle to make scene transitions (you can take control of the process by using an autoload that does the right thing).

Instead, I find it is easier to make main scene root a Control or a Node. Then I can use ViewportContainer or CanvasLayer to separate the game world from the UI. And I would create game world scenes of type Node2D or Node3D depending the game. In the main scene I would add a script with code to switch game world scenes, or load and unload multiple at the same time (e.g. have the world loads as you explore), and I would use background loading (ResourceLoader.load_threaded_request) to avoid hiccups.

So my answer for the main scene is: neither Node2D nor something more specific like TileMap.

\$\endgroup\$
1
\$\begingroup\$

In general, there's not necessarily a right answer for selecting one over the other in Godot. There's probably a measurable typically negligible performance impact to adding an extra layer of indirection in the scenes. But to my in mind, selecting one over the other is largely a matter of selecting the relationships that make it easier to manage the complexity of developing the game.

To me, using the primary "idea" as the parent node type is represents an "is a" type relationship whereas including one node as a child of another represents the "has a" relationship (also known as composition). And keep in mind that TileMap and Sprite2D (and any other node of the 2D category that I bothered to look up) inherit from Node2D. Since they are already specialized versions on Node2D, they have a built in "is a" type relationship with Node2D.

In Godot, I almost always lead with the main idea of a thing to select the "is a" relationship for the parent node. For the player and enemies I used KinematicBody2D, for hit boxes and hurt boxes I used Area2D and so forth because that's how I think of them. The player isn't 2d node with a kinematic body attached to it, it is the kinematic body. This also saves me the the extra mental overhead of needing to dig an extra layer into everything to get what I need. By that I mean since the player is a KinematicBody2D I can call move_and_slide(..) directly. If I used the "has a" relationship I would need to first "get" the KinematicBody2D that belonged to the player.

Sometimes though there's not a clear idea. Usually this happens for more abstract concepts that are a collection of things, none of which is more the main idea than the others. An example might be an explosion effect consisting of a sound, sprite & animation player. None of those parts better represents the idea of the explosion effect more than others. So in that case I used a Node2D and added the other nodes as children. Another example is the "main" or "world" scene. It's more a collection of stuff than it is the embodiment of one particular thing or idea. For that I would use Node because it doesn't need the position, rotation, etc that comes with Node2D.

Disclaimer: I've only used GDScript with Godot. One of the other bindings might lead me to a more composition heavy design as that's tended to be my preference with other engines / frameworks.

\$\endgroup\$
1
  • \$\begingroup\$ I didn't refresh before posting & didn't see the other answer until just now. While I do what I do, I also agree with the many excellent points made by @Theraot. \$\endgroup\$
    – Pikalek
    Commented Nov 17, 2023 at 18:20

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .