Operations

GDK for Unreal

If you're using the GDK for Unreal, this page does not apply to you.

This page is worded assuming that you're using chunk-based interest (for example, you'll see 'interest area' throughout the page), but query-based interest works as well.

Operations: how worker instances communicate with SpatialOS

If you’re building a worker type from scratch with our Worker SDK in C++, C# or Java or writing your own engine integration, you'll need to learn how worker instances interact with SpatialOS through operations.

SpatialOS worlds are simulated by a number of worker instances, each of which has a view on a part of the entire world, consisting of the components they have active read access to. Operations are granular, high-throughput messages sent between worker instances and SpatialOS. They update each worker instance on changes within the worker instance’s local view of the world, and notify SpatialOS of the changes that worker instances make to entities and components they control.

This page gives a high-level overview of operations - defining their purpose and properties in order to give you an idea of how to handle operations when writing a SpatialOS worker type. For detailed information about how to use the Worker SDK to receive operations, see the documentation on handling information received from SpatialOS (C++, C#, Java, C# bindings).

What are operations?

The Worker SDK uses operations to communicate with your code. Primarily, operations carry information about changes to entities and components.

Worker instances can subscribe to some or all incoming operations in order to:

  • keep local entity and component state in sync with the canonical versions maintained by SpatialOS
  • respond to incoming events and commands associated with entities simulated by the worker instance
  • receive and propagate SpatialOS metrics

Operations communicate updates at a granular level - for example, a ComponentUpdate operation carries information about a single entity component’s change in value, and may be sent hundreds of times a second to each worker instance.

Image: Worker structure diagram.

You can use the Worker SDK Connection object to receive operations, which you can then pass to a Dispatcher object in order to subscribe custom handlers for each type of operation.

The protocol does not automatically keep track of what entities and components that a worker instance has active read access to. However, the View object is available as a means of keeping track of entities and components present in the worker instance’s view of the world.

Operations received by a SpatialOS worker instance

This section explores all of the operations available in SpatialOS, organised into several groups for ease of reading. Please note that these groups are not reflected in the API itself.

Worker-related operations

Operation Description
Disconnect The worker instance is disconnected from SpatialOS.
FlagUpdate A worker flag has been created or deleted, or its value has changed.
LogMessage The SDK issues a log message for the worker instance to print.
Metrics The SDK reports built-in internal metrics.
CriticalSection A critical section is about to be entered or has just been left.

Entity-related operations

Operation Description
AddEntity An entity is added to the worker instance’s view of the world. This operation does not suggest that an entity was created in the world, rather that it has entered the worker instance’s view.
RemoveEntity An entity is removed from the worker’s view of the world. This operation does not suggest that the entity has been deleted from the world.
ReserveEntityIdResponse The worker instance has received a response for an entity ID reservation it requested.
ReserveEntityIdsResponse The worker instance has received a response for a reservation of an entity ID range it requested.
CreateEntityResponse The worker instance has received a response for an entity creation it requested.
DeleteEntityResponse The worker instance has received a response for an entity deletion it requested.
EntityQueryResponse The worker instance has received a response for an entity query it requested.

Component-related operations

Operation Description
AddComponent A component is added to an existing entity in the worker instance's view of the world.
RemoveComponent A component is removed from an existing entity in the worker instance’s view of the world.
AuthorityChange The worker instance’s authority state over a component is changed to Authoritative, Not Authoritative or Authority Loss Imminent.
ComponentUpdate A component for an entity in the worker instance’s view of the world has been updated.
CommandRequest The worker instance has received a command request for a component on an entity over which it has write access authority.
CommandResponse The worker instance has received a command response for a request it issued previously.

The Dispatcher and the View

Your worker implementation handles data received from SpatialOS using the Dispatcher object, used to subscribe a custom handling function for each type of operation received.

The Dispatcher does not process the incoming operations in any way: it’s your responsibility to keep track of the state of the entities and components in your worker instance’s view. One way to do this would be to keep an in-memory data structure that keeps track of visible entities and components, and update it when entities and components are added to and removed from the worker instance’s view (through the corresponding operations).

Alternatively, you can use the View object: a special type of dispatcher that automatically keeps track of the entities and components available in your worker instance’s local view of the world. It works by reading incoming operations before passing them to your subscribed handling functions. You can use a View instance instead of a Dispatcher instance if your worker instance needs to keep track of the entities and components in its interest area.

Example of operation handling in a worker implementation

To help you understand how a custom worker type may handle operations received from SpatialOS, let’s consider as a scenario a simple world with many non-player characters (NPCs) running on SpatialOS. A particular NPC is moving a large distance across the world, during which it crosses the boundaries of two worker instances:

Image: Operations scenario.

The NPC is controlled by an AI running on the worker instances. There are three important points in time during this scenario:

  1. When the NPC enters the interest area of worker instance 2, the worker instance receives operations containing the data needed to add the NPC to its local view of the world.
  2. When the NPC leaves the area of authority of worker instance 1 and enters the area of authority of worker instance 2, worker instance 2 receives operations telling it about newly gained write access authority over the NPC. Worker instance 1 receives operations to allow it to propagate any local AI state to SpatialOS, and revoking its write access authority over the NPCs components.
  3. When the NPC leaves the interest area of worker instance 1, the worker instance receives operations telling it to remove the NPC from its local view.

The diagram below shows some of the operations sent to the worker instances by SpatialOS, along with a sensible way in which these operations may be handled by a custom worker implementation. Worker instances receive many other operations, such as ComponentUpdate, sent every time the NPCs position changes within the simulation. However, these operations are not included in the diagram, to make it easier to understand.

Image: Scenario operation handling.

Let's look at the individual operations in the scenario above, when they are sent to worker instances and how they can be handled.

AddEntity

AddEntity is sent to worker instance 2 when the NPC moves into the worker instance's interest area. This operation tells the worker instance that there is a new entity in its local view of the world. We store this information in the worker instance's memory using a sensible data structure - such as a hash map from the entity id to a list of the entity's components.

AddComponent

AddComponent operations are sent to worker instance 2 after AddEntity, in order to inform the worker instance of all of the components available on the NPC entity. Each operation provides the data for a particular entity component, allowing the worker instance to store this information in-memory. Two AddComponent operations are received by the worker instance - one for the position and another for the ai_state component.

AuthorityChange

AuthorityChange operations are sent to both worker instance 1 and worker instance 2 at different points in time within the scenario. This type of operation tells worker instances that their write access authority over a particular component has changed. The values received in our scenario are:

  • Authority Loss Imminent - sent to worker instance 1 when the NPC leaves the worker instance's area of authority. This value alerts the worker instance that it's about to lose write access authority over NPC components, giving our implementation a chance to push any in-memory state related to each component to SpatialOS through component updates. In our case, we want to push any state relating to the NPC's AI (such as the current path followed by the AI) to SpatialOS, so that worker instance 2 can take over the NPCs simulation where worker instance 1 left off.

  • Not Authoritative - sent to worker instance 1 after Authority Loss Imminent to tell the worker instance that it no longer has write access authority over the NPC's components. We handle this by flagging the write access authority loss on each component, and ensure that our worker instance implementation stops sending component updates for the NPC.

  • Authoritative - sent to worker instance 2 when the NPC enters worker instance 2's area of authority. We handle this by flagging the write access authority gain on each component, triggering the worker instance to begin simulating the NPC using the values in ai_state, picking up from where worker instance 1 left off.

ComponentUpdate

ComponentUpdate operations are sent to each worker instance when any of the components on the NPC are updated. Each operation carries the value of a particular component after the update. For example, as worker instance 1 simulates the NPC and changes its position, worker instance 2 will receive each update as a ComponentUpdate operation (as long as the NPC is in worker instance 2's interest area). We handle this operation by writing the new values to the worker instance's in-memory store.

RemoveComponent

RemoveComponent operations are sent to worker instance 1 when the NPC leaves the worker instance's area of authority. These tell the worker instance that the component is no longer visible to the worker instance, and hence that it will no longer receive component updates for that component. We handle this by removing the component from our in-memory store.

RemoveEntity

RemoveEntity operations are sent to worker instance 1 when the NPC leaves the worker instance's area of authority, and after every RemoveComponent operation for the entity. This tells the worker instance that the entity is no longer visible, and we handle this by removing the entry for the entity from the worker instance's in-memory store.

Next steps

Now that you have learned about operations, you are ready to build a custom worker type or an engine integration for your SpatialOS project! Learn more by reading our C++,
C# or Java Worker SDK documentation.


2020-06-11: Page updated with editorial review: rewrote the definition of Operations; other minor edits

Updated about a year ago


Operations


Suggested Edits are limited on API Reference Pages

You can only suggest edits to Markdown body content, but not to the API spec.