@relu-interactives/spatial-ecs 0.2.11 → 0.2.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (225) hide show
  1. package/dist/{System-KTHuWc-i.d.cts → System-CTTwEGn1.d.cts} +312 -3
  2. package/dist/{System-KTHuWc-i.d.ts → System-CTTwEGn1.d.ts} +312 -3
  3. package/dist/{Video-Ds_0Aj66.d.ts → Video-BMWPYc3q.d.cts} +2 -241
  4. package/dist/{Video-BnrYbbzu.d.cts → Video-CV1-u6hL.d.ts} +2 -241
  5. package/dist/{chunk-OIOUWDOS.js → chunk-27RBPOVO.js} +40 -4
  6. package/dist/chunk-27RBPOVO.js.map +1 -0
  7. package/dist/{chunk-YLRCC4EK.js → chunk-7QBONTBW.js} +4 -4
  8. package/dist/{chunk-YLRCC4EK.js.map → chunk-7QBONTBW.js.map} +1 -1
  9. package/dist/{chunk-XPCVEXMY.js → chunk-FTIQQK62.js} +2 -2
  10. package/dist/chunk-FTIQQK62.js.map +1 -0
  11. package/dist/{chunk-UU6VYCIO.js → chunk-KDZ6VBRO.js} +4 -4
  12. package/dist/{chunk-UU6VYCIO.js.map → chunk-KDZ6VBRO.js.map} +1 -1
  13. package/dist/components/index.cjs.map +1 -1
  14. package/dist/components/index.d.cts +2 -2
  15. package/dist/components/index.d.ts +2 -2
  16. package/dist/components/index.js +1 -1
  17. package/dist/docs/api/Behaviour/classes/Behaviour.md +29 -29
  18. package/dist/docs/api/Component/classes/Component.md +1 -1
  19. package/dist/docs/api/components/classes/AnimationComponent.md +26 -26
  20. package/dist/docs/api/components/classes/AudioComponent.md +19 -19
  21. package/dist/docs/api/components/classes/CameraComponent.md +14 -14
  22. package/dist/docs/api/components/classes/EntityType.md +3 -3
  23. package/dist/docs/api/components/classes/Environment.md +7 -3
  24. package/dist/docs/api/components/classes/ImageComponent.md +7 -7
  25. package/dist/docs/api/components/classes/ImageTarget.md +7 -7
  26. package/dist/docs/api/components/classes/ImageTargetAnchor.md +4 -4
  27. package/dist/docs/api/components/classes/InstanceSlotComponent.md +4 -4
  28. package/dist/docs/api/components/classes/InstancedMeshComponent.md +10 -10
  29. package/dist/docs/api/components/classes/LightComponent.md +6 -6
  30. package/dist/docs/api/components/classes/MaterialComponent.md +11 -11
  31. package/dist/docs/api/components/classes/MeshComponent.md +3 -3
  32. package/dist/docs/api/components/classes/MeshGeometryComponent.md +9 -9
  33. package/dist/docs/api/components/classes/ModelComponent.md +4 -4
  34. package/dist/docs/api/components/classes/Name.md +3 -3
  35. package/dist/docs/api/components/classes/Object3DRef.md +4 -4
  36. package/dist/docs/api/components/classes/ParentId.md +3 -3
  37. package/dist/docs/api/components/classes/PhysicsComponent.md +6 -6
  38. package/dist/docs/api/components/classes/Postprocessing.md +7 -3
  39. package/dist/docs/api/components/classes/ScriptComponent.md +5 -5
  40. package/dist/docs/api/components/classes/Selectable.md +3 -3
  41. package/dist/docs/api/components/classes/SelectionTransformState.md +5 -5
  42. package/dist/docs/api/components/classes/SpriteComponent.md +7 -7
  43. package/dist/docs/api/components/classes/TransformComponent.md +12 -12
  44. package/dist/docs/api/components/classes/VideoComponent.md +28 -28
  45. package/dist/docs/api/components/functions/normalizePhysicsState.md +1 -1
  46. package/dist/docs/api/components/index.md +1 -1
  47. package/dist/docs/api/components/type-aliases/AnimationComponentOptions.md +9 -9
  48. package/dist/docs/api/components/type-aliases/CameraComponentOptions.md +13 -13
  49. package/dist/docs/api/components/type-aliases/CameraProjection.md +1 -1
  50. package/dist/docs/api/components/type-aliases/CameraRuntimeType.md +1 -1
  51. package/dist/docs/api/components/type-aliases/ColliderShape.md +1 -1
  52. package/dist/docs/api/components/type-aliases/ColliderState.md +20 -20
  53. package/dist/docs/api/components/type-aliases/CubeMeshParameters.md +4 -4
  54. package/dist/docs/api/components/type-aliases/EditableMeshObjectKind.md +1 -1
  55. package/dist/docs/api/components/type-aliases/EnvironmentFogState.md +8 -8
  56. package/dist/docs/api/components/type-aliases/EnvironmentFogType.md +1 -1
  57. package/dist/docs/api/components/type-aliases/EnvironmentGradientEffect.md +1 -1
  58. package/dist/docs/api/components/type-aliases/EnvironmentSkyboxState.md +7 -7
  59. package/dist/docs/api/components/type-aliases/EnvironmentSkyboxType.md +1 -1
  60. package/dist/docs/api/components/type-aliases/EnvironmentState.md +5 -5
  61. package/dist/docs/api/components/type-aliases/ImageTargetAnchorOptions.md +3 -3
  62. package/dist/docs/api/components/type-aliases/ImageTargetReference.md +7 -7
  63. package/dist/docs/api/components/type-aliases/InstanceTransform.md +13 -13
  64. package/dist/docs/api/components/type-aliases/InstancedMeshKind.md +1 -1
  65. package/dist/docs/api/components/type-aliases/LightValueState.md +11 -11
  66. package/dist/docs/api/components/type-aliases/MaterialTypeValue.md +1 -1
  67. package/dist/docs/api/components/type-aliases/MaterialValueState.md +28 -28
  68. package/dist/docs/api/components/type-aliases/MeshGeometryParameters.md +1 -1
  69. package/dist/docs/api/components/type-aliases/MeshGeometryParametersByKind.md +7 -7
  70. package/dist/docs/api/components/type-aliases/PhysicsState.md +3 -3
  71. package/dist/docs/api/components/type-aliases/PlaneMeshParameters.md +3 -3
  72. package/dist/docs/api/components/type-aliases/PostprocessingState.md +62 -62
  73. package/dist/docs/api/components/type-aliases/RadiusHeightMeshParameters.md +3 -3
  74. package/dist/docs/api/components/type-aliases/RadiusMeshParameters.md +2 -2
  75. package/dist/docs/api/components/type-aliases/RigidbodyState.md +17 -17
  76. package/dist/docs/api/components/type-aliases/RigidbodyType.md +1 -1
  77. package/dist/docs/api/components/type-aliases/ScriptEntry.md +9 -9
  78. package/dist/docs/api/components/type-aliases/TextureFilteringValue.md +1 -1
  79. package/dist/docs/api/components/type-aliases/TransformData.md +4 -4
  80. package/dist/docs/api/components/type-aliases/TransformModeValue.md +1 -1
  81. package/dist/docs/api/components/type-aliases/TransformSpaceValue.md +1 -1
  82. package/dist/docs/api/components/type-aliases/Vec3.md +4 -4
  83. package/dist/docs/api/components/variables/DEFAULT_COLLIDER_STATE.md +1 -1
  84. package/dist/docs/api/components/variables/DEFAULT_ENVIRONMENT_STATE.md +1 -1
  85. package/dist/docs/api/components/variables/DEFAULT_INSTANCED_MESH_PARAMETERS.md +1 -1
  86. package/dist/docs/api/components/variables/DEFAULT_INSTANCE_TRANSFORM.md +1 -1
  87. package/dist/docs/api/components/variables/DEFAULT_MESH_GEOMETRY_PARAMETERS.md +1 -1
  88. package/dist/docs/api/components/variables/DEFAULT_PHYSICS_STATE.md +1 -1
  89. package/dist/docs/api/components/variables/DEFAULT_POSTPROCESSING_STATE.md +1 -1
  90. package/dist/docs/api/components/variables/DEFAULT_RIGIDBODY_STATE.md +1 -1
  91. package/dist/docs/api/index/classes/AnimationStateMachine.md +16 -16
  92. package/dist/docs/api/index/classes/AnimationStateManager.md +13 -13
  93. package/dist/docs/api/index/classes/AnimationSystem.md +3 -3
  94. package/dist/docs/api/index/classes/AudioSystem.md +4 -4
  95. package/dist/docs/api/index/classes/CameraSyncSystem.md +2 -2
  96. package/dist/docs/api/index/classes/EnvironmentSyncSystem.md +4 -4
  97. package/dist/docs/api/index/classes/InputSystem.md +33 -33
  98. package/dist/docs/api/index/classes/InstancedMeshSystem.md +2 -2
  99. package/dist/docs/api/index/classes/LightSyncSystem.md +2 -2
  100. package/dist/docs/api/index/classes/MaterialSyncSystem.md +3 -3
  101. package/dist/docs/api/index/classes/MeshGeometrySystem.md +2 -2
  102. package/dist/docs/api/index/classes/ObjectManagementSystem.md +39 -19
  103. package/dist/docs/api/index/classes/ObjectVisibilitySystem.md +2 -2
  104. package/dist/docs/api/index/classes/PhysicsSyncSystem.md +4 -4
  105. package/dist/docs/api/index/classes/PostprocessingSyncSystem.md +4 -4
  106. package/dist/docs/api/index/classes/RenderSystem.md +3 -3
  107. package/dist/docs/api/index/classes/ScriptBehaviourSystem.md +4 -4
  108. package/dist/docs/api/index/classes/TransformSyncSystem.md +2 -2
  109. package/dist/docs/api/index/classes/VideoSystem.md +4 -4
  110. package/dist/docs/api/index/classes/World.md +146 -82
  111. package/dist/docs/api/index/functions/createAnimationComponent.md +1 -1
  112. package/dist/docs/api/index/functions/createAudioComponent.md +1 -1
  113. package/dist/docs/api/index/functions/createCameraComponent.md +1 -1
  114. package/dist/docs/api/index/functions/createEntityTypeComponent.md +1 -1
  115. package/dist/docs/api/index/functions/createEnvironmentComponent.md +1 -1
  116. package/dist/docs/api/index/functions/createImageComponent.md +1 -1
  117. package/dist/docs/api/index/functions/createImageTargetAnchorComponent.md +1 -1
  118. package/dist/docs/api/index/functions/createImageTargetComponent.md +1 -1
  119. package/dist/docs/api/index/functions/createInstanceSlotComponent.md +1 -1
  120. package/dist/docs/api/index/functions/createInstancedMeshComponent.md +1 -1
  121. package/dist/docs/api/index/functions/createLightComponent.md +1 -1
  122. package/dist/docs/api/index/functions/createMaterialComponent.md +1 -1
  123. package/dist/docs/api/index/functions/createMeshComponent.md +1 -1
  124. package/dist/docs/api/index/functions/createMeshGeometryComponent.md +1 -1
  125. package/dist/docs/api/index/functions/createModelComponent.md +1 -1
  126. package/dist/docs/api/index/functions/createNameComponent.md +1 -1
  127. package/dist/docs/api/index/functions/createObject3DRefComponent.md +1 -1
  128. package/dist/docs/api/index/functions/createParentIdComponent.md +1 -1
  129. package/dist/docs/api/index/functions/createPhysicsComponent.md +1 -1
  130. package/dist/docs/api/index/functions/createPostprocessingComponent.md +1 -1
  131. package/dist/docs/api/index/functions/createScriptComponent.md +1 -1
  132. package/dist/docs/api/index/functions/createSelectableComponent.md +1 -1
  133. package/dist/docs/api/index/functions/createSelectionTransformStateComponent.md +1 -1
  134. package/dist/docs/api/index/functions/createSpriteComponent.md +1 -1
  135. package/dist/docs/api/index/functions/createTransformComponent.md +1 -1
  136. package/dist/docs/api/index/functions/createVideoComponent.md +1 -1
  137. package/dist/docs/api/index/functions/hydrateWorldFromSnapshot.md +1 -1
  138. package/dist/docs/api/index/functions/hydrateWorldFromSnapshotDetailed.md +1 -1
  139. package/dist/docs/api/index/functions/registerDefaultComponentFactories.md +1 -1
  140. package/dist/docs/api/index/functions/registerDefaultFactories.md +1 -1
  141. package/dist/docs/api/index/interfaces/EcsSystem.md +3 -3
  142. package/dist/docs/api/index/interfaces/StateMachine.md +13 -13
  143. package/dist/docs/api/index/type-aliases/AnimationStateCallbacks.md +4 -4
  144. package/dist/docs/api/index/type-aliases/ComponentFactory.md +1 -1
  145. package/dist/docs/api/index/type-aliases/EcsComponentFactoryKind.md +1 -1
  146. package/dist/docs/api/index/type-aliases/EcsWorldComponentSnapshot.md +3 -3
  147. package/dist/docs/api/index/type-aliases/EcsWorldStateSnapshotLike.md +4 -4
  148. package/dist/docs/api/index/type-aliases/HydrateWorldFromSnapshotResult.md +3 -3
  149. package/dist/docs/api/index/type-aliases/KeyboardKey.md +1 -1
  150. package/dist/docs/api/index/type-aliases/MouseButton.md +1 -1
  151. package/dist/docs/api/index/type-aliases/SelectionContext.md +4 -4
  152. package/dist/docs/api/index/variables/HYDRATABLE_ENTITY_KINDS.md +1 -1
  153. package/dist/docs/api/index/variables/KeyboardKeys.md +89 -89
  154. package/dist/docs/api/types/type-aliases/AssetInput.md +3 -3
  155. package/dist/docs/api/types/type-aliases/CheckboxInput.md +12 -2
  156. package/dist/docs/api/types/type-aliases/ColorInput.md +1 -1
  157. package/dist/docs/api/types/type-aliases/ComponentInput.md +4 -4
  158. package/dist/docs/api/types/type-aliases/ComponentKind.md +1 -1
  159. package/dist/docs/api/types/type-aliases/DropdownInput.md +3 -3
  160. package/dist/docs/api/types/type-aliases/DropdownOption.md +3 -3
  161. package/dist/docs/api/types/type-aliases/EcsEntityEditorKind.md +1 -1
  162. package/dist/docs/api/types/type-aliases/EcsEntityKind.md +1 -1
  163. package/dist/docs/api/types/type-aliases/EntityId.md +1 -1
  164. package/dist/docs/api/types/type-aliases/EntityInput.md +3 -3
  165. package/dist/docs/api/types/type-aliases/FloatInput.md +1 -1
  166. package/dist/docs/api/types/type-aliases/IntersectionResult.md +3 -3
  167. package/dist/docs/api/types/type-aliases/ParentLookup.md +3 -3
  168. package/dist/docs/api/types/type-aliases/SelectionListener.md +1 -1
  169. package/dist/docs/api/types/type-aliases/SliderInput.md +5 -5
  170. package/dist/docs/api/types/type-aliases/TextInput.md +1 -1
  171. package/dist/docs/api/types/type-aliases/ToggleInput.md +1 -1
  172. package/dist/docs/api/types/type-aliases/Vec3.md +1 -1
  173. package/dist/docs/api/types/type-aliases/Vector2Input.md +3 -3
  174. package/dist/docs/api/types/type-aliases/Vector3Input.md +4 -4
  175. package/dist/docs/api/types/type-aliases/WorldEntityView.md +1 -1
  176. package/dist/docs/guide/accessing-components.md +135 -1
  177. package/dist/docs/guide/authoring-a-behaviour.md +1 -1
  178. package/dist/docs/guide/behaviour-data-binding/asset-input.md +54 -0
  179. package/dist/docs/guide/behaviour-data-binding/checkbox-input.md +38 -0
  180. package/dist/docs/guide/behaviour-data-binding/color-input.md +38 -0
  181. package/dist/docs/guide/behaviour-data-binding/component-input.md +79 -0
  182. package/dist/docs/guide/behaviour-data-binding/dropdown-input.md +53 -0
  183. package/dist/docs/guide/behaviour-data-binding/entity-input.md +100 -0
  184. package/dist/docs/guide/behaviour-data-binding/float-input.md +35 -0
  185. package/dist/docs/guide/behaviour-data-binding/index.md +158 -0
  186. package/dist/docs/guide/behaviour-data-binding/slider-input.md +37 -0
  187. package/dist/docs/guide/behaviour-data-binding/text-input.md +35 -0
  188. package/dist/docs/guide/behaviour-data-binding/toggle-input.md +36 -0
  189. package/dist/docs/guide/behaviour-data-binding/vector2-input.md +36 -0
  190. package/dist/docs/guide/behaviour-data-binding/vector3-input.md +41 -0
  191. package/dist/docs/guide/component-catalog.md +2 -0
  192. package/dist/docs/guide/components/animation.md +40 -1
  193. package/dist/docs/guide/components/instanced-mesh.md +1 -4
  194. package/dist/docs/guide/runtime-entity-management.md +302 -0
  195. package/dist/docs/guide/scene/environment.md +5 -6
  196. package/dist/docs/guide/scene/index.md +5 -10
  197. package/dist/docs/guide/scene/postprocessing.md +5 -6
  198. package/dist/docs/guide/spawning/audio.md +29 -7
  199. package/dist/docs/guide/systems/object-management-system.md +70 -0
  200. package/dist/docs/guide/world-api.md +3 -1
  201. package/dist/factories/index.cjs.map +1 -1
  202. package/dist/factories/index.d.cts +2 -2
  203. package/dist/factories/index.d.ts +2 -2
  204. package/dist/factories/index.js +3 -3
  205. package/dist/{index-D-gUELQS.d.ts → index-ByX7502C.d.ts} +2 -2
  206. package/dist/{index-ComEYKYI.d.cts → index-D7q4SRCp.d.cts} +2 -2
  207. package/dist/index.cjs +84 -1
  208. package/dist/index.cjs.map +1 -1
  209. package/dist/index.d.cts +5 -5
  210. package/dist/index.d.ts +5 -5
  211. package/dist/index.js +55 -8
  212. package/dist/index.js.map +1 -1
  213. package/dist/systems/index.cjs +37 -1
  214. package/dist/systems/index.cjs.map +1 -1
  215. package/dist/systems/index.d.cts +2 -2
  216. package/dist/systems/index.d.ts +2 -2
  217. package/dist/systems/index.js +3 -3
  218. package/dist/types.d.cts +1 -1
  219. package/dist/types.d.ts +1 -1
  220. package/dist/worldSnapshotUtils.d.cts +1 -1
  221. package/dist/worldSnapshotUtils.d.ts +1 -1
  222. package/package.json +1 -1
  223. package/dist/chunk-OIOUWDOS.js.map +0 -1
  224. package/dist/chunk-XPCVEXMY.js.map +0 -1
  225. package/dist/docs/guide/inspector-data-binding.md +0 -367
@@ -0,0 +1,158 @@
1
+ # Behaviour Data Binding
2
+
3
+ The `ScriptComponent.data` field is the bridge between the editor inspector and your `Behaviour` subclass. Anything you place on `data` is:
4
+
5
+ 1. Saved with the project.
6
+ 2. Rendered as a live inspector control in the editor.
7
+ 3. Available at runtime as `this.data` inside the script.
8
+
9
+ The **type annotation** on each field tells the editor which control to render. Import the input types from `@relu-interactives/spatial-ecs` and use them as `as` casts on the initial values in your data object.
10
+
11
+ ## Input types
12
+
13
+ | Type | Inspector control | Runtime value |
14
+ | --- | --- | --- |
15
+ | [`FloatInput`](./float-input) | Number input | `number` |
16
+ | [`TextInput`](./text-input) | Text input | `string` |
17
+ | [`ColorInput`](./color-input) | Color picker | `string` (hex, e.g. `"#ff0000"`) |
18
+ | [`Vector2Input`](./vector2-input) | XY number pair | `{ x: number; y: number }` |
19
+ | [`Vector3Input`](./vector3-input) | XYZ number triple | `{ x: number; y: number; z: number }` |
20
+ | [`SliderInput`](./slider-input) | Range slider | `{ min, max, step, value }` — read `field.value` at runtime |
21
+ | [`DropdownInput`](./dropdown-input) | Select dropdown | `{ options: DropdownOption[]; value: string }` — read `field.value` |
22
+ | [`CheckboxInput`](./checkbox-input) | Checkbox | `{ type: "checkbox"; value: boolean }` — read `.value` |
23
+ | [`ToggleInput`](./toggle-input) | Toggle switch | `boolean` |
24
+ | [`AssetInput`](./asset-input) | Asset file picker | `{ path: string; type: string }` — read `field.path` |
25
+ | [`EntityInput`](./entity-input) | Entity picker | `{ type: "entity"; value: WorldEntityView \| null }` — read `field.value` |
26
+ | [`ComponentInput`](./component-input) | Entity + component picker | `{ type: "component"; componentKind?: ComponentKind; value: Component \| null }` — read `field.value` |
27
+
28
+ ## Declaring inspector fields
29
+
30
+ Import the input types you need alongside `Behaviour`, then declare them directly on the `data` class property using `as` casts:
31
+
32
+ ```ts
33
+ import {
34
+ Behaviour,
35
+ type FloatInput,
36
+ type TextInput,
37
+ type ColorInput,
38
+ type Vector2Input,
39
+ type Vector3Input,
40
+ type SliderInput,
41
+ type DropdownInput,
42
+ type CheckboxInput,
43
+ type ToggleInput,
44
+ type AssetInput,
45
+ type EntityInput,
46
+ type ComponentInput,
47
+ } from "@relu-interactives/spatial-ecs";
48
+
49
+ export default class Demo extends Behaviour {
50
+ data = {
51
+ speed: 1 as FloatInput,
52
+ label: "Hello" as TextInput,
53
+ tint: "#ffffff" as ColorInput,
54
+ offset: { x: 0, y: 0 } as Vector2Input,
55
+ origin: { x: 0, y: 0, z: 0 } as Vector3Input,
56
+ range: { min: 0, max: 10, step: 0.1, value: 5 } as SliderInput,
57
+ axis: {
58
+ value: "y",
59
+ options: [
60
+ { label: "X", value: "x" },
61
+ { label: "Y", value: "y" },
62
+ { label: "Z", value: "z" },
63
+ ],
64
+ } as DropdownInput,
65
+ active: true as ToggleInput,
66
+ visible: { type: "checkbox", value: true } as CheckboxInput,
67
+ texture: { path: "", type: "image" } as AssetInput,
68
+ target: { type: "entity", value: null } as EntityInput,
69
+ camera: { type: "component", componentKind: "Camera", value: null } as ComponentInput,
70
+ };
71
+ }
72
+ ```
73
+
74
+ Each field in `data` maps directly to a live inspector control. The script above produces the following inspector panel:
75
+
76
+ ![Behaviour inspector controls](/images/behaviour-data-binding/behavior-inspector.gif)
77
+
78
+ ## Reading values at runtime
79
+
80
+ Most types map directly to their underlying primitive. The exceptions are `SliderInput`, `DropdownInput`, `AssetInput`, `EntityInput`, and `ComponentInput` — read the nested value:
81
+
82
+ ```ts
83
+ onUpdate() {
84
+ // Primitives — use directly
85
+ this.transform.rotation.y += this.data.speed * this.deltaTime;
86
+
87
+ // SliderInput → read .value
88
+ const volume = this.data.range.value;
89
+
90
+ // DropdownInput → read .value
91
+ const axis = this.data.axis.value as "x" | "y" | "z";
92
+
93
+ // AssetInput → read .path
94
+ const src = this.data.texture.path;
95
+
96
+ // EntityInput → cast to WorldEntityView | null
97
+ const entity = this.data.target.value as WorldEntityView | null;
98
+
99
+ // ComponentInput → cast to the concrete component type
100
+ const cam = this.data.camera.value as CameraComponent | null;
101
+ }
102
+ ```
103
+
104
+ ## Practical example — spinner with inspector controls
105
+
106
+ ```ts
107
+ import {
108
+ Behaviour,
109
+ type FloatInput,
110
+ type ColorInput,
111
+ type DropdownInput,
112
+ type ToggleInput,
113
+ } from "@relu-interactives/spatial-ecs";
114
+
115
+ export default class Spinner extends Behaviour {
116
+ data = {
117
+ speed: 1 as FloatInput,
118
+ color: "#00aaff" as ColorInput,
119
+ enabled: true as ToggleInput,
120
+ axis: {
121
+ value: "y",
122
+ options: [
123
+ { label: "X", value: "x" },
124
+ { label: "Y", value: "y" },
125
+ { label: "Z", value: "z" },
126
+ ],
127
+ } as DropdownInput,
128
+ };
129
+
130
+ onUpdate() {
131
+ if (!this.data.enabled) return;
132
+ const axis = this.data.axis.value as "x" | "y" | "z";
133
+ this.transform.rotation[axis] += this.data.speed * this.deltaTime;
134
+ }
135
+ }
136
+ ```
137
+
138
+ ## Defaulting fields
139
+
140
+ Defaults are set inline on the `data` property. When a saved project reloads, saved values take precedence — the inline defaults only apply when a field has never been saved. This means:
141
+
142
+ - Adding a new field with an inline default is safe — existing saves will pick it up on next load.
143
+ - The inspector always has a valid initial value when the script is first attached.
144
+ - For `SliderInput` and `DropdownInput`, the full object (including `options`) must be present in the inline default — the editor reads `options` to build the control.
145
+
146
+ ## Persistence
147
+
148
+ `ScriptComponent.data` is serialized and saved with the project. On reload, your `data` payload is restored verbatim. If you rename or restructure a field, migrate it inside `init()`:
149
+
150
+ ```ts
151
+ init() {
152
+ // migrate renamed field
153
+ if ((this.data as any).oldSpeed !== undefined) {
154
+ this.data.speed = (this.data as any).oldSpeed;
155
+ delete (this.data as any).oldSpeed;
156
+ }
157
+ }
158
+ ```
@@ -0,0 +1,37 @@
1
+ # SliderInput
2
+
3
+ A range slider. The inspector renders a horizontal slider with the current value displayed alongside it.
4
+
5
+ **Runtime value:** `{ min: number; max: number; step: number; value: number }` — read `field.value`
6
+
7
+ ![SliderInput inspector control](/images/behaviour-data-binding/slider-input.png)
8
+
9
+ ## Declaration
10
+
11
+ Provide the full object including `min`, `max`, `step`, and the initial `value`. The editor reads `min`/`max`/`step` to configure the slider control.
12
+
13
+ ```ts
14
+ import { Behaviour, type SliderInput } from "@relu-interactives/spatial-ecs";
15
+
16
+ export default class Demo extends Behaviour {
17
+ data = {
18
+ volume: { min: 0, max: 1, step: 0.01, value: 0.8 } as SliderInput,
19
+ quality: { min: 1, max: 10, step: 1, value: 5 } as SliderInput,
20
+ };
21
+ }
22
+ ```
23
+
24
+ ## Runtime usage
25
+
26
+ Read the `.value` property — the other fields (`min`, `max`, `step`) are for the editor control only:
27
+
28
+ ```ts
29
+ onUpdate() {
30
+ const volume = this.data.volume.value; // number between 0 and 1
31
+ }
32
+ ```
33
+
34
+ ## Notes
35
+
36
+ - Always include `min`, `max`, and `step` in the inline default — the editor needs them to render the control.
37
+ - `step` can be fractional for smooth sliders (e.g. `0.01`).
@@ -0,0 +1,35 @@
1
+ # TextInput
2
+
3
+ A single-line text field. The inspector renders a plain text input.
4
+
5
+ **Runtime value:** `string`
6
+
7
+ ![TextInput inspector control](/images/behaviour-data-binding/text-input.png)
8
+
9
+ ## Declaration
10
+
11
+ ```ts
12
+ import { Behaviour, type TextInput } from "@relu-interactives/spatial-ecs";
13
+
14
+ export default class Demo extends Behaviour {
15
+ data = {
16
+ label: "Hello world" as TextInput,
17
+ apiKey: "" as TextInput,
18
+ };
19
+ }
20
+ ```
21
+
22
+ ## Runtime usage
23
+
24
+ Use the value directly as a `string`:
25
+
26
+ ```ts
27
+ init() {
28
+ console.log(this.data.label); // "Hello world"
29
+ }
30
+ ```
31
+
32
+ ## Notes
33
+
34
+ - The default value is what the user sees when the script is first attached.
35
+ - Useful for URLs, display strings, or any freeform text parameter.
@@ -0,0 +1,36 @@
1
+ # ToggleInput
2
+
3
+ An on/off toggle switch. The inspector renders a pill-shaped toggle.
4
+
5
+ **Runtime value:** `boolean`
6
+
7
+ ![ToggleInput inspector control](/images/behaviour-data-binding/toggle-input.png)
8
+
9
+ ## Declaration
10
+
11
+ ```ts
12
+ import { Behaviour, type ToggleInput } from "@relu-interactives/spatial-ecs";
13
+
14
+ export default class Demo extends Behaviour {
15
+ data = {
16
+ enabled: true as ToggleInput,
17
+ loopAudio: false as ToggleInput,
18
+ };
19
+ }
20
+ ```
21
+
22
+ ## Runtime usage
23
+
24
+ Use the value directly as a `boolean`:
25
+
26
+ ```ts
27
+ onUpdate() {
28
+ if (!this.data.enabled) return;
29
+ // ... rest of update logic
30
+ }
31
+ ```
32
+
33
+ ## Notes
34
+
35
+ - Prefer `ToggleInput` for feature flags (e.g. "Enabled", "Loop") and [`CheckboxInput`](./checkbox-input) for property-style options.
36
+ - Both types resolve to a plain `boolean` at runtime.
@@ -0,0 +1,36 @@
1
+ # Vector2Input
2
+
3
+ An XY number pair. The inspector renders two side-by-side number inputs labelled **X** and **Y**.
4
+
5
+ **Runtime value:** `{ x: number; y: number }`
6
+
7
+ ![Vector2Input inspector control](/images/behaviour-data-binding/vector2-input.png)
8
+
9
+ ## Declaration
10
+
11
+ ```ts
12
+ import { Behaviour, type Vector2Input } from "@relu-interactives/spatial-ecs";
13
+
14
+ export default class Demo extends Behaviour {
15
+ data = {
16
+ offset: { x: 0, y: 0 } as Vector2Input,
17
+ uvScale: { x: 1, y: 1 } as Vector2Input,
18
+ };
19
+ }
20
+ ```
21
+
22
+ ## Runtime usage
23
+
24
+ Read `x` and `y` directly:
25
+
26
+ ```ts
27
+ onUpdate() {
28
+ this.transform.position.x += this.data.offset.x * this.deltaTime;
29
+ this.transform.position.y += this.data.offset.y * this.deltaTime;
30
+ }
31
+ ```
32
+
33
+ ## Notes
34
+
35
+ - Suitable for screen-space positions, UV offsets, or any 2D vector parameter.
36
+ - Use [`Vector3Input`](./vector3-input) for 3D world-space values.
@@ -0,0 +1,41 @@
1
+ # Vector3Input
2
+
3
+ An XYZ number triple. The inspector renders three side-by-side number inputs labelled **X**, **Y**, and **Z**.
4
+
5
+ **Runtime value:** `{ x: number; y: number; z: number }`
6
+
7
+ ![Vector3Input inspector control](/images/behaviour-data-binding/vector3-input.png)
8
+
9
+ ## Declaration
10
+
11
+ ```ts
12
+ import { Behaviour, type Vector3Input } from "@relu-interactives/spatial-ecs";
13
+
14
+ export default class Demo extends Behaviour {
15
+ data = {
16
+ spawnPoint: { x: 0, y: 1, z: 0 } as Vector3Input,
17
+ force: { x: 0, y: 0, z: 0 } as Vector3Input,
18
+ };
19
+ }
20
+ ```
21
+
22
+ ## Runtime usage
23
+
24
+ Read `x`, `y`, and `z` directly:
25
+
26
+ ```ts
27
+ import * as THREE from "three";
28
+
29
+ init() {
30
+ const point = new THREE.Vector3(
31
+ this.data.spawnPoint.x,
32
+ this.data.spawnPoint.y,
33
+ this.data.spawnPoint.z,
34
+ );
35
+ }
36
+ ```
37
+
38
+ ## Notes
39
+
40
+ - Ideal for world-space positions, directions, or scale factors.
41
+ - Values are plain numbers — no automatic unit conversion is applied.
@@ -27,6 +27,8 @@ Every entity in `@relu-interactives/spatial-ecs` is a bag of components. This ca
27
27
  - [Sprite](./components/sprite) — camera-facing billboard.
28
28
  - [Video](./components/video) — video texture with optional green-screen keying.
29
29
  - [Model](./components/model) — GLTF/GLB asset reference loaded asynchronously.
30
+ - [Instanced Mesh](./components/instanced-mesh) — groups instance-slot entities into a single GPU-instanced draw call for high-count identical objects.
31
+ - [Instance Slot](./components/instance-slot) — marks an entity as a single instance within an `InstancedMeshComponent` group.
30
32
 
31
33
  ## Lighting & atmosphere
32
34
 
@@ -109,9 +109,48 @@ export default class AnimationSpeedDriver extends Behaviour {
109
109
  ```
110
110
 
111
111
  ::: tip State machine
112
- Always use anim.switchState(name)` to change the active clip — do not assign to `active` directly. This ensures the animation system observes the transition and applies the configured cross-fade.
112
+ Always use `anim.switchState(name)` to change the active clip — do not assign to `active` directly. This ensures the animation system observes the transition and applies the configured cross-fade.
113
113
  :::
114
114
 
115
+ ### ⚠️ `addState` — positional args only (critical)
116
+
117
+ `addState` takes **three positional arguments**: `(name, clipRef, loop)`. Passing an object will silently resolve nothing because `resolveClipRef` won't find a clip named `[object Object]`.
118
+
119
+ ```typescript
120
+ // ✅ Correct — positional args
121
+ anim.addState("Walk", "Walk", true);
122
+ anim.addState("Attack", "Attack", false);
123
+
124
+ // ❌ Wrong — object arg; the clip will never resolve
125
+ anim.addState({ name: "Walk", clip: "Walk", loop: true }); // ← broken
126
+ ```
127
+
128
+ ### Typical deferred setup (model may not be loaded yet)
129
+
130
+ Guard on `availableClips.length > 0` inside `onUpdate` until the model is ready, then register states once:
131
+
132
+ ```typescript
133
+ import { Behaviour, AnimationComponent } from "@relu-interactives/spatial-ecs";
134
+
135
+ export default class AnimSetup extends Behaviour {
136
+ private ready = false;
137
+
138
+ protected onUpdate() {
139
+ if (this.ready) return;
140
+ const anim = this.getComponent(AnimationComponent);
141
+ if (!anim || anim.availableClips.length === 0) return;
142
+
143
+ const c = anim.availableClips;
144
+ if (c.includes("Walk")) anim.addState("Walk", "Walk", true);
145
+ if (c.includes("Run")) anim.addState("Run", "Run", true);
146
+ if (c.includes("Attack")) anim.addState("Attack", "Attack", false);
147
+ anim.crossFadeDuration = 0.25;
148
+ anim.switchState("Walk");
149
+ this.ready = true;
150
+ }
151
+ }
152
+ ```
153
+
115
154
  ### Via `ComponentInput` in the inspector
116
155
 
117
156
  You can also pick this component from the inspector using a `ComponentInput` field. Assign any entity in the inspector and the field resolves to the live `AnimationComponent` instance at runtime.
@@ -8,10 +8,7 @@ Use instanced meshes when you need tens, hundreds, or thousands of identical obj
8
8
 
9
9
  ## Editor inspector
10
10
 
11
- ::: tip Screenshot
12
- Add a screenshot of the **Instanced Mesh** component in the editor inspector here.
13
- Suggested asset path: `/public/images/inspector/instanced-mesh.png`
14
- :::
11
+ ![Instanced Mesh inspector](/images/components/instanced-mesh.png)
15
12
 
16
13
  ## Properties
17
14