Reputation: 643
Most materials I read online about entity component systems seem to indicate that it is used to veer away from using inheritance. But what I want to know is, is it feasible to continue using inheritance alongside an ECS?
Let's say I have a specific number of entities in an engine that are going to have mostly the same functionality. For example, entities that are capable of moving. Is it then feasible to create a MovableEntity
object which adds the necessary components?
public class MovableEntity extends Entity {
public MovableEntity(int x, int y) {
addComponent(new PositionComponent(x, y));
addComponent(new VelocityComponent());
...
}
}
Upvotes: 3
Views: 4209
Reputation:
I hope you don't mind my blunt opinion, but with the way you are doing it, I think it's a bad idea.
First of all, are you just defining new component types just to construct them more easily? If so, you could just use like:
Entity movable_entity(int x, int y)
{
Entity new_entity = ...;
new_entity.addComponent(new PositionComponent(x, y));
new_entity.addComponent(new VelocityComponent());
...
return new_entity;
}
And this might just seem like a stylistic difference, but it exhibits looser coupling when it doesn't involve inheritance.
Second, if you are going to actually add new state to MovableEntity
that Entity
doesn't have, that makes it so your entities are no longer uniformly-sized, we can no longer effectively represent all entities contiguously in memory with straightforward random-access, and they also possibly become prone to object slicing (ex: cloning an Entity
out of a movable one when the desire was to clone a MoveableEntity
).
So for entities at least, I really think you'd be better off not extending them. I could see more of a use case for inheritance of component types, though I still recommend against it because ECS is so flexible in terms of how you access components that polymorphism through component base types isn't needed. You can just use composition if you want to reuse data fields of one component in another.
Inheritance adds a competing kind of model to the ECS which doesn't jive so beautifully, unless you're just doing it to make it easier to construct a particular type of entity with a particular set of components which, again, can be accomplished with a simple function without introducing a whole new entity type.
Upvotes: 3
Reputation: 21
While not standard I have found this practice very useful. Imagine a game where a warrior has HP, attack and defense. You could write a stat component that takes an enum and a value. Another way would be to have a component that holds other entities and make each stat an entity itself with a value and type component. I tried both of these and I didn't like the early results. (The latter worked fine but it was really convoluted, but it does strictly adhere to ECS design)
In the end I made each one a StatComponent which inherited from Component. This meant that I could perform operations common to all stats which was very convenient. The trick is to make each bit of OOP you stick in a bubble. As long as it is self contained I don't see any major issues.
Upvotes: 1
Reputation:
If you don't require components to be added/removed dynamically to/from your entities, inheritance can be used to define entities (in languages with multiple inheritance). Consider the following example ECS from Evolve Your Hierarchy:
Your components would correspond to classes:
and your entities would correspond to classes:
Upvotes: 1