I made a thread about entities
a while ago, and ended up using Artemis
. Now, I'm not going to say a component based system solves all your problems instantly, but you might want to consider using it depending on what you're planning to do.
The problem with inheritance is that you might want many different combinations of properties in many different object types. Consider this strategy game example:
- You have a worker unit. He has no weapon, but he can move.
- You have a turret unit. It has a weapon, but it cannot move.
This is easy to implement. Just create a Worker class and a Turret class and have them both extend AbstractEntity. The problem arises when you want to implement a warrior unit. He has a weapon, AND he can walk. Now, you cannot have him extend both Worker and Turret, so you can either make the Warrior class a "attacking Worker", a "moving Turret" or a whole new class. All 3 possibilities are introduce lots of problems. The first two simply go against the definition of their super classes + other problems, while the last one requires lots of duplicate code from both Turret and Worker. One solution to the problem is to restructure the whole object hierarchy, and make a MovingEntity class that extends AbstractEntity.
Entity - AbstractEntity - MovingEntity - Worker
| + Warrior
This doesn't solve the duplicate attack code between the Turret and the Warrior though, but the real problem is that it is extremely time consuming to do this restructure every time you want to add a new object type that shares some properties with other classes. What about an Archer class? A Mage class? It got extremely hard to keep it all manageable for me.
Component based systems differ a lot from hierarchical systems. Instead of having a base class which all objects extend, you have a single Entity class. This Entity class basically only keeps a list of "components" which are properties that the object has. The logic code can either be inside the Components (every Component has an update(delta) function) or in a separate class.
The idea is then to define the different components and compose different object types. To continue the above example, we could use the following components:
- Position: Keeps the position of the object as doubles (double x, y;). All objects will probably have this.
- Movement: Keeps the data needed for movement. This is highly dependent on the game type. In a physics simulation, you could keep the x and y velocity. You could also keep a target position and move towards it.
- Attacking: The ability to attack other units. Can contain damage, attack range, attack type, which targets it can attack, e.t.c.
With only these 3 components, we can easily implement the first 2 objects above:
- Worker = Position + Movement
- Turret = Position + Attacking
The final Warrior objects actually becomes just as simple and doesn't require any restructuring:
- Warrior = Position + Movement + Attacking
Now you might obviously need custom AI for each unit type, but it's easier to reuse components between unit types in my opinion. I am not saying that component based systems are better for every single situation, but I've found it easier and most importantly faster to work with. The choice is definitely up to you, though. You could go for either a hierarchical or a composition system, or even a hybrid solution, where some things are kept in components and other in classes extending Entity. You could remove the dynamic list from the Entity and instead add a little composition to solve a problem in a hierarchical system. A new example then: You have an infantry unit and a tank unit. Both have weapons, armor and the ability to move, but they move very differently as one is a vehicle. You could have a CombatUnit which extends AbstractEntity with all the stuff that is common over these units, but have a Movement component field that controls the unit's movement. It works just as well as a pure component system, but might be easier and faster to implement than a pure component based system.
Composition systems obviously have problems that hierarchical systems do not have. The biggest problem is probably the insane dependencies you might end up with. Maybe your Movement component's update() function needs to know where to go, and this depends on which components the object has. If it has an Attacking component too, it should run towards the nearest unit, but if it has an X component, it should do Y, e.t.c. Just like a hierarchical system has problems with getting the right combination of properties for a specific object type, component systems have the problem of spaghetti-like component structure where every component depends on every other component. This is obviously something you want to avoid at all cost.
Like I wrote above, I still decided to use Artemis (a component based system) for my strategy game. It has a last little quirk though; the logic is not inside the components. They only store data. I then have separate EntitySystem (as they are called in Artemis) which provide a list of matching Entities given certain component requirements. This obviously doesn't remove component dependencies, but it makes them a lot more manageable. Personally I think the code is more understandable and elegant.
TL;DR: Some tips/rambling on pros and cons of a hierarchical system and a composition based system.