Appearance
Simulator runtime controls design
Context
The simulator page currently lets developers paste mapHex, pathHex, and roomProperties and preview the rendered map. It does not expose the SDK runtime layer, so developers cannot validate visibility toggles, room selection, interaction flags, or measurement settings without editing code.
This design adds a dedicated runtime control experience to the simulator while keeping the map preview large and the UI maintainable.
Goals
- Cover every field in
RuntimeConfig. - Make runtime changes apply in real time through
mapApi.updateRuntime(). - Represent field dependencies explicitly instead of exposing a flat form.
- Prefer direct manipulation when the map already provides the right affordance.
- Keep unsupported runtime fields visible but clearly disabled.
Non-goals
- Do not add full editing workflows for forbidden zones, carpets, furniture, waypoints, or spots in this iteration.
- Do not add a raw JSON editor as the primary runtime editing surface.
- Do not persist runtime state across page reloads in this iteration.
Recommended approach
Option 1: flat runtime form
Render every runtime field in a single long form with basic controls.
- Pros: fastest to build.
- Cons: poor dependency handling, weak discoverability, scales badly.
Option 2: runtime as a separate tab
Add a Runtime tab next to Map, Path, and Room.
- Pros: clear separation from source data.
- Cons: weak link between runtime controls and live map interaction.
Option 3: recommended, dedicated runtime console
Keep source data input and runtime controls separate. Add a dedicated Runtime panel in the left control column, and keep the right column focused on the large map preview.
- Pros: clear mental model, strong map-control linkage, scales well as more runtime fields and future config panels are added.
- Cons: more initial design and state management work.
This design uses option 3.
Page information architecture
The simulator stays in a two-column layout.
- Left column:
Datapanel forMap,Path, andRoomRuntimepanel for all runtime controlsInspectorpanel for runtime snapshot and live state
- Right column:
- large map preview
- light runtime summary overlay
The runtime panel is not merged into the existing source-data tabs. Source data answers "what is rendered"; runtime answers "how it behaves right now."
Runtime group design
Group runtime fields by behavior instead of by raw type.
Visibility
This group contains direct visibility toggles and uses a compact switch matrix.
showPathshowRobotshowChargingStationshowRoomNameshowRoomTypeshowRoomPropertyshowRoomOrdershowRoomFloorTypeshowCarpetshowDetectedObjectsshowChargingStationRingshowRobotRingshowRobotSleepAnimationshowRobotPulseCircle
Room selection
This is the highest-value interaction group and gets a dedicated sub-panel.
enableRoomSelectionroomSelectionModeselectRoomIdsroomPropertyFoldIdsdividingRoomId
Key behavior:
- When
enableRoomSelectionisfalse, dependent controls remain visible but disabled with a clear reason. selectRoomIdssupports two synchronized input channels:- room checklist in the panel
- direct room clicking on the map
- In
checkmarkmode, the panel uses a checkbox list. - In
ordermode, the panel shows ordered selected rooms and preserves order inselectRoomIds. dividingRoomIduses a room dropdown, not a free number field.roomPropertyFoldIdsuses room multi-select, not raw array input.
Interaction
enableInteractionenableMapClickCapture
Key behavior:
enableInteractionis the parent switch.- When
enableInteractionisfalse,enableMapClickCaptureis disabled and automatically normalized tofalse. - Captured click coordinates appear in the inspector as a read-only result.
Geometry and measurement
mapRotationunitunitLabel
Key behavior:
mapRotationuses a slider plus numeric input.unituses a segmented control or select.unitLabelfollows the default unit mapping until the user customizes it.
Editing state
editingForbiddenSweepZoneIdseditingForbiddenMopZoneIdseditingCleanZoneIdseditingVirtualWallIdseditingSpotIdseditingWayPointIdseditingCarpetIdseditingFurnitureIdsselectedCarpetIds
This group is visible but collapsed by default. Fields are disabled when the simulator lacks the supporting dataset or editing workflow.
Human-friendly behaviors
The runtime console needs a few usability features so it feels like a real debug surface rather than a schema viewer.
- Keep a light "modified" indicator when runtime differs from defaults.
- Provide safe presets such as
Default,Selection Debug,Minimal, andLabels Off. - Show the current runtime snapshot as formatted JSON for copy-and-compare workflows.
- Show why a control is disabled, not only that it is disabled.
- Derive room labels from parsed map rooms and prefer
roomPropertiesnames when available.
State model
Split state into three layers.
Source data state
Mutable source inputs:
mapHexpathHexroomProperties
This layer keeps its current render-and-cache flow.
Derived map state
Read-only values produced from parsed data and current map support:
availableRoomsparsedMapDataparsedPathDatamapTyperuntimeSupportMatrixcapturedMapClick
Runtime state
Mutable runtime state managed separately from source data:
runtimeDraft- optional
runtimeAppliedsnapshot for diagnostics
Runtime changes call updateRuntime(partial) and do not re-run map decoding.
Normalization rules
Runtime state must stay valid as source data changes.
- Keep
selectRoomIdswhenenableRoomSelectionis off, but disable the UI. - Force
enableMapClickCapturetofalsewhenenableInteractionisfalse. - Reset
dividingRoomIdto-1if the room no longer exists. - Filter invalid room IDs from
selectRoomIdsandroomPropertyFoldIds. - Preserve selection order in
ordermode. - Keep custom
unitLabelif the user has overridden it.
Error handling
Runtime updates use light feedback instead of full render errors.
- If
updateRuntime()fails, show a runtime-level error status and keep the last applied state. - If normalization removes invalid values, show a small informational status describing the change.
- Unsupported fields stay visible and disabled rather than hidden.
Component boundaries
Add runtime support without re-centralizing the simulator into one file.
MapPlayground.vue: layout orchestration onlyuseMapPlayground.ts: page-level state aggregationuseRuntimePlayground.ts: runtime draft, dependencies, presets, snapshotuseRuntimeBindings.ts: bridge between UI actions, map callbacks, andmapApi.updateRuntime()SimulatorRuntimePanel.vue: runtime console shellSimulatorRoomSelectionPanel.vue: dedicated room-selection UISimulatorInspectorPanel.vue: runtime JSON, selected rooms, click capture
Verification
Validate the design with the following outcomes.
- Every
RuntimeConfigfield appears in the runtime console. - Runtime changes update the map through
updateRuntime()without full redraw. - Room selection stays synchronized between panel and map.
- Invalid room-linked values are normalized after source data changes.
- Unsupported fields are visible, disabled, and labeled with the reason.
- The map preview remains visually dominant on desktop and mobile layouts.
Next steps
Write an implementation plan that phases the runtime console into composables and components without destabilizing the existing simulator page.