FacilityVR
← Back to Documentation

Scenario Authoring Guide

A guide to author better VR scenarios

This document is a reference for trainers creating scenarios in FacilityVR. It covers scenario configuration, equipment interaction, and advanced features.

Note: The facility layout and equipment reference sections below use the datacenter as an example. The same principles apply to all facility types (warehouse, oil rig, offshore, wind turbine, etc.). Each facility type has its own equipment with unique hotspots — use the dashboard’s equipment dropdowns to see available interactions for your layout.


New Features

Produce Mode Scenarios

Produce scenarios flip the model: instead of giving the trainee a fully-built layout to walk through, you give them a layout to build themselves. Their placements are graded against rule primitives you author. Each student gets their own per-attempt clone of the layout — their work never touches the original.

Use this when you want to assess design skills, not just procedure-following: “rack two production servers with redundant PDUs”, “lay out fire safety signage for this floor plan”, “wire the power chain from junction box to rack PDUs”, and so on.

Authoring a Produce scenario

  1. Create a new scenario, set Scenario Type to Produce (student constructs layout) at the top of Basic Information.
  2. Pick the facility layout the student will fork. Each attempt gets a clone of this layout — items the student places never affect the original.
  3. The Pre-Conditions, State Reactions, Scenario Equipment, and Cooperative sections are hidden because they don’t apply to Produce mode. (Equipment initial state and reactions live on the layout itself for Produce mode — author them in the in-VR layout editor.)
  4. Add one or more Steps. Each step has a title, description, and a set of rules that grade the student’s clone.
  5. Pick a Pass mode for each step:
    • All rules must pass — every rule has to come back green.
    • At least N rules pass — set the threshold below; useful for “do any 3 of these 5”.
    • Weighted score ≥ threshold — each rule gets a weight; passes if sum(passed weights) / sum(all weights) ≥ threshold.
  6. Save and publish as you would any scenario.

Produce rule primitives

PrimitiveWhat it checksExample
item_countCount placements matching a filter, assert min/maxAt least 2 server racks placed
spatialEvery subject within (or none within) a distance of a targetEvery rack within 5 m of a CRAH unit
coverageEvery subject is covered by at least one nearby targetEvery aisle has a smoke detector overhead
spacingMinimum pairwise distance between matching itemsNo two racks closer than 1.2 m
connectivityA and B are linked by a connector decorationPDUs cabled to racks
sequenceA connector path walks expected items in orderPower flow: junction box → switchboard → UPS → PDU → rack PDU

Filters in every primitive can match by equipment type, decoration type, tag on the placement, space, and (for signs) sign type. The dashboard’s rule editor pulls the equipment-type and space dropdowns from your selected layout — typing also works for tags or types you haven’t placed yet. When decoration type is set to sign, an extra Sign type picker appears, populated with all ISO-categorised safety signs so you can require a specific sign per space (e.g. fire_extinguisher in the kitchen, emergency_exit in the corridor).

Connector primitives (connectivity, sequence) look for connector-style decorations placed in the layout. Pick the style (cable, pipe, conduit, etc.) the student must use; tolerance defines how close (in metres) a connector vertex must be to an equipment item to count as touching it (default 0.5 m). Sequence has two modes: any (one path satisfies the order — “demonstrate flow to any rack PDU”) or each (every terminal item is reached by some sequence-matching path — “supply power to every rack PDU”).

Worked examples for every primitive — including one-rule-per-space patterns, weighted/mandatory mixes, and common pitfalls — live in the Build-Rules Cookbook.

Assigning a Produce scenario

Same flow as Perform scenarios: assign to a trainee or attach the scenario to a course step. On the assignment detail page, Produce scenarios show an Attempts panel instead of the usual Launch button:

  • Trainee clicks Open Editor → backend forks the layout into a clone owned by them → the 3D Designer opens in a browser tab.
  • Trainee builds, can Reset in practice mode (assessment mode is trainer-only reset), and clicks Submit when done.
  • Submit locks the clone, runs the rules server-side, and pops a result modal with per-step pass/fail and the overall score.
  • In-editor Start Assessment — assignments created in practice mode show a yellow Start Assessment button in the editor toolbar. Clicking it flips the assignment to assessment mode and resets the clone (the current practice attempt is marked abandoned and a fresh clone is forked) so the trainee can’t carry practice progress into the graded attempt. The switch is one-way.
  • Trainer sees every attempt in the panel with status + score and can open any attempt read-only.
  • Trainer can Re-evaluate a submitted attempt without unlocking — pick snapshot (rules-as-submitted) or current (whatever the rules say today, overwrites the score).

In-editor experience for the trainee

Produce exercises run in the browser — same desktop editor that trainers use to author layouts (mouse + WASD navigation). VR headsets are only used for Perform scenarios; the editor’s HTML overlay (sidebar pickers, step panel) doesn’t have a VR equivalent yet. The Produce-mode editor keeps the same placement controls as the layout editor but adds:

  • A left-side step panel listing every step with a live status indicator (green ✓ / red ✗ / grey). Click a step to expand it and see per-rule detail — the rule lines explain why a rule passed or failed (e.g. “Found 1 server_rack, expected 2-3”).
  • 3D failing-subject highlights — when a step is expanded, every failing item in that step gets a pulsing red ring on the floor and a bobbing arrow above it. Visible through walls so the student can find offenders fast.
  • A Submit button in the toolbar. Submit warns if there are unsaved changes and asks for confirmation since it’s irreversible.

After submit, the editor reloads in read-only mode — pickers are hidden, the banner reads “submitted”, and the student (and trainer) can still walk through the layout and inspect what was graded.

Walking the build in VR

The student’s most-recent Produce attempt for each scenario also appears in their VR headset’s lobby under a My Attempts section. They can put on a headset and walk through what they built (or what they’re still building). Other students don’t see each other’s clones — that’s a Phase 3 sharing feature. Trainers don’t see student clones in the lobby either; review happens via the dashboard’s Attempts panel.

Self-paced students in courses

Course modules can include scenario steps. When a self-paced student reaches a Produce-scenario step, the course-learn page shows the same Attempts panel — no trainer push needed. The assignment is materialised on demand; subsequent visits resume the in-progress clone.

Scenario Equipment (Temporary Items)

Scenarios can now add temporary equipment to a layout that only appears during that scenario. This enables:

  • Pick & pack training — place cartons with specific barcodes on racking shelves
  • Assembly training — place ingredients or components on a work surface
  • Inspection scenarios — place items that need to be found and checked

Configure in the Scenario Equipment section of the scenario form:

  1. Select the target space (room) in the layout
  2. Choose an equipment type (e.g. carton, pallet)
  3. Set a unique ID and label
  4. Set the position (x, y, z) within the space
  5. Use pre-conditions to set initial values (e.g. barcode numbers)
  6. Use Equipment Move task steps to validate pick-and-place actions

Temporary items are removed when the scenario ends.

Animated Equipment Parts

Equipment can have parts that move in response to interactions:

EquipmentInteractionAnimation
Counterbalance forkliftPull lift leverForks rise/lower smoothly
Reach truckPull lift leverFork carriage moves up/down mast
Pallet jackPump handleForks rise slightly

Animations are state-driven — use state reactions to chain them (e.g. pressing a button triggers a valve animation).

Custom equipment created by the AI can also have animated parts using stateBinding.transforms on procedural geometry parts.

Equipment Labels

Floating text labels above equipment can be controlled:

  • Per layout — toggle on the facility detail page Settings card
  • Assessment mode — automatically hidden
  • Hints disabled — automatically hidden

Template Scenario Bundling

When publishing a layout as a template, you can select scenarios to bundle with it. When another user forks the template, they can choose to import the bundled scenarios as drafts linked to their new layout.


Facility Layout (Demo Data Center Example)

                    +Z (south)

                      VESTIBULE
                      (entry — white/grey zone transition)
                           |
                      vestibule corridor
                           |
     COOLING ROOM                          POWER ROOM
     2× CRAH units                        2× UPS
          |                                4× PDU
          +--- west corridor ---+--- east corridor ---+
                                |
                         MAIN DATA HALL
                         12× Server Racks (rows A+B)
                         8× Raised Floor Tiles
                         1× EPO Button (south wall, near exit)
                                |
                    CONTROL ROOM
                    4× Patch Panels
                    1× Crash Cart
                    1× Fire Suppression Panel
                    3× Control Room Screens

     GENERATOR YARD (outdoor)
     2× Diesel Generators
     2× Fuel Tanks
     2× Fuel Pipes (with shutoff valves)
     1× Fire Extinguisher
          |
     yard access corridor
          |
     COOLING ROOM (north door)

                    -Z (north)

Equipment Reference

Server Rack

Location: Main Data Hall — 12 units in two rows (A1–A6, B1–B6)

Object IDInteractionPropertyPossible Values
rack-A1rack-B6LED indicatorstatus"ok" (green), "warning" (amber), "failed" (red)
rack-A1rack-B6Display labelvalueAny text (e.g. "A1 — DEGRADED")
rack-A1-doorrack-B6-doorToggleable — click to open/closeFront door swings open
rack-A1-drive1drive4Grabbable — click to remove/insertHot-swap drive bay
rack-A1-drive1drive4LED indicatorstatus"ok" (green), "warning" (amber), "failed" (red)

Each rack has 4 drive bays (drive1–drive4) and a front door.


PDU (Power Distribution Unit)

Location: Power Room — 4 units (pdu-1, pdu-2, pdu-3, pdu-4)

Object IDInteractionPropertyPossible Values
pdu-1Display labelloadAny text (e.g. "45%", "OVERLOAD")
pdu-1-switch1switch6Pressable — click to toggleontrue / false
pdu-1-switch1switch6LED indicatoronMirrors switch state
pdu-1-mainPressable — main breakerontrue / false

Each PDU has 6 individual breaker switches and 1 main power switch.


CRAH Unit (Computer Room Air Handler)

Location: Cooling Room — 2 units (crah-1, crah-2)

Object IDInteractionPropertyPossible Values
crah-1Display labeltempTemperature text (e.g. "22", "28")
crah-1Display labelsupply-tempSupply temperature (e.g. "18")
crah-1Display labelvalueGeneral display text
crah-1LED indicatorrunningtrue (green) / false (off)
crah-1LED indicatorfilterDirtytrue (amber) / false (off)
crah-1LED indicatorstatus"ok" (green), "warning" (amber), "failed" (red)
crah-1-filterToggleable — click to open/closeOpens filter access panel

UPS (Uninterruptible Power Supply)

Location: Power Room — 2 units (ups-1, ups-2)

Object IDInteractionPropertyPossible Values
ups-1Display labelbatteryLevelText (e.g. "100%", "15%")
ups-1LED indicatorstatus"ok" (green), "warning" (amber), "failed" (red)
ups-1LED indicatorchargingtrue (amber) / false (off)

Fire Suppression Panel

Location: Control Room — 1 unit (fire-panel)

The fire suppression panel is located in the control room, a secure and monitored location.

Object IDInteractionPropertyPossible Values
fire-panel-coverToggleable — click to open/closeOpens panel cover
fire-panelPressable — activation buttonactivatedtrue (activates suppression)
fire-panelLED indicatorarmedtrue (green) / false (off)
fire-panelLED indicatoractivatedtrue (red) / false (off)
fire-panelLED indicatorstatus"ok", "warning"

EPO Button (Emergency Power Off)

Location: Main Data Hall — south wall near the exit to the vestibule — 1 unit (epo-button)

The EPO button is positioned next to the evacuation route for quick access during emergencies.

Object IDInteractionPropertyPossible Values
epo-button-coverToggleable — click to lift safety coverLifts/lowers cover
epo-buttonPressable — mushroom buttonpressedtrue (cuts all power)

Floor Tiles (Raised Floor)

Location: Main Data Hall — 8 tiles between rack rows

Object IDInteractionPropertyPossible Values
tile-hall--6Toggleable — click to liftliftedSlides tile to reveal sub-floor
tile-hall--4.5"""
tile-hall--3"""
tile-hall--1.5"""
tile-hall-0"""
tile-hall-1.5"""
tile-hall-3"""
tile-hall-4.5"""

Patch Panel

Location: Control Room — 4 units (patch-1, patch-2, patch-3, patch-4)

Object IDInteractionPropertyPossible Values
patch-1-port1port32LED indicatorconnectedtrue (green) / false (off)

Each panel has 32 ports (8 columns × 4 rows). Ports are numbered left-to-right, top-to-bottom.


Crash Cart

Location: Control Room — 1 unit (kvm-cart)

Object IDInteractionPropertyPossible Values
kvm-cartGrabbable — click to repositionMove cart to a rack
kvm-cartDisplay labeldisplayScreen text (e.g. "KVM READY", "CONNECTED TO A3")

Control Room Screen

Location: Control Room — 3 screens mounted on the north wall (screen-power, screen-env, screen-alarms)

Control room screens display real-time equipment status. In cooperative mode, the operator uses these screens to monitor the facility and raise tickets.

Object IDLabelMonitored Equipment
screen-powerPowerpdu-A1, pdu-A2, ups-1, epo-main
screen-envEnvironmentalcrah-1, crah-2, crah-3, crah-4
screen-alarmsAlarmsfire-panel, epo-main, ups-1

Diesel Generator

Location: Generator Yard — 2 units (gen-1, gen-2)

Object IDInteractionPropertyPossible Values
gen-1Toggle switchontrue (running) / false (off)
gen-1LED indicator (status)status"ok" (green), "warning" (amber), "failed" (red)
gen-1LED indicator (fuel connection)fuelConnectedtrue (green) / false (off)
gen-1Display (load)loadText (e.g. "75%", "IDLE")
gen-1Display (fuel level)fuelLevelText (e.g. "85%", "LOW")
gen-1Display (label)valueText (e.g. "GEN-1")
gen-1-fuel-inletPort — fuel connectionconnectedtrue / false

Additional hotspots (disabled by default, can be enabled for custom models): exhaust temp display, runtime hours display, power outlet port, auditory alarm, emergency stop button.


Fuel Tank

Location: Generator Yard — 2 units (fuel-tank-1, fuel-tank-2)

Object IDInteractionPropertyPossible Values
fuel-tank-1Display (fuel level)fuelLevelText (e.g. "90%", "EMPTY")
fuel-tank-1LED indicator (fuel level)fuelLevelStatus"ok" (green), "warning" (amber), "failed" (red)
fuel-tank-1Display (label)valueText (e.g. "TANK-1")
fuel-tank-1-fuel-outletPort — fuel connectionconnectedtrue / false

Additional hotspots (disabled by default): fill cap, shutoff valve, low fuel alarm.


Fuel Pipe

Location: Generator Yard — 2 units connecting tanks to generators (fuel-pipe-1, fuel-pipe-2)

Each fuel pipe runs from a fuel tank to its paired diesel generator. The pipe has an interactive shutoff valve at the midpoint.

Object IDInteractionPropertyPossible Values
fuel-pipe-1Rotary dial — shutoff valveopentrue (open, fuel flowing) / false (closed)
fuel-pipe-1LED indicator (valve status)valveOpentrue (green) / false (red)
fuel-pipe-1Display (label)valueText (e.g. "PIPE-1 (TANK-1 → GEN-1)")

Additional hotspots (disabled by default): flow rate display, leak alarm.

Pipe pairings:

  • fuel-pipe-1 connects fuel-tank-1gen-1
  • fuel-pipe-2 connects fuel-tank-2gen-2

Fire Extinguisher

Location: Generator Yard — 1 unit near the yard entrance (yard-extinguisher)

Object IDInteractionPropertyPossible Values
yard-extinguisherLever latch — squeeze handledischargedtrue (used) / false (ready)
yard-extinguisherLED indicator (pressure)pressure"ok" (green), "low" (red)
yard-extinguisherDisplay (label)valueText (e.g. "EXT-1")
yard-extinguisher-pinSpring pin — safety pinpulledtrue (pin removed) / false (pin in place)

Additional hotspot (disabled by default): wall bracket.


Custom Equipment Types

The AI layout and scenario builders can create custom equipment types with procedural geometry and hotspots. These are stored in the layout’s customEquipmentTypes field and rendered by the ProceduralEquipment component.

Common custom types include:

  • Thermal Scanner — handheld device with power button, trigger, LED, and display
  • DCIM Workstation — desk with monitor, keyboard area, and interactive buttons (acknowledge alarm, clear alarm)
  • Blanking Panel Rack — wall-mounted storage with removable blanking panels

Custom equipment hotspots work the same as built-in equipment — they can be targeted by task-step validation, pre-conditions, and state reactions using the equipment placement ID and hotspot key.

To add custom equipment: Use the AI layout editor and describe the equipment you need. The AI will create the type definition (geometry + hotspots) and place it in the layout. You can then fine-tune appearance and hotspot positions with follow-up prompts.


Configuring Scenarios

Pre-Conditions

Pre-conditions set initial equipment state before the trainee starts. Each pre-condition has three fields:

FieldDescriptionExample
objectIdThe equipment object IDrack-A3-drive2
propertyThe state property to setstatus
valueThe initial value"failed"

Common pre-condition examples:

Failed drive:           { objectId: "rack-A3-drive2", property: "status", value: "failed" }
Rack degraded label:    { objectId: "rack-A3", property: "value", value: "A3 — DEGRADED" }
CRAH overheating:       { objectId: "crah-1", property: "temp", value: "28" }
Dirty filter warning:   { objectId: "crah-1", property: "filterDirty", value: true }
Fire alarm active:      { objectId: "fire-panel", property: "status", value: "warning" }
Fire panel armed:       { objectId: "fire-panel", property: "armed", value: true }
UPS low battery:        { objectId: "ups-1", property: "batteryLevel", value: "15%" }
PDU overloaded:         { objectId: "pdu-1", property: "load", value: "OVERLOAD" }
PDU breaker tripped:    { objectId: "pdu-1-switch3", property: "on", value: false }
Network port down:      { objectId: "patch-1-port5", property: "connected", value: false }
Generator running:      { objectId: "gen-1", property: "on", value: true }
Generator fuel low:     { objectId: "gen-1", property: "fuelLevel", value: "LOW" }
Fuel tank level:        { objectId: "fuel-tank-1", property: "fuelLevel", value: "90%" }
Fuel valve closed:      { objectId: "fuel-pipe-1", property: "open", value: false }
Extinguisher used:      { objectId: "yard-extinguisher", property: "discharged", value: true }

Powered displays: set the power switch too

Many canvas gauges in the equipment catalogue — voltmeters, ammeters, load meters, fuel gauges, RPM dials, battery indicators — are power-gated. Each such gauge declares a powerProperty naming the hotspot key of the switch, breaker, or ignition that energises it. The gauge only displays a meaningful reading when that named hotspot is set to a truthy value. When the power source is off (or unset), the gauge clamps to its minimum value and your pre-conditioned reading is silently ignored.

This models real-world behaviour: a voltmeter reads zero when its breaker is open; a tachometer reads zero when the engine is stopped.

Practical rule: whenever you set a pre-condition for a gauge value, also set a pre-condition for its powerProperty to true in the same scenario — unless you specifically want the gauge to start dark (e.g. the trainee’s first task is to energise the equipment).

Main switchboard, voltage reading visible:
  { objectId: "main_switchboard-1", property: "main-breaker",        value: true }
  { objectId: "main_switchboard-1", property: "bus-voltage-display", value: 415  }

Diesel generator under load, gauge reading visible:
  { objectId: "gen-1", property: "power-switch", value: true }
  { objectId: "gen-1", property: "load-display", value: 1200 }

UPS with battery indicator visible:
  { objectId: "ups-1", property: "power-button",     value: true }
  { objectId: "ups-1", property: "battery-display",  value: 85   }

Two ways to discover whether a gauge is power-gated:

  1. Hover the property in the pre-conditions editor dropdown — the helper text shows gated by <powerProperty> when applicable.
  2. AI scenarios — the AI’s get_equipment_hotspots tool surfaces the dependency in its output (the line for the gauge ends with gated by powerProperty=...).

Exception: tube-style gauges (sight glasses — fuel levels, water levels) are passive and ignore the power gate. They always show the live value.

The pre-conditions tool returns a warning when you set a gauge value without also setting its power switch, but accepts the call anyway (in case the dark-gauge state is intentional). If you saved a scenario before this guidance landed and the gauges aren’t showing the readings you set, the missing power-switch pre-conditions are the most likely cause.


Toolbox (Hand-carry items)

The Toolbox section lets you declare items the trainee starts the scenario with on a follower hip-belt strip — tools, PPE, and LOTO accessories. Items the trainee picks up off the belt with X appear in their inventory; Y drops them back. The strip auto-hides when no items are declared.

Each toolbox row has two fields:

FieldDescriptionExample
Equipment typeThe reference type (dropdown of toolbox-eligible items)hard_hat, multimeter, loto_padlock
CountHow many of this type to start with1

What’s eligible: the dropdown is filtered to the three classes of items that physically belong on a person rather than in a layout:

  • Tools — hand tools (multimeter, screwdriver, torque wrench, gas detector, …). Identified by equipmentType: 'tools' in the reference data.
  • PPE — personal protective equipment (hard hat, safety glasses, hi-vis vest, ear muffs, gloves, face mask, steel-capped boots, welding helmet). Identified by a 'ppe' tag.
  • LOTO accessories — items that physically attach to host equipment (padlocks, hasps, tags, permits). Identified by mountSurface: 'equipment' in the reference data.

These items are hidden from the layout equipment picker — they belong on the belt, not in a room.

Replenishment: the toolbox refills to its declared capacity every time the scenario (re-)starts, so a trainee who lost or misplaced an item on a prior attempt gets a fresh set on retry.


Task Steps — Validation Types

Each task step has a validationType that determines how the system checks whether the trainee has completed it.

object_interaction

The trainee must interact with a specific object (toggle, grab, release).

Config FieldDescriptionExample
targetIdObject to interact with"rack-A3-door"
actionExpected action type"toggle", "grab", "release"
currentStateState the object is in when the scenario starts"closed", "off"
requiredStateState the object should be in after this step (for auto-grading)"open", "removed"

button_press

The trainee must press a specific button or switch.

Config FieldDescriptionExample
targetIdButton to press"epo-button", "fire-panel", "pdu-1-switch3"
currentStateState the button is in when the scenario starts"off"
requiredStateState the button should be in after this step"pressed", "on"

location_visit

The trainee must navigate to a specific room.

Config FieldDescriptionExample
zoneIdRoom zone identifier"zone-data-hall", "zone-vestibule", "zone-cooling", "zone-power", "zone-network", "zone-generator-yard"

cable_action

The trainee must plug or unplug a cable.

Config FieldDescriptionExample
targetIdCable/port to act on"patch-1-port5", "gen-1-fuel-inlet", "fuel-tank-1-fuel-outlet"
actionPlug or unplug"plug", "unplug"
currentStateState the cable is in when the scenario starts"disconnected"
requiredStateState the cable should be in after this step"connected"

observation

The trainee must look at something for a minimum duration.

Config FieldDescriptionExample
targetIdObject to observe"crah-1", "rack-A3-drive2", "gen-1", "fuel-tank-1"
minDurationSecondsHow long to look3, 5

equipment_move

The trainee must pick up a piece of equipment and drop it near a target location.

Config FieldDescriptionExample
dropTargetIdEquipment to drop near"rack-B4"
targetPositionAuto-derived from dropTargetId{ x: 3, y: 0, z: -0.5 }
snapRadiusDistance threshold for valid drop (metres)1.5

The trainee grabs equipment (X on the left VR controller, X key on desktop), carries it to the target, and drops it (Y on the left VR controller, Y key on desktop). The step completes when the equipment is dropped within the snap radius.

equipment_grab

The trainee must pick up an item — either a specific placement in the layout, or any item of a given type from the toolbox strip. Step completes as soon as the correct item is grabbed.

The editor surfaces a toggle next to the Target field with two modes:

ModeWhat it gradesConfig field usedWhen to use
Specific item in layoutA specific placed equipmenttargetId (placement id)“Pick up the thermal scanner sitting on the rack”
From toolboxAny take of this type off the beltequipmentType (reference type)“Don the hard hat”, “Take a padlock”

The “From toolbox” dropdown is scoped to types you declared in the scenario’s Toolbox section — if the toolbox is empty, the option is disabled. Use this for any step where the trainee must put on PPE, take a tool from their kit, or grab a LOTO accessory off their belt.

Use Specific item in layout when the action is “take the tool from where it sits” and the drop location is handled by the next step (or by tool_use validation).

tool_use

The trainee must be holding a tool of a given category and cause a specific hotspot on another piece of equipment to reach the expected state. Polled continuously (no event required) — works for “scan the thing” / “spray the thing” / “measure the thing” flows.

Config FieldDescriptionExample
toolCategoryCategory of the held tool"fire_suppression", "thermal_imaging", "fastener"
targetIdEquipment being acted on"gen-1"
hotspotKeyHotspot on the target"temp-reading"
expectedStateValue that counts as success"ok", "true"

The trainee grabs the tool first (via an equipment_grab step or just by picking it up from the layout), then points/triggers it at the target. Equipment opts into this by declaring a toolCategory on its placement.

audio_cue

Plays a sound when the step activates. The sound is environmental stimulus — there’s no expected reaction from the trainee. The step ends on a timer or when the sound finishes naturally.

Config FieldDescriptionExample
audio.soundKeyLibrary sound key (built-in or org:.../...)"fire-alarm-t3", "evac-siren"
audio.cueCompletion.kindHow the step ends"auto-advance-after-seconds" or "auto-advance-on-sound-end"
audio.cueCompletion.seconds(for auto-advance-after-seconds)5
audio.continueSoundIf true, sound keeps playing into subsequent stepsfalse (default)

Use audio_cue when the recognition of a sound is the training value (the alarm fires, the scenario moves on, the trainee experiences the environment). Use audio_response instead when you want to assess what the trainee does about it. auto-advance-on-sound-end is only valid for one-shot sounds — loops have no natural end.

audio_response

Plays a sound and validates the trainee’s reaction. The step waits for the configured response: either a hotspot interaction (acknowledge button, silencer switch) or a zone entry (muster point, safe area).

Config FieldDescriptionExample
audio.soundKeyLibrary sound key"fire-alarm-t3"
audio.response.kindResponse shape"hotspot" or "zone"
audio.response.targetId(hotspot) Equipment being interacted with"fire-panel-1"
audio.response.hotspotKey(hotspot) Hotspot on the target"acknowledge"
audio.response.expectedState(hotspot) Value that counts as success"true"
audio.response.zoneId(zone) Zone the trainee must reach"zone-muster"
audio.timeoutSecondsOptional. Step fails if no response in this time30
audio.continueSoundIf true, sound keeps playing past completionfalse (default)
audio.visualMessageAccessibility: HUD message shown while step is active"Fire alarm — acknowledge at the panel"
audio.visualSeverityHUD colour: "normal", "warning", or "danger""danger"

The visual cue HUD supports deaf trainees, muted hardware, and noisy training environments. Setting it is strongly recommended for any safety-critical audio_response step. It only appears on audio_response (not audio_cue) — see the Temporal Audio section for the rationale.

build_rules

Reserved for Produce-mode scenarios — validation is driven by the step’s buildRules list (evaluated server-side on Submit and live in the editor panel). Authors don’t set this directly; it’s applied automatically when a Produce-mode step is saved. See Produce Mode Scenarios and the Build-Rules Cookbook.


Current State vs Required State

Each task step can optionally specify two state fields:

  • Current State — The state the object is in when the scenario begins. This supplements the scenario’s pre-conditions and ensures the VR environment displays the correct initial state for the equipment. For example, if a step requires the trainee to open a rack door, set the current state to "closed" so the door appears closed when the scenario loads.

  • Required State — The state the object should be in after the trainee completes this step. This serves as an auto-grading rubric: the system checks whether the trainee’s action resulted in the correct final state. For example, if the step is “Open rack A3 door”, the required state would be "open".


Zone IDs

Zone IDRoom
zone-data-hallMain Data Hall
zone-vestibuleEntry Vestibule
zone-coolingCooling / Mechanical Room
zone-powerPower Room
zone-networkControl Room
zone-generator-yardGenerator Yard (outdoor)

Step Videos

Each task step can optionally have a video assigned from the organisation’s Video Library. When the trainee reaches a step with a video, a centre-screen overlay plays the video automatically.

How it works:

  • Videos are registered in the Video Library page (admin/trainer) by entering a Vimeo video ID or URL.
  • In the scenario editor, each step has a Step Video dropdown to select from the library.
  • During VR playback, the video overlay appears in front of all other HUD elements.
  • Controls: play/pause, restart, and close buttons appear semi-transparently over the video (fade in on hover, fade out during playback).
  • The video auto-dismisses 2 seconds after playback ends, or the trainee can close it manually at any time.
  • Video playback is supplementary — the step’s validation still works via its normal mechanism (the trainee does not need to finish watching the video to proceed).

When to use step videos:

  • Demonstrating a physical procedure (e.g. how to operate a valve, how to don PPE) before the trainee attempts it.
  • Providing visual safety briefings at the start of a scenario.
  • Supporting trainees with low literacy or numeracy who may struggle with text-based HUD instructions.
  • Showing equipment-specific training clips alongside the relevant hands-on step.

Example: A scenario for offshore emergency response might have:

  • Step 1: Location visit to muster station — video: “Emergency muster procedure” (60s safety briefing)
  • Step 2: Interact with life jacket station — video: “How to don a life jacket” (30s demonstration)
  • Step 3: Interact with lifeboat entry hatch — no video (text instructions sufficient)

One Validation Surface Per Step

Each task step has a single validation contract — its validationType and the validationConfig that goes with it (see Task Steps — Validation Types above). The step completes when that one contract is satisfied.

If a procedure needs the trainee to perform several actions in sequence, model it as several steps rather than packing actions into one. This keeps each step’s pass/fail signal unambiguous, makes branching predictable, and shows the trainee a clear next action in the task panel.

Example — “lock out PDU A”:

Step 1  location_visit       zone-power
Step 2  object_interaction   pdu-1-main → off
Step 3  equipment_grab       loto_padlock (from toolbox)
Step 4  tool_use             padlock applied to pdu-1-main
Step 5  observation          pdu-1 power-led for 3 s (verify de-energised)

Each step grades one action. The trainee sees one task at a time on the HUD; branching can react to any individual step’s outcome.


Conditional Branching (Advanced)

By default, scenario steps execute in a fixed linear sequence. Conditional branching allows you to change which step the trainee goes to next based on what they did (or didn’t do) on the current step.

Each step can have optional branch rules — evaluated in order after the step completes, fails, or is skipped. The first matching rule determines the next step. If no rule matches, the scenario advances linearly as usual.

Branch Condition Types

ConditionDescriptionUse Case
Step completedThe trainee completed the step successfullyRoute to the next section after passing
Step failedThe trainee answered incorrectly or failed validationRoute to a remedial sequence
Step skippedThe trainee skipped an optional stepContinue on the main path
Equipment in stateA specific equipment hotspot is in a given stateRoute based on what the trainee has done to equipment — also covers “the trainee chose X” patterns by reading the state the choice left behind
Time exceededThe trainee took longer than N seconds on the stepTimeout consequences — branch to a failure path
Always (unconditional)Always matches — acts as a catch-all or “go to”Jumping back to retry, or converging branches

Branch Targets

Each rule specifies a target:

  • Step N — jump to a specific step in the scenario (by step number)
  • End Scenario — immediately complete the scenario

Setting Up Branch Rules

  1. Edit a scenario and expand a task step.
  2. Click + Advanced: Branch Rules at the bottom of the step card.
  3. Click Add Branch Rule.
  4. Select a condition type, configure condition-specific fields, and select the target step.
  5. Add multiple rules if needed — they evaluate top to bottom, first match wins.
  6. Optionally set a Branch Group label (e.g. “Main Path”, “Remedial”) to organise steps visually.

Steps with branch rules show a purple badge (e.g. “2 branches”) in the step header.

Practical Patterns

Wrong-action remediation:

Step 3: "Open the correct breaker" (object_interaction on pdu-1-switch3 → off)
  → If step failed → Step 7 (remedial walkthrough)
  → If step completed → Step 4 (continue main path)

Step 9: "Now try again" (end of remedial sequence)
  → Always → Step 3 (retry the action)

Triage / decision tree (state-driven):

Step 1: "Identify the primary hazard and press the matching panel button"
        (object_interaction on hazard-panel)
  → If equipment hazard-panel.selected = "electrical" → Step 10 (electrical response)
  → If equipment hazard-panel.selected = "chemical"  → Step 20 (chemical response)
  → If equipment hazard-panel.selected = "fire"      → Step 30 (fire response)

Competency skip:

Step 5: "Identify the correct breaker by toggling it off"
  → If step completed → Step 12 (skip to next section)
  → If step failed → Step 6 (detailed walkthrough)

Time-pressure consequence:

Step 8: "Isolate the leak before pressure reaches critical"
  → If time exceeded (60 seconds) → Step 15 (consequence path)
  → If step completed → Step 9 (continue normal path)

Cycle Detection

Branch rules can jump backwards (e.g. “try again” loops). To prevent infinite loops, the engine limits how many times a step can be revisited. The default is 3 retries — configurable via maxStepRetries in scenario settings. After exceeding the limit, the engine skips ahead.

Path History

When branching is used, the trainee’s actual path through the scenario is recorded in the attempt results as pathHistory. This shows each step visited, the outcome, which branch condition matched, and timestamps — useful for reviewing how trainees navigated decision points.


Difficulty Levels

  • beginner — Guided tasks, hints enabled, generous time limits
  • intermediate — Some complexity, multiple rooms involved
  • advanced — Time pressure, consequences for mistakes, multi-system procedures

State Reactions

State reactions define cause-and-effect chains between equipment. When one hotspot changes state, another hotspot is automatically updated. This makes the facility feel realistic — pressing a button updates a display, toggling a switch lights an LED, etc.

Reaction FieldDescriptionExample
whenObjectIdEquipment whose state triggers the reaction"dcim-workstation"
whenPropertyHotspot key to watch"acknowledge-alarm"
whenValueValue that triggers the reaction"true"
thenObjectIdEquipment to update"dcim-workstation"
thenPropertyHotspot key to set"main-screen"
thenValueValue to set"ALARM ACKNOWLEDGED"

Common reaction examples:

Button press updates display:
  WHEN dcim-workstation.acknowledge-alarm = "true"
  THEN SET dcim-workstation.main-screen = "ALARM ACKNOWLEDGED"

Button press clears alarm:
  WHEN dcim-workstation.clear-alarm = "true"
  THEN SET dcim-workstation.main-screen = ""

Power button lights LED:
  WHEN thermal-scanner.power-button = "true"
  THEN SET thermal-scanner.power-led = "true"

Tips for state reactions:

  • Reactions fire immediately when the trigger condition is met
  • Multiple reactions can chain together (button → display → LED)
  • Use reactions to simulate realistic equipment behaviour without code changes
  • For buttons that control LEDs, consider using the same hotspot key instead of a reaction (simpler)

Pseudo-objects

State reactions can also target three pseudo-objects that aren’t equipment placements. They behave the same as equipment in the reaction syntax — you just use a reserved id instead of a real placement id.

Pseudo-objectWhen/Then?What it does
narratorTHEN onlyShows a cinematic text overlay. Set thenObjectId="narrator", thenProperty="__narrative". The Then-value field expands into a structured editor: enter the narrative text and pick a Stop mode — Auto (8 s + fade), Timed (custom seconds), Dismissable (trainee clicks to close), Until next step, or Persistent (clears when another reaction overwrites it).
audioTHEN onlyPlays or stops a temporal sound. Set thenObjectId="audio", thenProperty=<sound-key>, thenValue="play" or "stop". See Temporal Audio.
playerWHEN onlyFires on space transitions. Set whenObjectId="player", whenProperty="currentZone", whenValue=<zoneId> or "__none" (player left all zones).

Pseudo-object examples:

Press a button → play a fire alarm:
  WHEN fire-test-panel.test-button = "true"
  THEN SET audio.fire-alarm-t3 = "play"

Press acknowledge → silence the alarm:
  WHEN fire-test-panel.acknowledge-button = "true"
  THEN SET audio.fire-alarm-t3 = "stop"

Enter the muster point → stop the evac siren and show a narrative:
  WHEN player.currentZone = "zone-muster"
  THEN SET audio.evac-siren = "stop"
  WHEN player.currentZone = "zone-muster"
  THEN SET narrator.__narrative = "You have reached the muster point. Well done."

Tickets

Scenarios can include a support ticket — a work order that describes the problem the trainee needs to investigate. Tickets are available in both single-player and cooperative modes.

Ticket FieldDescriptionExample
subjectShort title for the work order"Investigate Overheating at Rack B4"
descriptionDetailed background information"Temperature alarm triggered at 14:30..."
categoryType of workGeneral, Incident, Maintenance, Inspection, Safety, Change Request
priorityUrgency levelLow, Medium, High, Critical
dueDateOptional deadline"2026-03-25"

How tickets work:

  • The ticket is defined in the scenario editor when “Tickets enabled” is checked
  • When a trainee starts an attempt, a fresh ticket instance is created
  • The ticket appears in the trainee’s HUD (VR and desktop)
  • Trainees can add notes to the ticket during the exercise (e.g. observations, actions taken)
  • Notes are timestamped and attributed to the player
  • In cooperative mode, both players see the ticket and each other’s notes in real time
  • Trainers can review the full ticket and notes history in the assignment/result detail page

Spawn Rooms

You can specify which room each player starts in:

SettingDescriptionDefault
spawnRoomIdRoom where Player 1 spawnsLayout’s default entry point
coopSpawnRoomIdRoom where Player 2 spawns (cooperative only)Same as Player 1

Use the room select dropdown in the scenario editor to choose from available spaces in the layout.


Cooperative Scenarios

Cooperative (2-player) scenarios have two roles:

  • Field Technician — physically navigates the facility, interacts with equipment, follows procedure steps
  • Control Room Operator — monitors equipment from the control room, coordinates with the field technician

Configuring cooperative scenarios:

  1. Enable Cooperative mode in scenario settings
  2. Set Player 1 spawn room (typically the Data Hall for the field technician)
  3. Set Player 2 spawn room (typically the Control Room for the operator)
  4. Enable Tickets and define a ticket describing the work order
  5. Design task steps that require both players to coordinate (e.g. field technician inspects equipment, operator acknowledges alarms)
  6. Both players communicate via built-in voice chat — no external tools needed

Role assignment: The assigned trainee (the user the scenario was assigned to) always becomes the field technician. The other player who joins the session becomes the control room operator. This is automatic — roles are not chosen by the players.

Important: Each player must use a separate VR headset paired to their own account. The lobby shows “Signed in as: [email]” — verify identity before joining.


How-to Guide

On the scenario edit page, you can write a preparation guide for trainees using the TipTap WYSIWYG editor. This guide appears on the trainee’s assignment detail page before they launch the exercise. Use it to explain the procedure, safety considerations, and what to expect.

Click Generate with AI to auto-generate a how-to guide from the scenario’s steps and description. You can then edit the generated content as needed.


Learning Resources

Upload PDFs and images on the scenario edit page to provide reference materials for trainees. These resources appear on the trainee’s assignment detail page, where they can click to open them in a new tab.

Common uses:

  • Equipment reference manuals
  • Safety data sheets
  • Facility diagrams and floor plans
  • Photographs of real equipment

AI Scenario Builder

The fastest way to create a scenario is with the AI Scenario Builder:

  1. Navigate to Scenarios in the sidebar.
  2. Click AI Builder.
  3. Select the facility layout the scenario will use.
  4. Describe the training procedure in natural language.
  5. The AI reads the layout’s equipment and rooms, then generates a sequence of task steps (each with its own validation contract), pre-conditions, state reactions, custom equipment, and a how-to guide.
  6. Review the scenario preview on the right panel. Send follow-up messages to refine.
  7. A green Ready indicator appears when the AI is done. Click Save Scenario.

View past AI conversations under AI History in the sidebar. Browse by layout or scenario and click to view in read-only mode.


Narrative Popups

Scenarios can include narrative text that appears as a cinematic overlay during the exercise to provide story context or instructions to the trainee. Wire them up as state reactions with thenObjectId="narrator" and thenProperty="__narrative" (see the Pseudo-objects table); the Then-value editor exposes the narrative text plus a Stop mode:

Stop modeBehaviour
AutoDisplays for 8 seconds, then fades out (the default).
TimedDisplays for a custom number of seconds, then fades out.
DismissableStays until the trainee clicks the close control on the overlay.
Until next stepStays until the scenario advances to the next task step, then clears immediately.
PersistentStays indefinitely. Clears only when another reaction writes a new narrator value (an empty string is the explicit-clear signal).

Pick the mode that matches the role of the popup: short scene-setting → Auto; “read this before continuing” → Dismissable or Until next step; ambient context across many steps → Persistent (with an explicit clear at the end).


Temporal Audio

Scenarios can play event-driven sounds — fire alarms, evacuation sirens, industrial horns, telephone rings, doorbells, timer beeps. These are distinct from the ambient audio that loops while a trainee is in a particular space; temporal sounds fire in response to events, play for a defined period, and stop.

There are three ways to wire temporal audio into a scenario:

  1. audio_cue step type — environmental stimulus. The sound plays, the scenario moves on. Use when recognition is the training value (the alarm fires, the trainee notices, the exercise continues).
  2. audio_response step type — stimulus + assessment. The sound plays, the scenario waits for the trainee to do the right thing (acknowledge a panel, walk to a muster point). Use when response is the training value.
  3. State reactions via the audio pseudo-object — fire/stop sounds in response to any other event. Useful for “sound the alarm when the temperature gets too high” patterns or for stopping a sound that was started by a pre-condition or another reaction.

Audio library: scenarios can use platform-shipped sounds (fire alarm T3, evacuation siren, industrial horn, telephone ring, doorbell, timer expiry) or sounds the organisation has uploaded into its own audio library (Sidebar → Audio Library, admin only). Uploaded sounds let organisations train against the exact sounds trainees will encounter in the field — important for safety-critical recognition training where a generic substitute would be unsafe.

Looping vs one-shot: loops play until explicitly stopped (alarms, sirens). One-shots play once (doorbell, phone ring, timer beep). This is a property of the sound, not the step — the runtime handles it automatically.

Accessibility (visual cues): audio_response steps support a visual cue HUD — a top-centre flashing message shown while the step is active. Strongly recommended for safety-critical scenarios. Set the audio.visualMessage and audio.visualSeverity fields on the step. The HUD respects the trainee’s prefers-reduced-motion OS setting (flash becomes a static border) and hides alongside the other HUDs when the trainee right-grips the controller.

Visual cues only fire on audio_response, not audio_cue. audio_cue is environmental stimulus by design — a HUD message there would contradict the “this is ambient context” framing. If a sound carries instructional weight, model it as audio_response (even a trivial zone response works) so the visual cue surfaces correctly.

Authoring tips:

  • Use audio sparingly. Silent training is fine for most scenarios. Audio earns its place in emergency-response, evacuation, control-room-attention, and timer-driven training.
  • Sound the alarm at scenario start via a pre-condition (audio.<key> = play) when the scenario opens in medias res.
  • Always model the stop path explicitly. The trainee should be able to silence an alarm by completing the right action; a scenario that leaves the alarm playing forever is fatiguing.
  • Pair an audio_response step with a clear visualMessage for any sound the trainee must understand to pass.
  • Use audio.continueSound = true when an alarm should keep ringing across multiple response steps (e.g. fire alarm during evacuation + muster + headcount). Add an explicit stop reaction at the end of the sequence.

VR Controls Reference

When authoring scenarios, keep the following controls in mind as they affect how trainees interact with equipment:

Grab and Drop:

  • VR headset: X button (left controller) to grab equipment you are pointing at, Y button (left controller) to drop the currently-selected inventory item at the cursor.
  • Desktop: X key to grab, Y key to drop.
  • Equipment follows pointer/beam. Drop near a snap target to snap into place.

View height (VR only): A button (right controller) raises the point of view, B button (right controller) lowers it. Useful for stepping over rungs, looking over high equipment, or simulating ladders.

Inventory system: Trainees can carry multiple items. Grabbed items are added to an inventory bar at the bottom of the view (desktop) or a wrist-anchored inventory panel (VR — roadmap). On desktop, click a slot to select it before dropping; in VR today the active slot is selected automatically — multi-item inventory management in VR is on the roadmap.

Hotspot discovery mode: A toggle button on the Controls HUD highlights all interactive hotspots in the scene with a glow effect. Trainees use this to find equipment they need to interact with.

VR HUD toggle: Right grip button or “Hide HUD” button on Controls panel to show/hide the scenario tablet and ticket panel.


Tips for Scenario Authors

  1. Always set pre-conditions to establish the problem state before the trainee begins
  2. Start with a location_visit step so the trainee navigates to the correct room
  3. Use observation steps for inspection tasks — they require the trainee to look at the right thing
  4. Use equipment_move steps for tasks where trainees carry tools (thermal scanner, fire extinguisher). Set the target equipment and snap radius
  5. Mark non-critical steps as optional (e.g. closing a door after the procedure)
  6. Write clear hint text for each step — hints are shown in practice mode when enabled
  7. Use state reactions to make equipment respond realistically (button → display update, switch → LED)
  8. Create tickets for scenarios that simulate real-world work orders — trainees practice documenting observations
  9. Test your scenarios by assigning them to yourself (admins/trainers can self-assign)
  10. Use the AI Scenario Builder for faster creation — describe the procedure in natural language and the AI generates steps, pre-conditions, state reactions, and a how-to guide automatically
  11. Write a how-to guide or generate one with AI — trainees read this before launching the exercise
  12. Attach learning resources (PDFs, images) for reference materials trainees can review beforehand
  13. Generator yard scenarios — include a location_visit to zone-generator-yard and observation steps for fuel level checks
  14. Cooperative scenarios — set different spawn rooms for each player and design steps that require coordination