Code Implementation Template (The Gold Standard)
This is the flawless structural template for a modern Aircada Operator. Note the complete absence of 3D mesh code.
Published: 7/10/2026
typescript
import {
Setup, Dispose, Operator, FloatProperty, StringProperty,
Input, Output, States, Context,
FlowStateMap, AirEvent, PropertySystemType, AircadaContext
} from "@aircada/spec";
import { Events, EventPayloads, Tags, Roles } from "../registry/registry.generated";
import { SceneObjects } from "../registry/scene.generated";
// Auto-generated types from options.generated.ts
import { OptionsRegistry, DisplayFinishRow } from "../registry/options.generated";
@Operator({
name: "Smart Display Controller",
// CRITICAL: The 'type' must be globally unique within your project.
type: "DISPLAY_CONTROLLER"
})
export class SmartDisplayController {
@Context()
air!: AircadaContext;
// 1. Direct 3D Reference: Assigning a facade from the Scene Registry
@SceneObjectProperty()
targetMesh: ModelObject = SceneObjects.DISPLAY_SCREEN;
// 2. Studio Properties: Visible and linkable in the Visual Studio panels
@FloatProperty
displayBrightness: number = 0;
@StringProperty
displayText: string = "Welcome";
// 3. Declarative Flow States (Animations)
@States()
states = {
off: {
duration: 0.5,
properties: { displayBrightness: 0 },
onEvent: Events.TURN_OFF_DISPLAY
},
on: {
duration: 1.2,
properties: { displayBrightness: 100 },
onEvent: Events.TURN_ON_DISPLAY
}
} satisfies FlowStateMap<SmartDisplayController>;
// 4. Data-Driven Logic (Listening directly to option set selection changes in the store)
// Note: OptionsRegistry and DisplayFinishRow are auto-generated from options.generated.ts
@Input({ onStore: OptionsRegistry.DISPLAY_CUSTOMIZER.sets.DISPLAYFINISH.storePath })
onDisplayFinishChange(val: DisplayFinishRow) {
if (!val) return;
console.log("[SmartDisplay] Display finish change:", val.name);
// Direct manipulation of scene object materials using option row values
this.targetMesh.material.roughness = val.roughness ?? 0.8;
this.targetMesh.material.metalness = val.metalness ?? 0.1;
}
@Output({ name: "On Display Error", emits: Events.DISPLAY_ERROR })
onDisplayError = new AirEvent<EventPayloads[typeof Events.DISPLAY_ERROR]>();
@Setup()
setup() {
// Direct manipulation: Operators can directly set 3D properties
this.targetMesh.transform.position.set(0, 1.5, 0);
}
@Input({ name: "Force Reboot", onEvent: Events.FORCE_REBOOT })
reboot() {
this.onDisplayError.invoke({ reason: "Manual Reboot" });
}
}





