-
Notifications
You must be signed in to change notification settings - Fork 22
Gestalt Entity System Quick Start
The core elements of an entity system are:
Entities are identified objects. They have no behaviour or data of their own beyond their identifier, but are composed of Components.
Components are data objects that define the state of an entity. Each component implies a behaviour - a Physics component would imply the entity is affected by physics, a Sprite component would imply it is something that can be rendered in 2D, a Health component would imply the entity can be damaged. Each component then contains configuration and state about that behaviour - a health component may define the maximum health the entity can have (configuration) and its current health (state).
Systems process entities and components in order to produce desired behaviour. There's no strict standard for what a system looks like, although a typical system may process all entities with a particular type of component or set of components every frame. For example, a health regeneration system may iterate all entities with a Health component each frame, restoring a small amount of missing health based on a regeneration rate on that component.
Events are signals that can be sent against an entity. Systems can register to react to events based on the types of components the receiving entity has. For example, a Damage event could be sent against an entity when a situation would cause it to be damaged - such as landing at high speed or being shot. A system could subscribe to this event for entities with a Health component in order to apply that damage to the entity. Another system could subscribe to the event to make a damage sound based on a EventAudio component.
Prefabs are recipes for creating entities. A prefab may be for a single entity, or for a collection of related entities. For example, a vehicle might be comprised of a main entity for the vehicle, an entity for each wheel and an entity for an attached turret.
Components types are defined as classes implementing the Component interface.
public final class HealthComponent implements Component<HealthComponent> {
private int maxHealth = 100;
private int health = 100;
public HealthComponent () {
}
public HealthComponent(HealthComponent other) {
copy(other);
}
private int getMaxHealth() {
return maxHealth;
}
private void setMaxHealth(int value) {
this.maxHealth = value;
}
private int getHealth() {
return health;
}
private void setHealth(int value) {
this.health = value;
}
public void copy(BasicComponent other) {
this.maxHealth = other.maxHealth;
this.health = other.health;
}
}Component classes must implement a copy method. They may optionally implement a copy constructor in addition to an empty constructor. The copy method is very important - gestalt entity system copies components into its entity stores and then copies them back out when requested, so any value that isn't copied will be lost. Copies should be deep, so that components do not end up sharing references to mutable objects.
Some general rules when implementing components:
- Component should generally not inherit other components. For instance, you should not have a SpherePhysics component inheriting a Physics component. Rather, you would have a SphereCollider component and a Physics component, and behaviour would be driven by an entity having both. Remember entity systems are a compositional approach, not inheritance driven.
- Components should not reference other components. They may reference entities (via EntityRef) and component types (via Class<? extends Component>).