Share your tips and tricks to keep your code as abstract and clean as possible in Godot 4 - eviltoast
This is an automated archive made by the Lemmit Bot.

The original was posted on /r/godot by /u/DuckinDuck_ on 2024-01-09 13:16:36.


As of lately I’ve been working a lot with Godot, starting a few weeks back, and I came to a point where I gathered some knowledge about how to keep my code abstract and clean so I can scale my projects.Started off understanding basic OOP (Object-Oriented Programming) concepts such as Inheritance and Composition and developed some confidence to talk about these here. (Feel free to correct me if there’s something off).

Inheritance

In object-oriented programming (OOP), inheritance is a mechanism that allows a new class (called a subclass or derived class) to inherit the characteristics and behaviours of an existing class (called a superclass or base class). This concept is based on the idea of “is-a” relationships, where a subclass is considered to be a specialized version of its superclass.

Inheritance facilitates code reuse and promotes the creation of a hierarchical structure in your code. The subclass inherits the properties and methods of the superclass, and it can also extend or override them as needed.

Here’s a practical example of the use of inheritance in a game development context:

Imagine you want to create a bunch of different enemies that behave in a somewhat similar way or have different attributes from each other, such as Health, Speed, Damage.You can create a base enemy node that implements most of your enemy behaviours, for example:

  • Walk towards the closest player. - func _walk_to_target(target)

  • Attack the player. - func _attack_target()

  • Wonder around if no target is close. - func _wonder()

  • Regenerate it’s own health. - func _regenerate_health(amount)

  • Take damage if hit by the player. - func _take_hit(damage)

This is the default behaviour for a base enemy. Now you can create new enemies that inherit the base enemy and give them different attributes and/or different behaviours, or even override the base behaviours so they can act differently from other.

For a melee squishy enemy, you create a new enemy inheriting the base enemy, and change the _walk_to_target(target) function so that it get’s closer to the target, and change it’s base health to a lower value and bump up its speed a little bit.

For a melee tanky enemy you do the same but give it more health and less speed.

A better way to this this is just creating a new inherited scene from the base enemy and change it’s _walk_to_target(target) function so that it get’s closer to the player. And then if you want to create new melee enemies, just make new scenes that inherit from this new subclass.

And boom, that’s inheritance 101.

Composition

Composition is another key concept in object-oriented programming (OOP) that involves creating complex objects by combining simpler objects or components. Unlike inheritance, which focuses on an “is-a” relationship, composition emphasizes a “has-a” relationship. In composition, a class includes objects of other classes as part of its own structure, allowing for the creation of more flexible and modular designs.

Imagine you want to add new objects that the player can hit and deal damage to them even thought they are not enemies, just neutral objects, like crates, or barrels etc. These objects will have a _take_hit(damage) function just like the enemies did.

Since you are defining the same functionality but for different types of objects you can utilize composition to make your code simpler and more abstract. Here’s how you do it.

Since every enemy and object will have a given health, you can create a Health component node that stores that objects hp and defines the _take_damage(damage) function that will make it lose health on hit and link it to it’s parent. Now you can just add this node to anything that you want for the player to be able to hit and deal damage to it.

And voilá, composition 101.

Feel free to ask any questions you want, or leave any corrections.

I’m creating this open thread so everyone can share their knowledge about abstraction and clean code in Godot and leave tips and tricks for beginner and advanced developers.