Component Based Engine design
Besides making tutorials I am also working on my own project. It is my biggest one yet, but I think I have enough knowledge to get at least really far. Right now I am building my own engine on top of Leadwerks 3. The entire project is written mainly in C++.
Component Based engine design.
Since Leadwerks is very flexible you can do a lot of different things with it. The Lua scripts in the editor are a good example of component based design. However if you switch to C++ you don't have this directly at your disposal for C++. That means you would have to implement it yourself. Of course there are tons of ways of doing this but this blog shows how I do it in my project.
Instead of Component Based Design you can also choose to go for 'Direct programming' like Josh describes in his blog here. Both approaches have their pros and cons. The reason I am going for Component Based Design is because I want to create code that is highly flexible and can be interchanged between projects.
The GameObject class
The current system that I have is a combination of direct (hierarchical) and component based design. The following image shows how it starts.
The first class is the GameObject. The gameObject is completely empty at first, meaning it doesn't contain any models or textures. The only thing that it contains are components. Every frame all the updates that are enabled are being updated and/or drawn. This is the core of the component based design. Lets say we create a Player Gameobject. We can add several components to it:
- ModelComponent
- WalkComponent
- JumpComponent
- FPSCameraComponent
- HealthGUIComponent
Now lets say for instance that we want to have TPSCamera instead of a FPSCamera. All we need to do is remove the FPSCameraComponent and add a new TPSCameraComponent. Not only is this system very flexible, it allows us to create components that can be easily shared throughout your project and perhaps even other projects that also use this component based design.
The Component class
Every component is derived from the Component class. The component class itself is abstract and thus can not be instantiated.
Increasing complexity
When you look at the first 2 images, you will notice that some functions and variables are exactly the same. Most programmers will come to the conclusion that this is a bad design. So for that reason we enhance our design as follows:
This means that a GameObject is also a component. The complexity hereby increases but works a lot better when it is properly integrated. (Note that the images are toned down a bit to simplify the idea.)
It is debatable whether GameObject inherits from Component instead of the other way around. I decided to go for Component since it is called a Component Based Design and not a GameObject Based Design.
FSM and Components
At some point I came to the conclusion that it is not always necessary to create an entire component structure to get the desired hierarchy in a level. For instance in a menu it is easier to create a (finite) state machine rather then having to switch between components. Although components work perfectly well for menu's, I think it is a good principle to think about where to use FSM's and where to use Components.
The Scene class
The component based design is far from finished but the basics already work. The last thing that I show in this blog is the scene class. The scene class inherits from GameObject (and thus also Component) and contains a list of Components/GameObjects. Every gameObject that is created needs to be added to this list in order to be updated or drawn. I specifically want a scene to have a camera so that I allways know that when I load a new scene, a camera is being created.
Thanks for reading.
Jorn
- 2
19 Comments
Recommended Comments