@relu-interactives/spatial-ecs 0.8.0 → 0.10.0

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 (56) hide show
  1. package/dist/{System-8D-XBDKZ.d.cts → System-BldSHxZV.d.cts} +214 -81
  2. package/dist/{System-DPMAW30g.d.ts → System-CADhPyQs.d.ts} +214 -81
  3. package/dist/{XRHandPose-G0Dl-F0w.d.ts → XRHandPose-BNSwd1y9.d.ts} +145 -2
  4. package/dist/{XRHandPose-VQMT1WXj.d.cts → XRHandPose-D3Ab1Dfs.d.cts} +145 -2
  5. package/dist/{chunk-G4XJ53LS.js → chunk-JEPUCLZX.js} +3 -3
  6. package/dist/{chunk-G4XJ53LS.js.map → chunk-JEPUCLZX.js.map} +1 -1
  7. package/dist/{chunk-NNDUOQ7O.js → chunk-JNYPJB55.js} +250 -3
  8. package/dist/chunk-JNYPJB55.js.map +1 -0
  9. package/dist/{chunk-SGF73YTF.js → chunk-NXASMBDS.js} +4 -4
  10. package/dist/{chunk-SGF73YTF.js.map → chunk-NXASMBDS.js.map} +1 -1
  11. package/dist/{chunk-JIJQFW6P.js → chunk-TY3XCHOR.js} +1390 -485
  12. package/dist/chunk-TY3XCHOR.js.map +1 -0
  13. package/dist/{chunk-U727NTWQ.js → chunk-WWP46AEF.js} +26 -4
  14. package/dist/chunk-WWP46AEF.js.map +1 -0
  15. package/dist/components/index.cjs +151 -0
  16. package/dist/components/index.cjs.map +1 -1
  17. package/dist/components/index.d.cts +3 -3
  18. package/dist/components/index.d.ts +3 -3
  19. package/dist/components/index.js +1 -1
  20. package/dist/docs/guide/bone-attachments-and-ik.md +1 -1
  21. package/dist/docs/guide/multiplayer.md +65 -0
  22. package/dist/docs/guide/spatial-ui.md +83 -7
  23. package/dist/factories/index.cjs +151 -0
  24. package/dist/factories/index.cjs.map +1 -1
  25. package/dist/factories/index.d.cts +2 -2
  26. package/dist/factories/index.d.ts +2 -2
  27. package/dist/factories/index.js +3 -3
  28. package/dist/{index-C61n65PE.d.ts → index-6pZO_gV7.d.ts} +27 -2
  29. package/dist/{index-D9DjrUn3.d.cts → index-BXjwEdNq.d.cts} +6 -3
  30. package/dist/{index-C70N4BYG.d.cts → index-BdghvXKE.d.cts} +27 -2
  31. package/dist/{index-DppafVu4.d.ts → index-CVG-hREM.d.ts} +6 -3
  32. package/dist/index.cjs +1800 -626
  33. package/dist/index.cjs.map +1 -1
  34. package/dist/index.d.cts +8 -30
  35. package/dist/index.d.ts +8 -30
  36. package/dist/index.js +10 -10
  37. package/dist/network/index.cjs +858 -8
  38. package/dist/network/index.cjs.map +1 -1
  39. package/dist/network/index.d.cts +126 -5
  40. package/dist/network/index.d.ts +126 -5
  41. package/dist/network/index.js +683 -8
  42. package/dist/network/index.js.map +1 -1
  43. package/dist/systems/index.cjs +1702 -528
  44. package/dist/systems/index.cjs.map +1 -1
  45. package/dist/systems/index.d.cts +2 -2
  46. package/dist/systems/index.d.ts +2 -2
  47. package/dist/systems/index.js +4 -4
  48. package/dist/types.d.cts +1 -1
  49. package/dist/types.d.ts +1 -1
  50. package/dist/webgpu/index.d.ts +2 -2
  51. package/dist/worldSnapshotUtils.d.cts +1 -1
  52. package/dist/worldSnapshotUtils.d.ts +1 -1
  53. package/package.json +1 -1
  54. package/dist/chunk-JIJQFW6P.js.map +0 -1
  55. package/dist/chunk-NNDUOQ7O.js.map +0 -1
  56. package/dist/chunk-U727NTWQ.js.map +0 -1
@@ -1,6 +1,6 @@
1
- export { A as AnimationComponent, a as AnimationComponentOptions, b as AudioComponent, B as BoneAttachmentComponent, c as BoneAttachmentOptions, C as CameraComponent, d as CameraComponentOptions, e as CameraProjection, f as CameraRuntimeType, g as ColliderShape, h as ColliderState, i as CubeMeshParameters, D as DEFAULT_COLLIDER_STATE, j as DEFAULT_INSTANCED_MESH_PARAMETERS, k as DEFAULT_INSTANCE_TRANSFORM, l as DEFAULT_MESH_GEOMETRY_PARAMETERS, m as DEFAULT_PHYSICS_STATE, n as DEFAULT_POSE_CURLS, o as DEFAULT_POSE_DIRECTIONS, p as DEFAULT_RIGIDBODY_STATE, E as EditableMeshObjectKind, q as EntityType, I as ImageComponent, r as ImageTarget, s as ImageTargetAnchor, t as ImageTargetAnchorOptions, u as ImageTargetReference, v as InstanceSlotComponent, w as InstanceTransform, x as InstancedMeshComponent, y as InstancedMeshKind, L as LightComponent, z as LightShadowState, F as LightValueState, M as MODEL_NO_PATH_MESSAGE, G as MaterialComponent, H as MaterialTypeValue, J as MaterialValueState, K as MeshComponent, N as MeshGeometryComponent, O as MeshGeometryParameters, P as MeshGeometryParametersByKind, Q as ModelComponent, R as ModelLoadState, S as Name, T as Object3DRef, U as PhysicsComponent, V as PhysicsState, W as PlaneMeshParameters, X as RadiusHeightMeshParameters, Y as RadiusMeshParameters, Z as RigidbodyState, _ as RigidbodyType, $ as ScriptComponent, a0 as ScriptEntry, a1 as ScriptObjectComponent, a2 as ScriptObjectComponentInput, a3 as ScriptObjectRuntimeState, a4 as Selectable, a5 as SelectionTransformState, a6 as SpriteComponent, a7 as TextureFilteringValue, a8 as TransformModeValue, a9 as TransformSpaceValue, aa as UIButtonComponent, ab as UIButtonOptions, ac as UIPanelComponent, ad as UIPanelOptions, ae as UISliderComponent, af as UISliderOptions, ag as UITextComponent, ah as UITextOptions, ai as UIToggleComponent, aj as UIToggleOptions, ak as UiFollowMode, al as UiTextAlign, am as UiTextVAlign, an as VRTeleportAreaComponent, ao as VRTeleportAreaOptions, ap as VideoComponent, aq as VrTeleportShape, ar as XRAnchorComponent, as as XRAnchorOptions, at as XRHandPoseComponent, au as XRHandPoseOptions, av as XRInteractableComponent, aw as XRInteractableOptions, ax as XRInteractorComponent, ay as XRInteractorOptions, az as XRInteractorSideComponent, aA as XRRigComponent, aB as XRRigOptions, aC as XrAttachPoint, aD as XrDistanceGrabBehavior, aE as XrEnvironmentPhysics, aF as XrGrabGesture, aG as XrGrabHands, aH as XrGrabReach, aI as XrHandPoseEntry, aJ as XrHandPreset, aK as XrInteractorSide, aL as XrInteractorType, aM as XrLocomotionMode, aN as XrTrackingOrigin, aO as XrTwoHandRotation, aP as createAttachPoint, aQ as createHandPoseEntry, aR as defaultMaterialValue, aS as handPoseDefinitionFor, aT as normalizePhysicsState, aU as setModelLoadState, aV as setPhysicsLiveRef } from '../XRHandPose-VQMT1WXj.cjs';
2
- export { D as DEFAULT_ENVIRONMENT_LIGHTING, a as DEFAULT_ENVIRONMENT_STATE, b as DEFAULT_POSTPROCESSING_STATE, E as Environment, c as EnvironmentFogState, d as EnvironmentFogType, e as EnvironmentGradientEffect, f as EnvironmentLightingState, g as EnvironmentSkyboxImageProjection, h as EnvironmentSkyboxState, i as EnvironmentSkyboxType, j as EnvironmentState, k as EnvironmentToneMapping, I as IKChain, l as IKComponent, m as IKLimb, n as IKOptions, N as NetValue, o as NetworkIdentityComponent, p as NetworkSpawnerComponent, q as NetworkTransformComponent, r as NetworkTransformOptions, s as NetworkedPropsComponent, P as ParentId, t as Postprocessing, u as PostprocessingState, T as TransformComponent, v as TransformData, V as Vec3, w as normalizeEnvironmentLighting, x as normalizeIKChain } from '../System-8D-XBDKZ.cjs';
3
- export { P as PrefabInstance, a as PrefabNode, X as XREnvironmentComponent, b as XrEnvironmentKind, c as XrEnvironmentOrientation } from '../index-D9DjrUn3.cjs';
1
+ export { A as AnimationComponent, a as AnimationComponentOptions, b as AudioComponent, B as BoneAttachmentComponent, c as BoneAttachmentOptions, C as CameraComponent, d as CameraComponentOptions, e as CameraProjection, f as CameraRuntimeType, g as ColliderShape, h as ColliderState, i as CubeMeshParameters, D as DEFAULT_COLLIDER_STATE, j as DEFAULT_INSTANCED_MESH_PARAMETERS, k as DEFAULT_INSTANCE_TRANSFORM, l as DEFAULT_MESH_GEOMETRY_PARAMETERS, m as DEFAULT_PHYSICS_STATE, n as DEFAULT_POSE_CURLS, o as DEFAULT_POSE_DIRECTIONS, p as DEFAULT_RIGIDBODY_STATE, E as EditableMeshObjectKind, q as EntityType, I as ImageComponent, r as ImageTarget, s as ImageTargetAnchor, t as ImageTargetAnchorOptions, u as ImageTargetReference, v as InstanceSlotComponent, w as InstanceTransform, x as InstancedMeshComponent, y as InstancedMeshKind, L as LightComponent, z as LightShadowState, F as LightValueState, M as MODEL_NO_PATH_MESSAGE, G as MaterialComponent, H as MaterialTypeValue, J as MaterialValueState, K as MeshComponent, N as MeshGeometryComponent, O as MeshGeometryParameters, P as MeshGeometryParametersByKind, Q as ModelComponent, R as ModelLoadState, S as Name, T as Object3DRef, U as PhysicsComponent, V as PhysicsState, W as PlaneMeshParameters, X as RadiusHeightMeshParameters, Y as RadiusMeshParameters, Z as RigidbodyState, _ as RigidbodyType, $ as ScriptComponent, a0 as ScriptEntry, a1 as ScriptObjectComponent, a2 as ScriptObjectComponentInput, a3 as ScriptObjectRuntimeState, a4 as Selectable, a5 as SelectionTransformState, a6 as SpriteComponent, a7 as TextureFilteringValue, a8 as TransformModeValue, a9 as TransformSpaceValue, aa as UIButtonComponent, ab as UIButtonOptions, ac as UIPanelComponent, ad as UIPanelOptions, ae as UISliderComponent, af as UISliderOptions, ag as UITextComponent, ah as UITextOptions, ai as UIToggleComponent, aj as UIToggleOptions, ak as UiFollowMode, al as UiIconPosition, am as UiSliderVariant, an as UiTextAlign, ao as UiTextVAlign, ap as UiToggleVariant, aq as VRTeleportAreaComponent, ar as VRTeleportAreaOptions, as as VideoComponent, at as VrTeleportShape, au as XRAnchorComponent, av as XRAnchorOptions, aw as XRHandPoseComponent, ax as XRHandPoseOptions, ay as XRInteractableComponent, az as XRInteractableOptions, aA as XRInteractorComponent, aB as XRInteractorOptions, aC as XRInteractorSideComponent, aD as XRRigComponent, aE as XRRigOptions, aF as XrAttachPoint, aG as XrDistanceGrabBehavior, aH as XrEnvironmentPhysics, aI as XrGrabGesture, aJ as XrGrabHands, aK as XrGrabReach, aL as XrHandPoseEntry, aM as XrHandPreset, aN as XrInteractorSide, aO as XrInteractorType, aP as XrLocomotionMode, aQ as XrTrackingOrigin, aR as XrTwoHandRotation, aS as createAttachPoint, aT as createHandPoseEntry, aU as defaultMaterialValue, aV as handPoseDefinitionFor, aW as normalizePhysicsState, aX as setModelLoadState, aY as setPhysicsLiveRef } from '../XRHandPose-D3Ab1Dfs.cjs';
2
+ export { D as DEFAULT_ENVIRONMENT_LIGHTING, a as DEFAULT_ENVIRONMENT_STATE, b as DEFAULT_POSTPROCESSING_STATE, E as Environment, c as EnvironmentFogState, d as EnvironmentFogType, e as EnvironmentGradientEffect, f as EnvironmentLightingState, g as EnvironmentSkyboxImageProjection, h as EnvironmentSkyboxState, i as EnvironmentSkyboxType, j as EnvironmentState, k as EnvironmentToneMapping, I as IKChain, l as IKComponent, m as IKLimb, n as IKOptions, N as NetValue, o as NetworkIdentityComponent, p as NetworkSpawnerComponent, q as NetworkTransformComponent, r as NetworkTransformOptions, s as NetworkedPropsComponent, P as ParentId, t as Postprocessing, u as PostprocessingState, T as TransformComponent, v as TransformData, V as Vec3, w as normalizeEnvironmentLighting, x as normalizeIKChain } from '../System-BldSHxZV.cjs';
3
+ export { P as PrefabInstance, a as PrefabNode, X as XREnvironmentComponent, b as XrEnvironmentKind, c as XrEnvironmentOrientation } from '../index-BXjwEdNq.cjs';
4
4
  import 'three';
5
5
  import '@dimforge/rapier3d-compat';
6
6
  import '../handPose-DlcTtqgx.cjs';
@@ -1,6 +1,6 @@
1
- export { A as AnimationComponent, a as AnimationComponentOptions, b as AudioComponent, B as BoneAttachmentComponent, c as BoneAttachmentOptions, C as CameraComponent, d as CameraComponentOptions, e as CameraProjection, f as CameraRuntimeType, g as ColliderShape, h as ColliderState, i as CubeMeshParameters, D as DEFAULT_COLLIDER_STATE, j as DEFAULT_INSTANCED_MESH_PARAMETERS, k as DEFAULT_INSTANCE_TRANSFORM, l as DEFAULT_MESH_GEOMETRY_PARAMETERS, m as DEFAULT_PHYSICS_STATE, n as DEFAULT_POSE_CURLS, o as DEFAULT_POSE_DIRECTIONS, p as DEFAULT_RIGIDBODY_STATE, E as EditableMeshObjectKind, q as EntityType, I as ImageComponent, r as ImageTarget, s as ImageTargetAnchor, t as ImageTargetAnchorOptions, u as ImageTargetReference, v as InstanceSlotComponent, w as InstanceTransform, x as InstancedMeshComponent, y as InstancedMeshKind, L as LightComponent, z as LightShadowState, F as LightValueState, M as MODEL_NO_PATH_MESSAGE, G as MaterialComponent, H as MaterialTypeValue, J as MaterialValueState, K as MeshComponent, N as MeshGeometryComponent, O as MeshGeometryParameters, P as MeshGeometryParametersByKind, Q as ModelComponent, R as ModelLoadState, S as Name, T as Object3DRef, U as PhysicsComponent, V as PhysicsState, W as PlaneMeshParameters, X as RadiusHeightMeshParameters, Y as RadiusMeshParameters, Z as RigidbodyState, _ as RigidbodyType, $ as ScriptComponent, a0 as ScriptEntry, a1 as ScriptObjectComponent, a2 as ScriptObjectComponentInput, a3 as ScriptObjectRuntimeState, a4 as Selectable, a5 as SelectionTransformState, a6 as SpriteComponent, a7 as TextureFilteringValue, a8 as TransformModeValue, a9 as TransformSpaceValue, aa as UIButtonComponent, ab as UIButtonOptions, ac as UIPanelComponent, ad as UIPanelOptions, ae as UISliderComponent, af as UISliderOptions, ag as UITextComponent, ah as UITextOptions, ai as UIToggleComponent, aj as UIToggleOptions, ak as UiFollowMode, al as UiTextAlign, am as UiTextVAlign, an as VRTeleportAreaComponent, ao as VRTeleportAreaOptions, ap as VideoComponent, aq as VrTeleportShape, ar as XRAnchorComponent, as as XRAnchorOptions, at as XRHandPoseComponent, au as XRHandPoseOptions, av as XRInteractableComponent, aw as XRInteractableOptions, ax as XRInteractorComponent, ay as XRInteractorOptions, az as XRInteractorSideComponent, aA as XRRigComponent, aB as XRRigOptions, aC as XrAttachPoint, aD as XrDistanceGrabBehavior, aE as XrEnvironmentPhysics, aF as XrGrabGesture, aG as XrGrabHands, aH as XrGrabReach, aI as XrHandPoseEntry, aJ as XrHandPreset, aK as XrInteractorSide, aL as XrInteractorType, aM as XrLocomotionMode, aN as XrTrackingOrigin, aO as XrTwoHandRotation, aP as createAttachPoint, aQ as createHandPoseEntry, aR as defaultMaterialValue, aS as handPoseDefinitionFor, aT as normalizePhysicsState, aU as setModelLoadState, aV as setPhysicsLiveRef } from '../XRHandPose-G0Dl-F0w.js';
2
- export { D as DEFAULT_ENVIRONMENT_LIGHTING, e as DEFAULT_ENVIRONMENT_STATE, f as DEFAULT_POSTPROCESSING_STATE, g as Environment, h as EnvironmentFogState, i as EnvironmentFogType, j as EnvironmentGradientEffect, k as EnvironmentLightingState, l as EnvironmentSkyboxImageProjection, m as EnvironmentSkyboxState, n as EnvironmentSkyboxType, o as EnvironmentState, p as EnvironmentToneMapping, I as IKChain, q as IKComponent, r as IKLimb, s as IKOptions, N as NetValue, t as NetworkIdentityComponent, u as NetworkSpawnerComponent, v as NetworkTransformComponent, w as NetworkTransformOptions, x as NetworkedPropsComponent, y as ParentId, z as Postprocessing, b as PostprocessingState, T as TransformComponent, A as TransformData, V as Vec3, B as normalizeEnvironmentLighting, F as normalizeIKChain } from '../System-DPMAW30g.js';
3
- export { P as PrefabInstance, a as PrefabNode, X as XREnvironmentComponent, b as XrEnvironmentKind, c as XrEnvironmentOrientation } from '../index-DppafVu4.js';
1
+ export { A as AnimationComponent, a as AnimationComponentOptions, b as AudioComponent, B as BoneAttachmentComponent, c as BoneAttachmentOptions, C as CameraComponent, d as CameraComponentOptions, e as CameraProjection, f as CameraRuntimeType, g as ColliderShape, h as ColliderState, i as CubeMeshParameters, D as DEFAULT_COLLIDER_STATE, j as DEFAULT_INSTANCED_MESH_PARAMETERS, k as DEFAULT_INSTANCE_TRANSFORM, l as DEFAULT_MESH_GEOMETRY_PARAMETERS, m as DEFAULT_PHYSICS_STATE, n as DEFAULT_POSE_CURLS, o as DEFAULT_POSE_DIRECTIONS, p as DEFAULT_RIGIDBODY_STATE, E as EditableMeshObjectKind, q as EntityType, I as ImageComponent, r as ImageTarget, s as ImageTargetAnchor, t as ImageTargetAnchorOptions, u as ImageTargetReference, v as InstanceSlotComponent, w as InstanceTransform, x as InstancedMeshComponent, y as InstancedMeshKind, L as LightComponent, z as LightShadowState, F as LightValueState, M as MODEL_NO_PATH_MESSAGE, G as MaterialComponent, H as MaterialTypeValue, J as MaterialValueState, K as MeshComponent, N as MeshGeometryComponent, O as MeshGeometryParameters, P as MeshGeometryParametersByKind, Q as ModelComponent, R as ModelLoadState, S as Name, T as Object3DRef, U as PhysicsComponent, V as PhysicsState, W as PlaneMeshParameters, X as RadiusHeightMeshParameters, Y as RadiusMeshParameters, Z as RigidbodyState, _ as RigidbodyType, $ as ScriptComponent, a0 as ScriptEntry, a1 as ScriptObjectComponent, a2 as ScriptObjectComponentInput, a3 as ScriptObjectRuntimeState, a4 as Selectable, a5 as SelectionTransformState, a6 as SpriteComponent, a7 as TextureFilteringValue, a8 as TransformModeValue, a9 as TransformSpaceValue, aa as UIButtonComponent, ab as UIButtonOptions, ac as UIPanelComponent, ad as UIPanelOptions, ae as UISliderComponent, af as UISliderOptions, ag as UITextComponent, ah as UITextOptions, ai as UIToggleComponent, aj as UIToggleOptions, ak as UiFollowMode, al as UiIconPosition, am as UiSliderVariant, an as UiTextAlign, ao as UiTextVAlign, ap as UiToggleVariant, aq as VRTeleportAreaComponent, ar as VRTeleportAreaOptions, as as VideoComponent, at as VrTeleportShape, au as XRAnchorComponent, av as XRAnchorOptions, aw as XRHandPoseComponent, ax as XRHandPoseOptions, ay as XRInteractableComponent, az as XRInteractableOptions, aA as XRInteractorComponent, aB as XRInteractorOptions, aC as XRInteractorSideComponent, aD as XRRigComponent, aE as XRRigOptions, aF as XrAttachPoint, aG as XrDistanceGrabBehavior, aH as XrEnvironmentPhysics, aI as XrGrabGesture, aJ as XrGrabHands, aK as XrGrabReach, aL as XrHandPoseEntry, aM as XrHandPreset, aN as XrInteractorSide, aO as XrInteractorType, aP as XrLocomotionMode, aQ as XrTrackingOrigin, aR as XrTwoHandRotation, aS as createAttachPoint, aT as createHandPoseEntry, aU as defaultMaterialValue, aV as handPoseDefinitionFor, aW as normalizePhysicsState, aX as setModelLoadState, aY as setPhysicsLiveRef } from '../XRHandPose-BNSwd1y9.js';
2
+ export { D as DEFAULT_ENVIRONMENT_LIGHTING, e as DEFAULT_ENVIRONMENT_STATE, f as DEFAULT_POSTPROCESSING_STATE, g as Environment, h as EnvironmentFogState, i as EnvironmentFogType, j as EnvironmentGradientEffect, k as EnvironmentLightingState, l as EnvironmentSkyboxImageProjection, m as EnvironmentSkyboxState, n as EnvironmentSkyboxType, o as EnvironmentState, p as EnvironmentToneMapping, I as IKChain, q as IKComponent, r as IKLimb, s as IKOptions, N as NetValue, t as NetworkIdentityComponent, u as NetworkSpawnerComponent, v as NetworkTransformComponent, w as NetworkTransformOptions, x as NetworkedPropsComponent, y as ParentId, z as Postprocessing, b as PostprocessingState, T as TransformComponent, A as TransformData, V as Vec3, B as normalizeEnvironmentLighting, F as normalizeIKChain } from '../System-CADhPyQs.js';
3
+ export { P as PrefabInstance, a as PrefabNode, X as XREnvironmentComponent, b as XrEnvironmentKind, c as XrEnvironmentOrientation } from '../index-CVG-hREM.js';
4
4
  import 'three';
5
5
  import '@dimforge/rapier3d-compat';
6
6
  import '../handPose-DlcTtqgx.js';
@@ -1,4 +1,4 @@
1
- export { AnimationComponent, AudioComponent, BoneAttachmentComponent, CameraComponent, DEFAULT_COLLIDER_STATE, DEFAULT_ENVIRONMENT_LIGHTING, DEFAULT_ENVIRONMENT_STATE, DEFAULT_INSTANCED_MESH_PARAMETERS, DEFAULT_INSTANCE_TRANSFORM, DEFAULT_MESH_GEOMETRY_PARAMETERS, DEFAULT_PHYSICS_STATE, DEFAULT_POSE_CURLS, DEFAULT_POSE_DIRECTIONS, DEFAULT_POSTPROCESSING_STATE, DEFAULT_RIGIDBODY_STATE, EntityType, Environment, IKComponent, ImageComponent, ImageTarget, ImageTargetAnchor, InstanceSlotComponent, InstancedMeshComponent, LightComponent, MODEL_NO_PATH_MESSAGE, MaterialComponent, MeshComponent, MeshGeometryComponent, ModelComponent, Name, NetworkIdentityComponent, NetworkSpawnerComponent, NetworkTransformComponent, NetworkedPropsComponent, Object3DRef, ParentId, PhysicsComponent, Postprocessing, PrefabInstance, PrefabNode, ScriptComponent, ScriptObjectComponent, Selectable, SelectionTransformState, SpriteComponent, TransformComponent, UIButtonComponent, UIPanelComponent, UISliderComponent, UITextComponent, UIToggleComponent, VRTeleportAreaComponent, VideoComponent, XRAnchorComponent, XREnvironmentComponent, XRHandPoseComponent, XRInteractableComponent, XRInteractorComponent, XRInteractorSideComponent, XRRigComponent, createAttachPoint, createHandPoseEntry, defaultMaterialValue, handPoseDefinitionFor, normalizeEnvironmentLighting, normalizeIKChain, normalizePhysicsState, setModelLoadState, setPhysicsLiveRef } from '../chunk-NNDUOQ7O.js';
1
+ export { AnimationComponent, AudioComponent, BoneAttachmentComponent, CameraComponent, DEFAULT_COLLIDER_STATE, DEFAULT_ENVIRONMENT_LIGHTING, DEFAULT_ENVIRONMENT_STATE, DEFAULT_INSTANCED_MESH_PARAMETERS, DEFAULT_INSTANCE_TRANSFORM, DEFAULT_MESH_GEOMETRY_PARAMETERS, DEFAULT_PHYSICS_STATE, DEFAULT_POSE_CURLS, DEFAULT_POSE_DIRECTIONS, DEFAULT_POSTPROCESSING_STATE, DEFAULT_RIGIDBODY_STATE, EntityType, Environment, IKComponent, ImageComponent, ImageTarget, ImageTargetAnchor, InstanceSlotComponent, InstancedMeshComponent, LightComponent, MODEL_NO_PATH_MESSAGE, MaterialComponent, MeshComponent, MeshGeometryComponent, ModelComponent, Name, NetworkIdentityComponent, NetworkSpawnerComponent, NetworkTransformComponent, NetworkedPropsComponent, Object3DRef, ParentId, PhysicsComponent, Postprocessing, PrefabInstance, PrefabNode, ScriptComponent, ScriptObjectComponent, Selectable, SelectionTransformState, SpriteComponent, TransformComponent, UIButtonComponent, UIPanelComponent, UISliderComponent, UITextComponent, UIToggleComponent, VRTeleportAreaComponent, VideoComponent, XRAnchorComponent, XREnvironmentComponent, XRHandPoseComponent, XRInteractableComponent, XRInteractorComponent, XRInteractorSideComponent, XRRigComponent, createAttachPoint, createHandPoseEntry, defaultMaterialValue, handPoseDefinitionFor, normalizeEnvironmentLighting, normalizeIKChain, normalizePhysicsState, setModelLoadState, setPhysicsLiveRef } from '../chunk-JNYPJB55.js';
2
2
  import '../chunk-CKTHDXPS.js';
3
3
  import '../chunk-XE4OXN2W.js';
4
4
  //# sourceMappingURL=index.js.map
@@ -114,7 +114,7 @@ Chain fields:
114
114
 
115
115
  Change chains at runtime by editing `chains` on the component; turn all of them off with `enabled = false`, which puts every bone back to the animation's pose.
116
116
 
117
- Targets out of reach are reached for as far as the limb allows. Ask the system how far a limb fell short:
117
+ Targets out of reach are reached for as far as the limb allows. Ask the system how far a limb fell short. It answers `null` for a limb whose chain didn't run that frame, because the chain is off or has no target:
118
118
 
119
119
  ```ts
120
120
  import { Behaviour } from "@relu-interactives/spatial-ecs";
@@ -77,6 +77,71 @@ export class Gun extends Behaviour {
77
77
  }
78
78
  ```
79
79
 
80
+ ## Sounds everyone hears
81
+
82
+ `this.network.playSlot` plays a [sound-bank](./audio-mixing-and-sound-banks) slot here and for everyone else in the room. Each client needs the bank loaded. If a slot's chance or cooldown keeps it quiet, no one hears it.
83
+
84
+ ```ts
85
+ import { Behaviour } from "@relu-interactives/spatial-ecs";
86
+
87
+ export class Shooter extends Behaviour {
88
+ async init() {
89
+ await this.loadSoundBank("assets/audio/weapons.soundbank.json");
90
+ }
91
+
92
+ fire() {
93
+ const { x, y, z } = this.transform.position;
94
+ this.network?.playSlot("shot", { position: { x, y, z } });
95
+ }
96
+ }
97
+ ```
98
+
99
+ Only slot ids travel, so a client can't make another one load a file. The room limits each player to 30 sounds a second.
100
+
101
+ ## Voice chat
102
+
103
+ Turn on voice in the project's Multiplayer settings and players get a mic button. Voice is direct between players: the game server only passes the messages that set each connection up, and never hears the audio. Nothing is captured until a player turns voice on, and only others who turned it on can hear them.
104
+
105
+ Voices play through the `voice` bus, so `setBusVolume("voice", …)` applies and music ducks while someone talks. Each voice comes from that player's character, the first thing they spawned. To hear everyone everywhere, set `positional` to false.
106
+
107
+ To build your own controls, use `this.network.voice`. It's `null` when the project doesn't have voice on:
108
+
109
+ ```ts
110
+ import { Behaviour } from "@relu-interactives/spatial-ecs";
111
+
112
+ export class VoiceKey extends Behaviour {
113
+ // call from a key or a tap: that's what lets the browser ask for the mic
114
+ async toggle() {
115
+ const voice = this.network?.voice;
116
+ if (!voice?.available) return;
117
+ if (voice.state === "off") await voice.enable();
118
+ else voice.disable();
119
+ }
120
+
121
+ whoIsTalking() {
122
+ return this.network?.voice?.peers.filter((peer) => peer.talking) ?? [];
123
+ }
124
+
125
+ quiet(playerId: string) {
126
+ this.network?.voice?.setPeerMuted(playerId, true);
127
+ }
128
+ }
129
+ ```
130
+
131
+ Things to know:
132
+
133
+ - **Rooms stop at 8 people in voice.** Everyone sends to everyone, so each person's upload grows with the room. The quality steps down as it fills and on a poor connection. A ninth person sees "Voice is full in this room".
134
+ - **A mic needs https.** `voice.available` is false on a plain http page, except localhost.
135
+ - **Direct connections show players each other's IP address.** On a public game, set `VOICE_RELAY_ONLY=1` on the server to send everything through the relay instead. That needs a TURN relay, and all voice then costs relay bandwidth. Without a relay, voice stays off rather than connecting directly.
136
+ - **Some networks can't connect directly.** Mobile carriers often block it. Set `TURN_URLS` and `TURN_SECRET` on your server to give those players a relay, using a TURN server such as coturn in its `use-auth-secret` mode. Without one, those players connect to voice but hear nothing.
137
+
138
+ ## Where a published game runs
139
+
140
+ Set this in the project's Multiplayer settings. Local tests always stay on your machine.
141
+
142
+ - **Relu's servers.** Nothing to set up. Your plan sets how many players can be online at once in the game, across all its rooms, and whether voice chat is on. Past the limit, a new player sees that the game is full and plays alone. These servers run the standard room only, so `server/rooms/game.ts` doesn't run there.
143
+ - **Your own server.** The editor gives you one command to run on a machine you own. This is the choice for server rules, and it isn't limited by your plan.
144
+
80
145
  ## Server rules
81
146
 
82
147
  Clients can't be trusted, so anything that decides who won belongs on the server, in `server/rooms/game.ts`. Every hook is optional, and with none the room just relays:
@@ -21,8 +21,9 @@ raise its `width`/`height` fields and it re-renders crisply.
21
21
  1. Create a **UI Panel** — the backdrop. A comfortable read is 1–2 m from the
22
22
  player, centred around eye height (y ≈ 1.2–1.6).
23
23
  2. Create **Text**, **Button**, **Toggle**, **Slider** entities and parent
24
- them under the panel. Place them with local transforms, a hair in front of
25
- the backdrop (local z ≈ 0.01) so they draw over it.
24
+ them under the panel. Place them with local transforms. Children always
25
+ draw over their parent, from any angle, so local z is only for depth you
26
+ want to see.
26
27
  3. Give each interactive widget an `actionId` (empty means "use the entity's
27
28
  name").
28
29
  4. Attach **one Behaviour to the panel**. UI events fire on the widget's own
@@ -71,7 +72,9 @@ independent: each panel script hears only its own children.
71
72
  | Toggle | `UIToggleComponent` | On/off switch. Fires `onUiToggle`; `value` persists with the scene. |
72
73
  | Slider | `UISliderComponent` | Draggable value in `[min, max]`. Fires `onUiChange`. |
73
74
 
74
- Images need no widget: parent an ordinary `image` entity under the panel.
75
+ Images need no widget: parent an ordinary `image` entity under the panel. A
76
+ transparent mesh under a widget draws with it, in front of that widget and
77
+ behind the widget's own children.
75
78
 
76
79
  ### Press semantics
77
80
 
@@ -90,6 +93,65 @@ and always fires once more with the final value on release.
90
93
  panel's texture density. Lines wrap automatically to the component's `width`;
91
94
  overflow past `height` is clamped with an ellipsis.
92
95
 
96
+ ## Styling
97
+
98
+ Every widget takes a `style`, which wins over its plain colour fields. Leave it
99
+ out and the widget draws as it always has.
100
+
101
+ ```ts
102
+ import { UIPanelComponent } from "@relu-interactives/spatial-ecs/components";
103
+
104
+ const panel = new UIPanelComponent({
105
+ width: 0.9,
106
+ height: 0.6,
107
+ tokens: { plate: "#1b2432", plateDeep: "#121824" },
108
+ style: {
109
+ fill: {
110
+ kind: "linear",
111
+ angle: 160,
112
+ stops: [
113
+ { at: 0, color: "$plate" },
114
+ { at: 1, color: "$plateDeep" },
115
+ ],
116
+ },
117
+ radius: 0.036,
118
+ shadows: [{ x: 0, y: -0.02, blur: 0.06, color: "#00000099" }],
119
+ edge: { width: 0.0035, color: "#ffffff30" },
120
+ },
121
+ });
122
+ ```
123
+
124
+ | Field | What it does |
125
+ | --- | --- |
126
+ | `fill` | `solid`, `linear` (angle in degrees, reads like CSS), `radial`, or `image` (`cover`, `contain`, `fill`, with an optional `tint`) |
127
+ | `border` | Width in metres and a paint |
128
+ | `radius` | One radius, or four: top-left, top-right, bottom-right, bottom-left |
129
+ | `shadows` | Drop shadows, in metres, outside the shape only. They don't change what a pointer can hit |
130
+ | `edge` | A thin highlight along the top inner edge |
131
+ | `opacity` | 0–1. Multiplies down the widget tree, so fading a panel fades its menu, and a fade never redraws anything |
132
+ | `text` | `font`, `weight`, `tracking`, `transform`, `paint`, `maxLines`, `shadow` |
133
+
134
+ ### Tokens
135
+
136
+ `tokens` on a panel name values for every widget under it, as `$name` in any
137
+ colour or file field, the nearest panel winning. A theme therefore travels with
138
+ a prefab, and one edit restyles a whole menu, redrawing only the widgets that
139
+ use that token.
140
+
141
+ ### Fonts and images
142
+
143
+ `style.text.font` takes a font file in the project, and `fill` with
144
+ `kind: "image"` or a button's `icon` takes an image or SVG. Files load on
145
+ demand and the widget redraws when they arrive. Until then text uses a system
146
+ face.
147
+
148
+ ### Variants
149
+
150
+ - Toggle `variant`: `switch` (default), `checkbox`, `radio`.
151
+ - Slider `variant`: `slider` (default), `progress`, `ring`. The last two only
152
+ show a value. `readOnly` does the same for a plain slider, and `step` snaps
153
+ a dragged value.
154
+
93
155
  ## Follow modes
94
156
 
95
157
  - `follow: "world"` (default) — the panel stays where you put it.
@@ -148,7 +210,8 @@ export class Inspect extends Behaviour {
148
210
  }
149
211
 
150
212
  onUiHoverStart(event: UiInteractionEvent) {
151
- // The pointer moved onto the widget (also fires for mouse hover).
213
+ // A ray or the mouse moved onto the widget. Two hands on one widget count
214
+ // as one hover. Vision Pro has no hover before a pinch.
152
215
  console.log("hovering", event.targetEntityId);
153
216
  }
154
217
  }
@@ -160,6 +223,19 @@ export class Inspect extends Behaviour {
160
223
  idle menu costs nothing per frame.
161
224
  - Slider drags and toggle flips move **geometry** (the knob and fill quads),
162
225
  not pixels, so dragging never re-renders the texture.
163
- - `pixelDensity` (panel) trades texture memory for sharpness: the default
164
- 1024 px/m is crisp at arm's length; raise it only for panels the player
165
- inspects up close.
226
+ - `pixelDensity` (every widget) trades texture memory for sharpness: the
227
+ default 1024 px/m is crisp at arm's length; raise it only for widgets the
228
+ player inspects up close.
229
+
230
+ ## Draw order and blending
231
+
232
+ Widgets draw in a fixed order: within one UI tree, parents before children;
233
+ between trees, back to front by plane distance. Widgets on one plane that are
234
+ not parented to each other draw large before small, so parent them when the
235
+ order matters.
236
+
237
+ Text and controls show from the front only. A panel keeps its back.
238
+
239
+ On a WebGPU project a translucent widget over a bright background looks a
240
+ little duller than on WebGL, because WebGPU blends in linear light. Over dark
241
+ backgrounds the two match. Opaque widgets are identical on both.
@@ -2680,6 +2680,127 @@ function createXRInteractorSideComponent(world, entityId, ...args) {
2680
2680
  }
2681
2681
  __name(createXRInteractorSideComponent, "createXRInteractorSideComponent");
2682
2682
 
2683
+ // core/ui/uiStyle.ts
2684
+ var isRecord = /* @__PURE__ */ __name((value) => typeof value === "object" && value !== null && !Array.isArray(value), "isRecord");
2685
+ var finite = /* @__PURE__ */ __name((value) => typeof value === "number" && Number.isFinite(value), "finite");
2686
+ var nonEmpty = /* @__PURE__ */ __name((value) => typeof value === "string" && value.length > 0, "nonEmpty");
2687
+ function normalizeStops(value) {
2688
+ if (!Array.isArray(value)) return null;
2689
+ const stops = [];
2690
+ for (const stop of value) {
2691
+ if (isRecord(stop) && finite(stop.at) && nonEmpty(stop.color)) {
2692
+ stops.push({ at: Math.min(1, Math.max(0, stop.at)), color: stop.color });
2693
+ }
2694
+ }
2695
+ return stops.length >= 2 ? stops : null;
2696
+ }
2697
+ __name(normalizeStops, "normalizeStops");
2698
+ function normalizePaint(value) {
2699
+ if (!isRecord(value)) return void 0;
2700
+ if (value.kind === "solid" && nonEmpty(value.color)) {
2701
+ return { kind: "solid", color: value.color };
2702
+ }
2703
+ if (value.kind === "linear") {
2704
+ const stops = normalizeStops(value.stops);
2705
+ if (stops) {
2706
+ return {
2707
+ kind: "linear",
2708
+ angle: finite(value.angle) ? value.angle : 180,
2709
+ stops
2710
+ };
2711
+ }
2712
+ }
2713
+ if (value.kind === "radial") {
2714
+ const stops = normalizeStops(value.stops);
2715
+ if (stops) return { kind: "radial", stops };
2716
+ }
2717
+ if (value.kind === "image" && nonEmpty(value.src)) {
2718
+ const fit = value.fit === "contain" || value.fit === "fill" ? value.fit : "cover";
2719
+ return {
2720
+ kind: "image",
2721
+ src: value.src,
2722
+ fit,
2723
+ ...nonEmpty(value.tint) ? { tint: value.tint } : {}
2724
+ };
2725
+ }
2726
+ return void 0;
2727
+ }
2728
+ __name(normalizePaint, "normalizePaint");
2729
+ function normalizeShadow(value) {
2730
+ if (!isRecord(value) || !nonEmpty(value.color)) return void 0;
2731
+ return {
2732
+ x: finite(value.x) ? value.x : 0,
2733
+ y: finite(value.y) ? value.y : 0,
2734
+ blur: finite(value.blur) ? Math.max(0, value.blur) : 0,
2735
+ color: value.color
2736
+ };
2737
+ }
2738
+ __name(normalizeShadow, "normalizeShadow");
2739
+ function normalizeText(value) {
2740
+ if (!isRecord(value)) return void 0;
2741
+ const text = {};
2742
+ if (nonEmpty(value.font)) text.font = value.font;
2743
+ if (finite(value.weight)) text.weight = value.weight;
2744
+ if (finite(value.tracking)) text.tracking = value.tracking;
2745
+ if (value.transform === "upper" || value.transform === "lower") {
2746
+ text.transform = value.transform;
2747
+ }
2748
+ const paint = normalizePaint(value.paint);
2749
+ if (paint) text.paint = paint;
2750
+ if (finite(value.maxLines) && value.maxLines >= 1) {
2751
+ text.maxLines = Math.floor(value.maxLines);
2752
+ }
2753
+ const shadow = normalizeShadow(value.shadow);
2754
+ if (shadow) text.shadow = shadow;
2755
+ return Object.keys(text).length > 0 ? text : void 0;
2756
+ }
2757
+ __name(normalizeText, "normalizeText");
2758
+ function normalizeUiStyle(value) {
2759
+ if (!isRecord(value)) return void 0;
2760
+ const style = {};
2761
+ const fill = normalizePaint(value.fill);
2762
+ if (fill) style.fill = fill;
2763
+ if (isRecord(value.border) && finite(value.border.width)) {
2764
+ const paint = normalizePaint(value.border.paint);
2765
+ if (paint) {
2766
+ style.border = { width: Math.max(0, value.border.width), paint };
2767
+ }
2768
+ }
2769
+ if (finite(value.radius)) {
2770
+ style.radius = Math.max(0, value.radius);
2771
+ } else if (Array.isArray(value.radius) && value.radius.length === 4 && value.radius.every(finite)) {
2772
+ style.radius = value.radius.map((r) => Math.max(0, r));
2773
+ }
2774
+ if (Array.isArray(value.shadows)) {
2775
+ const shadows = value.shadows.map(normalizeShadow).filter((s) => !!s);
2776
+ if (shadows.length > 0) style.shadows = shadows;
2777
+ }
2778
+ if (isRecord(value.edge) && finite(value.edge.width) && nonEmpty(value.edge.color)) {
2779
+ style.edge = {
2780
+ width: Math.max(0, value.edge.width),
2781
+ color: value.edge.color
2782
+ };
2783
+ }
2784
+ if (finite(value.opacity)) {
2785
+ style.opacity = Math.min(1, Math.max(0, value.opacity));
2786
+ }
2787
+ const text = normalizeText(value.text);
2788
+ if (text) style.text = text;
2789
+ return Object.keys(style).length > 0 ? style : void 0;
2790
+ }
2791
+ __name(normalizeUiStyle, "normalizeUiStyle");
2792
+ function normalizeUiTokens(value) {
2793
+ if (!isRecord(value)) return void 0;
2794
+ const tokens = {};
2795
+ for (const [key, token] of Object.entries(value)) {
2796
+ if (nonEmpty(token) && key.length > 0 && !key.includes("/")) {
2797
+ tokens[key] = token;
2798
+ }
2799
+ }
2800
+ return Object.keys(tokens).length > 0 ? tokens : void 0;
2801
+ }
2802
+ __name(normalizeUiTokens, "normalizeUiTokens");
2803
+
2683
2804
  // core/components/UIButton.ts
2684
2805
  var _UIButtonComponent = class _UIButtonComponent extends Component {
2685
2806
  constructor(options) {
@@ -2696,6 +2817,13 @@ var _UIButtonComponent = class _UIButtonComponent extends Component {
2696
2817
  this.cornerRadius = options?.cornerRadius ?? 0.02;
2697
2818
  this.borderWidth = options?.borderWidth ?? 2e-3;
2698
2819
  this.borderColor = options?.borderColor ?? "#3a3a3a";
2820
+ if (options?.pixelDensity !== void 0) {
2821
+ this.pixelDensity = options.pixelDensity;
2822
+ }
2823
+ const style = normalizeUiStyle(options?.style);
2824
+ if (style) this.style = style;
2825
+ if (options?.icon) this.icon = options.icon;
2826
+ if (options?.iconPosition) this.iconPosition = options.iconPosition;
2699
2827
  }
2700
2828
  };
2701
2829
  __name(_UIButtonComponent, "UIButtonComponent");
@@ -2722,6 +2850,10 @@ var _UIPanelComponent = class _UIPanelComponent extends Component {
2722
2850
  this.borderColor = options?.borderColor ?? "#333333";
2723
2851
  this.pixelDensity = options?.pixelDensity ?? 1024;
2724
2852
  this.follow = options?.follow ?? "world";
2853
+ const style = normalizeUiStyle(options?.style);
2854
+ if (style) this.style = style;
2855
+ const tokens = normalizeUiTokens(options?.tokens);
2856
+ if (tokens) this.tokens = tokens;
2725
2857
  }
2726
2858
  };
2727
2859
  __name(_UIPanelComponent, "UIPanelComponent");
@@ -2750,6 +2882,14 @@ var _UISliderComponent = class _UISliderComponent extends Component {
2750
2882
  this.trackColor = options?.trackColor ?? "#2a2a2a";
2751
2883
  this.accentColor = options?.accentColor ?? "#ff6b35";
2752
2884
  this.knobColor = options?.knobColor ?? "#ffffff";
2885
+ if (options?.pixelDensity !== void 0) {
2886
+ this.pixelDensity = options.pixelDensity;
2887
+ }
2888
+ const style = normalizeUiStyle(options?.style);
2889
+ if (style) this.style = style;
2890
+ if (options?.variant) this.variant = options.variant;
2891
+ if (options?.step !== void 0) this.step = options.step;
2892
+ if (options?.readOnly !== void 0) this.readOnly = options.readOnly;
2753
2893
  }
2754
2894
  };
2755
2895
  __name(_UISliderComponent, "UISliderComponent");
@@ -2777,6 +2917,11 @@ var _UITextComponent = class _UITextComponent extends Component {
2777
2917
  this.valign = options?.valign ?? "middle";
2778
2918
  this.lineHeight = options?.lineHeight ?? 1.25;
2779
2919
  this.padding = options?.padding ?? 0.01;
2920
+ if (options?.pixelDensity !== void 0) {
2921
+ this.pixelDensity = options.pixelDensity;
2922
+ }
2923
+ const style = normalizeUiStyle(options?.style);
2924
+ if (style) this.style = style;
2780
2925
  }
2781
2926
  };
2782
2927
  __name(_UITextComponent, "UITextComponent");
@@ -2801,6 +2946,12 @@ var _UIToggleComponent = class _UIToggleComponent extends Component {
2801
2946
  this.trackColor = options?.trackColor ?? "#2a2a2a";
2802
2947
  this.accentColor = options?.accentColor ?? "#ff6b35";
2803
2948
  this.knobColor = options?.knobColor ?? "#ffffff";
2949
+ if (options?.pixelDensity !== void 0) {
2950
+ this.pixelDensity = options.pixelDensity;
2951
+ }
2952
+ const style = normalizeUiStyle(options?.style);
2953
+ if (style) this.style = style;
2954
+ if (options?.variant) this.variant = options.variant;
2804
2955
  }
2805
2956
  };
2806
2957
  __name(_UIToggleComponent, "UIToggleComponent");