XSMP Assembly (.xsmpasb)¶
Assembly files instantiate systems from catalogue types, configure instances and define local links between instantiated components.
This page documents the assembly grammar in detail, including template parameters, instance forms, configuration blocks, links, invocations, values and paths.
Document comments and metadata¶
Assembly files use the shared document-comment rules described in Shared Syntax: Comments, Paths, Templates and Values.
Use a leading documentation comment with the shared root-level tags @title, @date, @creator and @version when you want to enrich exported SMP metadata.
Example:
/**
* Orbital segment assembly.
* @title Orbital Segment Assembly
* @creator alice
* @date 2026-03-27T08:00:00Z
* @version 1.0
*/
assembly OrbitalSegment
Root structure¶
An Assembly declares one reusable instantiated system: optional template parameters, optional configuration blocks and exactly one root model instance.
Syntax¶
assembly [<template-parameter>[, <template-parameter>]*] <name>
<configure-block>*
<root-model-instance>
<configure-block>*
Required:
assembly- the assembly name
- exactly one root model instance
Optional:
- template parameters
- configuration blocks before the root model instance
- configuration blocks after the root model instance
Example:
assembly <Lane = "Ops"> OrbitalSegment
configure Avionics{Lane}
{
property mode = demo.foundation.Mode.Nominal
}
Scenario{Lane}: demo.orbit.OrbitalPlatform
{
avionics += Avionics{Lane}: demo.avionics.AvionicsUnit
}
Template parameters¶
Template Parameters let one assembly definition be reused with different names or numeric settings.
Assemblies support two parameter kinds:
- string parameters
int32parameters
Assemblies use the shared template-parameter forms documented in Template parameters and placeholders.
Examples:
<Lane: string>
<Lane: string = "Ops">
<Index: int32 = 1>
configure blocks¶
A Configure Block applies local subscriptions, calls, property updates or field assignments to one named instance in the assembly.
Syntax¶
configure <instance-path>
{
(<subscribe> | <call> | <property> | <field-assignment>)*
}
Required:
configure- one instance path
- one block body
Inside the block you can write:
- global-event subscriptions
- operation calls
- property assignments
- field assignments
Example:
configure Avionics{Lane}
{
subscribe step -> "PlatformReady"
property mode = demo.foundation.Mode.Nominal
call apply(requestedMode = demo.foundation.Mode.Nominal)
}
Global event subscriptions¶
A Global Event Subscription connects one local entry point to one named global event.
Syntax¶
subscribe <entrypoint> -> "<global-event-name>"
Required:
subscribe- one local entrypoint reference
->- one string event name
Example:
subscribe step -> "PlatformReady"
Root model instance¶
A Root Model Instance is the top-level component instantiated by the assembly.
Syntax¶
<instance-name> : <component-type-or-string> [ { ... } ]
Required:
- the instance name
:- one implementation
Optional:
- a block body
The implementation is usually a qualified component type such as:
Scenario: demo.orbit.OrbitalPlatform
You may also use a quoted implementation name:
Scenario: "legacy.platform.type"
The block may contain:
subscribe- sub-instances
- links
- invocations
- field assignments
Sub-instances¶
Sub-Instances populate a container of the current model instance with either child model instances or child assembly instances.
Syntax¶
<container> += <model-instance-or-assembly-instance>
Required:
- one local container reference
+=- one model instance or assembly instance
Optional:
unsafeon the container reference
Behavior:
- the container determines which child component or assembly types are valid
- the statement adds one occurrence to the selected container
The container reference may be marked unsafe:
unsafe payload += PayloadA: PayloadSegment
Sub model instances¶
A Sub Model Instance creates one direct child component inside a container.
Syntax¶
<container> += <instance-name> : <component-type-or-string> [ { ... } ]
Required:
- the target container
- the instance name
- one implementation
Optional:
- a block body
Behavior:
- the created child is typed against the selected container
- the optional block initializes the child instance locally
Example:
avionics += Avionics{Lane}: demo.avionics.AvionicsUnit
Sub assembly instances¶
A Sub Assembly Instance creates one child from another assembly definition, optionally with template arguments, configuration and a reusable link base.
Syntax¶
<container> += <instance-name> : <assembly-name>
[<template-argument>[, <template-argument>]*]
['using' 'config' <configuration-name>]
['using' 'link' <link-base-name>]
[ { <configure-block>* } ]
Required:
- the target container
- the instance name
- the referenced assembly name
Optional:
- template arguments
using config ...using link ...- inline
configureblocks
Example:
payload += PayloadA: PayloadSegment<Lane = "A", Index = 1>
using config PayloadNominal
using link PayloadLinks
{
configure SensorHead
{
property mode = demo.foundation.Mode.Nominal
}
}
Template arguments¶
Template Arguments bind concrete values to the template parameters expected by a referenced assembly.
Assemblies support the same argument kinds as schedules:
- string arguments
int32arguments
Syntax:
<parameter-name> = "<value>"
<parameter-name> = <integer>
Required:
- one parameter name
=- one concrete argument value
Optional:
- additional arguments separated by commas
Behavior:
- each argument is matched by parameter name
- argument types are checked against the referenced assembly template parameters
Examples:
<Lane = "A", Index = 1>
Local links¶
Local Links let an assembly define wiring directly inside instance bodies when links should stay close to instantiation logic.
Assemblies may define local links directly inside model-instance bodies.
Event link¶
An Event Link connects one event source path to one compatible event sink path.
Syntax:
event link <owner-path> -> <client-path>
Required:
event link- one owner path
->- one client path
Behavior:
- the owner path must resolve to an event source
- the client path must resolve to a compatible event sink
Example:
event link publishedMode -> child.commandedMode
Field link¶
A Field Link connects one output field path to one compatible input field path.
Syntax:
field link <owner-path> -> <client-path>
Required:
field link- one owner path
->- one client path
Behavior:
- the owner path must resolve to an output-compatible field
- the client path must resolve to an input-compatible field
Example:
field link power.lineVoltage -> router.incomingBus
Interface link¶
An Interface Link connects one published reference to one client instance, optionally with a back reference on the client side.
Syntax:
interface link <source-path> -> <client-path> [ :<back-reference> ]
Required:
interface link- one source path
->- one client path
Optional:
:<back-reference>
Important behavior:
- the last segment of
source-pathselects the published reference - earlier source-path segments navigate to the owner instance
back-referenceselects a local reference on the client side
Examples:
interface link logger -> payload
interface link nested.logger -> payload:backLogger
Invocations¶
Invocations let an assembly initialize behavior-oriented members instead of only writing raw field values.
Invocations are:
- operation calls
- property assignments
call¶
A Call Invocation invokes one local operation with zero or more named arguments.
Syntax¶
call <operation>( [<parameter-name> = <simple-value>[, ...]] )
Required:
call- one local operation reference
- parentheses
Optional:
- named parameters
Example:
call apply(requestedMode = demo.foundation.Mode.Nominal)
property¶
A Property Invocation initializes one local property through its setter semantics.
Syntax¶
property <property> = <simple-value>
Required:
property- one local property reference
=- one simple value
Example:
property mode = demo.foundation.Mode.Nominal
Field assignments¶
Field Assignments initialize direct field state either inside an instance body or inside a configure block.
Syntax¶
<field-path> = <value>
These can appear:
- inside model-instance bodies
- inside
configureblocks
Required:
- one target field path
=- one value
Optional:
- no extra syntax beyond the target path and value
Behavior:
- the assigned value is checked against the resolved field type
Example:
missionMode = demo.foundation.Mode.Standby
Values¶
Assembly Values group the literal forms accepted in field assignments, property assignments and operation arguments.
Assemblies support:
- simple values
- arrays
- structures
The shared scalar literal rules, including numeric suffixes such as i32, u16, f64, lit, d and dt, are documented in Shared Syntax: Comments, Paths, Templates and Values and Numeric suffixes.
Simple values¶
Simple Values are the shared scalar literals accepted in field assignments, property assignments and operation arguments.
Examples:
priority = 1u8
gain = 0.5f32
mode = 2lit
timeout = "PT5S"d
When the target type is already clear from the surrounding field, property or parameter, you may also write plain integers and plain floating-point values.
Arrays¶
An Array Literal initializes an array-typed value in one expression.
Syntax:
[<value>[, <value>]*]
Required:
- opening and closing brackets
- zero or more array elements
Optional:
- commas between elements
Behavior:
- each element is checked against the target item type
Example:
tuning = [1.0, 0.6, 0.3]
Structures¶
A Structure Literal initializes a structure-typed value with positional or designated members.
Syntax:
{
[<field-path> =] <value>[, ...]
}
Required:
- opening and closing braces
- zero or more structure elements
Optional:
- designated member paths
- commas between elements
Assembly structure elements may be:
- positional values
- designated field assignments using a path
Behavior:
- positional values follow member order
- designated paths let you initialize members explicitly by name
Example:
thermal = {
sensor = 17.5,
target = 20.0,
enabled = true
}
Paths¶
An Assembly Path identifies instances, members and linked endpoints inside the instantiated hierarchy.
Assembly paths are used in:
configure- field assignments
- event links
- field links
- interface links
Assembly paths use the shared path model described in Shared Syntax: Comments, Paths, Templates and Values, the shared unsafe behavior documented in unsafe, and the shared placeholder forms described in Template parameters and placeholders.
Behavior:
- an absolute path starts from the root model instance
- a relative path starts from the current instance context
- the last segment may resolve to a field, event source, event sink, reference or other member depending on usage
Examples¶
/platform
avionics.power
nested.logger
../router
payloads[0]
{BusMember}.logger
unsafe child.inValue
Minimal complete example¶
/**
* @title Orbital Segment Assembly
* @creator alice
* @date 2026-03-27T08:00:00Z
* @version 1.0
*/
assembly <Lane = "Ops"> OrbitalSegment
configure Avionics{Lane}
{
subscribe step -> "PlatformReady"
property mode = demo.foundation.Mode.Nominal
}
Scenario{Lane}: demo.orbit.OrbitalPlatform
{
avionics += Avionics{Lane}: demo.avionics.AvionicsUnit
router += Router{Lane}: demo.orbit.PowerRouter
logger += Logger{Lane}: demo.orbit.SegmentLogger
interface link logger -> avionics:backLogger
}