This document explains how Archetypes work internally. If you're looking for how Level of Detail works in coherence with CoherenceSync, see this page instead.
Level of Detail (or LOD-ing, for short) is a technique to optimize the amount of data being sent from the Replication Server to each Client. Often a Client doesn't need to get as much information about an Entity if it's far away. The way this is achieved when working with coherence is by using Archetypes.
Archetypes let you group components together and create distinct "levels of detail". Each such level must have a distance threshold, and a list of components that should be present at that distance. Optionally it can also contain per-field overrides that make the primitive data types in the components take up less space (at the cost of less precision.)
To define an Archetype, use the
archetypekeyword in your schema, then list the LODs in ascending order. Notice that LOD 0 does not need a distance, since it always starts at 0. Here's an example of a simple Archetype:
lod 1 [distance "10"]
lod 2 [distance "200"]
In this example, any Enemy Entity that is 200 or more units away from the LiveQuery of a particular Client will only get updates for the
WorldPosition. Any client with a distance of 10 – 200 will get
WorldOrientation, and anything closer than that will get the full Entity.
Given one or more Archetype definitions in your schema, you will have access to a few different data types and methods in your project (these will be generated when you run the Protocol Code Generator.)
ArchetypeComponent– this component has a field index that keeps track of which one of the Archetypes in your schema that is being used. If you add the
ArchetypeComponentyourself you have to use the static constants in the
Coherence.Generated.Archetypeto set the index. These all have the name "Archetype name" + "Index", e.g.
EnemyIndexin the example above.
- An individual "tag" component (with no fields) called "Archetype name" + "Archetype", e.g.
EnemyArchetypein the example above. This component can be used to create optimized ForEach queries for a specific Archetype.
LastObservedLod– this component holds the current LOD for the Entity. This can be used to detect when the Entity changes LOD, if that's something you want to react to. Note that this component is not networked, since the exact LOD for an Entity is unique for each Client.
- Static helper methods on the
Archetypeclass to instantiate the Archetype in a usable state. These are named "Instantiate" + "Archetype name", e.g.
InstantiateEnemyin the example above.
If a component isn't present at a certain LOD, no updates will be sent for that component. This is a great optimization, but sometimes a little too extreme. We might actually need the information, but be OK with a slightly less fine-grained version of it.
To achieve this, you can use the same field settings that are available when defining components, but use them as overrides on specific LOD's instead.
Here's an example of the syntax to use:
value [bits "24"]
lod 1 [distance "100"]
value [bits "16"]
lod 2 [distance "1000"]
value [bits "8"]
Notice that the settings are exactly the same as when defining components. To override a field, you must know its name (
valuein this case.) Any field that is not overridden will use the settings of the LOD above, or the original component if at LOD 0.
Each component in an Archetype can also override the default priority for that component. Just add the priority meta data after the component, like this:
WorldPosition [prio "high"]