The Entity System that will be part of Tetragon from version 1.1.0 (Centauri) on is a solution to get a consistent and flexible architecture into the engine that will manage all game objects. If you’re unfamiliar with Entity Systems (ES) I recommend to read these articles posted by T=Machine which explains the approach behind an ES very well. If on the other side you’ve already worked with a tool like Unity or another engine like PBE then you already used an Entity System because they are exactly that, with the difference that Entities are just called Game Objects in Unity and that the system works somewhat different in PBE.
Tetragon’s ES follows a truly separated architecture between entities, components and systems. It essentially follows the rationale that “A game is just a real time database with a graphical front end”. What this means is best explained by describing the three major parts of an ES and what they do …
An entity is a game object that has a role somewhere in your game (or application). Many things can be defined as an entity, here are some examples: a player or non-player character, an enemy space ship, a weapon, a med pack, a vehicle, a building, a country, a world, a galaxy, a magic spell, a skill (e.g in a role-playing game), a quest, a graphical user interface element … you see there’s almost no limit to what might be defined as an entity.
However there are sometimes decisions to make about what should be an entity and what not. Take for example a tile-based game. Would you want to make every tile an entity? You could but you have to ask yourself if this is really necessary. In Tetragon there are several ‘intermediate’ objects that are not entities, for example SpriteSets and SpriteFrames.
The way how entities are designed in Tetragon makes them almost essentially into flyweights because an entity is nothing more than a dynamic object with a unique ID, a few very small helper methods and a list of components which define the type of the entity (over at T=Machine he calls this ‘aspect’ though I’m not really happy with that term in this relation). All the logic that processes entities are in the systems (more about them below).
Entities are purely dynamic and don’t exist as classes. You have to somewhat rethink your OOP practices for them as there is absolutely no strong-typed implementation for any of an entity’s properties. The only place where you ever define entities (actually entity definitions) is in your entity data files. More about this later.
Entity components are the parts that define an entity so any entity has to possess one or more entity components. Components define what characteristics an entity has and by that they ultimately define what an entity can do and how it behaves. In most cases one component is responsible for only one aspect of an entity (uh, now I’m using that word too. Maybe it makes sense after all) but this is not a rule that is set in stone. Depending on the purpose there can be components that fulfill multiple aspects at once or are only used for a specific type of entity.
Some very basic examples for entity components would be for example the Spacial2DComponent that simply tells that an entity can have a two-dimensional position and rotation or a GraphicsComponent that determines that the entity has renderable graphics.
More specific types of components in Tetragon are for example the WorldSpaceComponent and the CellComponent. These describe properties that really only adhere to worldspace or cell entities.
Just like entities, components do not possess any logic. The only implementation they possess are properties for a specific aspect of an entity. They may of course have getter and setter methods though. Every entity component of a specific type also has a unique ID.
Systems are the most complex parts of an ES because they contain all the logic that processes the data of entities. A system often has a one-to-one relationship with a specific type of component but again this isn’t mandatory. A Render2DSystem is only able to render entities to the screen that possess a Graphics2DComponent whereas a Render3DSystem might be specific to only entities that represent a 3D graphics object. Another example would be an AIComponent and an AISystem that only cares about processing the A.I. of all entities that possess an AIComponent.
Most of the systems run permanently as long as they game runs but not all necessarily have something to do all the time (if that would be the case we’d be running into performance issues real quick). Rendering-related systems are triggered by the render loop while non-rendering-related systems are triggered by the game loop, for example A.I. processing which needs a lot less frequent updating than rendering.