I've recently decided to revamp my game architecture to get rid of deep class hierarchies and replace them with configurable components. The first hierarchy I'm replacing is the Item hierarchy and I would like some advice to know if I'm on the right track.
Previously, I had a hierarchy that went something like this:
Item -> Equipment -> Weapon
-> Armor
-> Accessory
-> SyntehsisItem
-> BattleUseItem -> HealingItem
-> ThrowingItem -> ThrowsAsAttackItem
Needless to say it was starting to get messy and these was no easy solution to items that needed to be multiple types (i.e. some equipment is used in item synthesis, some equipment is throwable, etc.)
I then attempted to refactor and place functionality into the base item class. But then I was noting that the Item had alot of unused/superfluous data. Now I'm trying to do a component like architecture, at least for my items before attempting to do so to my other game classes.
Here's what I'm currently thinking for the component setup:
I have a base item class that has slots for various components (i.e. an equipment component slot, a healing component slot, etc. as well as a map for arbitrary components) so something like this:
class Item
{
//Basic item properties (name, ID, etc.) excluded
EquipmentComponent* equipmentComponent;
HealingComponent* healingComponent;
SynthesisComponent* synthesisComponent;
ThrowComponent* throwComponent;
boost::unordered_map<std::string, std::pair<bool, ItemComponent*> > AdditionalComponents;
}
All item components would inherit from a base ItemComponent class, and each Component type is responsible for telling the engine how to implement that functionality. i.e. the HealingComponent tells the battle mechanics how to consume the item as a healing item, while the ThrowComponent tells the battle engine how to treat the item as a throwable item.
The map is used to store arbitrary components that are not core item components. I'm pairing it with a bool to indicate whether the Item Container should manage the ItemComponent or if it's being managed by an external source.
My idea here was that I define the core components used by my game engine up front, and my item factory would assign the components that the item actually has, otherwise they are null. The map would contain arbitrary components that would generally be added/consumed by scripting files.
My question is, is this a good design? If not, how can it be improved? I considered grouping all components into the map, but using string indexing seemed unecessary for the core item components