@relu-interactives/spatial-ecs 0.2.12 → 0.2.14

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 (220) hide show
  1. package/dist/{System-CHCucemW.d.cts → System-BeuJ1xt5.d.cts} +291 -2
  2. package/dist/{System-CHCucemW.d.ts → System-BeuJ1xt5.d.ts} +291 -2
  3. package/dist/{Video-B9ZKmBIT.d.ts → Video-Cym2C52L.d.ts} +2 -241
  4. package/dist/{Video-ACTSfWjH.d.cts → Video-D4B-z74P.d.cts} +2 -241
  5. package/dist/{chunk-PH43YHUT.js → chunk-27RBPOVO.js} +3 -3
  6. package/dist/{chunk-PH43YHUT.js.map → chunk-27RBPOVO.js.map} +1 -1
  7. package/dist/{chunk-ZCEMOTH4.js → chunk-7QBONTBW.js} +4 -4
  8. package/dist/{chunk-ZCEMOTH4.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-ON4E5E5O.js → chunk-KDZ6VBRO.js} +4 -4
  12. package/dist/{chunk-ON4E5E5O.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 +14 -14
  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 +186 -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/components/parent-id.md +25 -0
  192. package/dist/docs/guide/runtime-entity-management.md +302 -0
  193. package/dist/docs/guide/scene/environment.md +5 -6
  194. package/dist/docs/guide/scene/index.md +5 -10
  195. package/dist/docs/guide/scene/postprocessing.md +5 -6
  196. package/dist/docs/guide/systems/object-management-system.md +61 -0
  197. package/dist/docs/guide/world-api.md +37 -1
  198. package/dist/factories/index.cjs.map +1 -1
  199. package/dist/factories/index.d.cts +2 -2
  200. package/dist/factories/index.d.ts +2 -2
  201. package/dist/factories/index.js +3 -3
  202. package/dist/{index-B5JcGMJ5.d.ts → index-BfoOC2CG.d.cts} +2 -2
  203. package/dist/{index-kx5O2mVU.d.cts → index-BoJ3_6a3.d.ts} +2 -2
  204. package/dist/index.cjs +65 -0
  205. package/dist/index.cjs.map +1 -1
  206. package/dist/index.d.cts +5 -5
  207. package/dist/index.d.ts +5 -5
  208. package/dist/index.js +73 -8
  209. package/dist/index.js.map +1 -1
  210. package/dist/systems/index.cjs.map +1 -1
  211. package/dist/systems/index.d.cts +2 -2
  212. package/dist/systems/index.d.ts +2 -2
  213. package/dist/systems/index.js +3 -3
  214. package/dist/types.d.cts +1 -1
  215. package/dist/types.d.ts +1 -1
  216. package/dist/worldSnapshotUtils.d.cts +1 -1
  217. package/dist/worldSnapshotUtils.d.ts +1 -1
  218. package/package.json +1 -1
  219. package/dist/chunk-XPCVEXMY.js.map +0 -1
  220. package/dist/docs/guide/inspector-data-binding.md +0 -367
@@ -10,7 +10,7 @@
10
10
  type WorldEntityView = NonNullable<ReturnType<World["getEntityById"]>>;
11
11
  ```
12
12
 
13
- Defined in: [types.ts:126](https://github.com/Relu-Interactives/relu-spatial-ecs-engine/blob/7fc62aaeb41923795e50fda6e082908528d5abe6/core/types.ts#L126)
13
+ Defined in: [types.ts:126](https://github.com/Relu-Interactives/relu-spatial-ecs-engine/blob/f4080487315dc2ea88332b3160fc071e7828b385/core/types.ts#L126)
14
14
 
15
15
  Lightweight, read-only view of an entity returned by `World.getEntityById`.
16
16
  Contains the entity id and its current component list at the moment of the
@@ -392,8 +392,142 @@ See [World API](./world-api) for the full set of entity and component query meth
392
392
 
393
393
  ---
394
394
 
395
+ ## Adding and removing components at runtime
396
+
397
+ You can add or remove components on any entity from a Behaviour script at runtime using `this.world` or through `ObjectManagementSystem`.
398
+
399
+ ### `world.addComponent` — attach a data component
400
+
401
+ Use `world.addComponent` to attach a simple, data-only component that carries no runtime handles:
402
+
403
+ ```ts
404
+ import { Behaviour } from "@relu-interactives/spatial-ecs";
405
+ import { Name } from "@relu-interactives/spatial-ecs/components";
406
+
407
+ export default class Tagger extends Behaviour {
408
+ protected init() {
409
+ const entity = this.world.getEntityByName("Target");
410
+ if (!entity) return;
411
+
412
+ // Give the entity a display name
413
+ this.world.addComponent(entity.entityId, new Name({ value: "Tagged" }));
414
+ }
415
+ }
416
+ ```
417
+
418
+ ### `world.removeComponent` — detach a component by class
419
+
420
+ ```ts
421
+ import { Behaviour } from "@relu-interactives/spatial-ecs";
422
+ import { PhysicsComponent } from "@relu-interactives/spatial-ecs/components";
423
+
424
+ export default class Freezer extends Behaviour {
425
+ protected init() {
426
+ // Remove physics from this entity to freeze it in place
427
+ this.world.removeComponent(this.entityId, PhysicsComponent);
428
+ }
429
+ }
430
+ ```
431
+
432
+ ### `oms.createComponentNow` — factory-initialized components
433
+
434
+ For components that require full runtime setup — Rapier physics bodies, Web Audio nodes, Three.js material instances, animation clip catalogs — use `createComponentNow` on `ObjectManagementSystem`. It calls the same registered factory used during scene construction, ensuring all runtime handles are correctly wired:
435
+
436
+ ```ts
437
+ import { Behaviour } from "@relu-interactives/spatial-ecs";
438
+
439
+ export default class DynamicPhysics extends Behaviour {
440
+ protected init() {
441
+ const oms = this.world.getObjectManagementSystem();
442
+ if (!oms) return;
443
+
444
+ // Add a physics component with full Rapier rigidbody and collider setup
445
+ oms.createComponentNow("physics", this.world, this.entityId, {
446
+ rigidbody: { type: "dynamic", mass: 1, gravityScale: 1 },
447
+ collider: { shape: "box" },
448
+ });
449
+ }
450
+ }
451
+ ```
452
+
453
+ **Registered component factory kinds:**
454
+
455
+ | Kind | Component |
456
+ |------|-----------|
457
+ | `"animation"` | AnimationComponent |
458
+ | `"audio"` | AudioComponent |
459
+ | `"camera"` | CameraComponent |
460
+ | `"physics"` | PhysicsComponent |
461
+ | `"environment"` | EnvironmentComponent |
462
+ | `"entityType"` | EntityTypeComponent |
463
+ | `"image"` | ImageComponent |
464
+ | `"imageTarget"` | ImageTargetComponent |
465
+ | `"imageTargetAnchor"` | ImageTargetAnchorComponent |
466
+ | `"light"` | LightComponent |
467
+ | `"material"` | MaterialComponent |
468
+ | `"mesh"` | MeshComponent |
469
+ | `"meshGeometry"` | MeshGeometryComponent |
470
+ | `"model"` | ModelComponent |
471
+ | `"name"` | Name |
472
+ | `"object3DRef"` | Object3DRef |
473
+ | `"parentId"` | ParentId |
474
+ | `"postprocessing"` | PostprocessingComponent |
475
+ | `"script"` | ScriptComponent |
476
+ | `"sprite"` | SpriteComponent |
477
+ | `"transform"` | TransformComponent |
478
+ | `"video"` | VideoComponent |
479
+ | `"instancedMesh"` | InstancedMeshComponent |
480
+
481
+ **Decision guide:**
482
+
483
+ | Scenario | Use |
484
+ |----------|-----|
485
+ | Tagging with name, type, or other pure-data component | `world.addComponent(id, new ComponentClass(...))` |
486
+ | Adding physics with Rapier body/collider | `oms.createComponentNow("physics", world, id, config)` |
487
+ | Adding audio with Web Audio node | `oms.createComponentNow("audio", world, id, path, options, ctx)` |
488
+ | Adding a material with Three.js material instance | `oms.createComponentNow("material", world, id, values)` |
489
+ | Detaching any component | `world.removeComponent(id, ComponentClass)` |
490
+
491
+ ### Post-spawn example: add physics to a spawned cube
492
+
493
+ ```ts
494
+ import { Behaviour } from "@relu-interactives/spatial-ecs";
495
+
496
+ export default class PhysicsCube extends Behaviour {
497
+ private spawnedId: number | null = null;
498
+
499
+ protected init() {
500
+ const oms = this.world.getObjectManagementSystem();
501
+ if (!oms) return;
502
+
503
+ oms.requestCreate("cube", {
504
+ name: "PhysicsCube",
505
+ transform: { position: { x: 0, y: 3, z: 0 } },
506
+ }, (entityId) => {
507
+ this.spawnedId = entityId;
508
+ // Physics factory wires up Rapier body + collider automatically
509
+ oms.createComponentNow("physics", this.world, entityId, {
510
+ rigidbody: { type: "dynamic", mass: 1, gravityScale: 1 },
511
+ collider: { shape: "box" },
512
+ });
513
+ });
514
+ }
515
+
516
+ dispose(world: any) {
517
+ if (this.spawnedId !== null) {
518
+ this.world.getObjectManagementSystem()?.deleteEntity(this.world, this.spawnedId, true);
519
+ }
520
+ }
521
+ }
522
+ ```
523
+
524
+ For the full guide covering `setParent`, async loading patterns, and complete worked examples, see [Runtime Entity Management](./runtime-entity-management).
525
+
526
+ ---
527
+
395
528
  ## See also
396
529
 
397
530
  - [Custom Behaviours](./authoring-a-behaviour) — script anatomy and lifecycle
398
- - [Inspector Data Binding](./inspector-data-binding) — exposing fields to the inspector
531
+ - [Behaviour Data Binding](./behaviour-data-binding/) — exposing fields to the inspector
399
532
  - [World API](./world-api) — querying entities and components across the scene
533
+ - [Runtime Entity Management](./runtime-entity-management) — addComponent, createComponentNow, setParent, deleteEntity
@@ -116,7 +116,7 @@ export default class Spinner extends Behaviour {
116
116
  }
117
117
  ```
118
118
 
119
- See [Inspector Data Binding](./inspector-data-binding) for the full reference of all input types (`TextInput`, `ColorInput`, `Vector2Input`, `Vector3Input`, `SliderInput`, `CheckboxInput`, `ToggleInput`, `AssetInput`, and more).
119
+ See [Behaviour Data Binding](./behaviour-data-binding/) for the full reference of all input types (`TextInput`, `ColorInput`, `Vector2Input`, `Vector3Input`, `SliderInput`, `CheckboxInput`, `ToggleInput`, `AssetInput`, and more).
120
120
 
121
121
  See [Accessing Components](./accessing-components) to read and mutate built-in components such as `PhysicsComponent`, `AudioComponent`, `AnimationComponent`, `LightComponent`, and `MaterialComponent` from script.
122
122
 
@@ -0,0 +1,54 @@
1
+ # AssetInput
2
+
3
+ A file picker that lets the user select an asset from the project's `assets/` folder. The inspector renders a file browser button showing the selected filename.
4
+
5
+ **Runtime value:** `{ path: string; type: string }` — read `field.path`.
6
+
7
+ ![AssetInput inspector control](/images/behaviour-data-binding/asset-input.png)
8
+
9
+ ## Declaration
10
+
11
+ Provide the `type` string to categorize the asset. Set `path` to an empty string for "no file selected".
12
+
13
+ ```ts
14
+ import { Behaviour, type AssetInput } from "@relu-interactives/spatial-ecs";
15
+
16
+ export default class Demo extends Behaviour {
17
+ data = {
18
+ clip: { path: "", type: "audio" } as AssetInput,
19
+ model: { path: "", type: "model" } as AssetInput,
20
+ video: { path: "", type: "video" } as AssetInput,
21
+ texture: { path: "", type: "image" } as AssetInput,
22
+ };
23
+ }
24
+ ```
25
+
26
+ > [!IMPORTANT]
27
+ > Do **not** use `type: "texture"` or `type: "texturemap"` — the inspector treats those as a legacy URL text field rather than the asset file picker. Use `"image"` instead for image/texture assets.
28
+
29
+ ## Runtime usage
30
+
31
+ Read the `.path` property. Guard for an empty string (no file selected):
32
+
33
+ ```ts
34
+ init() {
35
+ const path = this.data.clip.path;
36
+ if (!path) return; // no file selected in the inspector
37
+ console.log(path); // e.g. "./assets/sounds/click.mp3"
38
+ }
39
+ ```
40
+
41
+ ## Common `type` values
42
+
43
+ | `type` | Asset kind |
44
+ | --- | --- |
45
+ | `"audio"` | Audio files (mp3, wav, ogg, …) |
46
+ | `"image"` | Image files (png, jpg, webp, …) |
47
+ | `"model"` | 3D model files (glb, gltf, …) |
48
+ | `"video"` | Video files (mp4, webm, …) |
49
+
50
+ ## Notes
51
+
52
+ - The `type` string is for categorization only — it has no effect at runtime.
53
+ - `path` is relative to the project root (e.g. `"./assets/audio/click.mp3"`).
54
+ - `AssetInput` provides the path only. Load the asset yourself at runtime if needed.
@@ -0,0 +1,38 @@
1
+ # CheckboxInput
2
+
3
+ A checkbox. The inspector renders a standard checkbox control.
4
+
5
+ **Runtime value:** `{ type: "checkbox"; value: boolean }` — read `.value`
6
+
7
+ ![CheckboxInput inspector control](/images/behaviour-data-binding/checkbox-input.png)
8
+
9
+ ## Declaration
10
+
11
+ Declare with a `type: "checkbox"` envelope and an initial `value`:
12
+
13
+ ```ts
14
+ import { Behaviour, type CheckboxInput } from "@relu-interactives/spatial-ecs";
15
+
16
+ export default class Demo extends Behaviour {
17
+ data = {
18
+ visible: { type: "checkbox", value: true } as CheckboxInput,
19
+ castShadow: { type: "checkbox", value: false } as CheckboxInput,
20
+ };
21
+ }
22
+ ```
23
+
24
+ ## Runtime usage
25
+
26
+ Read the `.value` property:
27
+
28
+ ```ts
29
+ onUpdate() {
30
+ if (!this.data.visible.value) return;
31
+ // ... rest of update logic
32
+ }
33
+ ```
34
+
35
+ ## Notes
36
+
37
+ - Use `CheckboxInput` for property-style options (e.g. "Cast shadow", "Visible") and [`ToggleInput`](./toggle-input) for simple on/off feature flags.
38
+ - `ToggleInput` is a plain `boolean` and requires no envelope — use it when you don't need the checkbox visual.
@@ -0,0 +1,38 @@
1
+ # ColorInput
2
+
3
+ A color picker field. The inspector renders a swatch that opens a full color picker on click.
4
+
5
+ **Runtime value:** `string` (hex, e.g. `"#ff0000"`)
6
+
7
+ ![ColorInput inspector control](/images/behaviour-data-binding/color-input.png)
8
+
9
+ ## Declaration
10
+
11
+ ```ts
12
+ import { Behaviour, type ColorInput } from "@relu-interactives/spatial-ecs";
13
+
14
+ export default class Demo extends Behaviour {
15
+ data = {
16
+ tint: "#ffffff" as ColorInput,
17
+ emissive: "#000000" as ColorInput,
18
+ };
19
+ }
20
+ ```
21
+
22
+ ## Runtime usage
23
+
24
+ Use the value directly as a hex string:
25
+
26
+ ```ts
27
+ import * as THREE from "three";
28
+
29
+ init() {
30
+ const color = new THREE.Color(this.data.tint);
31
+ // apply to a material, light, etc.
32
+ }
33
+ ```
34
+
35
+ ## Notes
36
+
37
+ - Value must be a valid hex color string (`#rgb`, `#rrggbb`, or `#rrggbbaa`) — the inspector detects the format automatically and renders the color picker.
38
+ - Alpha is not included in the default 6-digit form — use a separate `FloatInput` if you need opacity control.
@@ -0,0 +1,79 @@
1
+ # ComponentInput
2
+
3
+ An entity + component picker. The inspector renders an entity dropdown and, once an entity is selected, a component-kind filter. Use this when you need direct access to a specific component on another entity.
4
+
5
+ **Runtime value:** `{ type: "component"; componentKind?: ComponentKind; value: Component | null }` — read `field.value`
6
+
7
+ ![ComponentInput inspector control](/images/behaviour-data-binding/component-input.png)
8
+
9
+ ## Declaration
10
+
11
+ Set `componentKind` to pre-filter the picker to a specific component type. Omit it to allow any component.
12
+
13
+ ```ts
14
+ import { Behaviour, type ComponentInput } from "@relu-interactives/spatial-ecs";
15
+
16
+ export default class Demo extends Behaviour {
17
+ data = {
18
+ cam: { type: "component", componentKind: "CameraComponent", value: null } as ComponentInput,
19
+ audio: { type: "component", componentKind: "AudioComponent", value: null } as ComponentInput,
20
+ };
21
+ }
22
+ ```
23
+
24
+ ## Runtime usage
25
+
26
+ At runtime, `.value` is resolved to the **live component instance**. Cast to the concrete class for full TypeScript autocompletion. Always guard for `null`:
27
+
28
+ ```ts
29
+ import {
30
+ Behaviour,
31
+ CameraComponent,
32
+ type ComponentInput,
33
+ } from "@relu-interactives/spatial-ecs";
34
+
35
+ export default class FovReader extends Behaviour {
36
+ data = {
37
+ camera: { type: "component", componentKind: "CameraComponent", value: null } as ComponentInput,
38
+ };
39
+
40
+ onUpdate() {
41
+ const cam = this.data.camera.value as CameraComponent | null;
42
+ if (!cam) return; // no component assigned
43
+
44
+ console.log(cam.fov); // current field of view in degrees
45
+ }
46
+ }
47
+ ```
48
+
49
+ ## Mutating the component
50
+
51
+ Mutate the instance directly — the system that owns the component picks up changes next frame:
52
+
53
+ ```ts
54
+ import {
55
+ Behaviour,
56
+ CameraComponent,
57
+ type ComponentInput,
58
+ type FloatInput,
59
+ } from "@relu-interactives/spatial-ecs";
60
+
61
+ export default class FovAnimator extends Behaviour {
62
+ data = {
63
+ camera: { type: "component", componentKind: "CameraComponent", value: null } as ComponentInput,
64
+ targetFov: 90 as FloatInput,
65
+ speed: 30 as FloatInput,
66
+ };
67
+
68
+ onUpdate() {
69
+ const cam = this.data.camera.value as CameraComponent | null;
70
+ if (!cam) return;
71
+
72
+ // Lerp the field of view toward targetFov
73
+ cam.fov += (this.data.targetFov - cam.fov) * this.data.speed * this.deltaTime;
74
+ }
75
+ }
76
+ ```
77
+
78
+ > [!TIP]
79
+ > Always cast to the concrete component type (e.g. `as CameraComponent | null`) for full autocompletion and always guard the null case — the field is `null` until the user picks both an entity and a component in the inspector.
@@ -0,0 +1,53 @@
1
+ # DropdownInput
2
+
3
+ A select dropdown. The inspector renders a menu populated from the `options` array.
4
+
5
+ **Runtime value:** `{ options: DropdownOption[]; value: string }` — read `field.value`
6
+
7
+ ![DropdownInput inspector control](/images/behaviour-data-binding/dropdown-input.png)
8
+
9
+ ## Declaration
10
+
11
+ Provide the full object including `options` and the initial selected `value`. The editor reads `options` to build the dropdown.
12
+
13
+ ```ts
14
+ import { Behaviour, type DropdownInput } from "@relu-interactives/spatial-ecs";
15
+
16
+ export default class Demo extends Behaviour {
17
+ data = {
18
+ axis: {
19
+ value: "y",
20
+ options: [
21
+ { label: "X", value: "x" },
22
+ { label: "Y", value: "y" },
23
+ { label: "Z", value: "z" },
24
+ ],
25
+ } as DropdownInput,
26
+ blendMode: {
27
+ value: "normal",
28
+ options: [
29
+ { label: "Normal", value: "normal" },
30
+ { label: "Additive", value: "additive" },
31
+ { label: "Multiply", value: "multiply" },
32
+ ],
33
+ } as DropdownInput,
34
+ };
35
+ }
36
+ ```
37
+
38
+ ## Runtime usage
39
+
40
+ Read the `.value` property. Cast to a union type for TypeScript narrowing:
41
+
42
+ ```ts
43
+ onUpdate() {
44
+ const axis = this.data.axis.value as "x" | "y" | "z";
45
+ this.transform.rotation[axis] += 0.01;
46
+ }
47
+ ```
48
+
49
+ ## Notes
50
+
51
+ - Always include the full `options` array in the inline default — the editor needs it to render the dropdown.
52
+ - `label` is what the user sees; `value` is what you read at runtime.
53
+ - The initial `value` must match one of the option `value` strings.
@@ -0,0 +1,100 @@
1
+ # EntityInput
2
+
3
+ An entity picker. The inspector renders a dropdown populated with all named entities in the scene.
4
+
5
+ **Runtime value:** `{ type: "entity"; value: WorldEntityView | null }` — read `field.value`
6
+
7
+ ![EntityInput inspector control](/images/behaviour-data-binding/entity-input.png)
8
+
9
+ ## Declaration
10
+
11
+ ```ts
12
+ import { Behaviour, type EntityInput } from "@relu-interactives/spatial-ecs";
13
+
14
+ export default class Demo extends Behaviour {
15
+ data = {
16
+ target: { type: "entity", value: null } as EntityInput,
17
+ };
18
+ }
19
+ ```
20
+
21
+ ## Runtime usage
22
+
23
+ At runtime, `.value` is resolved to a **`WorldEntityView`** — not a raw ID. Always guard for `null` (no entity selected):
24
+
25
+ ```ts
26
+ import { type WorldEntityView } from "@relu-interactives/spatial-ecs";
27
+
28
+ onUpdate() {
29
+ const target = this.data.target.value as WorldEntityView | null;
30
+ if (!target) return; // no entity assigned in the inspector
31
+ }
32
+ ```
33
+
34
+ ## WorldEntityView shape
35
+
36
+ ```ts
37
+ type WorldEntityView = {
38
+ name: string; // entity name from NameComponent
39
+ entityId: number; // runtime entity ID
40
+ type: string; // entity type ("mesh", "camera", "light", …)
41
+ object: THREE.Object3D | null; // live three.js scene object
42
+ components: Component[]; // all components attached to this entity
43
+ };
44
+ ```
45
+
46
+ ## Reading entity data
47
+
48
+ ```ts
49
+ onUpdate() {
50
+ const target = this.data.target.value as WorldEntityView | null;
51
+ if (!target) return;
52
+
53
+ // Name and ID
54
+ console.log(target.name); // e.g. "Camera"
55
+ console.log(target.entityId); // runtime numeric ID
56
+
57
+ // Access the three.js object directly
58
+ const obj = target.object;
59
+ if (obj) {
60
+ console.log(obj.position); // THREE.Vector3
61
+ }
62
+ }
63
+ ```
64
+
65
+ ## Moving another entity from a script
66
+
67
+ Use the entity's `components` array to find and mutate a specific component:
68
+
69
+ ```ts
70
+ import {
71
+ Behaviour,
72
+ TransformComponent,
73
+ type EntityInput,
74
+ type WorldEntityView,
75
+ type FloatInput,
76
+ } from "@relu-interactives/spatial-ecs";
77
+
78
+ export default class Mover extends Behaviour {
79
+ data = {
80
+ target: { type: "entity", value: null } as EntityInput,
81
+ speed: 5 as FloatInput,
82
+ };
83
+
84
+ onUpdate() {
85
+ const target = this.data.target.value as WorldEntityView | null;
86
+ if (!target) return;
87
+
88
+ const transform = target.components.find(
89
+ (c) => c instanceof TransformComponent,
90
+ ) as TransformComponent | undefined;
91
+
92
+ if (transform) {
93
+ transform.position.x += this.data.speed * this.deltaTime;
94
+ }
95
+ }
96
+ }
97
+ ```
98
+
99
+ > [!TIP]
100
+ > Always guard with `if (!target) return;` — the field is `null` until the user picks an entity in the inspector, and may be `null` in freshly opened scenes.
@@ -0,0 +1,35 @@
1
+ # FloatInput
2
+
3
+ A numeric input field. The inspector renders a number input that the user can type into or scrub with a drag.
4
+
5
+ **Runtime value:** `number`
6
+
7
+ ![Floating input inspector](/images/behaviour-data-binding/float-input.png)
8
+
9
+ ## Declaration
10
+
11
+ ```ts
12
+ import { Behaviour, type FloatInput } from "@relu-interactives/spatial-ecs";
13
+
14
+ export default class Demo extends Behaviour {
15
+ data = {
16
+ speed: 1 as FloatInput,
17
+ mass: 0.5 as FloatInput,
18
+ };
19
+ }
20
+ ```
21
+
22
+ ## Runtime usage
23
+
24
+ Use the value directly as a `number`:
25
+
26
+ ```ts
27
+ onUpdate() {
28
+ this.transform.rotation.y += this.data.speed * this.deltaTime;
29
+ }
30
+ ```
31
+
32
+ ## Notes
33
+
34
+ - Supports any finite `number` — positive, negative, or fractional.
35
+ - Use [`SliderInput`](./slider-input) when you want to clamp the value to a min/max range.