@relu-interactives/spatial-ecs 0.3.19 → 0.3.21

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 (49) hide show
  1. package/dist/{chunk-JYKFLQB5.js → chunk-CDSE7476.js} +38 -3
  2. package/dist/chunk-CDSE7476.js.map +1 -0
  3. package/dist/docs/guide/accessing-components.md +7 -6
  4. package/dist/docs/guide/behaviour-data-binding/component-input.md +10 -6
  5. package/dist/docs/guide/behaviour-data-binding/entity-input.md +13 -5
  6. package/dist/docs/guide/camera-rigs.md +2 -2
  7. package/dist/docs/guide/components/animation.md +12 -5
  8. package/dist/docs/guide/components/audio.md +13 -6
  9. package/dist/docs/guide/components/camera.md +10 -4
  10. package/dist/docs/guide/components/entity-type.md +13 -6
  11. package/dist/docs/guide/components/image-target-anchor.md +6 -2
  12. package/dist/docs/guide/components/image-target.md +10 -5
  13. package/dist/docs/guide/components/image.md +10 -4
  14. package/dist/docs/guide/components/instance-slot.md +7 -3
  15. package/dist/docs/guide/components/instanced-mesh.md +15 -7
  16. package/dist/docs/guide/components/light.md +10 -4
  17. package/dist/docs/guide/components/material.md +14 -8
  18. package/dist/docs/guide/components/mesh-geometry.md +10 -4
  19. package/dist/docs/guide/components/mesh.md +10 -4
  20. package/dist/docs/guide/components/model.md +4 -2
  21. package/dist/docs/guide/components/name.md +11 -6
  22. package/dist/docs/guide/components/object3d-ref.md +7 -3
  23. package/dist/docs/guide/components/parent-id.md +10 -4
  24. package/dist/docs/guide/components/physics.md +12 -6
  25. package/dist/docs/guide/components/script.md +10 -4
  26. package/dist/docs/guide/components/sprite.md +10 -4
  27. package/dist/docs/guide/components/transform.md +6 -2
  28. package/dist/docs/guide/components/video.md +10 -4
  29. package/dist/docs/guide/prefabs.md +2 -0
  30. package/dist/docs/guide/runtime-entity-management.md +1 -1
  31. package/dist/docs/guide/spawning/instanced-mesh.md +11 -6
  32. package/dist/docs/guide/systems/input-system.md +4 -1
  33. package/dist/docs/guide/systems/script-object-system.md +9 -1
  34. package/dist/docs/guide/vr-and-hand-poses.md +105 -1
  35. package/dist/docs/guide/world-api.md +23 -15
  36. package/dist/{index-C_589fc4.d.ts → index-6l4hn2Sh.d.ts} +14 -0
  37. package/dist/{index-3pNbH0iP.d.cts → index-C2I5PxCI.d.cts} +14 -0
  38. package/dist/index.cjs +36 -1
  39. package/dist/index.cjs.map +1 -1
  40. package/dist/index.d.cts +2 -2
  41. package/dist/index.d.ts +2 -2
  42. package/dist/index.js +2 -2
  43. package/dist/systems/index.cjs +36 -1
  44. package/dist/systems/index.cjs.map +1 -1
  45. package/dist/systems/index.d.cts +1 -1
  46. package/dist/systems/index.d.ts +1 -1
  47. package/dist/systems/index.js +1 -1
  48. package/package.json +4 -2
  49. package/dist/chunk-JYKFLQB5.js.map +0 -1
@@ -48,7 +48,8 @@ if (other) {
48
48
  Animate material transparency to create a pulsing ghost or reveal effect. Use `updateValue` so the state persists in the ECS snapshot — `MaterialSyncSystem` applies it to the live material each frame.
49
49
 
50
50
  ```typescript
51
- import { Behaviour, MaterialComponent } from "@relu-interactives/spatial-ecs";
51
+ import { Behaviour } from "@relu-interactives/spatial-ecs";
52
+ import { MaterialComponent } from "@relu-interactives/spatial-ecs/components";
52
53
  import type { FloatInput } from "@relu-interactives/spatial-ecs";
53
54
 
54
55
  export default class MaterialFade extends Behaviour {
@@ -64,14 +65,14 @@ export default class MaterialFade extends Behaviour {
64
65
  if (!mat) return;
65
66
 
66
67
  const opacity = (Math.sin(this.elapsed * this.data.speed) + 1) * 0.5;
67
- mat.updateValue(0, 'transparent', true);
68
- mat.updateValue(0, 'opacity', opacity);
68
+ mat.updateValue(0, { transparent: true });
69
+ mat.updateValue(0, { opacity: opacity });
69
70
  }
70
71
  }
71
72
  ```
72
73
 
73
74
  ::: warning Transient vs persistent opacity
74
- `mat.updateValue(0, 'opacity', value)` keeps `values[]` in sync with the live material — changes survive a project reload.
75
+ `mat.updateValue(0, { opacity: value })` keeps `values[]` in sync with the live material — changes survive a project reload.
75
76
 
76
77
  Mutating `mat.material?.opacity` directly can work for transient visual-only effects, but `MaterialSyncSystem` may overwrite it when other material properties change. Prefer `updateValue` for any state you want to persist.
77
78
  :::
@@ -81,7 +82,8 @@ Mutating `mat.material?.opacity` directly can work for transient visual-only eff
81
82
  Let the inspector drive the diffuse color live without restarting the scene.
82
83
 
83
84
  ```typescript
84
- import { Behaviour, MaterialComponent } from "@relu-interactives/spatial-ecs";
85
+ import { Behaviour } from "@relu-interactives/spatial-ecs";
86
+ import { MaterialComponent } from "@relu-interactives/spatial-ecs/components";
85
87
  import type { ColorInput } from "@relu-interactives/spatial-ecs";
86
88
 
87
89
  export default class MaterialColorDriver extends Behaviour {
@@ -98,7 +100,7 @@ export default class MaterialColorDriver extends Behaviour {
98
100
 
99
101
  const mat = this.getComponent(MaterialComponent);
100
102
  if (!mat) return;
101
- mat.updateValue(0, 'color', this.data.color);
103
+ mat.updateValue(0, { color: this.data.color });
102
104
  }
103
105
  }
104
106
  ```
@@ -114,9 +116,11 @@ You can also pick this component from the inspector using a `ComponentInput` fie
114
116
  ```typescript
115
117
  import {
116
118
  Behaviour,
117
- MaterialComponent,
118
119
  type ComponentInput,
119
120
  } from "@relu-interactives/spatial-ecs";
121
+ import {
122
+ MaterialComponent,
123
+ } from "@relu-interactives/spatial-ecs/components";
120
124
 
121
125
  export default class Example extends Behaviour {
122
126
  data = {
@@ -141,10 +145,12 @@ Alternatively, pick an entity from the inspector using an `EntityInput` field an
141
145
  ```typescript
142
146
  import {
143
147
  Behaviour,
144
- MaterialComponent,
145
148
  type EntityInput,
146
149
  type WorldEntityView,
147
150
  } from "@relu-interactives/spatial-ecs";
151
+ import {
152
+ MaterialComponent,
153
+ } from "@relu-interactives/spatial-ecs/components";
148
154
 
149
155
  export default class Example extends Behaviour {
150
156
  data = {
@@ -43,7 +43,8 @@ if (other) {
43
43
  Let the inspector or game logic control whether the mesh casts and receives shadows.
44
44
 
45
45
  ```typescript
46
- import { Behaviour, MeshGeometryComponent } from "@relu-interactives/spatial-ecs";
46
+ import { Behaviour } from "@relu-interactives/spatial-ecs";
47
+ import { MeshGeometryComponent } from "@relu-interactives/spatial-ecs/components";
47
48
  import type { ToggleInput } from "@relu-interactives/spatial-ecs";
48
49
 
49
50
  export default class ShadowDriver extends Behaviour {
@@ -66,7 +67,8 @@ export default class ShadowDriver extends Behaviour {
66
67
  Pulse the radius of a sphere primitive by writing to its geometry `parameters` each frame. The mesh-geometry system rebuilds the `BufferGeometry` when parameters change.
67
68
 
68
69
  ```typescript
69
- import { Behaviour, MeshGeometryComponent } from "@relu-interactives/spatial-ecs";
70
+ import { Behaviour } from "@relu-interactives/spatial-ecs";
71
+ import { MeshGeometryComponent } from "@relu-interactives/spatial-ecs/components";
70
72
  import type { FloatInput } from "@relu-interactives/spatial-ecs";
71
73
 
72
74
  export default class SphereGrow extends Behaviour {
@@ -97,9 +99,11 @@ You can also pick this component from the inspector using a `ComponentInput` fie
97
99
  ```typescript
98
100
  import {
99
101
  Behaviour,
100
- MeshGeometryComponent,
101
102
  type ComponentInput,
102
103
  } from "@relu-interactives/spatial-ecs";
104
+ import {
105
+ MeshGeometryComponent,
106
+ } from "@relu-interactives/spatial-ecs/components";
103
107
 
104
108
  export default class Example extends Behaviour {
105
109
  data = {
@@ -124,10 +128,12 @@ Alternatively, pick an entity from the inspector using an `EntityInput` field an
124
128
  ```typescript
125
129
  import {
126
130
  Behaviour,
127
- MeshGeometryComponent,
128
131
  type EntityInput,
129
132
  type WorldEntityView,
130
133
  } from "@relu-interactives/spatial-ecs";
134
+ import {
135
+ MeshGeometryComponent,
136
+ } from "@relu-interactives/spatial-ecs/components";
131
137
 
132
138
  export default class Example extends Behaviour {
133
139
  data = {
@@ -39,7 +39,8 @@ if (other) {
39
39
  Walk the mesh hierarchy and enable or disable shadow casting based on a boolean inspector field.
40
40
 
41
41
  ```typescript
42
- import { Behaviour, MeshComponent } from "@relu-interactives/spatial-ecs";
42
+ import { Behaviour } from "@relu-interactives/spatial-ecs";
43
+ import { MeshComponent } from "@relu-interactives/spatial-ecs/components";
43
44
  import type { ToggleInput } from "@relu-interactives/spatial-ecs";
44
45
 
45
46
  export default class ShadowToggle extends Behaviour {
@@ -67,7 +68,8 @@ export default class ShadowToggle extends Behaviour {
67
68
  Access the underlying `THREE.Object3D` directly for low-level material mutations that are not exposed through `MaterialComponent`.
68
69
 
69
70
  ```typescript
70
- import { Behaviour, MeshComponent } from "@relu-interactives/spatial-ecs";
71
+ import { Behaviour } from "@relu-interactives/spatial-ecs";
72
+ import { MeshComponent } from "@relu-interactives/spatial-ecs/components";
71
73
  import type { ColorInput } from "@relu-interactives/spatial-ecs";
72
74
 
73
75
  export default class MeshColorDriver extends Behaviour {
@@ -99,9 +101,11 @@ You can also pick this component from the inspector using a `ComponentInput` fie
99
101
  ```typescript
100
102
  import {
101
103
  Behaviour,
102
- MeshComponent,
103
104
  type ComponentInput,
104
105
  } from "@relu-interactives/spatial-ecs";
106
+ import {
107
+ MeshComponent,
108
+ } from "@relu-interactives/spatial-ecs/components";
105
109
 
106
110
  export default class Example extends Behaviour {
107
111
  data = {
@@ -126,10 +130,12 @@ Alternatively, pick an entity from the inspector using an `EntityInput` field an
126
130
  ```typescript
127
131
  import {
128
132
  Behaviour,
129
- MeshComponent,
130
133
  type EntityInput,
131
134
  type WorldEntityView,
132
135
  } from "@relu-interactives/spatial-ecs";
136
+ import {
137
+ MeshComponent,
138
+ } from "@relu-interactives/spatial-ecs/components";
133
139
 
134
140
  export default class Example extends Behaviour {
135
141
  data = {
@@ -36,7 +36,8 @@ if (other) {
36
36
  Wait for the async model load to complete, then animate opacity to 1 over one second.
37
37
 
38
38
  ```typescript
39
- import { Behaviour, ModelComponent } from "@relu-interactives/spatial-ecs";
39
+ import { Behaviour } from "@relu-interactives/spatial-ecs";
40
+ import { ModelComponent } from "@relu-interactives/spatial-ecs/components";
40
41
 
41
42
  export default class ModelFadeIn extends Behaviour {
42
43
  private fadeProgress = 0;
@@ -72,7 +73,8 @@ export default class ModelFadeIn extends Behaviour {
72
73
  Show or hide the loaded model at runtime using the `Object3DRef` visibility flag.
73
74
 
74
75
  ```typescript
75
- import { Behaviour, ModelComponent, Object3DRef } from "@relu-interactives/spatial-ecs";
76
+ import { Behaviour } from "@relu-interactives/spatial-ecs";
77
+ import { ModelComponent, Object3DRef } from "@relu-interactives/spatial-ecs/components";
76
78
  import type { ToggleInput } from "@relu-interactives/spatial-ecs";
77
79
 
78
80
  export default class ModelVisibility extends Behaviour {
@@ -39,7 +39,8 @@ if (other) {
39
39
  Rename the entity at runtime from an inspector string field. Useful for dynamic labels or debug output.
40
40
 
41
41
  ```typescript
42
- import { Behaviour, Name } from "@relu-interactives/spatial-ecs";
42
+ import { Behaviour } from "@relu-interactives/spatial-ecs";
43
+ import { Name } from "@relu-interactives/spatial-ecs/components";
43
44
  import type { TextInput } from "@relu-interactives/spatial-ecs";
44
45
 
45
46
  export default class EntityRenamer extends Behaviour {
@@ -61,7 +62,8 @@ export default class EntityRenamer extends Behaviour {
61
62
  Query all `Name` components to locate a sibling entity and read its position.
62
63
 
63
64
  ```typescript
64
- import { Behaviour, Name, TransformComponent } from "@relu-interactives/spatial-ecs";
65
+ import { Behaviour } from "@relu-interactives/spatial-ecs";
66
+ import { Name, TransformComponent } from "@relu-interactives/spatial-ecs/components";
65
67
  import type { TextInput } from "@relu-interactives/spatial-ecs";
66
68
 
67
69
  export default class LookAtTarget extends Behaviour {
@@ -72,9 +74,10 @@ export default class LookAtTarget extends Behaviour {
72
74
  protected onUpdate() {
73
75
  let targetTransform: TransformComponent | null = null;
74
76
 
75
- for (const [id, nameComp] of this.world.query([Name])) {
76
- if (nameComp.value === this.data.targetName) {
77
- targetTransform = this.world.getComponent(id, TransformComponent);
77
+ for (const id of this.world.query(Name)) {
78
+ const nameComp = this.world.getComponent(id, Name);
79
+ if (nameComp?.value === this.data.targetName) {
80
+ targetTransform = this.world.getComponent(id, TransformComponent) ?? null;
78
81
  break;
79
82
  }
80
83
  }
@@ -96,10 +99,12 @@ Alternatively, pick an entity from the inspector using an `EntityInput` field an
96
99
  ```typescript
97
100
  import {
98
101
  Behaviour,
99
- Name,
100
102
  type EntityInput,
101
103
  type WorldEntityView,
102
104
  } from "@relu-interactives/spatial-ecs";
105
+ import {
106
+ Name,
107
+ } from "@relu-interactives/spatial-ecs/components";
103
108
 
104
109
  export default class Example extends Behaviour {
105
110
  data = {
@@ -38,7 +38,8 @@ if (other) {
38
38
  Expose a boolean that shows or hides the entity's scene object at runtime.
39
39
 
40
40
  ```typescript
41
- import { Behaviour, Object3DRef } from "@relu-interactives/spatial-ecs";
41
+ import { Behaviour } from "@relu-interactives/spatial-ecs";
42
+ import { Object3DRef } from "@relu-interactives/spatial-ecs/components";
42
43
  import type { ToggleInput } from "@relu-interactives/spatial-ecs";
43
44
 
44
45
  export default class VisibilityDriver extends Behaviour {
@@ -58,7 +59,8 @@ export default class VisibilityDriver extends Behaviour {
58
59
  Alternate visibility every half-second, useful for damage flashes or blinking pickups.
59
60
 
60
61
  ```typescript
61
- import { Behaviour, Object3DRef } from "@relu-interactives/spatial-ecs";
62
+ import { Behaviour } from "@relu-interactives/spatial-ecs";
63
+ import { Object3DRef } from "@relu-interactives/spatial-ecs/components";
62
64
  import type { FloatInput } from "@relu-interactives/spatial-ecs";
63
65
 
64
66
  export default class ObjectFlash extends Behaviour {
@@ -86,10 +88,12 @@ Alternatively, pick an entity from the inspector using an `EntityInput` field an
86
88
  ```typescript
87
89
  import {
88
90
  Behaviour,
89
- Object3DRef,
90
91
  type EntityInput,
91
92
  type WorldEntityView,
92
93
  } from "@relu-interactives/spatial-ecs";
94
+ import {
95
+ Object3DRef,
96
+ } from "@relu-interactives/spatial-ecs/components";
93
97
 
94
98
  export default class Example extends Behaviour {
95
99
  data = {
@@ -36,7 +36,8 @@ if (other) {
36
36
  Set `ParentId.value` to `null` to reparent the entity to the scene root. The `ObjectManagementSystem` reconciles the actual scene-graph hierarchy every frame.
37
37
 
38
38
  ```typescript
39
- import { Behaviour, ParentId, KeyboardKeys } from "@relu-interactives/spatial-ecs";
39
+ import { Behaviour, KeyboardKeys } from "@relu-interactives/spatial-ecs";
40
+ import { ParentId } from "@relu-interactives/spatial-ecs/components";
40
41
 
41
42
  export default class DetachOnKey extends Behaviour {
42
43
  protected onUpdate() {
@@ -53,7 +54,8 @@ export default class DetachOnKey extends Behaviour {
53
54
  Assign a new parent entity ID to move the entity (and its children) under a different part of the hierarchy at runtime.
54
55
 
55
56
  ```typescript
56
- import { Behaviour, ParentId, Name, KeyboardKeys } from "@relu-interactives/spatial-ecs";
57
+ import { Behaviour, KeyboardKeys } from "@relu-interactives/spatial-ecs";
58
+ import { ParentId, Name } from "@relu-interactives/spatial-ecs/components";
57
59
  import type { TextInput } from "@relu-interactives/spatial-ecs";
58
60
 
59
61
  export default class Reparenter extends Behaviour {
@@ -66,8 +68,10 @@ export default class Reparenter extends Behaviour {
66
68
 
67
69
  // Find the target parent entity by name
68
70
  const parentEntity = this.world.getEntityByName(this.data.newParentName);
71
+ if (!parentEntity) return;
72
+
69
73
  const parent = this.getComponent(ParentId);
70
- if (parent) parent.value = id;
74
+ if (parent) parent.value = parentEntity.entityId;
71
75
  }
72
76
  }
73
77
  ```
@@ -79,10 +83,12 @@ Alternatively, pick an entity from the inspector using an `EntityInput` field an
79
83
  ```typescript
80
84
  import {
81
85
  Behaviour,
82
- ParentId,
83
86
  type EntityInput,
84
87
  type WorldEntityView,
85
88
  } from "@relu-interactives/spatial-ecs";
89
+ import {
90
+ ParentId,
91
+ } from "@relu-interactives/spatial-ecs/components";
86
92
 
87
93
  export default class Example extends Behaviour {
88
94
  data = {
@@ -1,6 +1,6 @@
1
1
  # Physics
2
2
 
3
- Combined rigid body and collider component backed by Rapier. `values.rigidbody.type` is one of `dynamic`, `fixed`, `kinematicPosition`, or `kinematicVelocity`. Per-axis translation/rotation locks constrain motion (e.g. lock Y rotation for top-down characters). Supported collider shapes: `cuboid`, `ball`, `capsule`, `cylinder`, `trimesh`. Set `values.collider.isSensor` to receive collision events without producing a physical response.
3
+ Combined rigid body and collider component backed by Rapier. `values.rigidBody.type` is one of `dynamic`, `fixed`, `kinematicPosition`, or `kinematicVelocity`. Per-axis translation/rotation locks constrain motion (e.g. lock Y rotation for top-down characters). Supported collider shapes: `cuboid`, `ball`, `capsule`, `cylinder`, `trimesh`. Set `values.collider.isSensor` to receive collision events without producing a physical response.
4
4
 
5
5
  > **Managed by:** [`PhysicsSyncSystem`](../systems/physics-sync-system)
6
6
 
@@ -55,7 +55,8 @@ if (other) {
55
55
  Apply a one-shot upward impulse to a dynamic rigid body when the player presses Space.
56
56
 
57
57
  ```typescript
58
- import { Behaviour, PhysicsComponent, KeyboardKeys } from "@relu-interactives/spatial-ecs";
58
+ import { Behaviour, KeyboardKeys } from "@relu-interactives/spatial-ecs";
59
+ import { PhysicsComponent } from "@relu-interactives/spatial-ecs/components";
59
60
  import type { FloatInput } from "@relu-interactives/spatial-ecs";
60
61
 
61
62
  export default class Jumper extends Behaviour {
@@ -79,7 +80,8 @@ export default class Jumper extends Behaviour {
79
80
  Displace a `kinematicPosition` body each frame using the Rapier `setNextKinematicTranslation` API.
80
81
 
81
82
  ```typescript
82
- import { Behaviour, PhysicsComponent, KeyboardKeys } from "@relu-interactives/spatial-ecs";
83
+ import { Behaviour, KeyboardKeys } from "@relu-interactives/spatial-ecs";
84
+ import { PhysicsComponent } from "@relu-interactives/spatial-ecs/components";
83
85
  import type { FloatInput } from "@relu-interactives/spatial-ecs";
84
86
 
85
87
  export default class KinematicMover extends Behaviour {
@@ -116,9 +118,11 @@ You can also pick this component from the inspector using a `ComponentInput` fie
116
118
  ```typescript
117
119
  import {
118
120
  Behaviour,
119
- PhysicsComponent,
120
121
  type ComponentInput,
121
122
  } from "@relu-interactives/spatial-ecs";
123
+ import {
124
+ PhysicsComponent,
125
+ } from "@relu-interactives/spatial-ecs/components";
122
126
 
123
127
  export default class Example extends Behaviour {
124
128
  data = {
@@ -143,10 +147,12 @@ Alternatively, pick an entity from the inspector using an `EntityInput` field an
143
147
  ```typescript
144
148
  import {
145
149
  Behaviour,
146
- PhysicsComponent,
147
150
  type EntityInput,
148
151
  type WorldEntityView,
149
152
  } from "@relu-interactives/spatial-ecs";
153
+ import {
154
+ PhysicsComponent,
155
+ } from "@relu-interactives/spatial-ecs/components";
150
156
 
151
157
  export default class Example extends Behaviour {
152
158
  data = {
@@ -169,5 +175,5 @@ export default class Example extends Behaviour {
169
175
 
170
176
 
171
177
  ::: tip Rigid body type
172
- Set `values.rigidbody.type` to `"kinematicPosition"` in the inspector for the second example. Applying impulses requires a `"dynamic"` rigid body.
178
+ Set `values.rigidBody.type` to `"kinematicPosition"` in the inspector for the second example. Applying impulses requires a `"dynamic"` rigid body.
173
179
  :::
@@ -43,7 +43,8 @@ if (other) {
43
43
  `ScriptComponent.scriptInstances` maps entity IDs to their compiled behaviour instances. You can cast an instance to a known shape and call public methods on it, enabling script-to-script communication.
44
44
 
45
45
  ```typescript
46
- import { Behaviour, ScriptComponent } from "@relu-interactives/spatial-ecs";
46
+ import { Behaviour } from "@relu-interactives/spatial-ecs";
47
+ import { ScriptComponent } from "@relu-interactives/spatial-ecs/components";
47
48
 
48
49
  // Assumes another script on this entity exposes a `reset()` method.
49
50
  export default class ScriptBridge extends Behaviour {
@@ -65,7 +66,8 @@ export default class ScriptBridge extends Behaviour {
65
66
  Read the authored `entries` array to find which scripts are attached and inspect their saved field overrides.
66
67
 
67
68
  ```typescript
68
- import { Behaviour, ScriptComponent } from "@relu-interactives/spatial-ecs";
69
+ import { Behaviour } from "@relu-interactives/spatial-ecs";
70
+ import { ScriptComponent } from "@relu-interactives/spatial-ecs/components";
69
71
 
70
72
  export default class ScriptInspector extends Behaviour {
71
73
  protected init() {
@@ -86,9 +88,11 @@ You can also pick this component from the inspector using a `ComponentInput` fie
86
88
  ```typescript
87
89
  import {
88
90
  Behaviour,
89
- ScriptComponent,
90
91
  type ComponentInput,
91
92
  } from "@relu-interactives/spatial-ecs";
93
+ import {
94
+ ScriptComponent,
95
+ } from "@relu-interactives/spatial-ecs/components";
92
96
 
93
97
  export default class Example extends Behaviour {
94
98
  data = {
@@ -113,10 +117,12 @@ Alternatively, pick an entity from the inspector using an `EntityInput` field an
113
117
  ```typescript
114
118
  import {
115
119
  Behaviour,
116
- ScriptComponent,
117
120
  type EntityInput,
118
121
  type WorldEntityView,
119
122
  } from "@relu-interactives/spatial-ecs";
123
+ import {
124
+ ScriptComponent,
125
+ } from "@relu-interactives/spatial-ecs/components";
120
126
 
121
127
  export default class Example extends Behaviour {
122
128
  data = {
@@ -43,7 +43,8 @@ if (other) {
43
43
  Animate the sprite's width and height to create a breathing or highlight effect. The initial dimensions are captured on `init` so the pulse is relative to the authored size.
44
44
 
45
45
  ```typescript
46
- import { Behaviour, SpriteComponent } from "@relu-interactives/spatial-ecs";
46
+ import { Behaviour } from "@relu-interactives/spatial-ecs";
47
+ import { SpriteComponent } from "@relu-interactives/spatial-ecs/components";
47
48
  import type { FloatInput } from "@relu-interactives/spatial-ecs";
48
49
 
49
50
  export default class SpritePulse extends Behaviour {
@@ -81,7 +82,8 @@ export default class SpritePulse extends Behaviour {
81
82
  Show or hide the sprite by toggling `Object3DRef.visibility`.
82
83
 
83
84
  ```typescript
84
- import { Behaviour, Object3DRef, KeyboardKeys } from "@relu-interactives/spatial-ecs";
85
+ import { Behaviour, KeyboardKeys } from "@relu-interactives/spatial-ecs";
86
+ import { Object3DRef } from "@relu-interactives/spatial-ecs/components";
85
87
 
86
88
  export default class SpriteToggle extends Behaviour {
87
89
  private visible = true;
@@ -103,9 +105,11 @@ You can also pick this component from the inspector using a `ComponentInput` fie
103
105
  ```typescript
104
106
  import {
105
107
  Behaviour,
106
- SpriteComponent,
107
108
  type ComponentInput,
108
109
  } from "@relu-interactives/spatial-ecs";
110
+ import {
111
+ SpriteComponent,
112
+ } from "@relu-interactives/spatial-ecs/components";
109
113
 
110
114
  export default class Example extends Behaviour {
111
115
  data = {
@@ -130,10 +134,12 @@ Alternatively, pick an entity from the inspector using an `EntityInput` field an
130
134
  ```typescript
131
135
  import {
132
136
  Behaviour,
133
- SpriteComponent,
134
137
  type EntityInput,
135
138
  type WorldEntityView,
136
139
  } from "@relu-interactives/spatial-ecs";
140
+ import {
141
+ SpriteComponent,
142
+ } from "@relu-interactives/spatial-ecs/components";
137
143
 
138
144
  export default class Example extends Behaviour {
139
145
  data = {
@@ -99,9 +99,11 @@ You can also pick this component from the inspector using a `ComponentInput` fie
99
99
  ```typescript
100
100
  import {
101
101
  Behaviour,
102
- TransformComponent,
103
102
  type ComponentInput,
104
103
  } from "@relu-interactives/spatial-ecs";
104
+ import {
105
+ TransformComponent,
106
+ } from "@relu-interactives/spatial-ecs/components";
105
107
 
106
108
  export default class Example extends Behaviour {
107
109
  data = {
@@ -126,10 +128,12 @@ Alternatively, pick an entity from the inspector using an `EntityInput` field an
126
128
  ```typescript
127
129
  import {
128
130
  Behaviour,
129
- TransformComponent,
130
131
  type EntityInput,
131
132
  type WorldEntityView,
132
133
  } from "@relu-interactives/spatial-ecs";
134
+ import {
135
+ TransformComponent,
136
+ } from "@relu-interactives/spatial-ecs/components";
133
137
 
134
138
  export default class Example extends Behaviour {
135
139
  data = {
@@ -49,7 +49,8 @@ if (other) {
49
49
  Toggle video playback when the player presses Space.
50
50
 
51
51
  ```typescript
52
- import { Behaviour, VideoComponent, KeyboardKeys } from "@relu-interactives/spatial-ecs";
52
+ import { Behaviour, KeyboardKeys } from "@relu-interactives/spatial-ecs";
53
+ import { VideoComponent } from "@relu-interactives/spatial-ecs/components";
53
54
 
54
55
  export default class VideoController extends Behaviour {
55
56
  protected onUpdate() {
@@ -72,7 +73,8 @@ export default class VideoController extends Behaviour {
72
73
  Expose volume and loop settings as inspector fields so they can be tuned without re-entering the code.
73
74
 
74
75
  ```typescript
75
- import { Behaviour, VideoComponent } from "@relu-interactives/spatial-ecs";
76
+ import { Behaviour } from "@relu-interactives/spatial-ecs";
77
+ import { VideoComponent } from "@relu-interactives/spatial-ecs/components";
76
78
  import type { FloatInput, ToggleInput } from "@relu-interactives/spatial-ecs";
77
79
 
78
80
  export default class VideoSettings extends Behaviour {
@@ -97,9 +99,11 @@ You can also pick this component from the inspector using a `ComponentInput` fie
97
99
  ```typescript
98
100
  import {
99
101
  Behaviour,
100
- VideoComponent,
101
102
  type ComponentInput,
102
103
  } from "@relu-interactives/spatial-ecs";
104
+ import {
105
+ VideoComponent,
106
+ } from "@relu-interactives/spatial-ecs/components";
103
107
 
104
108
  export default class Example extends Behaviour {
105
109
  data = {
@@ -124,10 +128,12 @@ Alternatively, pick an entity from the inspector using an `EntityInput` field an
124
128
  ```typescript
125
129
  import {
126
130
  Behaviour,
127
- VideoComponent,
128
131
  type EntityInput,
129
132
  type WorldEntityView,
130
133
  } from "@relu-interactives/spatial-ecs";
134
+ import {
135
+ VideoComponent,
136
+ } from "@relu-interactives/spatial-ecs/components";
131
137
 
132
138
  export default class Example extends Behaviour {
133
139
  data = {
@@ -145,6 +145,8 @@ register a resolver that maps them onto the deployed `assets/` folder:
145
145
  ```ts
146
146
  import { setPrefabAssetUrlResolver } from "@relu-interactives/spatial-ecs";
147
147
 
148
+ declare function rewriteToMyCdn(url: string): string;
149
+
148
150
  setPrefabAssetUrlResolver((url) => rewriteToMyCdn(url));
149
151
  ```
150
152
 
@@ -64,7 +64,7 @@ export default class Tagger extends Behaviour {
64
64
  const entity = this.world.getEntityByName("Target");
65
65
  if (!entity) return;
66
66
 
67
- this.world.addComponent(entity.entityId, new Name({ value: "Tagged" }));
67
+ this.world.addComponent(entity.entityId, new Name("Tagged"));
68
68
  }
69
69
  }
70
70
  ```
@@ -85,7 +85,8 @@ The asset loads asynchronously. `InstancedMeshSystem` rebuilds the instanced mes
85
85
  Each slot is a separate entity. To add more instances after the group is created, use `requestCreate("instanceSlot")` and push the new ID into the group component:
86
86
 
87
87
  ```typescript
88
- import { Behaviour, InstancedMeshComponent } from "@relu-interactives/spatial-ecs";
88
+ import { Behaviour } from "@relu-interactives/spatial-ecs";
89
+ import { InstancedMeshComponent } from "@relu-interactives/spatial-ecs/components";
89
90
 
90
91
  export default class AddInstances extends Behaviour {
91
92
  protected init() {
@@ -135,7 +136,7 @@ export default class AddInstances extends Behaviour {
135
136
 
136
137
  ```typescript
137
138
  import { Behaviour } from "@relu-interactives/spatial-ecs";
138
- import { InstancedMeshComponent } from "@relu-interactives/spatial-ecs";
139
+ import { InstancedMeshComponent } from "@relu-interactives/spatial-ecs/components";
139
140
 
140
141
  export default class CubeGrid extends Behaviour {
141
142
  private groupId: number | null = null;
@@ -193,9 +194,11 @@ Mutate the `TransformComponent` of the slot entity. `InstancedMeshSystem` picks
193
194
  ```typescript
194
195
  import {
195
196
  Behaviour,
197
+ } from "@relu-interactives/spatial-ecs";
198
+ import {
196
199
  InstancedMeshComponent,
197
200
  TransformComponent,
198
- } from "@relu-interactives/spatial-ecs";
201
+ } from "@relu-interactives/spatial-ecs/components";
199
202
 
200
203
  export default class OrbitInstances extends Behaviour {
201
204
  private elapsed = 0;
@@ -208,7 +211,7 @@ export default class OrbitInstances extends Behaviour {
208
211
 
209
212
  for (let i = 0; i < instanced.instanceEntityIds.length; i++) {
210
213
  const slotId = instanced.instanceEntityIds[i];
211
- const transform = this.world.getComponentById(slotId, TransformComponent);
214
+ const transform = this.world.getComponent(slotId, TransformComponent);
212
215
  if (!transform) continue;
213
216
 
214
217
  const angle = this.elapsed + (i / instanced.instanceEntityIds.length) * Math.PI * 2;
@@ -225,7 +228,8 @@ export default class OrbitInstances extends Behaviour {
225
228
  Update the group component's fields. `InstancedMeshSystem` detects the change and rebuilds:
226
229
 
227
230
  ```typescript
228
- import { Behaviour, InstancedMeshComponent } from "@relu-interactives/spatial-ecs";
231
+ import { Behaviour } from "@relu-interactives/spatial-ecs";
232
+ import { InstancedMeshComponent } from "@relu-interactives/spatial-ecs/components";
229
233
 
230
234
  export default class ExpandSpheres extends Behaviour {
231
235
  protected onUpdate() {
@@ -244,7 +248,8 @@ export default class ExpandSpheres extends Behaviour {
244
248
  Remove the slot entity from the world and splice its ID out of the group:
245
249
 
246
250
  ```typescript
247
- import { Behaviour, InstancedMeshComponent } from "@relu-interactives/spatial-ecs";
251
+ import { Behaviour } from "@relu-interactives/spatial-ecs";
252
+ import { InstancedMeshComponent } from "@relu-interactives/spatial-ecs/components";
248
253
 
249
254
  export default class RemoveLastInstance extends Behaviour {
250
255
  protected init() {
@@ -149,12 +149,15 @@ Toggle visibility on Space, fire on left-click.
149
149
 
150
150
  ```ts
151
151
  import { KeyboardKeys, Behaviour } from "@relu-interactives/spatial-ecs";
152
+ import { Object3DRef } from "@relu-interactives/spatial-ecs/components";
152
153
 
153
154
  export default class ActionHandler extends Behaviour {
154
155
  protected onUpdate() {
155
156
  // getKeyDown fires only on the first frame the key is pressed.
156
157
  if (this.world.getKeyDown(KeyboardKeys.Space)) {
157
- this.transform.visible = !this.transform.visible;
158
+ // Visibility lives on Object3DRef, not on the transform.
159
+ const ref = this.getComponent(Object3DRef);
160
+ if (ref) ref.visibility = !ref.visibility;
158
161
  }
159
162
 
160
163
  // Left mouse button
@@ -29,7 +29,15 @@ The `moduleLoader` owns cache-busting: with the default dynamic-import loader th
29
29
  Construct it and pass it to `World.setup`:
30
30
 
31
31
  ```ts
32
- import { ScriptObjectSystem } from "@relu-interactives/spatial-ecs";
32
+ import {
33
+ ScriptObjectSystem,
34
+ World,
35
+ type ModuleLoader,
36
+ } from "@relu-interactives/spatial-ecs";
37
+
38
+ declare const world: World;
39
+ // Resolves a script URL to its ES module — the templates supply this.
40
+ declare const myModuleLoader: ModuleLoader;
33
41
 
34
42
  world.setup({
35
43
  systems: [new ScriptObjectSystem(myModuleLoader)],