Skip to main content

Devices

Introduction

Within the simulation environment, devices represent interactive elements that mimic any smart objects commonly found in domestic or workplace contexts, such as lights, thermostats, smart meters, coffee machines, smart speakers, smart TVs, blinds, and more. Each device is a structured object placed spatially within the 3D simulated environment and is associated with a set of interaction modalities and visual states. Participants can engage with these devices, and their state can be monitored or changed by the rule engine.

Devices are embedded within simulation space by assigning them to specific walls in the environment (see Wall Configuration). While each wall can host multiple devices, each device instance is placed on only one wall. This constraint allows for a coherent mapping of the virtual environment and ensures consistent spatial interactions.

Device Configuration

Always start by defining the basic properties (name, id, position, interactions) before adding complex visual states. This makes it easier to test and debug your device configuration.

JSON Schema

Loading ....
JSON Schema Code

Device Schema

{
"type": "object",
"title": "Device",
"description": "A device in the game",
"properties": {
"name": {
"type": "string",
"description": "Name of the device"
},
"id": {
"type": "string",
"description": "Unique identifier for the device, used for referencing in rules and tasks"
},
"position": {
"$ref": "devicePositionSchema.json"
},
"interactions": {
"type": "array",
"items": {
"oneOf": [
{
"$ref": "booleanActionScheme.json"
},
{
"$ref": "numericalActionScheme.json"
},
{
"$ref": "dynamicPropertyScheme.json"
},
{
"$ref": "genericActionScheme.json"
},
{
"$ref": "statelessActionScheme.json"
}
]
}
},
"visualState": {
"type": "array",
"items": {
"$ref": "visualStateSchema.json"
},
"minItems": 1
}
},
"required": [
"name",
"interactions",
"position",
"visualState"
],
"additionalProperties": false
}

Top-Level Properties

PropertyTypeRequiredDescription
namestringYesThe human-readable name of the device, which may be displayed to the player in the UI.
idstringNoA unique machine-readable identifier for the device. This ID is crucial for linking the device to game logic, such as rules, events, or task objectives. It is highly recommended to provide this for any interactive device.
positionobjectYesAn object defining the device's placement and orientation in the game world. This property references an external schema.
interactionsarrayYesAn array of interaction objects that define how a player can engage with the device. Each element in the array must conform to one of the specified action schemas.
visualStatearrayYesAn array defining the different visual states the device can be in. This allows the device's appearance to change based on its internal state (e.g., "on" vs. "off"). There must be at least one visual state defined.

Property: Device Identification

Each device requires two identifiers: a human-readable name and a unique system id.

  • name: The display name shown to users (e.g., "Deep Fryer", "Coffee Machine"). This field enhances usability and participant immersion by providing intuitive, natural-language names for each device.

  • id: A unique system-wide identifier used for all internal referencing. The id is essential for:

    • Rules: Referencing devices in preconditions and actions (See Rule).
    • Tasks: Specifying devices in goals and default properties (See Task).
    • Game Logic: Managing internal device state and inter-device interactions (See Interactions )
{
"name": "Deep Fryer",
"id": "deep_fryer",
// ... other properties
}

Property: Position

The position property determines where a device appears on a wall and how it is displayed. It contains the following attributes that define its transform.

  • x: The horizontal coordinate (in pixels) on the wall.
  • y: The vertical coordinate (in pixels) on the wall.
  • scale: A multiplier for the device's size (e.g., 1 for original size, 0.5 for half size).
  • origin: Reference point for positioning (1 represents center)
Origin Property

The origin dictates which part of the device's image is placed at the (x, y) coordinates:

  • origin: 0: Aligns the top-left corner of the image to the (x, y) point.
  • origin: 1: Aligns the center of the image to the (x, y) point.

These positioning parameters are fully compatible with Phaser 3’s GameObject model, which underpins the simulation’s rendering layer. For more information:

Property: Interactions

Each device in the simulation can expose interactions , these are the ways participants can observe or manipulate the device’s state. For example:

  • Turning a lamp on or off
  • Adjusting the temperature of an oven
  • Selecting the input source of a smart TV
  • Triggering a stateless action like “Brew Coffee”

The interactions array in the Device schema defines all such interaction points for a specific device. Each interaction conforms to a specific schema based on its type, including:

  • Boolean Actions – toggle states (e.g., power on/off)
  • Numerical Actions – continuous or stepped values (e.g., brightness, temperature)
  • Dynamic Properties – internal device values that are read-only (e.g., water level, energy usage)
  • Generic Actions – options from a fixed set (e.g., mode selectors)
  • Stateless Actions – trigger-like interactions with no memory (e.g., “Start”, “Reset”) Each of these interaction types has a dedicated structure and purpose.

Structure

To learn more about how each interaction type works in detail, including JSON schema and examples see the full Interaction Schema Documentation at Interacting with Devices.

Interaction Validation

Always validate that your interaction types match the expected input ranges in your visual states. Mismatched values can lead to undefined behavior.

Property: Visual States

Devices in the game environment can change their appearance in response to user interactions or internal state changes. These changes are defined through the Visual State property in the device configuration.

In this context, a visual state refers to the concrete graphical representation (i.e., image asset) rendered on screen within the game environment. It determines how the device is visually presented to participants at any given moment, based on its current internal or interaction-driven state.

Each device must define at least one visual state, and it is strongly recommended to include a default visual state to serve as a fallback if no conditions are met.

Structure

Visual states are configured as an array of state objects. Each state can include:

  • default: A boolean indicating whether this is the fallback state.
  • conditions: A list of state-based conditions that must be satisfied for the visual state to apply.
  • image: The image asset (e.g., PNG or WebP) representing the device’s visual appearance.
  • position: An optional override of the device’s default position properties (such as x, y, scale, or origin) for this specific state.
Visual States Best Practice

Always include a default state as a fallback for when no conditions are met. This prevents devices from becoming invisible due to undefined states.

Position Overrides in Visual States

Visual states can optionally override a device’s default position properties to accommodate visual transformations that occur in different states, such as resizing, shifting, or re-aligning the image.

{
"default": false,
"conditions": [
{ "name": "Open", "value": true }
],
"image": "assets/images/alice_room/devices/wall1_bookopen.webp",
"position": {
"scale": 0.2
}
}

The position field may include any of the following optional properties:

  • x: Override the X-coordinate of the device image
  • y: Override the Y-coordinate of the device image
  • scale: Override the scale (size) of the image
  • origin: Override the origin anchor point used for rendering

Common Use Cases: Position overrides are particularly useful when:

  • The visual representation of the device changes substantially (e.g., a book opens)
  • Specific states require repositioning to align correctly with other elements
  • Different scales improve clarity or layout across states

Examples

Basic Default State

This defines a fallback image shown when no specific condition is met.

{
"default": true,
"image": "assets/images/living_room/devices/tv.png"
}
Simple Power States

These visual states reflect the Power interaction value of the device. When power is turned on or off, the displayed image updates accordingly.

[
{
"conditions": [
{ "name": "Power", "value": true }
],
"image": "assets/images/living_room/devices/tv_on.png"
},
{
"conditions": [
{ "name": "Power", "value": false }
],
"image": "assets/images/living_room/devices/tv_off.png"
}
]
State with Position Override

This example shows how a visual state can not only change the displayed image but also override the default position properties, useful for reflecting transformations like opening a book or zooming in on an object as explained above.

[
{
"default": true,
"image": "assets/images/alice_room/devices/wall1_book.webp"
},
{
"default": false,
"conditions": [
{ "name": "Open", "value": true }
],
"image": "assets/images/alice_room/devices/wall1_bookopen.webp",
"position": {
"scale": 0.2
}
}
]
Complex Multi-Condition States

This example demonstrates how visual states can be driven by multiple interaction values — here, both Power and Temperature determine the rendered image of an oven.

[
{
"default": true,
"image": "assets/images/kitchen/devices/oven_off.png"
},
{
"conditions": [
{ "name": "Power", "value": true },
{ "name": "Temperature", "operator": "<", "value": 50 }
],
"image": "assets/images/kitchen/devices/oven_on_low.png"
},
{
"conditions": [
{ "name": "Power", "value": true },
{ "name": "Temperature", "operator": ">=", "value": 50 },
{ "name": "Temperature", "operator": "<", "value": 100 }
],
"image": "assets/images/kitchen/devices/oven_on_med.png"
},
{
"conditions": [
{ "name": "Power", "value": true },
{ "name": "Temperature", "operator": ">=", "value": 100 }
],
"image": "assets/images/kitchen/devices/oven_on_high.png"
}
]

Important Considerations

  1. Condition Evaluation All conditions within a visual state are combined using logical AND. That means every condition must be satisfied for the state to activate.
  2. State Priority Visual states are evaluated in order, from top to bottom. The first state whose conditions evaluate to true will be applied.
danger

Ensure that the conditions defined across your visual states do not overlap. If multiple states match the current conditions simultaneously, only the first matching state in the array will be rendered. This may lead to unintended visual output if not carefully structured.

tip

To ensure reliable behavior, order your visual states from most specific to most general. Place more narrowly defined or critical states earlier in the list to avoid premature matching.

  1. Condition Operators The following operators are supported in condition definitions:
  • Equality: ==, !=
  • Comparison: >, >=, <, <=
  • Boolean Match: Direct match with true or false values
  1. Asset Management Every visual state must reference a valid image path that exists in your project directory. These paths are critical for rendering.
Asset Loading

If a referenced image asset is missing or incorrectly defined, the device may not render correctly, leading to runtime errors. Always verify that all paths are accurate and that required assets are available.

Complete Device Example

Here's a complete example showing all device properties:

{
"name": "Deep Fryer",
"id": "deep_fryer",
"position": {
"x": 657,
"y": 285,
"scale": 1,
"origin": 1
},
"interactions": [
{
"InteractionType": "Boolean_Action",
"name": "Power",
"inputData": {
"valueType": ["PrimitiveType", "Boolean"],
"unitOfMeasure": null,
"type": {
"True": "On",
"False": "Off"
}
},
"currentState": {
"visible": true,
"value": false
}
}
],
"visualState": [
{
"default": true,
"image": "assets/images/shared_room/devices/wall1_deepfryer.webp"
},
{
"default": false,
"conditions": [
{ "name": "Power", "value": true }
],
"image": "assets/images/shared_room/devices/wall1_deepfryer_on.webp"
}
]
}

Best Practices

  1. Device Identification
    • Use clear and descriptive name values intended for end-user display.
    • Define id values using lowercase letters with underscores (e.g., kitchen_light).
    • Ensure all device IDs are unique to avoid conflicts during rule evaluation and referencing.
  2. Visual State Management
    • Always define a default visual state as a fallback to guarantee device visibility under all conditions.
    • Order visual states from most specific to most general to ensure correct evaluation priority.
    • Use position overrides only when necessary, and document their purpose clearly (e.g., for transformations or scale adjustments).
  3. Asset Organization
    • Optimize all image assets to reduce loading times and improve runtime performance.
    • Adopt consistent and meaningful naming conventions for image files.
    • Store assets in logically structured directories that reflect room names or device categories.
  4. Configuration Testing
    • Validate all state combinations to ensure consistent visual behavior across different conditions.
    • Test each defined interaction type individually and in combination with others to identify edge cases.
    • Verify that position overrides do not cause misalignment or visual artifacts in the rendered scene.
Documentation

Maintain a structured registry of all devices used in the project. This registry should include:

  • Device IDs
  • Interaction types
  • Associated visual states
  • Special behaviors or conditions Comprehensive documentation facilitates team collaboration and future maintenance.