So, I've read various tutorials that talk about Objects, I understand they are more lightweight then Nodes, however, I assume you can't/don't want to use them for everything.

My specific use case where I am debating Node vs Object is for my Ship class. The ships get instantiated by either the players UnitController, or the AIController. They are mainly used to hold a sprite and a crop ton of variables that will be changed by the controller parent (movement, health, special ability CD etc...). They are accessed primarily in the scene via a group that they are added to when they join the scene, so it is easy to reference them. They will be being referenced a lot, by various Nodes (move, attack, select, turn_order etc...). They will also need to be able to have their data saved and retrieved for later levels.

Is this a use case where Object is better than Node, there could be anywhere from 6-12 of these ships being instantiated and destroyed every level.

Thanks!

  • xyz, Toxe, and correojon replied to this.
  • xRegnarokx You should stay away from Objects, RefCounteds and other such computery stuff. The intended way to build things in Godot is by using scenes. You'd be well-off thinking only about scenes when figuring out the "big picture".

    A scene is meant to work as a specific thing in your game. If you were making a tabletop game, each thing that you can point a finger at and say - that's X, can and should be represented by a scene in Godot. Such things can be big (like a human player) or small (like dice). Complicated things (like a gameboard) can be assembled from many smaller things (like hexes, drawing cards, counters and figurines).

    So assemble your game from actual things and make each thing a Godot scene. Here's an example.
    Scenes for my game:

    • Map (single for level, many levels) - consists of other things listed below:
      • Hex (many, various types) - represents terrain, can hold a single unit
      • Unit (many, various types) - move and fight on hexes
    • Player (several) - commands units on map, can be controlled by human or AI

    You can see that in my breakdown I don't have any smart sounding abstract things like "controller" or "processor". The intent is to make those "real" things work as they would in the real world. The Player commands and passes/receives information, the Unit receives commands and moves or fights, the Hex displays terrain etc... Try to keep clear of programming and abstractions when organizing the project. Instead, model your system as if you were making it out of wood.

    xRegnarokx If it needs to go into the scene tree, then it must be a node. Godot can handle thousands of nodes before their "weight" starts becoming an issue.

      Also, most of the time you don't want to use Objects. Better use a RefCounted. That is only one step up from Object and not much more heavy weight, but provides automatic cleanup.

      xRegnarokx Do not work against the engine. Just use Nodes or instantiate scenes and make your life easier. Also no premature optimizations unless you benchmarked and measured it.

      xRegnarokx anywhere from 6-12 of these ships

      That's nothing. 😀 You will not notice any difference.

      xRegnarokx When you have such a big, general-purpose object/node/whatever you must always try to think if it can be broken down into smaller pieces. For example, you mention that ships have health, so you could create a custom "Health" node where you define all the variables and methods related to this: hp, take_damage(damage_amount), heal(heal_amount), die()...Your ships can be selected? Create a custom "Selectable" node that handles all this functionality. It will much easier to deal with your ships if you have these small, independent pieces than if you have a monolithic ship node that tries to do everything and mixes everything all at once. It will also allow you to quickly create new types of ships and give them these behaviours, or modifications of these behaviours, without breaking anything else.

        correojon Okay, my ships don't hold really any func, just variables. They are moved/selected/ordered/attack via other nodes giving them commands. They just hold variables in order for other nodes to change as they get damaged and as they move and such.

        Right now I have it like this...

        TurnControl(orders unit movement/activates) -> MyUnits(registers input and sends signal depending on input) -> ShipMove(Takes ship information and passes it to MapGrid) -> MapGrid(plots viable movement hexes, and sends the command to move back) -> ShipMove(now moves ship to the hex that MyUnit registered the click on).

        When I have weapons I plan on having those referenced possibly in a RefCounted, or some other way (haven't figured out what I'll use to implement that section yet.)

        So ship holds all the variables for itself, I thought that'd make it easier to save, maybe I'm wrong in my thinking.

          xyz Awesome, it is good to know about the scene tree aspect. So, it'd be better if they are custom resources that are referenced but not instantiated into the scene to maybe use a RefCounted?

          An example would be a reference to a weapon that doesn't physically exist in the scene tree but you want to pull data.

          xRegnarokx

          Resource might be a step better than RefCounted for data objects. You can embed them in the scene or save them in res//.

          xRegnarokx You should stay away from Objects, RefCounteds and other such computery stuff. The intended way to build things in Godot is by using scenes. You'd be well-off thinking only about scenes when figuring out the "big picture".

          A scene is meant to work as a specific thing in your game. If you were making a tabletop game, each thing that you can point a finger at and say - that's X, can and should be represented by a scene in Godot. Such things can be big (like a human player) or small (like dice). Complicated things (like a gameboard) can be assembled from many smaller things (like hexes, drawing cards, counters and figurines).

          So assemble your game from actual things and make each thing a Godot scene. Here's an example.
          Scenes for my game:

          • Map (single for level, many levels) - consists of other things listed below:
            • Hex (many, various types) - represents terrain, can hold a single unit
            • Unit (many, various types) - move and fight on hexes
          • Player (several) - commands units on map, can be controlled by human or AI

          You can see that in my breakdown I don't have any smart sounding abstract things like "controller" or "processor". The intent is to make those "real" things work as they would in the real world. The Player commands and passes/receives information, the Unit receives commands and moves or fights, the Hex displays terrain etc... Try to keep clear of programming and abstractions when organizing the project. Instead, model your system as if you were making it out of wood.

            xyz Awesome sounds good! Yeah, I have been trying to simplify my code, where I have a node handling each unique action.

            Example:
            TurnControl - starts move turn and attack turn
            ShipMove - moves ships
            MapGrid - handles data to give to other nodes for map coordinates, and calculates eligible tile for movement, attack ect..

            So, I have been trying to simplify as well as streamline the communication between nodes.

            • xyz replied to this.

              xRegnarokx Those are again some abstract functionalities you for some reason want to ascribe to random nodes. Why? Your TurnCotrol and ShipMove are not things. They are bureaucratic go-betweens that have no reason to exist in a well designed system. Turns are controlled by players, and ships are moved also by players or by themselves following the orders from players.

              So instead nodes named TurnControl and ShipMove, you need to have scenes named Player and Ship. These will represent exactly those things.

              Each scene will have to have a script attached to its top node. This script should contain functions that perform actions that the thing is capable of doing. So, for example the Ship thing may have functions like: move_to(), attack(), take_damage(), set_weapon(), get_hitpoints(), etc...

              Now the Player thing can communicate with any Ship thing by calling these functions. It can order it what to do or check its status. Just like a player in a board game would do with their units on the board. In object oriented programming we call those functions an "interface". It's the means by which other things manipulate that thing.

              In the above example, the Ship thing is autonomous. It can perform actions that Player requests of it but Player doesn't need to know how exactly the Ship does it. The Player need not to care about any nodes inside the Ship. It just has to call functions provided in Ships' "interface" and reap the results. This greatly simplifies Player's life. In other words, each thing keeps the details of its inner working to itself, making it self-contained and thus easier to maintain and repair if it breaks down. In object oriented programming, this is known as "encapsulation".

                xyz You should stay away from Objects, RefCounteds and other such computery stuff. The intended way to build things in Godot is by using scenes.

                (If you use the default SceneTree. But mentioning custom MainLoop is probably a bit too much and off topic here, still may be worth being aware of it...)

                • xyz replied to this.

                  Megalomaniak My answer was specifically for OP, after seeing what they struggle with through half a dozen previous question threads they started.

                  That being said, I'm not sure it would be worthwhile to go with a custom main loop from GDScript. You'd need to maintain some alternative system to organize all scene data. This sounds like a lot of per frame iteration. GDScript may have hard time keeping up the performance there.

                    xyz That being said, I'm not sure it would be worthwhile to go with a custom main loop from GDScript.

                    Yeah I recon it makes sense via C/C++ or perhaps Rust or something to that nature and only for a very strict need that the SceneTree can't cover.

                    • xyz replied to this.

                      xyz Okay, so I was trying to have nodes that controlled each aspect rather than have a massive code that controls everything.

                      So I should control everything related to the ship directly within the ship node, and call the func with the parent node.

                      Where would I place my tile map in relation? As the parent node? Also, what would my structure look like with UI for ships, would that be as children of ships? I guess my structure was designed trying to prevent having a lot of signals calling up and callbacks to transfer needed data, as well as hige quantities of code held in each node. I tried to use my parent to connect and give the parameters for when to start a phase. Then use the nodes for specific actions (move, attack, UI, AI, camera etc...). So, I guess I've either been reading counterdictory things about structuring or am misunderstanding good structure.

                      So would you say it should be tilemap->player->ship->shipUI/shipcomponents
                      Where would I put AI node, gameUI, and camera ect...

                        Toxe I have read it, I'll try reading it again with what people have said here in mind so make sure I am understanding it.

                        xRegnarokx You're constantly mentioning nodes, but you never seem to mention scenes. And all I was talking about in my previous long winded posts are scenes 🙂 Are you at least familiar with the concept of scene in Godot, and how to use scenes to create reusable game components?

                          Megalomaniak Yeah I recon it makes sense via C/C++ or perhaps Rust or something to that nature and only for a very strict need that the SceneTree can't cover.

                          I see it primarily as a way to create a system that completely circumvents nodes and tree-like organization of scenes, like ECS or something similar. Doing this would make a lot of editor functionality useless. That's one additional reason to do it via native code and just use Godot's servers and other useful classes like a framework. It would be nice to see a project that attempts this.