Adding and removing components during runtime
During runtime, a worker instance can request SpatialOS to:
- add a component to an entity using
Worker_Connection_SendAddComponent
- remove a component from an entity using
Worker_Connection_SendRemoveComponent
In order to use these functions, you must set Worker_ConnectionParameters::enable_dynamic_components
to 1
(true).
Non-existent components
This feature introduces the concept of non-existent components. A non-existent component is a component which can be added to an entity but is not currently on the entity. In other words, a worker instance has write access authority over the component, but the component is not currently on the entity in the game world.
Write access authority over non-existent components works the same as write access authority over existing components.
Authority change and component state synchronization
When you set Worker_ConnectionParameters::enable_dynamic_components
to 1
(true), worker instances will receive an Worker_AddComponentOp
or Worker_RemoveComponentOp
(instead of a Worker_ComponentUpdateOp
) when the worker instance gains or loses write access authority over a component.
This is to synchronize the worker instance’s local view with that of the Runtime.
Immediately before a worker instance gains write access authority over a component, the worker instance receives either:
- a
Worker_AddComponentOp
(if the component exists) - a
Worker_RemoveComponentOp
(if the component is non-existent)
Likewise, after losing write access authority over a component, the worker instance receives either:
- a
Worker_AddComponentOp
(if the component exists) - a
Worker_RemoveComponentOp
(if the component is non-existent)
Worker_AddComponentOp
and Worker_RemoveComponentOp
must be treated in an idempotent way. In other words, if the worker instance receives:
- a
Worker_AddComponentOp
, you should replace any existing state for the component in the worker instance’s local view withWorker_AddComponentOp.data
- a
Worker_RemoveComponentOp
, you must remove any existing state for the component in the worker instance’s local view
The following table summarizes the ops and the order in which the worker instance receives them:
Existing component | Non-existent component | |
---|---|---|
Gaining write access authority | 1. Worker_AddComponentOp 2. Worker_AuthorityChangeOp (kAuthoritative ) |
1. Worker_RemoveComponentOp 2. Worker_AuthorityChangeOp (kAuthoritative ) |
Losing write access authority | 1. Worker_AuthorityChangeOp (kNotAuthoritative ) 2. Worker_AddComponentOp |
1. Worker_AuthorityChangeOp (kNotAuthoritative ) 2. Worker_RemoveComponentOp |
Example
Imagine you have a component which is used to temporarily give super strength to a player:
component SuperStrength {
id = 2345;
int32 power_level = 1;
}
Example of adding a component
This example assumes that you have followed the serialization reference to create a Worker_ComponentData
for SuperStrength
.
The worker instance which has write access authority over the SuperStrength
component can add it to the entity:
void add_super_strength_component_to_entity(Worker_Connection* connection,
Worker_EntityId entity_id,
Worker_ComponentData* super_strength_component_data) {
Worker_Connection_SendAddComponent(connection, entity_id, super_strength_component_data,
NULL /* short-circuit */);
}
Example of removing a component
The worker instance which has write access authority over the SuperStrength
component can remove it from the entity:
void remove_super_strength_component_from_entity(Worker_Connection* connection,
Worker_EntityId entity_id) {
Worker_Connection_SendRemoveComponent(connection, entity_id, 2345, NULL /* short-circuit */);
}