March 6, 2014
High Level Design: Entities and Components
Inside of each entity is a list of components that describe the entity. Each component is made up of a number of properties, and could be described as a list of mutable data. Components do not know anything about other components or types of components – they only keep track of their own data.
There are a number of benefits to using a component-based engine. First, it helps avoid monolithic programming by taking a modular approach. By breaking down entities into more manageable units, the engine, and games built on the engine, are significantly more understandable and easier to maintain. Second, using components eliminates the need to waste memory or duplicate code, as is demonstrated in the following example.
Consider how to build an entity that responds to physics and is renderable. One approach is to create a linear hierarchy that forces renderable objects to have physics, or forces physics entities to be renderable; this method wastes memory on entities that are renderable but don’t require physics. Another approach creates three separate subclasses of the basic Entity class, one for rendering, one for physics, and one for both; this method results in duplicate code. The final approach makes use of two components, a renderable component and a physics component, and attaches them to a simple entity object. Non-physical renderable entities don’t have unnecessary information about physics, and non-renderable physical entities don’t have unnecessary information about rendering. Furthermore, no duplication of code is required in the component model. This becomes extremely important as additional components are required. Rather than having a hierarchy of convoluted inheritance or giving every entity a number of unnecessary properties, using components keeps entities simple and flexible [http://gameprogrammingpatterns.com/component.html].
One obvious approach to implementing components is to split each entity up into parts that can communicate with one another via their parent entity and can communicate with other entities’ components using a list of entities in the scene. A rendering component, for example, could get position from the physics component of its parent. A collision component could look for the collision components of other entities by looking through all the entities on the active scene, then check for collisions with them. This hypothetical model, however, has a number of potential issues to address. There would be a lot of game loops running; the scene would propagate the loop to each entity, and each entity would propagate the loop to each of its components. Worse than that, there would be a lot of repeated comparisons; if there are 100 entities in a scene and only 10 have collidable components, each collidable will have to loop through all 100 entities to check which ones have collidable components. Components would also be tightly coupled; a renderable component would not function unless its parent entity had a physics component in the given example, but it might not be apparent until a runtime error is thrown or strange behavior is observed.
All of these issues can be resolved by stripping out all logic from the components. This reduces components to nothing but data – a list of data, just like entities are lists of components. The logic is moved into the final part of the entity component system model – that is, systems – which will be examined in a future post.