Skip to main content
Version: 0.9.0

Launcher Configuration Reference

The runtime launcher (qar-runtime-launcher.exe) is configured by one JSON object. This page lists every key it reads.

Where the configuration comes from​

Started byConfiguration used
Launcher alone, empty inputqar-runtime-launcher.jsonc next to the launcher executable.
Tray (qaros-hub-service.exe <config-path>)The file given as the tray's first argument.
Tray, no argumentqar-runtime-launcher.jsonc next to the launcher executable.
  • Every config file may contain // and /* */ comments.
  • A file that cannot be parsed is reported and the Hub does not start on defaults: fix the file.

The tray always adds startupTarget and startupTargetPath (see Hub interconnect) and sets prewarmVisualizer: true unless the file sets it.

  • Unknown keys are ignored.
  • "Default" below is the value used when the key is omitted. The shipped qar-runtime-launcher.jsonc sets some keys differently; those are noted.

Schema version​

KeyTypeDefaultEffect
schema_versioninteger-Config schema version. Current: 3. Older versions are migrated on load; a newer version is rejected. _sv is accepted as an alias; schema_version wins if both are set.

Migrations applied on load:

FromChange
1 -> 2onboardingInviteIntervalSec renamed to codeRotationSec. maxAutoPipelines and handleSourceAppLaunchRequests removed.
2 -> 3targetApps entries with deviceType: "ZedCamera" dropped (a ZED is a source app, not a target).

Identity and logging​

KeyTypeDefaultEffect
hubCommonNamestring"hub.qaros.local"Common name of the Hub's mTLS identity. Give federated Hubs distinct names.
logSeveritystring or integer"debug"Log level for the launcher and the processes it spawns. trace, debug, info, warn (or warning), error, fatal, or 0-5 in the same order.
zenohRustLogLevelstring"info"Log level of the message-router (Zenoh) crates; other Rust crates stay at warn. One of trace, debug, info, warn, error, off. Any other value fails startup.
peerIdstring (UUID)-Overrides the Hub's peer id. Omit it: the Hub keeps a durable id in its own store.
{ "hubCommonName": "hub.lab2.qaros.local", "logSeverity": "info", "zenohRustLogLevel": "warn" }

Paths​

Paths default to the data root or the log root (Installation: Where data and logs live).

KeyTypeDefaultEffect
caDirpath<data root>/hub-caHub certificate authority directory.
runtimeStorageRootpath<data root>Root of identity store, trust store and launcher session state.
logFolderpath<log root>/qar-launcher-default/<session-id>Log folder. The default folder is emptied on every start; a configured one is not.
startupTargetPathpath-File the launcher writes the Hub-interconnect target to after connecting to another Hub. Without it the interconnect is not restored on the next start. Set by the tray to startup-target.json: next to the config file passed as the tray's first argument, otherwise in the tray's log folder (<log root>/qaros-hub-service).
{ "caDir": "C:/ProgramData/Quaternar/hub-ca", "logFolder": "C:/ProgramData/Quaternar/logs/runtime-launcher" }

Networking​

KeyTypeDefaultEffect
routerPortinteger-Fixed message-router port. Omit it: the Hub takes the first port in the range below free on both TCP and UDP, so several local Hubs coexist. Pin it only for a firewalled deployment.
routerPortRangeStartinteger19120First port searched when routerPort is unset. The onboarding listener (discovery, pairing, shared-password onboarding) takes its port from the same range, skipping the router port, unless discoveryPort / onboardingPakePort pins it.
routerPortRangeEndinteger19199Last port searched when routerPort is unset, and for the onboarding listener.
sessionEndpointsarray of locator strings or address objects-Endpoints put into invites sent to devices. Omit (or leave empty) to derive them from the router's listening address. Must be an array (a bare string is rejected). Each entry is either a locator string "<protocol>/<host>:<port>" (IPv6 host in brackets) or {"Protocol": "tcp", "Hostname": "<ip-or-host>", "Port": <1-65535>} with all three fields; both forms may be mixed. A malformed entry stops the launcher with an error message.
discoveryHoststring""Host name or IP advertised in the discovery beacon as the discovery server address.
discoveryPortinteger0TCP port of the onboarding listener (discovery requests, pairing, shared-password onboarding). 0 takes the first free port of the router range. Nonzero pins it: that port, or the Hub does not start. Same listener as onboardingPakePort; if both are set they must match. The UDP multicast beacon stays on 7445.
discoveryDisplayNamestring-Overrides the Hub name shown in discovery. Omit it: the Hub keeps its persisted name (initially "QAROS Hub").
hubRoomNamestring-Overrides the Hub's room name. Omit it: the Hub keeps its persisted room.
{
"routerPort": 19120,
"sessionEndpoints": [ "tcp/192.168.1.20:19120", { "Protocol": "tcp", "Hostname": "hub.lab2.local", "Port": 19120 } ]
}

See Networking & Federation for firewall rules.

Onboarding​

KeyTypeDefaultEffect
onboardingPakePortinteger0Same listener as discoveryPort, kept for older configs. 0 takes the first free port of the router range; nonzero pins it, or the Hub does not start.
codeRotationSecinteger8Seconds between freshly minted pairing codes. A code lives at least 10 s, or longer if this is larger.
pakeCodeLengthinteger8Characters in the human-entered pairing code.
certLifetimeHoursintegerCA defaultLifetime of certificates issued to onboarded devices.
{ "codeRotationSec": 8, "pakeCodeLength": 8, "certLifetimeHours": 168 }

See Security Model and Managing Devices.

Visualizer​

KeyTypeDefaultEffect
autoLaunchVisualizerbooleanfalse (shipped file: true)Open the single control visualizer when the Hub starts. A launcher an application starts through the C API without this key opens no window.
prewarmVisualizerbooleanfalse (tray: true)When autoLaunchVisualizer is off, start the visualizer hidden so opening it later is instant.
openVisualizerOnStartupbooleantrueRead by the tray, not the launcher: show the visualizer once the Hub has started.

Pipeline behaviour​

KeyTypeDefaultEffect
enableMixerbooleantrueInsert the mixer between source apps and targets. See The Mixer.
unifyTargetAppWithMixerbooleanfalseRun the mixer inside the target's process where the target supports it, instead of as its own process. Only with enableMixer.
applyDeterministicIdsbooleantrueKeep launcher-assigned peer ids stable across restarts, so child processes reuse their onboarding identities instead of re-enrolling.
targetAppOverridestring"None"Launch this target app for every target request instead of the one matching the device. None, StreamVisualizer, HoloLens, MetaQuest, StereoKit, AndroidStreamer.
handleInvitesbooleantrueAnswer session-invite requests.
detectConnectedPeersbooleantrueTrack peers connecting to the session.
replyToServiceExistsbooleantrueAnswer service-existence probes.

Source apps (sourceApps[])​

Each enabled entry is a source application added to every new target pipeline, with its app volume registered at startup. A missing or empty array means no source apps.

KeyTypeDefaultEffect
enabledbooleantruefalse skips the entry.
typestring"StereoKit"Source app kind: StereoKit, CpuRenderer, Ogre, ZedCamera, VRGB, OpenXr.
appVolumeCommonNamestringrequiredStable name of the app volume (get-or-create key, not a UUID). Use a reverse-domain name unique across Hubs, e.g. slot0.hub1.example.com. An empty or missing name fails startup. Alias: appVolumeId.
appVolumeDisplayNamestring"AppVolume_<index>"Name shown in the UI. Alias: displayName.
appVolumePoseobjectplaced on a diagonal by indexposition [x,y,z] and orientation [x,y,z,w] (or {x,y,z[,w]} objects). Each field optional.
appVolumeSize[x,y,z] or object[1.5,1.5,1.5]Volume size in metres. Alias: size.

Entries must be objects; bare type strings are rejected.

"sourceApps": [
{
"enabled": true,
"type": "StereoKit",
"appVolumeCommonName": "slot0.hub1.example.com",
"appVolumeDisplayName": "StereoKit Source",
"appVolumePose": { "position": [0.2, 0.0, 0.2], "orientation": [0, 0, 0, 1] },
"appVolumeSize": [1.5, 1.5, 1.5]
}
]

Target apps (targetApps[])​

Each enabled entry is a device the Hub invites into the session at startup. Startup waits for each invite to be accepted.

KeyTypeDefaultEffect
enabledbooleantruefalse skips the entry.
hostnamestring""Host name or IP of the device.
deviceTypestring"Visualizer"HoloLensARHeadset, MetaQuestHeadset or AndroidStreamer. Visualizer and CameraVisualizer are ignored with a warning: use autoLaunchVisualizer instead.
configOverridesobject{}Passed into the launched app's config (e.g. roomTag). Aliases: specialKeys, config.
"targetApps": [
{ "enabled": true, "hostname": "192.168.1.42", "deviceType": "MetaQuestHeadset", "configOverrides": { "roomTag": "default" } }
]

Hub interconnect (startupTarget)​

Selects whether the launcher hosts a local Hub or rejoins another Hub at startup. Normally written by the tray from startup-target.json; you rarely set it by hand. See Networking & Federation.

KeyTypeDefaultEffect
typestring"auto""local" or "auto". Any other value means "auto".
hubConnectionIdstring-Id of a saved connection to another Hub. When set, the launcher rejoins that Hub instead of hosting a local one.
trustedHubCaBundlesarray[]CA bundles of other Hubs to trust. Each entry: HubId, CaBundlePem, CertificateFingerprints[]. A malformed array is ignored with a warning.
"startupTarget": { "type": "auto" }