How to get stats to affect Classes/Components? and which approach should I use?

Godot Version 4.7.1

So I’m in the process of figuring out what things should be in a class and what things should be Components.

For example, I want an Entities speed stat to affect how fast they move or their strength stat to affect how much damage they do. From what I understand I would need to put any node that controls movement or attacks as a child of a node with the stats inside of it.

Stat Parent

@export_group ("Stats")
 @export var Strength_Stat =: 10
 @export var Speed_Stat =: 10
 @export ...

Movement Child

@export var Move_Speed =: 8.0*(1+(Speed_Stat/10))

Attack Child

@export var Attack_Damage =: Weapon_attack+(Strength_Stat/2)

So would I make a “Stat Sheet” Class and have any Entity inherit that while movement and attack are components?

or
Do I make a “Stat Sheet” Component then have attacking and movement lumped into one class that pulls the variables from the component?

or

Do I just do Composition or Inheritance and not worry about using a mixture of both? I am quite new and I understand each one has it’s own uses but I’ve never taken a computer science class in my life and a friend of mine only has resources in German

I feel I’m just a couple of steps away from Tutorial Hell xD I understand that this kind of thing has more to do with coding efficiently/neatly than actually coding but I wanna make sure I get this right early in my project so I don’t end up in a mess later down the road. (I keep dreading I’ll become a Yandere Dev)

Also, what kind of node would I put the stats in? would it be a Character3DBody since Godot can’t Inherit from different kinds of nodes and I want stats to affect the movement or some kind of Control Node? I am programming what I want in theory just trying to figure out the order of things. I would need to adjust the stats between entities and in the case of the Player Character and co, They’d need to increase (I’m gonna iron out how later, xp or sphere grid or summin).

Thanks for reading, I understand people can write a full thesis on these things and spend years learning them but I’m on my 8th video of the day and making no progress

“Class” and “Component” aren’t opposites of each other.

The problem is that this can be as simple or as complex as your game requires.

For this case, you probably don’t need to introduce any additional inheritance. If you create separate classes/scripts for movement and attack handling, you’ll likely notice that there is very little overlap between them, so there’s no reason to introduce unnecessary abstraction just for the sake of inheritance.

Personally, I would separate things like movement and attacking into different classes/components and keep their responsibilities separate. Why? Because later you might want an entity that can move but cannot attack, or a stationary entity that can attack, like a turret.

But it really depends on the game you are making. Do all entities have static stats? Can weapons be swapped? Can movement speed change from equipment or buffs? Those kinds of requirements should influence how you structure it.

For a simple case, it could be as straightforward as:

Entity (CharacterBody3D)
│   └── holds a Stats Resource (damage, move speed, strength, etc.)
├── Movement (Node)
│   └── calculates movement speed from Entity.stats.speed
└── Attack (Node)
    └── calculates damage from Entity.stats.strength

But if you have run time changes in the stats, or an equipment system you might need a bit more:

Entity (CharacterBody3D)
│   └── provides the base Stats Resource
├── Movement (Node)
│   └── calculates movement speed from the current Stats.stats
├── Attack (Node)
│   └── calculates damage from current Stats.stats + weapon data
└── Stats (Node)
    └── handles runtime stats, modifiers, buffs, etc.

With this structure, Movement and Attack are optional behaviors. If an entity doesn’t need one, you simply don’t add that component.

The Stats component can also handle runtime changes without making the movement or attack code responsible for managing buffs, equipment, stat increases, and so on.

In both cases, you can use Resources for reusable data such as base character stats, weapon stats, or enemy archetypes.

I usually use simple Nodes for anything that handles business/game logic and doesn’t need a transform, physics, or UI functionality.

Edit:
I was partially wrong with the simpler structure. Movement and Attack shouldn’t need to know about Entity, because it’s goes against the general “signal up, call down” idea.

A better solution would be to let Entity wire its components together:

class_name Entity
extends CharacterBody3D

@export var stats: Stats

@onready var attack: Attack = $Attack
@onready var movement: Movement = $Movement


func _ready() -> void:
    attack.set_stats(stats.attack)
    movement.set_stats(stats.movement)

Then Attack only knows about the data it actually needs:

class_name Attack
extends Node

var _strength: float
var weapon_damage: float = 120.0


func set_stats(strength: float) -> void:
    _strength = strength


func calculate_damage() -> float:
    return weapon_damage + (_strength / 2.0)

Now Attack doesn’t care whether it belongs to a player, enemy, turret, or something else. It only receives the data it needs.

The same applies to Movement: the parent/entity can provide its movement-related stats, while the component remains independent of the entity that owns it.

Disclaimer : I’m old; this is where I come from…
I started in ‘IT’ with the invention of DTL logic circuits, working on hybrid systems for calculating how to weigh cigarettes being manufactured. Time passes; micro-circuits arrive, with the Sinclair Calculator, the ZX, Atari 68K ASM programming, then databases, OOP and RAD (Rapid Application Development…) for industrial production systems. Now retired, I keep my modest hand in with Blender and Godot after RPG Maker. I have never attended programming theory courses, only for dedicated software for Production Management.
All this to say that, in the several years I’ve spent doing modest games for my own education, I have no formal knowledge concerning Components, Classes etc. Certainly very useful for those embarking on a development career, but not necessary for producing working games when starting out as a hobby or personal interest. There is merit in not over-thinking these theories and practices; they are apt to evolve over time (sometimes very rapidly…); one’s own experience gained from having constructed anything, anything at all, is invaluable, and not at all a waste of time. My own Dungeon Master, with a myriad of animated creatures, several Levels and all sorts of enigmas and puzzles is still growing, from its original ‘one room, one exit’ to the current ‘castle’ has been, and continues to be, built from simple scripts at first, modified as the needs, my ideas and my modest knowledge dictated. I pose my questions here, when I’m at a loss, and thank those that have always responded by sharing their wisdom, thus increasing my own. I’ve recently ‘invested’ in a couple of books on the subject of best practices and components, and will assimilate what I can from the giddy heights enounced within; meanwhile my creatures roam around my dungeon floors, unaware of any future ‘optimisations’ that may befall them.
All this to say : it’s fine to think of the ‘correct’ way to do stuff, and probably even better to actually do things the ‘correct’ way, but, to me, it’s more important still to actually ‘do’ stuff; that’s the way forward, even if that means returning to re-work things when better methods are mastered later on. Code whatever you have in mind in the best way you currently can and move forward. Get it working, ‘warts’n’all’, and go on to the next challenge. Each Project, even small ones, finished, is a win, however neat and tidy (or not…) the code. There’s a whole lifetime ahead to refine, improve, learn and apply theories and methods, but it only makes sense if ‘stuff’ is being done at the same time.
Apologies for the long post/rant; hope this helps (but it’s doubtful…).
Have a great day.

Thank you so much :stuck_out_tongue: I really appreciate this. I’m making an rpg so I guess I’m using all of it xD

If I’m understanding it right, A class can be a component so I can use the character 3D body to store all the variables then any of the classes I put underneath will use those variables. I was under the impression that components had to be kind of simple and the same type of node and that specifically movement had to be on the 3Dbody node but thinking on it that doesn’t make sense.

Then when it comes to organizing the code I can just have 1 folder containing all the parts rather than one for classes and one for components.

I also would have never thought to separate out the buff/debuffs either. Having a “stat warden” would stop any weird instances of stats not resetting themselves or multiple buffs and debuffs needing to be calculated in every part

Also thank you for the additional notes I would of had to look at some additional tutorials but you read my mind.

A component just means an object is being used as one part of a larger object. It’s an architectural role, not a special kind of class.

For example, ignoring Godot for a moment (become the one class/file approach ain’t gonna help use here):

class Movement:
    def move(self):
        pass

class Entity:
    def __init__(self, movement: Movement):
        self.movement = movement
    def do_something(self): self.movement.move()

Both Movement and Entity are classes.

The Movement object is called a component because the Entity is accept it, and use it to build a more complex system by using it.

Then when it comes to organizing the code I can just have 1 folder containing all the parts rather than one for classes and one for components.

If you say this because my “folder structures”, that was the Scene hierarchy, not folder a structure.

right so thats why godot is weird. Whenever I mentioned I was programming on Godot I got some funny looks from computer people.

also I’m aware that it wasnt a folder structure but thank you for clarifying either way. I would lose my head if it wasnt screwed on so I was just saying about staying organised (I had separate class and component folders so I was getting myself in a mess with it)