Get SpatialOS

Sites

Menu

The standard schema library

This page describes the standard schema library.

The standard schema library is a set of schema types and components provided alongside SpatialOS. The standard library components are special in the sense that they are read by SpatialOS at runtime to control built-in behaviour and runtime features, but are otherwise no different from any component defined by the project itself: to a worker, they look just like any other component, and can be manipulated in exactly the same way.

Some of these components are required: SpatialOS will refuse to create an entity without the improbable.Position or improbable.EntityAcl components, for example.

The standard schema library is defined in an a file called improbable/standard_library.schema, which can be imported by any other schema file as usual in order to reuse its type definitions. The library is usually provided by the standard_library (previously WorkerSdkSchema) dependency in the project’s spatialos.json.

Each type and component defined by the standard library is explained here. All of them reside in the improbable schema package.

Summary

Component What it’s for ID
Position Defines an entity’s location in the world. 54
EntityAcl Determines which workers have read access to an entity, and which workers have write access to each of its components. 50
Persistence Marks entities that should be saved in snapshots (persisted). 55
Metadata Used to associate entities with game assets (Unity and Unreal SDKs only). 53

Position (required)

The most important standard library type is improbable.Position. This defines the canonical position of an entity for load-balancing, authority delegation, and entity query purposes. Every entity must have this component. It is defined like so:

type Coordinates {
  double x = 1;
  double y = 2;
  double z = 3;
}

component Position {
  id = 54;
  Coordinates coords = 1;
}

Note that updating this component is only necessary to let SpatialOS know where the positions of entities are for a few specific purposes (load-balancing and queries). In particular, there’s no reason that this component must be used to represent entity positions inside, say, worker logic: for example, a 2D simulation could use a custom position component with only two fields, and treat improbable.Position as a write-only component that’s updated at a lower frequency to save bandwidth.

EntityAcl (required)

The improbable.EntityAcl component determines which workers have read access to an entity, and which workers have write access to each of its components. (ACL here stands for “access control list”.) Like Position, every entity must have this component.

This component is a bit more complicated. Its definition is as follows:

type WorkerAttributeSet {
  list<string> attribute = 1;
}

type WorkerRequirementSet {
  list<WorkerAttributeSet> attribute_set = 1;
}

component EntityAcl {
  id = 50;

  WorkerRequirementSet read_acl = 1;
  map<uint32, WorkerRequirementSet> component_write_acl = 2;
}

The WorkerRequirementSet type is used twice in the definition of the EntityAcl component. This type acts as a filter on worker instances by matching against their worker attributes (generally defined in the bridge configuration, but note that some special attributes can be added at runtime by SpatialOS as well).

A WorkerRequirementSet acts like an OR operation: a worker is considered to match a particular requirement set if the worker matches any of the WorkerAttributeSets contained in the requirement set. On the other hand, a WorkerAttributeSet acts like an AND operation: a worker is considered to match an attribute set if the worker has all of the attributes in the set (i.e. if the worker’s attribute set, as defined in its bridge configutation, is a superset of the WorkerAttributeSet in the ACL).

For a simple example, a WorkerRequirementSet containing a single WorkerAttributeSet with the two strings "visual" and "physics" would match any worker with both the "visual" and "physics" attributes. A WorkerRequirementSet containing two WorkerAttributeSets, each with a single attribute ("visual" and "physics" respectively), would match any worker with either one of the attributes.

One way to create requirement sets is to hard-code them to match the attribute sets specified in the bridge configurations of particular worker types. However, there’s also a way to make sure a requirement set matches only a particular worker instance (for example, a game client). All incoming command requests provide the runtime attribute set of the calling worker, which includes a special attribute unique to that worker instance. Therefore, a requirement set containing just the attribute set provided by a command request is guaranteed to match exactly the worker instance that initiated the command.

Now, the component_write_acl field in the EntityAcl component defines which workers have write access over each component on the entity. The keys of this map are component IDs (as defined in the schema), and the values are requirement sets. SpatialOS will only grant authority over any component on the entity to a worker matching the requirement set associated with its component ID in this map. (Furthermore, if no such worker exists, but there is a launch configuration for a managed worker type that could match the requirement set, it will launch new managed workers based on the launch and load-balancing configurations in an attempt to satisfy the constraint.)

The read_acl field of the EntityAcl component defines which workers have read access to the entity. Assuming the entity is within the interest region of a given worker, the entity will only be sent down to the worker if the worker matches this requirement set. Note that this applies even if the worker is authoritative over some component on the entity. For this reason, the ACLs should usually be configured such that any worker with write access to some component will also have read access to the entity.

Persistence (optional)

The improbable.Persistence component is extremely simple, with no fields at all:

component Persistence {
  id = 55;
}

This component is optional, and has a single purpose: to mark entities for persistence. All entities with this component will be saved in simulation snapshots, and all entities without it will not be. Note that, for consistency, the snapshot APIs in the worker SDKs will not allow any entities without the Persistence component to be written out to a snapshot.

It’s a good idea to think about what sort of entities make sense to be saved in a simulation snapshot, and add the component as appropriate, even if the project isn’t making use of snapshots from live deployments yet. Examples of entities that might make sense to exclude from snapshots are entities representing connected clients or players (which will no longer exist if a deployment is restarted from a snapshot), or short-lived entities (perhaps representing things like bullets or explosions in a game).

Metadata (optional)

The improbable.Metadata component is for storing metadata related to an entity:

component Metadata {
  id = 53;

  string entity_type = 1;
}

This component is optional. The only built-in special behaviour of the entity_type field is that it’s used by the SpatialOS inspector to categorise entities (the type is displayed beside each entity when hovering over it with the mouse, and so on). However, this field can also be used as a general entity type field for other purposes: by default, this field is used by the Unity and Unreal integrations to associate SpatialOS entities with game assets, for example.

Was this page helpful?

Thanks for letting us know!

Thanks for your feedback

Need more help? Ask on the forums