use best of two worlds! Those are only concepts and tools in your work. I usually prefer using simple inheritance no more then 1-2 level deep and totally fine and ok with it. Basically it's good for thin abstraction layer, implementing really common and basic routines.
UIButton -> UIButtonUpgrade
UIButton -> UIButtonConfirm
UIMenu -> UIMenuSkills
Composition requires more mental work and planning. I'm writing a game on ecs and we have more than 60 components right now ( in C# ) and average setup for an object looks like this
protected override void Setup()
{
entity.Set(tags.ally);
var cobject = entity.Set<ComponentObject>();
var cmotion = entity.Set<ComponentMotion>();
var canimator = entity.Set<ComponentAnimator>();
var crender = entity.Set<ComponentRender>();
var ccollider = entity.Set<ComponentCollider>();
var cplayer = entity.Set<ComponentPlayer>();
var chealth = entity.Set<ComponentHealth>();
var carea = entity.Set<ComponentArea>();
//// Weapon
cplayer.weapon.source = db.weapon[db.weapons.gun];
cplayer.weapon.muzzle = math.pixels3(29, -3, 0);
cplayer.weapon.clip = 16;
Personally I DO prefer composition over inheritance but preferring is not versus, it's that I use composition for the most tasks and it took time for this mind shift.
So compositions aspects :
Nim. Nim is puuuuurrrrfect for all of this stuff. Really. Every day I cry for joy after finding this language. It reduces so much noise and boilerplate for me.
I've already implemented my c# ecs in nim ( and it took way less work ) and my workflow looks like this:
type ComponentHealth = object
val: int
type ComponentAI = object
type ComponentBurning = object
type ComponentAnimal = object
type TagAlpaca = object
ecs.add ComponentHealth
ecs.add ComponentAI
ecs.add ComponentBurning
ecs.add ComponentAnimal
proc newAnimal(): ent
result = entity()
result.add ComponentHealth
result.add ComponentAI
result.add ComponentBurning
result.add ComponentAnimal
var alpaca = newAnimal()
alpaca.add TagAlpaca
ecs.group burning_animals:
comps: (ComponentHealth,ComponentAI,ComponentBurning,ComponentAnimal)
app.start:
echo "blazing"
app.run:
for entity in burning_animals:
entity.chealth.val -= 10 * dt
if input.down escape:
app.quit()
app.close:
echo "alpaca"