Component Composition
Storing Data
In Frent, you compose entities using components. Components can be almost anything.
To create an entity from some components, you must use the World
class. Think of the World
like an optimized collection of entities.
In the example on the right, you can see the Name
and Species
component being used to create an entity. But components can do more than just store data - they can have behavior.
Adding Behavior
Implementing behavior in a component usually starts with some kind of a IComponent
interface. The most simple of these interfaces is, well, IComponent
. This interface requires an Update
method with zero arguments. Different IComponent
interfaces have different arguments for different purposes.
On the right, you can see the behavior of Name.Update
, but where is its output? Add a world.Update();
call after entity creation, which calls all Update
methods on all components in the world.
Component interfaces
There are many component interfaces, each with a different purpose, all with a Update
method. The main interfaces are: IComponent
, IEntityComponent
, IUniformComponent<TUniform>
, and IEntityUniformComponent<TUniform>
. Each interface name follows the scheme of I[...]Component
. The content inside the brackets tell you what arguments the component will have. For example, IComponent
has no arguments and IEntityUniformComponent<TUniform>
has two arguments (Entity self, TUniform uniform)
.
Try adding behavior to the Decay
component below such that the entity is deleted once the decay timer is over. You will need to change the interface used to IEntityComponent
to get access to the Entity
from inside the component. You can delete an entity by calling the .Delete()
instance method.
Interacting Components
A single component is boring. Components together strong. While you can use entity.Get<T>
to get components on the same entity to interact with, this method is verbose and slow.
To automatically inject a component value into the Update
method, simply add a generic type. IComponent.Update()
becomes IComponent<TComp>.Update(ref TComp)
. If you need another component injected, add another generic type.
Try modifying the Decay
component above to take into account DecaySpeed
when decrementing. You'll need IEntityComponent<T>
for this one.