Saturday, November 24, 2012

Component Systems

Over the course of this semester, a topic has been brought up between some groups regarding different ways to approach engine design. We wanted to come up with a way that we could make our engine flexible and provided a lot of functionality. One of the subjects of the topic went over something called a "Component" based engine. Before I go into what this system is I want to explain what I did last year for my 2nd year game.

UGC: 80 AD - Inheritance

In the code for our group's game from the last year, it used inheritance, a lot of inheritance. There would be a class called "Character" which had subcatagories of "Player", "Enemy", and further subclasses such as "EnemyFinalBoss", "EnemyLion" and such. The cool thing about this is that I could easily make put all of my Character objects into a list and update them all. All of them would have a "virtual" update function that could be inherited and overwritten so that specific characters could update to different parameters. For example the player character could update to increase his HP over time, while the EnemyLion would instead update his stamina or something of the sort.

If I wanted to access specific functions, I wouldn't be able to with the EnemyLion normally since he would be created as a "Character" class and insert into a "CharacterList". However if I really needed to I could "cast" it which forces my EnemyLion into an actual EnemyLion class temporarily so that I am allowed to access it's functions. Normally I would have only been able to access the character class.

Character class needs to pass in the four values on the right, but not every class under it has use for these

Now the problem with this entire structure while it sounds like it works well is that it was cluttered, unorganised and I had functionality and attributes in some classes that never even used it. For example, my Character class had a whole bunch of integers to represent health, damage, speed, etc, and some of the classes under it didn't always use them all. I had "Damage1 and Damage2" that were only used by the Player character but the Lion had to inherit both of these even though he only needed "Damage1". This happened for quite a few classes in fact since I needed to update these parameters all the time and check for them. This made the entire system clunkier than it needed to be.

Introducing Components

Now that I have covered the flaws of my engine last year lets talk about this "Component" System. Components basically mean that they are attachments to a base object class. So for example I create an object, it essentially has nothing inside of it. What I do to make it have functionality is attach "Components" to it. These components can literally be almost anything, they can represent a model, rigid body, health, damage, etc. This means almost any object can be anything and do anything, it makes for an extremely flexible system that allows a lot more freedom for the objects to perform actions.

For example I could attach a health component and damage component to the player but for an NPC that can't attack I will only attach the health component, or I might not even attach that since I probably won't need to hurt him. He would simply have his model and rigid body and perhaps some other component to trigger an event to talk with him. The skies are limitless with what you can do with these components.

With components we can attach any component to any other component. We can also make certain components interact with each other such as health to AI.

There are a lot more complex aspects of the component system that we haven't touched yet or learned but these are the basics of the system. We used a combination of inheritance and components, making a pseudo component system. We add a component list to each object. Each of these components is essentially a really empty class template that will be inherited from by the Health Component, attack component, etc. We simply override it to have the functionality we need and if we need to access specific functions, we simply cast it to the appropriate component type (i.e. Health component).

Final Thoughts

I don't want to reveal everything about our component system but that's basically a simple gist of how a real component system might work, or at least a pseudo component system. We hope to learn more about it because so far the results of the component system have been infinitely more flexible to use than with the old inheritance system. Essentially we can make any object do anything. I can make a key turn into an enemy and attack people, make it have an inventory and give it some gold to hold onto.