The standard schema library
This page describes the standard schema library. The standard schema library is a set of
schema type
s and
component
s 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 in a project’s schema. 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.
Required components
Position
The most important standard library component is improbable.Position
.
Read about the Position component in the glossary.
It is defined like so:
type Coordinates {
double x = 1;
double y = 2;
double z = 3;
}
component Position {
id = 54;
Coordinates coords = 1;
}
EntityAcl
ACL here stands for “access control list”. The EntityAcl
component determines:
- read access permission: which types of workers can have active read access to the components on an entity
- write access permission: for each component on the entity, which type of worker can have write access authority
The definition of EntityAcl
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;
}
EntityAcl
contains two fields: read_acl
and component_write_acl
.
read_acl
In the read_acl
field, you specify a worker requirement set. This is made up of one or more worker attribute sets, and determines which worker types have active read access to the components on the entity.
For example, if you specified physics
and AI
in the read_acl
component, then all worker instances that are in the physics
or AI
layer will be able to read from all the components on this entity.
Note: You can’t specify both attributes within the same worker attribute set. You need to specify each worker attribute set separately, for example:
ReadACL = WorkerRequirementSet { WorkerAttributeSet { "physics" }, WorkerAttributeSet { "AI" } }
component_write_acl
In the component_write_acl
field you also specify a worker requirement set, this time for each component on the entity. The worker requirement set must contain one worker attribute set per component.
Because a worker type’s worker attribute set specifies the layer that the worker type belongs to, you’re effectively using the component_write_acl
field to specify the layer that you want each entity component to belong to (in other words, to specify that worker instances of a specific type should simulate this component on this entity).
For example, if there’s a worker type UnrealWorker
with the worker attribute set physics
, and an entity with a component_write_acl
that specifies that the physics
layer should simulate the Position
component for that entity, then an instance of UnrealWorker
will always simulate the Position
component for that entity.
Which worker instance gets write access authority at which time depends on your load balancing strategy for the layer:
If there are several running instances of a worker type that has this layer as its worker attribute set, SpatialOS grants write access authority to one of those instances. (If there’s only one, that instance gets write access authority.)
If there are no such running instances, but there is a worker configuration file for a worker type that has this layer as its worker attribute set, SpatialOS launches new worker instances based on the worker configuration file and load balancing strategy in an attempt to make sure there is a worker instance to simulate this component.
Optional components
Persistence
The improbable.Persistence
component is extremely simple, with no fields at all:
component Persistence {
id = 55;
}
Read about the Persistence component in the glossary.
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 SDK in C++, C# and Java 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).
For managing persistence at the component field level, use transient fields.
Metadata
The improbable.Metadata
component is for storing metadata related to an entity:
component Metadata {
id = 53;
string entity_type = 1;
}
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: to associate SpatialOS entities with game assets, for example.
Interest
The improbable.Interest
lets you specify interest based on the components you have write access authority over, using queries. It provides a mapping from a component ID (such as 54
for Position
) to a list of queries.
component Interest {
id = 58;
map<uint32, ComponentInterest> component_interest = 1;
}
type ComponentInterest {
...
list<Query> queries = 1;
}
You use the improbable.Interest
component to specify query-based interest.
System (restricted) components
These components apply only to system entities. The SpatialOS Runtime creates system entities and their components.
System
All system entities have the improbable.restricted.System
component:
package improbable.restricted;
component System {
id = 59;
}
Worker
Worker entities have the System component and, additionally, the improbable.restricted.Worker
component.
package improbable.restricted;
type Connection {
enum ConnectionStatus {
UNKNOWN = 0;
AWAITING_WORKER_CONNECTION = 1;
CONNECTED = 2;
DISCONNECTED = 3;
}
ConnectionStatus status = 1;
uint32 data_latency_ms = 2;
uint64 connected_since_utc = 3;
}
type DisconnectRequest {
}
type DisconnectResponse {
}
component Worker {
id = 60;
string worker_id = 1;
string worker_type = 2;
Connection connection = 3;
command DisconnectResponse disconnect(DisconnectRequest);
}
PlayerClient
Worker entities that are client-worker instances have the System and Worker components, and, additionally, the improbable.restricted.PlayerClient
component. The Runtime creates this component when the client-worker instance logs in to a deployment.
package improbable.restricted;
type PlayerIdentity {
string player_identifier = 1;
string provider = 2;
bytes metadata = 3;
}
component PlayerClient {
id = 61;
PlayerIdentity player_identity = 1;
}
Table of component IDs
Component | ID |
---|---|
Position |
54 |
EntityAcl |
50 |
Persistence |
55 |
Metadata |
53 |
Interest |
58 |