This weekend I’ve been switching over to a entity/component based architecture for managing units. So far, I like it. Perhaps it’s just because I’m re-writing portions of the code, but the entity/component system is so much cleaner than the inheritance system. This should make units in game far more expandable and end user customizable. My system is pretty similar to the some other entity/component systems out there, it’s broken up into:
Entities:
Pretty much just the containers that get passed around. These have unique IDs that distinguish them from other entities.
Attributes:
The data parts of entities. Things like Health, Position, Motion, Model,Inventory and much more. These are added to the Entity containers to create a unique class of unit. Typically these attributes don’t do much in the way of functionality, beyond just basic logic. Using Health as an example, it has two ints: currentHealth and maxHealth. Some basic logic would be checking to see if health is below a critical level or zero. As an example of how these are used to create entities, something like a
spore plant would get Health, Position, Model and Attack attributes. While a goblin would get all those plus Inventory, Motion and more. This allows for so much flexibility when it comes to creating units. With the inheritance system I’d have to either find some common unit for both spore plant and goblin to inherit from, or one of them would have portions of themselves that would never be used.
Behaviors:
These are entity processing centers. Behaviors cycle over all the entities looking to see if they have the attributes required for a particular behavior. For example, the path following behavior. An entity has to have Position, Motionand Path attributes in order to follow a path. If an entity has all those attributes then the path following behavior can act on that entity. It’ll take the entity’s Path attribute to see where the next way-point in the path is, then update the entity’s Motion attribute to have it moving in the direction of the next way-point. Later another behavior handles updating the entity’s position based on the movement attribute.
I got it to the point where it’s taken over unit rendering and path following. Having a nice clean system like this make it much simpler to add new functionality. So when I add in combat I just have to create an attribute and behavior for it. Then add the attribute to the entities that engage in combat, and everything else is taken care of. Really nice.
While implementing this entity/component system, I threw in a system for loading brand new entities from text files. This means that end users can take existing attributes and mix them to create a new type of unit. Even allowing you to define the model, texture and animation! Obviously this makes things easier for me too, so Win-Win.
Unit rendering using the new entity system, with no visible difference from before!