CBES – Entity Manager and Co.

In the last post about Component-based entity systems I talked about the way you can structure your project if you are using CBES. Now it’s time to start diving into the guts of our implementation to see how it works behind the scenes.

I’ll start with some of the work horses of our framework, namely the Component, Entity and Blueprint managers.

Storing components

All data in CBES is stored in components. Each component belongs to an entity. The component managers do the mapping between the entity identifiers (simple integers) and the components. Each component manager takes care about one specific component type. So in the end a component manager is not much more than a fancy dictionary:

Interface for entity creation

While working with components, you won’t work with component managers directly. Instead the access is conducted through an Entity Manager which is unique in a game. To add/get/remove a component, there are according methods:

Furthermore the Entity Manager allows to easily create and initialize whole entities from a blueprint (see below) and a configuration of initial data:

Blueprints and how to store them

Blueprints are templates for entities. A blueprint contains a list of component types the entities will have and an attribute table with default values:

The main advantage of having blueprints is that they can be created from data, so entities doesn’t have to be created from code. A blueprint can be easily stored e.g. as Xml:

To take care about all the blueprints of a game, there’s a Blueprint Manager which stores each blueprint under a unique string identifier. Like the component managers, the Blueprint Manager is not much more than a fancy dictionary, too. Beside the access to available blueprints, it also allows to read/write blueprints from/to Xml.

Furthermore a Blueprint Manager can be setup hierarchically to assemble the one manager which is used for a game from multiple specialized managers:

Creating an entity

With those managers on board, we have some easy ways to create the entities in our game. Let’s start with the most basic way, creating an entity and adding its components via code:

CreateEntity returns a new, unique id which can be used for an entity. Each AddComponent call creates the component of the specified type and connects it with the specified entity id. The created component is returned, so you can set its data.

If you have entities which are created more than once (e.g. for projectiles), you should create a blueprint once and use it to do the whole creation and initialization process for you:

You can pass a configuration as well to overwrite any default values the blueprint has defined (e.g. initial position/rotation). Furthermore the blueprint doesn’t have to be created in code, but received from the Blueprint Manager which might have loaded it from Xml:

Conclusion

As you can see, there’s not much magic behind the basic parts of our CBES implementation. But it makes up a pretty solid foundation to build upon and the game-specific parts can be completely moved to separate (component) classes and (Xml) data.

This way we didn’t have to make any bigger changes to the core of our framework for the last projects and see no need to change it for the upcoming ones, too. Maybe some refactoring and optimization, but the basic architecture should remain.

In the next part in two weeks, I’ll talk about the parts which use and modify the data of the components: the game systems. If you like to have a look at our full implementation, let me know and I’ll give you access to our repository to check it out in detail.

If you have any questions or suggestions for improvements, a comment would be great! Or maybe you have already written a CBES implementation on your own? I’m always looking for experiences from other programmers to learn from.