Entity & Component Lifecycle
Component Hooks Recap
To remind, the basic lifecycle hooks on every component are:
The distinction between create
and init
specifically can be confusing, so it may be helpful to understand how the entity lifecycle works.
Lifecycle Overview
Creating an entity constructs instances of your components, but does nothing else:
At this point, no hooks on components are called, and the object hasn't been added to the game world.
When an entity is added:
The entity is moved to the created
state, and the create()
hook on components is called. The create hook can access sibling components at this point, but it depends on the order they were added in the components array.
In general, you should defer anything that depends on other components or entities to the init()
hook.
When an object is added, it is initialized on the next frame. This may change, but currently, it's done to make it easier to reason about adding entities. On the next frame, before any component's update()
hook is called, all added entities are initialized, meaning their init()
is called and all components are set up.
One nice guarantee from this is that if you add two entities on the same frame, you can safely reference one from the other in the first update()
tick. Of course, the flip side of this is that it's not necessarily so safe to reference each other in init()
.
Impact of Lifecycles on Component Access
In general:
Inside a component's
create()
, you should not reference sibling components or components on other entities created in the same frame, as they may not have been created yet.Inside a component's
init()
, you should not expect sibling components, or components on other entities created in the same frame, to have had theirinit()
methods run yet.
Of course, there are potential workarounds for this behavior. For example, you could defer initialization of some dependent property on a component until its first update()
:
This should only be done as a last resort - obviously, in this case, there would be several other ways to handle this, such as setting the string in create()
, or simply not copying the string and instead accessing it through AComponent
every time.
Last updated