Store
Twin-Proxy Vault Architecture#
ReactStoreAPI: Optimistic and immediate updates for a responsive UI.
EngineStoreAPI: Deferred and batched updates to protect high-frequency physics and logic loops.
Engine Operator Guidelines#
Bound State (Local Ownership): Use @Property({ store: "path.to.key" }) to bind a class variable. Mutate directly (e.g., this.brightness += 1).
Recommendation: Prefer using typed property decorators like @FloatProperty({ store: "path" }) or @StringProperty({ store: "path" }) for better Studio integration and type safety.
Unbound State (Global Mutations): Use this.air.store.patch() or this.air.store.patchByPath() for headless mutations.
State Listeners: Use @Input({ onStore: "path.to.key" }) to react to store changes.
import { Operator, Context, FloatProperty, Input, AircadaContext } from "@aircada/spec";
@Operator({ name: "State Controller", type: "STATE_CONTROLLER" })
export class StateController {
@Context() air!: AircadaContext;
// 1. BOUND STATE: Automatically syncs this.brightness with vault path
@FloatProperty({ store: "app.settings.brightness" })
brightness: number = 100;
// 2. STATE LISTENER: Triggered when the store value changes
@Input({ onStore: "app.settings.brightness" })
onBrightnessChange(newVal: number) {
console.log("Brightness updated in Vault:", newVal);
}
// 3. UNBOUND STATE: Imperatively patching other parts of the global store
@Input({ name: "Reset System" })
reset() {
this.air.store.patch({ app: { status: "ready" } });
}
}The Store Interface#
All interactions should be typed against the global store interface, typically located in src/store.config.ts.
Use normalized collections (Dictionaries) instead of arrays for scalable game state.
Collection & Array Scaling (GC Protocol)#
The Vault treats Arrays as singular primitive values. To update an array, a new reference must be passed, which incurs high Garbage Collection (GC) costs.
Scaling Protocol: Use Dictionaries (Record<string, Data>) for normalized state to allow surgical, zero-waste deep-patching.






