Sites

Menu
These are the docs for 13.7, an old version of SpatialOS. The docs for this version are frozen: we do not correct, update or republish them. 14.0 is the newest →

Adding and removing components during runtime

In order to add or remove a component on an entity, a worker instance must have authority over the component. For more information on authority, see understanding read and write access.

During runtime, a worker instance can request SpatialOS to:

  • add a component to an entity using the sendAddComponent method of the Connection class
  • remove a component from an entity using sendRemoveComponent method of the Connection class

In order to use these functions, you must set ConnectionParameters.enableDynamicComponents to 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 authority over the component, but the component is not currently on the entity in the game world.

Authority over non-existent components works the same as authority over existing components. If you are unsure of how to change authority, see the example of changing authority.

Authority change and component state synchronization

When you set ConnectionParameters.enableDynamicComponents to true, worker instances will receive an AddComponent op or RemoveComponent op (instead of a ComponentUpdate op) when the worker instance gains or loses 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 authority over a component, the worker instance receives either:

  • an AddComponent op (if the component exists)
  • a RemoveComponent op (if the component is non-existent)

Likewise, after losing authority over a component, the worker instance receives either:

  • an AddComponent op (if the component exists)
  • a RemoveComponent op (if the component is non-existent)

AddComponent and RemoveComponent ops must be treated in an idempotent way. In other words, if the worker instance receives:

  • an AddComponent op, you should replace any existing state for the component in the worker instance’s local view with AddComponent.data
  • a RemoveComponent op, 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 authority 1. AddComponent
2. AuthorityChange (AUTHORITATIVE)
1. RemoveComponent
2. AuthorityChange (AUTHORITATIVE)
Losing authority 1. AuthorityChange (NOT_AUTHORITATIVE)
2. AddComponent
1. AuthorityChange (NOT_AUTHORITATIVE)
2. RemoveComponent

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;
}

The worker instance which has authority over the write ACL of a given entity can give a worker instance authority over the SuperStrength component, as described in the example of changing authority.

Example of adding a component

The worker instance which has authority over the SuperStrength component can add it to the entity:

public static void addSuperStrengthComponentToEntity(Connection connection, EntityId entityId) {
  SuperStrengthData componentData = new SuperStrengthData(100 /* power level */);
  UpdateParameters updateParameters = new UpdateParameters();
  updateParameters.Loopback = ComponentUpdateLoopback.SHORT_CIRCUITED;
  connection.sendAddComponent(SuperStrength.COMPONENT, entityId, componentData, updateParameters);
}

Example of removing a component

The worker instance which has authority over the SuperStrength component can remove it from the entity:

public static void removeSuperStrengthComponentFromEntity(Connection connection, EntityId entityId) {
  UpdateParameters updateParameters = new UpdateParameters();
  updateParameters.Loopback = ComponentUpdateLoopback.SHORT_CIRCUITED;
  connection.sendRemoveComponent(SuperStrength.COMPONENT, entityId, updateParameters);
}

Search results

Was this page helpful?

Thanks for letting us know!

Thanks for your feedback

Need more help? Ask on the forums