Skip to content

Open Digital Twin Format (rv-ODT) Specification

{/* GENERATED — run npm run sync:odt */}

Status: Released Format version: 1.0 Canonical machine-readable schema: rv-odt.json ($id: https://realvirtual.io/schema/odt/v1/rv-odt.json) License: This specification and the accompanying rv-odt.json are licensed under Creative Commons Attribution 4.0 International (CC BY 4.0) — see ../LICENSE. The reference implementation (realvirtual WEB) is separately licensed under AGPL-3.0-only.

Normative precedence: Where this document and rv-odt.json disagree on field names, types, defaults, units, or enum values, the JSON schema is normative. The prose tables in Section 7 are non-normative and provided for human readability.


This document specifies version 1.0 of the realvirtual Open Digital Twin Format (rv-ODT): a convention for embedding industrial digital-twin component data — drives, sensors, transport surfaces, material sources and sinks, grippers, robot kinematics, PLC signal wiring, and 3D-HMI markers — inside standard glTF 2.0 / GLB files.

A single self-describing GLB file carries both the geometry and the complete behavioral/HMI configuration of a machine or plant. No side-car files, no external schema registry, no vendor runtime is required to read it.

URL stability commitment: the canonical schema URL https://realvirtual.io/schema/odt/v1/rv-odt.json serves the latest compatible 1.x schema and changes only through the documented additive release process. Every minor release is also published under /schema/odt/v1.N/ as a byte-immutable snapshot. The canonical and snapshot URLs are committed to remain reachable until at least 2037, in line with the documentation-availability requirements of EU Machinery Regulation 2023/1230.

Industrial machine documentation and 3D visualization are typically locked into vendor tools. rv-ODT makes the delivered digital twin an open artifact:

  • One file — geometry plus component semantics in a single GLB.
  • Tool independence — any glTF-capable tool can read the geometry; any JSON-capable tool can read the component data and validate it against rv-odt.json.
  • Longevity — glTF 2.0 is an ISO/IEC 12113 standard; the component layer is plain JSON under the standardized extras mechanism.
  • Ecosystem — authoring tools (Unity exporter, Blender add-on, CAD importers) and consumers (web viewers, CI validators, documentation generators) can interoperate against one published contract.

The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in RFC 2119.

  • A writer is a tool that produces rv-ODT GLB files (e.g. the realvirtual Unity exporter).
  • A reader is a tool that consumes rv-ODT GLB files (e.g. realvirtual WEB).
  • A component is a named block of key/value configuration attached to a glTF node.

rv-ODT data lives in the standard glTF extras object of each node, under the reserved key realvirtual:

{
"nodes": [
{
"name": "ConveyorDrive",
"extras": {
"realvirtual": {
"Drive": {
"Direction": "LinearX",
"TargetSpeed": 200
},
"TransportSurface": {
"TransportDirection": { "x": 1, "y": 0, "z": 0 },
"DriveReference": {
"type": "ComponentReference",
"path": "Cell/ConveyorDrive",
"componentType": "Drive"
}
}
}
}
}
]
}

Rules:

  • A node MAY carry zero, one, or several components under extras.realvirtual.
  • Each key of extras.realvirtual that matches a component name in the components index of rv-odt.json MUST validate against that component’s $def.
  • Readers MUST ignore unknown keys (forward compatibility). Writers SHOULD NOT emit keys that are not defined in this specification or in a documented extension.
  • Fields omitted by the writer take the default declared in rv-odt.json.
  • glTF interoperability is unaffected: extras is ignored by standard glTF loaders.
  • Container: glTF 2.0, typically binary (.glb). JSON .gltf is equally valid.
  • Attachment point: node.extras.realvirtual (object). rv-ODT v1 does not define a glTF extension (extensionsUsed); it uses only the extras mechanism.
  • Node identity: components reference other nodes by scene path — the slash-joined chain of node names from the scene root to the node (e.g. "Cell/Conveyor1/Drive"). Writers MUST produce unique node names within a parent so paths are unambiguous.
  • Coordinate systems: glTF is right-handed (+Y up, +Z forward); Unity is left-handed. Scalar positions/speeds are in Unity component conventions (millimeters, mm/s) regardless of the glTF unit (meters). Vector-valued fields marked with the unityCoords keyword are serialized in Unity coordinates and readers MUST negate the X component when applying them in glTF space (Section 8).
  • Format version: writers SHOULD stamp _formatVersion: "1.0" at the root of extras.realvirtual. Readers MUST report an incompatibility when the major version is greater than the version they implement.

Component fields use the following types. The machine-readable definition in rv-odt.json is normative.

rv-ODT typeJSON representationNotes
numberJSON numberUnit per field via the unit keyword (UCUM code), where applicable.
booleanJSON boolean
stringJSON string
enumJSON stringSee “Enum wire format” below.
Vector3{ "x": n, "y": n, "z": n }$ref: #/$defs/Vector3. May carry unityCoords.
Quaternion{ "x": n, "y": n, "z": n, "w": n }$ref: #/$defs/Quaternion. Reserved for future component fields.
ComponentReferenceobject$ref: #/$defs/ComponentReference, see below.
ComponentReference[]JSON array of ComponentReference
{
"type": "ComponentReference",
"path": "Cell/PLC/StartSignal",
"componentType": "PLCOutputBool",
"componentIndex": 0
}
  • path — scene path of the referenced node (Section 5).
  • componentType — the component (or PLC signal type) expected at that node. PLC signal types follow the Unity/PLC convention: PLCOutputBool|Int|Float are written by the PLC and read by the twin; PLCInputBool|Int|Float are written by the twin and read by the PLC.
  • componentIndex — disambiguates multiple components of the same type on one node (OPTIONAL, default 0).

Enum fields are serialized as strings. Writers MUST emit one of the values listed in the field’s enum array in rv-odt.json (the canonical wire values — the C# enum member names). Conforming readers MUST accept any string listed in the enum array. The order of values in the enum array is documentary only and carries no semantics.

Some enum fields additionally declare an enumMap keyword (Section 8): a complete map of accepted wire strings — including legacy integer indices serialized as strings (e.g. "0") — to the reader-internal value. Where present, readers SHOULD accept all enumMap keys; writers MUST still emit only canonical enum values.

Reminder (normative precedence): where a prose table below disagrees with rv-odt.json on names, types, defaults, units, or enum values, the JSON schema is normative.

rv-ODT v1 defines the complete extras.realvirtual surface in five groups, mirroring the index groups in rv-odt.json:

GroupIndex keyContents
7a Componentscomponents34 instantiable simulation/HMI components
7b Logic StepslogicSteps26 sequential-logic step types
7c PLC Signalssignals6 PLC signal types
7d Scene & StructurestructureGroups, kinematic re-parenting, MU, colliders, layout, splats, AAS links
7e RecordingrecordingDrive recording and replay

Each subsection gives the field table (non-normative; rv-odt.json is normative) and, for components, a minimal example of the node extras.realvirtual payload. The Default column shows the JSON default value; - means the field has no default. The Description column mirrors the description texts maintained in rv-odt.json (informative). Fields listed in a second “Raw field” table are consumed by the reference implementation outside the schema mapper (custom rawFields keyword, Section 8).

Common serialization metadata emitted by some writers on any component — Name, Active (where not explicitly listed), _fullTypeName, _version, _enabled — is NOT part of the format; readers MUST ignore it (exception: _enabled: false on a Group entry disables that group entry).

Linear or rotational motion control along a local axis. The base motion component.

FieldTypeDefaultDescription
Directionenum(LinearX, LinearY, LinearZ, RotationX, RotationY, RotationZ, Virtual)-Motion axis of the drive in Unity local coordinates; ‘Virtual’ drives no transform.
ReverseDirectionbooleanfalseSet to true if the direction needs to be inverted.
Offsetnumber0Start offset of the drive from zero position in millimeters or degrees.
StartPositionnumber0Start position of the drive in millimeters or degrees.
TargetSpeednumber100The target speed of the drive in millimeters per second (degrees per second for rotational drives).
Accelerationnumber100The acceleration in millimeters per second squared.
UseAccelerationbooleanfalseIf set to true the drive uses the acceleration.
UseLimitsbooleanfalseIf set to true the drive motion is limited to the range between LowerLimit and UpperLimit.
LowerLimitnumber-180Lower drive limit in millimeters or degrees.
UpperLimitnumber180Upper drive limit in millimeters or degrees.
JogForwardbooleanfalseJog the drive continuously forward at TargetSpeed.
JogBackwardbooleanfalseJog the drive continuously backward at TargetSpeed.
TargetPositionnumber0The destination position of the drive in millimeters or degrees.
{ "Drive": { "Direction": "RotationZ", "TargetSpeed": 90, "UseLimits": true, "LowerLimit": -180, "UpperLimit": 180 } }

Drive behavior: jog control with speed and directional bits plus feedback signals.

FieldTypeDefaultDescription
SpeedComponentReference-PLC output for the speed of the drive in millimeters per second; can be scaled by ScaleSpeed.
AccelarationComponentReference-PLC output for the acceleration of the drive in millimeters per second squared; field name keeps the original C# spelling.
ForwardComponentReference-Signal to move the drive forward.
BackwardComponentReference-Signal to move the drive backward.
IsAtPositionComponentReference-Signal for the current position of the drive in millimeters.
IsAtSpeedComponentReference-Signal for the current speed of the drive in millimeters per second.
IsDrivingComponentReference-Signal is true while the drive is driving.
ScaleSpeednumber1Scale factor for the input and output speed and acceleration.
CurrentPositionScalenumber1Scale factor for the current position feedback.
CurrentPositionOffsetnumber0Offset applied to the position feedback in millimeters.
ScaleFeedbackPositionbooleantrueIf true, applies scale and offset to the position feedback.
{ "Drive_Simple": { "Forward": { "type": "ComponentReference", "path": "PLC/ConveyorStart", "componentType": "PLCOutputBool" } } }

Drive behavior: two-position cylinder with in/out command and end-position feedback.

FieldTypeDefaultDescription
MinPosnumber0Minimum position of the cylinder in millimeters.
MaxPosnumber100Maximum position of the cylinder in millimeters.
TimeOutnumber1Time for moving out from minimum to maximum position in seconds.
TimeInnumber1Time for moving in from maximum to minimum position in seconds.
OneBitCylinderbooleanfalseIf set to true only one bit controls the cylinder; when Out is false the cylinder moves in.
InvertOutputLogicbooleanfalseWhen true, inverts the Out/In signal logic (Out=false extends, Out=true retracts).
OutComponentReference-Signal for moving the cylinder out.
InComponentReference-Signal for moving the cylinder in.
IsOutComponentReference-Signal is true when the cylinder is out or stopped by the Max sensor.
IsInComponentReference-Signal is true when the cylinder is in or stopped by the Min sensor.
IsMaxComponentReference-Signal is true when the cylinder is at the maximum position.
IsMinComponentReference-Signal is true when the cylinder is at the minimum position.
IsMovingOutComponentReference-Signal is true while the cylinder is moving out.
IsMovingInComponentReference-Signal is true while the cylinder is moving in.
{ "Drive_Cylinder": { "MinPos": 0, "MaxPos": 250, "TimeOut": 0.8, "TimeIn": 0.8 } }

Drive behavior: speed-controlled motion via PLC target-speed signal with feedback.

FieldTypeDefaultDescription
SignalTargetSpeedComponentReference-Target (maximum) speed of the drive in millimeters per second.
SignalAccelerationComponentReference-Acceleration of the drive in millimeters per second squared.
SignalCurrentSpeedComponentReference-Signal for the current drive speed in millimeters per second.
SignalCurrentPositionComponentReference-Signal for the current drive position in millimeters.
SignalIsDrivingComponentReference-Signal is true while the drive is driving.
TargetSpeednumber100Default target speed in millimeters per second when no signal is wired.
Accelerationnumber100Default acceleration in millimeters per second squared when no signal is wired.
CurrentPositionScalenumber1Scale factor for the current position feedback.
CurrentPositionOffsetnumber0Offset applied to the position feedback in millimeters.
ScaleFeedbackPositionbooleantrueIf true, applies scale and offset to the position feedback.
{ "Drive_Speed": { "TargetSpeed": 500 } }

Drive behavior: slaves this node’s Drive to a master Drive with gear ratio and offset.

FieldTypeDefaultDescription
MasterDriveComponentReference-Master drive which defines the position of this drive.
GearFactornumber1Gear factor between master and slave position.
Offsetnumber0Offset of the gear in millimeters.
{ "Drive_Gear": { "MasterDrive": { "type": "ComponentReference", "path": "Cell/MainAxis", "componentType": "Drive" }, "GearFactor": 2 } }

Drive behavior: directly follows a PLC position signal (no ramping).

FieldTypeDefaultDescription
PositionComponentReference-Signal (PLC output) for the commanded position of the drive.
CurrentPositionComponentReference-PLC input for the current position of the drive (without offset and scaling).
Offsetnumber0Offset in millimeters added to the position signal.
Scalenumber1Scale factor applied to the position value.
CurrentPositionScalenumber1Scale factor for the current position feedback.
ScaleFeedbackPositionbooleantrueIf true, applies scale and offset to the position feedback.
{ "Drive_FollowPosition": { "Scale": 1000 } }

Drive behavior: point-to-point positioning motor with destination command and feedback.

FieldTypeDefaultDescription
StartDriveComponentReference-Start-to-drive signal; a value change starts motion towards Destination.
DestinationComponentReference-Destination position of the drive in millimeters.
TargetSpeedComponentReference-Target (maximum) speed of the drive in millimeters per second.
AccelerationComponentReference-Acceleration of the drive in millimeters per second squared.
IsAtPositionComponentReference-Signal for the current position of the drive in millimeters.
IsAtSpeedComponentReference-Signal for the current drive speed in millimeters per second.
IsAtDestinationComponentReference-Signal is true when the drive is at the destination.
IsDrivingComponentReference-Signal is true while the drive is currently driving.
CurrentPositionScalenumber1Scale factor for the current position feedback.
CurrentPositionOffsetnumber0Offset applied to the position command and feedback in millimeters.
ScaleFeedbackPositionbooleantrueIf true, applies scale and offset to the position feedback.
{ "Drive_DestinationMotor": { "CurrentPositionScale": 1 } }

Drive behavior: boolean output true while the drive position is inside configured areas.

FieldTypeDefaultDescription
OutputSignalComponentReference-Output signal to the PLC; true when the drive position is inside any configured area (inverted when InvertAreas is true).
InvertAreasbooleanfalseIf true, areas define false zones instead of true zones (inverts the output).
PositionOffsetnumber0Global offset in millimeters or degrees applied to the drive position before area checking.
{ "Drive_PositionSwitch": { "InvertAreas": false } }

Drive behavior: moves the drive to random (or alternating min/max) positions.

FieldTypeDefaultDescription
MinPosnumber0Minimum position of the range where the drive is allowed to move to, in millimeters.
MaxPosnumber100Maximum position of the range where the drive is allowed to move to, in millimeters.
Speednumber100Speed of the drive in millimeters per second.
IterateBetweenMaxAndMinbooleanfalseIf true the drive only iterates between MinPos and MaxPos; if false it moves to random positions.
SignalEnableComponentReference-While this signal is true the drive moves to erratic positions; when unwired it is always enabled.
{ "Drive_ErraticPosition": { "MinPos": 0, "MaxPos": 500, "Speed": 250 } }

Presence sensor: AABB overlap (collision mode) or raycast mode.

FieldTypeDefaultDescription
UseRaycastbooleanfalseIf true the sensor uses raycast mode instead of collider (AABB overlap) mode.
RayCastDirectionVector3-Raycast direction vector in Unity local coordinates (readers negate X in glTF space).
RayCastLengthnumber1000Raycast length in millimeters.
SensorOccupiedComponentReference-Boolean PLC input for the sensor signal; true when the sensor is occupied.
SensorNotOccupiedComponentReference-Boolean PLC input for the sensor; true when the sensor is NOT occupied.
AutoRaybooleanfalseDerives the ray beam from the node bounding box (naming-convention sensors).
PhysicsModebooleanfalseIf true and the sensor overlaps a physics zone, the sensor is physics-managed: collision mode uses a physics sensor collider (enter/leave events), raycast mode a physics raycast. Physics-managed sensors detect only physics-owned MUs; sensors that must detect kinematic MUs keep the default false.

Raw fields (rawFields):

Raw fieldTypeNotes
ModestringLegacy ‘Raycast’/‘Collision’; readers SHOULD convert to UseRaycast when UseRaycast is absent
{ "Sensor": { "UseRaycast": true, "RayCastDirection": { "x": 0, "y": -1, "z": 0 }, "RayCastLength": 500 } }

Conveyor surface that moves MUs along a direction at the referenced Drive’s speed.

FieldTypeDefaultDescription
TransportDirectionVector3-Transport direction in Unity local coordinates, set by the Drive component at export (readers negate X in glTF space).
RadialbooleanfalseIf true the surface transports radially around the drive axis (turntables).
TextureScalenumber1Texture animation speed multiplier in texture units per meter.
HeightOffsetOverridenumber0Manual override for the transport height offset in millimeters.
AnimateSurfacebooleantrueEnables texture animation to visualize surface movement.
DriveReferenceComponentReference-Optional drive reference for special cases; normally empty to use the auto-detected parent drive.
AccumulatebooleantrueIf true MUs on this surface accumulate: each MU clamps its advance to the free distance up to the next MU in move direction (no penetration). Ignored on Radial surfaces.
MinGapnumber0Minimum front gap in millimeters kept between accumulated MUs.
PhysicsModebooleanfalseIf true and the surface lies fully inside a physics zone, the surface runs in physics mode: a kinematic conveyor body carries MUs via friction and jams/stacking are simulated physically. Ignored on Radial surfaces (v1 exclusion) and when the deployment switch simulation.physicsSurfaceDefault is false.
{ "TransportSurface": { "TransportDirection": { "x": 1, "y": 0, "z": 0 }, "DriveReference": { "type": "ComponentReference", "path": "Cell/Conveyor1", "componentType": "Drive" } } }

Spawns new MU (Movable Unit) instances at intervals or by distance.

FieldTypeDefaultDescription
AutomaticGenerationbooleantrueAutomatic generation of MUs when the last MU is farther than GenerateIfDistance from the source.
Intervalnumber0Interval in seconds between the generation of MUs; 0 disables interval generation.
GenerateIfDistancenumber300Distance in millimeters from the source at which new MUs are generated.
PlaceOnTransportSurfacebooleantrueIf true newly spawned MUs are placed onto the transport surface below the source.
ThisObjectAsMUstring""Name of the GameObject used as the MU prototype; defaults to this node when empty.

Raw fields (rawFields):

Raw fieldTypeNotes
SpawnstringLegacy spawn-mode hint
{ "Source": { "AutomaticGeneration": true, "Interval": 5 } }

Destroys MUs that touch it. Carries no configuration fields in v1 — the presence of the (empty) Sink object on a node marks the node as a sink.

{ "Sink": {} }

Gripper for pick-and-place operations.

FieldTypeDefaultDescription
GripRangenumber50Search radius in millimeters for automatic MU detection when no sensor is assigned.
OneBitControlbooleantrueIf true a single signal controls the gripper (rising edge picks, falling edge places).
PlaceModeenum(Auto, Static, Physics)“Auto”Controls how MUs are released on place: Auto (context-dependent), Static (stays kinematic) or Physics (falls onto surface).
GripTargetSearchRadiusnumber500Search radius in millimeters for finding the nearest GripTarget on place.
SignalPickComponentReference-Signal that triggers picking.
SignalPlaceComponentReference-Signal that triggers placing.
PartToGripComponentReference-Sensor identifying the MU to be gripped; when empty, auto-detection uses GripRange.
{ "Grip": { "PlaceMode": "Auto", "GripRange": 80 } }

Placement marker for precise MU positioning during Grip auto-place.

FieldTypeDefaultDescription
AlignPositionbooleantrueIf true the MU position is snapped to the GripTarget position when placed.
AlignRotationbooleantrueIf true the MU rotation is aligned to the GripTarget rotation when placed.
{ "GripTarget": { "AlignPosition": true, "AlignRotation": true } }

One-way signal bridge: copies the referenced source signal onto this node’s own signal.

FieldTypeDefaultDescription
ConnectedSignalComponentReference-Source signal whose value is copied onto this node’s own signal on every change.
{ "ConnectSignal": { "ConnectedSignal": { "type": "ComponentReference", "path": "PLC/MotorOn", "componentType": "PLCOutputBool" } } }

3D-HMI marker: visualizes a bool or int signal as Low/High/Warning/Error states.

FieldTypeDefaultDescription
SignalBoolComponentReference-Binary input: false = Low, true = High; use for 2-state sensors.
SignalIntComponentReference-Integer input: value mapped to a state via IntStateMap; use for sensors with more states.
IntStateMapstring""Mapping of integer signal values to visual states, e.g. ‘0=Low;1=High;2=Warning;3=Error’.
Labelstring""Optional label shown in the tooltip and sensor list.
{ "WebSensor": { "Label": "Light barrier B4", "SignalBool": { "type": "ComponentReference", "path": "PLC/B4", "componentType": "PLCInputBool" } } }

3D-HMI marker: safety-door overlay with hazard-zone halo and label.

FieldTypeDefaultDescription
HazardZoneRadiusnumber1500Hazard-zone halo radius in millimeters.
LabelHeightnumber200Label position above the floor in millimeters.
{ "WebSafetyDoor": { "HazardZoneRadius": 2000 } }

3D-HMI marker: semantic error state bound to a bool signal.

FieldTypeDefaultDescription
SignalErrorComponentReference-Error signal: true = error active, false = OK; leave empty for a static hint marker.
ErrorTextstring""Human-readable error message shown as 3D badge and in the message panel.
HighlightStyleenum(Auto, FlashObject, Circle)“Auto”How the faulty part is highlighted: Auto (by part size), FlashObject or Circle. Writers MUST emit the named string; readers additionally accept the legacy integer index per the enumMap.
{ "WebError": { "ErrorText": "Motor overtemperature", "SignalError": { "type": "ComponentReference", "path": "PLC/MotorFault", "componentType": "PLCOutputBool" } } }

3D-HMI marker: shows/hides the node (and additional targets) from a bool signal; optionally carries an error state.

FieldTypeDefaultDescription
SignalVisibleComponentReference-Visibility signal: true = visible, false = hidden; leave empty to use DefaultVisible.
InvertSignalbooleanfalseIf true the visibility signal logic is inverted (signal false = visible).
DefaultVisiblebooleantrueVisibility used when no visibility signal is bound.
AdditionalTargetsComponentReference[][]Optional additional objects (node references) that are shown/hidden together with this object.
SignalErrorComponentReference-Error signal: true = error active (red, flashing), false = OK; leave empty for no error state.
ErrorTextstring""Human-readable error message shown as 3D badge and in the message panel.
HighlightStyleenum(Auto, FlashObject, Circle)“Auto”How the faulty part is highlighted: Auto (by part size), FlashObject or Circle. Writers MUST emit the named string; readers additionally accept the legacy integer index per the enumMap.
BlinkSpeednumber2Blink speed of the error highlight in Hz; higher is faster.

Raw fields (rawFields):

Raw fieldTypeNotes
ErrorColorobjectUnity Color {r,g,b,a}, floats 0..1
{ "WebVisibility": { "DefaultVisible": false, "SignalVisible": { "type": "ComponentReference", "path": "PLC/ShowGuard", "componentType": "PLCOutputBool" } } }

3D-HMI marker: operator instruction bound to an activation signal.

FieldTypeDefaultDescription
typeenum(Info, Maintenance, Warning, Error, Success)“Info”Instruction category (Info, Maintenance, Warning, Error, Success). Writers MUST emit the C# enum name; readers map it to the lowercase internal value and additionally accept the legacy integer index per the enumMap.
dismissiblebooleantrueIf true the operator can dismiss the instruction via an OK/close button (offered on the last step only); once dismissed it reappears only on the next rising signal edge.
Isolatebooleanfalserealvirtual WEB only: when the operator clicks the message, the step’s target objects are additionally isolated (rest of the scene dimmed) on top of the camera focus and highlight.
signalComponentReference-Activation signal; the instruction is shown while the signal is true.
BlinkSpeednumber2Blink speed of the attention highlight in Hz. 0 = no blinking, the part is only highlighted; higher = faster.

Raw fields (rawFields):

Raw fieldTypeNotes
stepsarrayArray of { instruction, targetObject (node path), url }
UseCustomErrorColorbooleanEnables ErrorColor
ErrorColorobjectUnity Color {r,g,b,a}, floats 0..1
{ "CustomRuntimeInstruction": { "type": "Maintenance", "dismissible": true } }

Tooltip/annotation content for an object.

FieldTypeDefaultDescription
contentstring""XML-like annotation markup shown as tooltip content for the object.
{ "RuntimeMetadata": { "content": "<b>SEW motor</b> KA77 DRN90L4" } }

Robot inverse-kinematics path: ordered IKTarget references with start/end signals.

FieldTypeDefaultDescription
SpeedOverridenumber1Speed override factor for this path.
SetNewTCPbooleanfalseSets a new TCP (tool center point) for this path.
DrawPathbooleantrueDraws the path in the scene view.
DrawTargetsbooleantrueDraws the targets in the scene view.
DebugPathbooleanfalseDebugs the path by drawing points.
DebugBlendingbooleanfalseLogs detailed blending state transitions for debugging.
StartPathbooleanfalseStarts the path on simulation start.
LoopPathbooleanfalseLoops the path after it has ended.
SignalStartComponentReference-Signal to start the path.
SignalIsStartedComponentReference-Signal that the path is started.
SignalEndedComponentReference-Signal that the path has ended.
PathComponentReference[]-Ordered list of IKTarget references forming the path.

Raw fields (rawFields):

Raw fieldTypeNotes
StartNextPathobjectComponentReference to the IKPath started when this path ends
{ "IKPath": { "LoopPath": true, "Path": [ { "type": "ComponentReference", "path": "Robot/Targets/Pick", "componentType": "IKTarget" } ] } }

Robot inverse-kinematics target: pose, interpolation, blending and pick/place settings.

FieldTypeDefaultDescription
FollowInEditModebooleantrueIf true the target follows the robot in edit mode.
SpeedToTargetnumber1Speed to target as a factor of the axis speeds.
LinearAccelerationnumber100Linear acceleration in millimeters per second squared.
InterpolationToTargetenum(PointToPoint, PointToPointUnsynced, Linear)“PointToPoint”Interpolation to the target: PointToPoint, PointToPointUnsynced or Linear.
LinearSpeedToTargetnumber500Linear speed to the target in millimeters per second.
TurnCorrectionbooleanfalseIf true the robot applies the 180-degree turn correction of axes 4 and 6.
SetSignalDurationnumber0.5Duration of the set signal in seconds.
WaitForSecondsnumber0Wait time in seconds after the target is reached.
PickAndPlacebooleanfalseEnables pick/place handling at this target.
PickbooleanfalsePicks with the assigned grip when the target is reached.
PlacebooleanfalsePlaces with the assigned grip when the target is reached.
EnableBlendingbooleanfalseEnables zone blending: the robot transitions to the next target at BlendRadius distance instead of stopping exactly at this target.
BlendRadiusnumber25Radius in millimeters of the blending zone around this target.
SetSignalComponentReference-Signal set when the target is reached.
WaitForSignalComponentReference-Signal to wait for after the target is reached.

Raw fields (rawFields):

Raw fieldTypeNotes
AxisPosarrayPre-computed joint-angle solution (number[6], degrees)
gripTargetobjectComponentReference to the Grip used for pick/place
fixerobjectComponentReference to a Fixer (fallback when gripTarget absent)
{ "IKTarget": { "InterpolationToTarget": "Linear", "LinearSpeedToTarget": 300, "EnableBlending": true, "BlendRadius": 50 } }

Robot inverse-kinematics solver configuration on the robot root node.

FieldTypeDefaultDescription
WristTypeenum(Spherical, NonSpherical)“Spherical”Wrist topology: Spherical (standard industrial robot, analytical solution) or NonSpherical (cobot with wrist offsets).
ElbowInUnityXbooleanfalseIf true the elbow axis is oriented along Unity X.
DrawGizmosbooleantrueDraws IK debug gizmos.
{ "RobotIK": { "WristType": "Spherical" } }

Pure metadata on an imported CAD root: original file reference plus import parameters.

FieldTypeDefaultDescription
Filestring""Original CAD file name this subtree was imported from.
Sha256string""Content hash of the original CAD file.
Qualitystring”standard”Tessellation quality preset used at import.
ImportScaleFactornumber0.001Scale factor applied at import (CAD units to meters).
ZIsUpVectorbooleantrueIf true the CAD source used Z-up orientation.
{ "CADLink": { "File": "gripper-v3.step", "Sha256": "9f2c...", "Quality": "standard" } }

Process-industry pipe segment for the 3D-HMI tooltip and fluid-network topology.

FieldTypeDefaultDescription
resourceNamestring""Name of the fluid/resource flowing through the pipe.
flowRatenumber0Current flow rate through the pipe.
sourceComponentReference-Reference to the upstream component (tank, pump or pipe).
destinationComponentReference-Reference to the downstream component (tank, pump or pipe).
uvDirectionnumber1Texture flow-animation direction (+1/-1).
circuitIdnumber-1Fluid-circuit grouping id; -1 = unassigned.
pressurenumber0Gauge pressure in bar.
temperatureCnumber0Fluid temperature in degrees Celsius.
velocityMsnumber0Flow velocity in meters per second.
dnSizenumber0Nominal pipe diameter (DN), e.g. 50, 100, 200.
{ "Pipe": { "resourceName": "Cooling water", "flowRate": 12.5, "dnSize": 50 } }

Process-industry pump with instrumentation values for the 3D-HMI tooltip.

FieldTypeDefaultDescription
flowRatenumber0Current flow rate delivered by the pump.
pipeComponentReference-Reference to the connected pipe.
circuitIdnumber-1Fluid-circuit grouping id; -1 = unassigned.
resourceNamestring""Medium currently flowing through the pump.
statestring”ok”Pump state: ‘ok’, ‘warning’ or ‘fault’.
suctionPressurenumber0Suction-side gauge pressure in bar.
dischargePressurenumber0Discharge-side gauge pressure in bar.
speedRpmnumber0Motor speed in revolutions per minute.
speedPercentnumber0VFD speed command in percent (0..100).
powerKwnumber0Shaft power in kilowatts.
currentAnumber0Motor current in amperes.
bearingTempCnumber0Bearing temperature in degrees Celsius.
motorTempCnumber0Motor temperature in degrees Celsius.
vibrationMmSnumber0Vibration velocity in mm/s RMS (ISO 10816).
npshAvailablenumber0Net positive suction head available in meters.
npshRequirednumber0Net positive suction head required in meters.
runHoursnumber0Total operating hours.
{ "Pump": { "state": "ok", "speedRpm": 1450, "powerKw": 7.5 } }

Process-industry tank with fill level and instrumentation values.

FieldTypeDefaultDescription
resourceNamestring""Name of the stored fluid/resource.
capacitynumber0Tank capacity.
amountnumber0Current fill amount.
pressurenumber0Gauge pressure in bar.
temperaturenumber0Fluid temperature in degrees Celsius.
densitynumber0Fluid density in kilograms per cubic meter.
phnumber0pH value; 0 = not measured.
agitatorOnbooleanfalseTrue while the mixer/agitator is running.
heatingOnbooleanfalseTrue while the jacket heater is on.
tempHighLimitnumber0High temperature alarm limit in degrees Celsius; 0 = no alarm.
tempLowLimitnumber0Low temperature alarm limit in degrees Celsius; 0 = no alarm.
pressureHighLimitnumber0High pressure alarm limit in bar; 0 = no alarm.
{ "ResourceTank": { "resourceName": "Base resin", "capacity": 5000, "amount": 3250 } }

Production machine/station with OEE and production telemetry.

FieldTypeDefaultDescription
connectionsComponentReference[]-References to connected upstream/downstream components.
statestring”idle”Machine state: ‘running’, ‘idle’, ‘down’, ‘setup’ or ‘maintenance’.
availabilitynumber0OEE availability factor (0..1).
performancenumber0OEE performance factor (0..1).
qualitynumber0OEE quality factor (0..1).
cycleTimeSnumber0Current actual cycle time in seconds.
cycleTargetSnumber0Target (ideal) cycle time in seconds.
throughputPerHournumber0Throughput in units per hour.
goodCountnumber0Good units produced shift-to-date.
scrapCountnumber0Scrap units produced shift-to-date.
mtbfHoursnumber0Mean time between failures in hours.
mttrMinutesnumber0Mean time to repair in minutes.
runHoursnumber0Run time in hours this period.
downHoursnumber0Down time in hours this period.
lastFaultstring""Description of the last fault.
{ "ProcessingUnit": { "state": "running", "availability": 0.92, "performance": 0.88, "quality": 0.99 } }

JavaScript behavior component stored in the GLB: sandboxed script following the global setup(self) contract, executed by the viewer’s QuickJS runtime. Script execution is gated per model (trust gate): a conforming viewer MUST NOT execute Code from an untrusted file without explicit user consent. An empty Code creates no VM; the component stays inactive but remains editable.

FieldTypeDefaultDescription
ActivebooleantrueIf false the component is parsed but never executed.
ApiVersionnumber1Component-SDK contract version the code was written against.
Languagestring”js”Source language of Code; stored code is always conservative JavaScript.
DesSafebooleanfalseAuthor claim that the script uses only event-driven primitives (checked by the DES lint).
TypeIdstring""Library/type identity for reuse, inspector display and statistics.
Codestring""JavaScript source following the global setup(self) contract; empty means no VM is created.
{ "WebComponent": { "Active": true, "ApiVersion": 1, "TypeId": "Gate", "Code": "function setup(self){ return { continuous: {} }; }" } }

3D-HMI marker: couples a PLC error signal to the AI error diagnosis. A rising edge of SignalBool (or a change of SignalInt to a non-zero value) raises a diagnose request for this node; the falling edge (or SignalInt returning to 0) clears it. Without a bound signal the marker is inactive.

FieldTypeDefaultDescription
SignalBoolComponentReference-Error signal: rising edge (false to true) triggers the diagnosis; falling edge clears it.
SignalIntComponentReference-Error-code signal: any change to a non-zero value triggers the diagnosis with that code; 0 clears it.
DocFilterstring""Metadata filter passed to the diagnosis backend (machine, component or error-code range).
ErrorIdstring""Stable error ID used as the key for the shared operator comment store; defaults to the node path.
Labelstring""Optional human-readable label shown on the diagnosis card.
AutoOpenbooleantrueIf true the diagnosis dialog opens automatically on a rising edge; if false only the card is shown.
{ "WebDiagnostics": { "Label": "Axis 2 overload", "ErrorId": "SYST-320", "DocFilter": "crx-manual", "SignalInt": { "type": "ComponentReference", "path": "PLC/ErrorCode", "componentType": "PLCOutputInt" } } }

WebViewer-native arc-length-parametrised path (plan-268) for path-based movement (AGV/FTS, overhead conveyors): an ordered chain of line/arc segments plus id-based graph chaining. Detection is coupled to this payload (type "Path" or absent), never to node names. The structured fields are parsed by parsePathExtras() in src/core/engine/rv-path.ts — that module is the executable TS-SSOT for the segment grammar; the JSON spec lists the scalar fields and documents the structure here.

FieldTypeDefaultDescription
versionnumber1Path schema version (migration anchor). Unknown versions parse best-effort with a warning.
closedbooleanfalseCirculating path (loop): arc-length addresses wrap modulo length.

Structured fields (parsed by the TS-SSOT, not part of the scalar $def properties above):

Structured fieldShapeDefaultDescription
typestring”Path”Payload discriminator; a foreign value rejects the payload.
idstringnode nameStable path id used by successors graph edges.
segmentsarray[]Segment chain: { "kind": "line", "from": [x,y,z], "to": [x,y,z] } or { "kind": "arc", "center": [x,y,z], "radius": r, "startAngle": deg, "degrees": deg, "clockwise": bool?, "plane": "XZ"|"XY"|"YZ"? }. Unknown kinds are skipped; unknown planes fall back to "XZ".
successorsstring[][]Ids of successor paths (junction candidates); dangling ids are tolerated.
align[x,y,z][0,1,0]Up vector for the carrier pose (lookRotation(tangent, align)).
{ "Path": { "type": "Path", "version": 1, "segments": [ { "kind": "line", "from": [0,0,0], "to": [0,0,5] }, { "kind": "arc", "center": [-2,0,5], "radius": 2, "startAngle": 0, "degrees": 90, "plane": "XZ" } ], "closed": false, "successors": ["Route-B"], "align": [0,1,0] } }

Physics zone: 3D box volume inside which MUs are simulated as free dynamic rigid bodies (falling, sliding, tipping, stacking in bins). Strictly opt-in — without this component no physics engine is loaded. The zone volume comes from the node’s BoxCollider extras (Section 7d.4); with WholeScene the scene bounding box is used instead. Not to be confused with AGV path zones (Path.zone, routing capacity) — a physics zone is a spatial 3D volume.

FieldTypeDefaultDescription
ZoneEnabledbooleantrueEnables physics simulation inside this zone.
WholeScenebooleanfalseIf true the box volume is ignored and the whole scene bounding box becomes the physics zone.
Frictionnumber0.8Default friction coefficient for MUs inside the zone.
Restitutionnumber0Bounciness of MUs inside the zone (0 = none).
RemoveBelowYnumber-10MUs falling below this world Y (meters) are removed.
ShowGizmobooleantrueShows the zone as a wireframe box in the viewer.

Raw fields (rawFields):

Raw fieldTypeNotes
StaticCollidersarrayNode paths (strings) of additional static collision geometry (chutes, bins, machine frames); resolved via the node registry, read raw
{ "WebPhysicsZone": { "ZoneEnabled": true, "Friction": 0.8, "StaticColliders": ["Container/WallLeft"] }, "BoxCollider": { "center": { "x": 0, "y": 0, "z": 0 }, "size": { "x": 1.5, "y": 1.5, "z": 2.5 } } }

Logic steps describe sequential control logic. A node carrying a LogicStep_* component is one step; hierarchy order defines execution order inside a container. The top-level LogicStep_SerialContainer loops automatically. The Active field on every step is an ActiveOnly gate (Section 7c table footnote): enum(Always, Connected, Disconnected, Never, DontChange), default "Always".

Steps marked “MAY be a no-op” have Unity-only semantics; a web runtime is conforming when it treats them as zero-duration steps.

Sequential container — children execute one after another.

FieldTypeDefaultDescription
ActiveActiveOnly-Connection-state gate: whether this step participates depending on the live-connection state.

Parallel container — children execute concurrently; ends when all children ended.

FieldTypeDefaultDescription
ActiveActiveOnly-Connection-state gate: whether this step participates depending on the live-connection state.
FieldTypeDefaultDescription
SignalComponentReference-Bool signal to set.
SetToTruebooleantrueValue written to the signal.
ActiveActiveOnly-Connection-state gate: whether this step participates depending on the live-connection state.
FieldTypeDefaultDescription
SignalComponentReference-Bool signal to wait for.
WaitForTruebooleantrueExpected signal value.
ActiveActiveOnly-Connection-state gate: whether this step participates depending on the live-connection state.
FieldTypeDefaultDescription
SensorComponentReference-Sensor to wait for.
WaitForOccupiedbooleantrueIf true waits for occupied, otherwise for not occupied.
ActiveActiveOnly-Connection-state gate: whether this step participates depending on the live-connection state.
FieldTypeDefaultDescription
Durationnumber1Wait duration in seconds.
ActiveActiveOnly-Connection-state gate: whether this step participates depending on the live-connection state.

Drives a Drive to a destination and waits for arrival.

FieldTypeDefaultDescription
driveComponentReference-Drive to move.
Destinationnumber0Destination position in millimeters or degrees.
RelativebooleanfalseIf true Destination is relative to the current position.
Directionstring-Reserved; consumed for parity, not evaluated by the v1 reference implementation.
ActiveActiveOnly-Connection-state gate: whether this step participates depending on the live-connection state.

Same semantics as LogicStep_DriveToPosition.

FieldTypeDefaultDescription
driveComponentReference-Drive to move.
Destinationnumber0Destination position in millimeters or degrees.
RelativebooleanfalseIf true Destination is relative to the current position.
Directionstring-Reserved; consumed for parity, not evaluated by the v1 reference implementation.
ActiveActiveOnly-Connection-state gate: whether this step participates depending on the live-connection state.

Starts the motion without waiting for arrival.

FieldTypeDefaultDescription
driveComponentReference-Drive to start.
Destinationnumber0Destination position in millimeters or degrees.
RelativebooleanfalseIf true Destination is relative to the current position.
Directionstring-Reserved; consumed for parity, not evaluated by the v1 reference implementation.
ActiveActiveOnly-Connection-state gate: whether this step participates depending on the live-connection state.
FieldTypeDefaultDescription
driveComponentReference-Drive whose target speed is set.
Speednumber100Target speed in millimeters per second.
ActiveActiveOnly-Connection-state gate: whether this step participates depending on the live-connection state.
FieldTypeDefaultDescription
driveComponentReference-Drive to start.
Speednumber100Target speed in millimeters per second.
ActiveActiveOnly-Connection-state gate: whether this step participates depending on the live-connection state.
FieldTypeDefaultDescription
DrivesComponentReference[]-Drives that must all reach their targets.
ActiveActiveOnly-Connection-state gate: whether this step participates depending on the live-connection state.

Shows/hides a target object.

FieldTypeDefaultDescription
Targetstring""Scene path of the object to enable/disable.
EnablebooleantrueIf true the target is enabled (shown), otherwise disabled (hidden).
ActiveActiveOnly-Connection-state gate: whether this step participates depending on the live-connection state.

Debugging breakpoint. MAY be a no-op.

FieldTypeDefaultDescription
ActiveActiveOnly-Connection-state gate: whether this step participates depending on the live-connection state.
FieldTypeDefaultDescription
SignalComponentReference-Float signal to set.
Valuenumber0Value written to the signal.
ActiveActiveOnly-Connection-state gate: whether this step participates depending on the live-connection state.
FieldTypeDefaultDescription
SignalComponentReference-Float signal to wait for.
Comparisonstring”Equals”Comparison operator name (e.g. Equals, Greater, Smaller).
Valuenumber0Comparison value.
Tolerancenumber0.0001Tolerance for the Equals comparison.
ActiveActiveOnly-Connection-state gate: whether this step participates depending on the live-connection state.
FieldTypeDefaultDescription
GripComponentReference-Grip that picks.
BlockingbooleanfalseIf true the step waits until the pick completed.
ActiveActiveOnly-Connection-state gate: whether this step participates depending on the live-connection state.
FieldTypeDefaultDescription
GripComponentReference-Grip that places.
BlockingbooleanfalseIf true the step waits until the place completed.
ActiveActiveOnly-Connection-state gate: whether this step participates depending on the live-connection state.

Jumps to a named step in the parent container when the signal matches.

FieldTypeDefaultDescription
SignalComponentReference-Bool signal evaluated for the jump.
JumpOnbooleantrueSignal value that triggers the jump.
JumpToStepstring""Step (node) name inside the parent container to jump to.
ActiveActiveOnly-Connection-state gate: whether this step participates depending on the live-connection state.

Starts an IKPath and waits until it ended.

FieldTypeDefaultDescription
IKPathComponentReference-IKPath to start; the step waits until the path ended.
ActiveActiveOnly-Connection-state gate: whether this step participates depending on the live-connection state.

MAY be a no-op in web runtimes.

FieldTypeDefaultDescription
ActiveActiveOnly-Connection-state gate: whether this step participates depending on the live-connection state.

Unity-only camera activation. MAY be a no-op.

FieldTypeDefaultDescription
ActiveActiveOnly-Connection-state gate: whether this step participates depending on the live-connection state.

Statistics cycle start. MAY be a no-op.

FieldTypeDefaultDescription
ActiveActiveOnly-Connection-state gate: whether this step participates depending on the live-connection state.

Statistics cycle end. MAY be a no-op.

FieldTypeDefaultDescription
ActiveActiveOnly-Connection-state gate: whether this step participates depending on the live-connection state.

Statistics state set. MAY be a no-op.

FieldTypeDefaultDescription
ActiveActiveOnly-Connection-state gate: whether this step participates depending on the live-connection state.

Statistics output increment. MAY be a no-op.

FieldTypeDefaultDescription
ActiveActiveOnly-Connection-state gate: whether this step participates depending on the live-connection state.

Signal nodes carry exactly one of the six PLC signal types. The signal’s identity is its scene path; Name (when non-empty) is the display/logical name. All six types share the same field set. Signal direction follows the PLC convention: PLCOutput* is written by the PLC and read by the twin, PLCInput* is written by the twin and read by the PLC.

ActiveOnly (the type of every Active field in this specification) is enum(Always, Connected, Disconnected, Never, DontChange) with default "Always" — see #/$defs/ActiveOnly.

FieldTypeDefaultDescription
Namestring""Signal name; falls back to the node name when empty.
Commentstring""Human-readable comment shown in signal tooltips.
OriginDataTypestring""Original PLC data type of the signal (e.g. BOOL, DINT, REAL).
Settingsobject-Writer-specific signal settings object (e.g. { Active, Override }).
Metadataobject-Free-form protocol metadata object.
ActiveActiveOnly-Connection-state gate for the signal.
Statusobject-Runtime status object; Status.Value seeds the initial signal value.
FieldTypeDefaultDescription
Namestring""Signal name; falls back to the node name when empty.
Commentstring""Human-readable comment shown in signal tooltips.
OriginDataTypestring""Original PLC data type of the signal (e.g. BOOL, DINT, REAL).
Settingsobject-Writer-specific signal settings object (e.g. { Active, Override }).
Metadataobject-Free-form protocol metadata object.
ActiveActiveOnly-Connection-state gate for the signal.
Statusobject-Runtime status object; Status.Value seeds the initial signal value.
FieldTypeDefaultDescription
Namestring""Signal name; falls back to the node name when empty.
Commentstring""Human-readable comment shown in signal tooltips.
OriginDataTypestring""Original PLC data type of the signal (e.g. BOOL, DINT, REAL).
Settingsobject-Writer-specific signal settings object (e.g. { Active, Override }).
Metadataobject-Free-form protocol metadata object.
ActiveActiveOnly-Connection-state gate for the signal.
Statusobject-Runtime status object; Status.Value seeds the initial signal value.
FieldTypeDefaultDescription
Namestring""Signal name; falls back to the node name when empty.
Commentstring""Human-readable comment shown in signal tooltips.
OriginDataTypestring""Original PLC data type of the signal (e.g. BOOL, DINT, REAL).
Settingsobject-Writer-specific signal settings object (e.g. { Active, Override }).
Metadataobject-Free-form protocol metadata object.
ActiveActiveOnly-Connection-state gate for the signal.
Statusobject-Runtime status object; Status.Value seeds the initial signal value.
FieldTypeDefaultDescription
Namestring""Signal name; falls back to the node name when empty.
Commentstring""Human-readable comment shown in signal tooltips.
OriginDataTypestring""Original PLC data type of the signal (e.g. BOOL, DINT, REAL).
Settingsobject-Writer-specific signal settings object (e.g. { Active, Override }).
Metadataobject-Free-form protocol metadata object.
ActiveActiveOnly-Connection-state gate for the signal.
Statusobject-Runtime status object; Status.Value seeds the initial signal value.
FieldTypeDefaultDescription
Namestring""Signal name; falls back to the node name when empty.
Commentstring""Human-readable comment shown in signal tooltips.
OriginDataTypestring""Original PLC data type of the signal (e.g. BOOL, DINT, REAL).
Settingsobject-Writer-specific signal settings object (e.g. { Active, Override }).
Metadataobject-Free-form protocol metadata object.
ActiveActiveOnly-Connection-state gate for the signal.
Statusobject-Runtime status object; Status.Value seeds the initial signal value.

Named group membership. A node MAY belong to several groups; writers serialize additional memberships under the keys Group1, Group2, … with the same shape.

FieldTypeDefaultDescription
GroupNamestring”Group”Name of the group this node belongs to.
GroupNamePrefixstring-Scene path of a node whose name prefixes GroupName (resolved group name = prefixNode.name + GroupName). Shown when present in the GLB, never stamped on newly authored components.

Post-load re-structuring directive from the Unity Kinematic tool.

FieldTypeDefaultDescription
IntegrateGroupEnablebooleanfalseIf true, top-level members of the named group are re-parented under this node after load.
GroupNamestring""Group whose members are re-parented under this node.
GroupNamePrefixstring""Scene path of a prefix node (resolved group name = prefixNode.name + GroupName).
SimplifyHierarchybooleanfalseIf true only mesh nodes of the group are re-parented.
KinematicParentEnablebooleanfalseIf true this node is re-parented under Parent after load.
Parentstring""Scene path of the new parent node.

Movable Unit template marker: the marked node is the template that Source components clone. Carries no consumed configuration fields in v1.

Axis-aligned collider volume in node-local space (sensors, transport surfaces, sources, sinks).

FieldTypeDefaultDescription
centerVector3-Collider center in Unity node-local coordinates (readers negate X in glTF space).
sizeVector3-Absolute box dimensions in node-local units (no coordinate flip).

Layout-planner marker on a placed library object.

FieldTypeDefaultDescription
Labelstring""Display label of the placed object.
CatalogIdstring""Library catalog id the object was placed from.
LockedbooleanfalseIf true the object is locked against layout edits.
VisiblebooleantrueVisibility of the placed object.

Gaussian-splat placement settings.

FieldTypeDefaultDescription
InvertXbooleanfalseInverts the splat along X.
InvertYbooleanfalseInverts the splat along Y.
InvertZbooleanfalseInverts the splat along Z.
CropMinXnumber-1000Local-frame crop box minimum X; splats outside the box are culled.
CropMaxXnumber1000Local-frame crop box maximum X.
CropMinYnumber-1000Local-frame crop box minimum Y (raise to hide floor noise).
CropMaxYnumber1000Local-frame crop box maximum Y (lower to hide ceilings).
CropMinZnumber-1000Local-frame crop box minimum Z.
CropMaxZnumber1000Local-frame crop box maximum Z.

Asset Administration Shell link.

FieldTypeDefaultDescription
AASIdstring""AAS identifier (e.g. ‘http://smart.festo.com/aas/9992020…’).
Descriptionstring""Optional description shown in the tooltip header.
ServerUrlstring""Optional AAS server URL; when empty the AASX is loaded from the local aasx/ folder.

Playback settings for a recorded drive sequence.

FieldTypeDefaultDescription
PlayOnStartbooleantrueIf true playback starts automatically on simulation start.
ReplayStartFramenumber0First frame of the replay range.
ReplayEndFramenumber0Last frame of the replay range; 0 = to end.
LoopbooleanfalseIf true the replay loops.
DrivesRecordingobject-Inline recording data (Unity ScriptableObject serialization).
ActiveActiveOnly-Connection-state gate: controls playback in connected/disconnected mode.

Compact drive recording: positions[frame * driveCount + driveIndex].

FieldTypeDefaultDescription
fixedDeltaTimenumber0.02Fixed timestep of the recording in seconds.
numberFramesnumber0Number of recorded frames.
driveCountnumber0Number of recorded drives.
drivesobject[]-Array of { id, path } drive descriptors.
sequencesobject[]-Optional array of { name, startFrame, endFrame } named sequences.
positionsnumber[]-Flat drive positions array indexed as positions[frame * driveCount + driveIndex].

Signal-triggered replay of a named sequence.

FieldTypeDefaultDescription
Sequencestring""Name of the sequence inside the recording to replay.
StartOnSignalComponentReference-Bool signal that starts the replay on a rising edge.
IsReplayingSignalComponentReference-Bool signal set true while the replay is running.
ActiveActiveOnly-Connection-state gate: controls replay in connected/disconnected mode.
  • Drive_CAM — present in Unity exports; not yet consumed by the reference implementation. Reserved for a future minor version; readers MUST ignore it.

Typed, directed connections between components. A connection is a named bidirectional call: the source invokes the target with request parameters, the target answers — usually deferred through a reply handle — with response parameters. Edges are stored as a flat list (serialization truth); readers build any adjacency index at runtime. Readers MUST ignore a missing Connections block (older assets load unchanged) and MUST treat edges whose source/target paths do not resolve as inactive.

Built-in, engine-semantic types (currently StopOnExit) are registered in reader code and need no connectionTypes entry. StopOnExit links a sensor (source) to a station (target): an MU reaching the sensor is stopped — on an accumulating transport surface as a single-MU hold (the belt keeps running), otherwise (or for instanced MUs) by stopping the surface’s drive — handed to the station as a reference (onArrival(mu)) and released with mu.release().

Note: the top-level Connections block is distinct from the ProcessingUnit.connections component property (pipe network fan-in/out) — the names collide, the data does not.

Scene-level container, typically carried on the root node.

FieldTypeDefaultDescription
connectionsarray-Flat edge list (RvConnection records). 1:n fan-out/fan-in via repeated source/target paths.
connectionTypesarray-User-defined connection type signatures (ConnectionType records).

One directed connection edge.

FieldTypeDefaultDescription
idstring-Stable edge id, unique within the scene.
sourcestring-Slash-separated node path of the source (caller) end.
targetstring-Slash-separated node path of the target (callee) end.
typestring-Connection type name — built-in (StopOnExit) or user-defined via connectionTypes.
configobject-Type-specific per-edge configuration, e.g. { "ProcessTime": 3.0 } for StopOnExit.

User-defined connection type signature — makes a GLB self-describing: the viewer renders typed inspector fields and validates call parameters without any code. Parameter wire types are bool, int, float, string.

FieldTypeDefaultDescription
typestring-Type name referenced by RvConnection.type.
requestobject-Request parameter schema: parameter name to wire type (bool, int, float, string).
responseobject-Response parameter schema: parameter name to wire type (bool, int, float, string).

rv-odt.json uses the following custom keywords beyond JSON Schema 2020-12. Generic JSON Schema validators MUST ignore unknown keywords, so rv-odt.json remains a valid 2020-12 schema.

Property description texts are informative: they are maintained in rv-odt.json (the single source for inspector tooltips, add-ons and third-party tools) and mirrored into the Section-7 tables of this document.

  • unit (string, OPTIONAL, on number properties)UCUM-conformant unit code (e.g. mm, mm/s, s, Hz, bar, Cel). Documentation-only; validators MUST ignore it. Readers MUST NOT perform unit conversion based on it.
  • unityCoords (boolean, OPTIONAL, on properties with $ref: "#/$defs/Vector3") — When true, the vector is serialized in Unity left-handed coordinates and a conforming reader operating in glTF right-handed space MUST negate the X component when applying the value.
  • aliases (object, OPTIONAL, top-level on a component $def) — Maps a primary field name to an array of legacy field names. When the primary field is absent in the data but a legacy alias is present, a conforming reader SHOULD read the value from the alias. Writers MUST emit only the primary field name.
  • enumMap (object, OPTIONAL, on enum properties) — Complete map of accepted wire strings to reader-internal values, including legacy integer indices serialized as strings. When absent, the mapping is the identity over the enum array. Writers MUST emit only canonical enum values.
  • signal (string, OPTIONAL, on ComponentReference properties) — Declares the slot as a standard PLC signal of the given type (PLCOutputBool, PLCInputFloat, …). A conforming runtime SHOULD auto-provision an unwired slot as a signal named <node>/Signals/<slot>.
  • readonly (boolean, OPTIONAL) — The field is informational; interactive tools SHOULD display it but MUST NOT offer editing.
  • rawFields (object, OPTIONAL, top-level on a component $def) — Documents fields that the reference implementation consumes OUTSIDE the schema mapper (e.g. nested object lists, colors, pre-computed solver arrays, legacy hints). They are part of the wire format but carry no default/coercion semantics; readers MAY consume them and MUST tolerate their absence. Documentation-only for validators.
  • deprecated (object, OPTIONAL, on properties){ "since": "<semver>", "replacedBy": "<fieldName>" &#125;. Documentation-only; for actual field migration use aliases. (No field is deprecated in v1.0.)

A conforming writer:

  1. MUST emit component data only under node.extras.realvirtual.
  2. MUST emit field values that validate against the component $def in rv-odt.json.
  3. MUST emit enum values as canonical strings from the enum array.
  4. MUST emit primary field names (never aliases).
  5. SHOULD stamp _formatVersion: "1.0" at the root of extras.realvirtual.
  6. SHOULD omit fields whose value equals the declared default.

A conforming reader:

  1. MUST apply declared defaults for absent fields.
  2. MUST ignore unknown components and unknown fields.
  3. MUST accept every canonical enum value; SHOULD accept all enumMap keys.
  4. SHOULD read legacy aliases when the primary field is absent.
  5. MUST negate the X component of unityCoords vectors when operating in glTF space.
  6. MUST report an incompatibility when _formatVersion has a greater major version than the reader implements.

The directory conformance/ contains test GLB files with *.expected.json fixtures describing the exact component state a conforming reader must produce after loading (defaults applied, aliases resolved, enums mapped). realvirtual WEB is the reference implementation and runs this suite in CI (tests/conformance.test.ts).

  • The format uses semantic versioning; this document specifies 1.0.
  • Minor versions (1.x) are additive only: new components, new OPTIONAL fields, new enum values. A 1.0 reader remains conforming when reading 1.x data (unknown keys are ignored).
  • Major versions change or remove existing semantics and get a new URL prefix (/schema/odt/v2/). /v1/rv-odt.json serves the latest compatible 1.x schema; each /v1.N/rv-odt.json release snapshot is byte-immutable.
  • Component schema changes require a matching update of the reference implementation’s frozen baseline test in the same change set (drift protection).
  • The specification is maintained by realvirtual GmbH in the realvirtual WEB repository (schema/ subtree).
  • Proposals for new components or fields are accepted via issues/pull requests on the public repository. Acceptance criteria: implementable by at least the reference implementation, no breaking change within a major version, complete field documentation (type, default, unit).
  • The spec text and rv-odt.json are CC BY 4.0; anyone may implement readers and writers, commercially or otherwise, with attribution.
  • Out of scope for v1 (explicitly): DES (discrete-event simulation) plugin components (DES*) and dynamically registered library behavior schemas (ConveyorBehavior, TurntableBehavior, SourceBehavior, SinkBehavior, ChainTransferBehavior, and the material-flow types Conveyor, Turntable, ChainTransfer). These are realvirtual WEB runtime concerns, not part of the interchange format. Drive_CAM is reserved (Section 7f).