Scene types

fancy-3d

Engine-agnostic JSON shape (nodes, edges, widget specs).

Registry JSON
Why
Without a schema-driven scene description, WebGL 3D engines and DOM renderers can't agree on what to draw. Ad-hoc mesh creation or imperative React trees couple the authoring surface to the rendering engine, forcing rewrites when switching from BabylonJS to three.js or adding a second viewport. Scene types bake the contract into JSON—plain data that adapters consume to render identically across DOM, BabylonJS, three.js, or any future engine without reauthoring.
What
Scene is a JSON-serializable type hierarchy: a root Scene contains arrays of SceneNode (positioned widgets) and SceneEdge (connections). WidgetSpec is a discriminated union of 14 widget kinds—kind: "kpi" through kind: "screen"—each with its own shape (e.g., KpiSpec has label, value, optional delta and trend). WidgetAdapter<T> is the engine-agnostic render contract: a render() method consumes a WidgetSpec and AdapterContext to produce engine-native output (React elements for DOM, Mesh for Babylon, Object3D for three).
How
Import types from @particle-academy/fancy-3d and define your scene as plain data: const scene: Scene = { nodes: [...], edges: [...] }. Call renderScene(scene, adapter, ctxFor) (where adapter comes from the engine you choose—@particle-academy/fancy-3d/dom, @particle-academy/fancy-3d-babylon, etc.) and place the results into your engine's scene graph. The nextId(prefix) helper generates stable node identifiers for agents to reference.