@relu-interactives/spatial-ecs 0.9.0 → 0.11.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 (39) 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-CWSrsnYN.d.ts → XRHandPose-BNSwd1y9.d.ts} +1 -1
  4. package/dist/{XRHandPose-Dn2yiALk.d.cts → XRHandPose-D3Ab1Dfs.d.cts} +1 -1
  5. package/dist/{chunk-VYIWOXAY.js → chunk-TY3XCHOR.js} +18 -10
  6. package/dist/chunk-TY3XCHOR.js.map +1 -0
  7. package/dist/components/index.d.cts +3 -3
  8. package/dist/components/index.d.ts +3 -3
  9. package/dist/docs/guide/bone-attachments-and-ik.md +1 -1
  10. package/dist/docs/guide/multiplayer.md +65 -0
  11. package/dist/factories/index.d.cts +2 -2
  12. package/dist/factories/index.d.ts +2 -2
  13. package/dist/{index-D5MmJNyj.d.ts → index-6pZO_gV7.d.ts} +1 -1
  14. package/dist/{index-CAZHrh0q.d.cts → index-BXjwEdNq.d.cts} +2 -2
  15. package/dist/{index-DiIjV2lm.d.cts → index-BdghvXKE.d.cts} +1 -1
  16. package/dist/{index-CLtSMf2M.d.ts → index-CVG-hREM.d.ts} +2 -2
  17. package/dist/index.cjs +16 -8
  18. package/dist/index.cjs.map +1 -1
  19. package/dist/index.d.cts +8 -30
  20. package/dist/index.d.ts +8 -30
  21. package/dist/index.js +2 -2
  22. package/dist/network/index.cjs +681 -4
  23. package/dist/network/index.cjs.map +1 -1
  24. package/dist/network/index.d.cts +126 -5
  25. package/dist/network/index.d.ts +126 -5
  26. package/dist/network/index.js +680 -5
  27. package/dist/network/index.js.map +1 -1
  28. package/dist/systems/index.cjs +16 -8
  29. package/dist/systems/index.cjs.map +1 -1
  30. package/dist/systems/index.d.cts +2 -2
  31. package/dist/systems/index.d.ts +2 -2
  32. package/dist/systems/index.js +1 -1
  33. package/dist/types.d.cts +1 -1
  34. package/dist/types.d.ts +1 -1
  35. package/dist/webgpu/index.d.ts +2 -2
  36. package/dist/worldSnapshotUtils.d.cts +1 -1
  37. package/dist/worldSnapshotUtils.d.ts +1 -1
  38. package/package.json +1 -1
  39. package/dist/chunk-VYIWOXAY.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 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-Dn2yiALk.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-CAZHrh0q.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 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-CWSrsnYN.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-CLtSMf2M.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';
@@ -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:
@@ -1,5 +1,5 @@
1
- import { A as AnimationComponent, b as AudioComponent, d as CameraComponentOptions, C as CameraComponent, Z as RigidbodyState, h as ColliderState, U as PhysicsComponent, q as EntityType, I as ImageComponent, s as ImageTargetAnchor, r as ImageTarget, L as LightComponent, G as MaterialComponent, K as MeshComponent, N as MeshGeometryComponent, Q as ModelComponent, S as Name, T as Object3DRef, a0 as ScriptEntry, $ as ScriptComponent, a2 as ScriptObjectComponentInput, a1 as ScriptObjectComponent, a4 as Selectable, a5 as SelectionTransformState, a6 as SpriteComponent, y as InstancedMeshKind, O as MeshGeometryParameters, x as InstancedMeshComponent, v as InstanceSlotComponent, as as VideoComponent, aD as XRRigComponent, aq as VRTeleportAreaComponent, aw as XRHandPoseComponent, au as XRAnchorComponent, B as BoneAttachmentComponent, ay as XRInteractableComponent, aA as XRInteractorComponent, aC as XRInteractorSideComponent, aa as UIButtonComponent, ac as UIPanelComponent, ae as UISliderComponent, ag as UITextComponent, ai as UIToggleComponent } from '../XRHandPose-Dn2yiALk.cjs';
2
- import { W as World, j as EnvironmentState, E as Environment, P as ParentId, u as PostprocessingState, t as Postprocessing, T as TransformComponent, l as IKComponent, o as NetworkIdentityComponent, p as NetworkSpawnerComponent, q as NetworkTransformComponent, s as NetworkedPropsComponent, X as ObjectManagementSystem } from '../System-8D-XBDKZ.cjs';
1
+ import { A as AnimationComponent, b as AudioComponent, d as CameraComponentOptions, C as CameraComponent, Z as RigidbodyState, h as ColliderState, U as PhysicsComponent, q as EntityType, I as ImageComponent, s as ImageTargetAnchor, r as ImageTarget, L as LightComponent, G as MaterialComponent, K as MeshComponent, N as MeshGeometryComponent, Q as ModelComponent, S as Name, T as Object3DRef, a0 as ScriptEntry, $ as ScriptComponent, a2 as ScriptObjectComponentInput, a1 as ScriptObjectComponent, a4 as Selectable, a5 as SelectionTransformState, a6 as SpriteComponent, y as InstancedMeshKind, O as MeshGeometryParameters, x as InstancedMeshComponent, v as InstanceSlotComponent, as as VideoComponent, aD as XRRigComponent, aq as VRTeleportAreaComponent, aw as XRHandPoseComponent, au as XRAnchorComponent, B as BoneAttachmentComponent, ay as XRInteractableComponent, aA as XRInteractorComponent, aC as XRInteractorSideComponent, aa as UIButtonComponent, ac as UIPanelComponent, ae as UISliderComponent, ag as UITextComponent, ai as UIToggleComponent } from '../XRHandPose-D3Ab1Dfs.cjs';
2
+ import { W as World, j as EnvironmentState, E as Environment, P as ParentId, u as PostprocessingState, t as Postprocessing, T as TransformComponent, l as IKComponent, o as NetworkIdentityComponent, p as NetworkSpawnerComponent, q as NetworkTransformComponent, s as NetworkedPropsComponent, a1 as ObjectManagementSystem } from '../System-BldSHxZV.cjs';
3
3
  import * as THREE from 'three';
4
4
  import '@dimforge/rapier3d-compat';
5
5
  import '../handPose-DlcTtqgx.cjs';
@@ -1,5 +1,5 @@
1
- import { A as AnimationComponent, b as AudioComponent, d as CameraComponentOptions, C as CameraComponent, Z as RigidbodyState, h as ColliderState, U as PhysicsComponent, q as EntityType, I as ImageComponent, s as ImageTargetAnchor, r as ImageTarget, L as LightComponent, G as MaterialComponent, K as MeshComponent, N as MeshGeometryComponent, Q as ModelComponent, S as Name, T as Object3DRef, a0 as ScriptEntry, $ as ScriptComponent, a2 as ScriptObjectComponentInput, a1 as ScriptObjectComponent, a4 as Selectable, a5 as SelectionTransformState, a6 as SpriteComponent, y as InstancedMeshKind, O as MeshGeometryParameters, x as InstancedMeshComponent, v as InstanceSlotComponent, as as VideoComponent, aD as XRRigComponent, aq as VRTeleportAreaComponent, aw as XRHandPoseComponent, au as XRAnchorComponent, B as BoneAttachmentComponent, ay as XRInteractableComponent, aA as XRInteractorComponent, aC as XRInteractorSideComponent, aa as UIButtonComponent, ac as UIPanelComponent, ae as UISliderComponent, ag as UITextComponent, ai as UIToggleComponent } from '../XRHandPose-CWSrsnYN.js';
2
- import { W as World, o as EnvironmentState, g as Environment, y as ParentId, b as PostprocessingState, z as Postprocessing, T as TransformComponent, q as IKComponent, t as NetworkIdentityComponent, u as NetworkSpawnerComponent, v as NetworkTransformComponent, x as NetworkedPropsComponent, a0 as ObjectManagementSystem } from '../System-DPMAW30g.js';
1
+ import { A as AnimationComponent, b as AudioComponent, d as CameraComponentOptions, C as CameraComponent, Z as RigidbodyState, h as ColliderState, U as PhysicsComponent, q as EntityType, I as ImageComponent, s as ImageTargetAnchor, r as ImageTarget, L as LightComponent, G as MaterialComponent, K as MeshComponent, N as MeshGeometryComponent, Q as ModelComponent, S as Name, T as Object3DRef, a0 as ScriptEntry, $ as ScriptComponent, a2 as ScriptObjectComponentInput, a1 as ScriptObjectComponent, a4 as Selectable, a5 as SelectionTransformState, a6 as SpriteComponent, y as InstancedMeshKind, O as MeshGeometryParameters, x as InstancedMeshComponent, v as InstanceSlotComponent, as as VideoComponent, aD as XRRigComponent, aq as VRTeleportAreaComponent, aw as XRHandPoseComponent, au as XRAnchorComponent, B as BoneAttachmentComponent, ay as XRInteractableComponent, aA as XRInteractorComponent, aC as XRInteractorSideComponent, aa as UIButtonComponent, ac as UIPanelComponent, ae as UISliderComponent, ag as UITextComponent, ai as UIToggleComponent } from '../XRHandPose-BNSwd1y9.js';
2
+ import { W as World, o as EnvironmentState, g as Environment, y as ParentId, b as PostprocessingState, z as Postprocessing, T as TransformComponent, q as IKComponent, t as NetworkIdentityComponent, u as NetworkSpawnerComponent, v as NetworkTransformComponent, x as NetworkedPropsComponent, a6 as ObjectManagementSystem } from '../System-CADhPyQs.js';
3
3
  import * as THREE from 'three';
4
4
  import '@dimforge/rapier3d-compat';
5
5
  import '../handPose-DlcTtqgx.js';
@@ -1,4 +1,4 @@
1
- import { K as EcsSystem, W as World, E as EcsRenderer, R as RenderBackend, ai as InputSystem, M as EntityId } from './System-DPMAW30g.js';
1
+ import { S as EcsSystem, W as World, E as EcsRenderer, R as RenderBackend, ap as InputSystem, X as EntityId } from './System-CADhPyQs.js';
2
2
  import * as THREE from 'three';
3
3
  import { m as XrHandJoints, r as XrHandShape } from './handPose-DlcTtqgx.js';
4
4
 
@@ -1,5 +1,5 @@
1
- import { 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-Dn2yiALk.cjs';
2
- import { C as Component, 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';
1
+ import { 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
+ import { C as Component, 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
3
 
4
4
  /**
5
5
  * Marks the ROOT entity of a prefab instance and records its link to the
@@ -1,4 +1,4 @@
1
- import { B as EcsSystem, W as World, ab as EcsRenderer, R as RenderBackend, af as InputSystem, G as EntityId } from './System-8D-XBDKZ.cjs';
1
+ import { K as EcsSystem, W as World, ai as EcsRenderer, $ as RenderBackend, am as InputSystem, M as EntityId } from './System-BldSHxZV.cjs';
2
2
  import * as THREE from 'three';
3
3
  import { m as XrHandJoints, r as XrHandShape } from './handPose-DlcTtqgx.cjs';
4
4
 
@@ -1,5 +1,5 @@
1
- import { 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-CWSrsnYN.js';
2
- import { d as Component, 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';
1
+ import { 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
+ import { d as Component, 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
3
 
4
4
  /**
5
5
  * Marks the ROOT entity of a prefab instance and records its link to the
package/dist/index.cjs CHANGED
@@ -16297,9 +16297,14 @@ function uiImage(src) {
16297
16297
  const blob = await response.blob();
16298
16298
  const typed = /\.svg(\?|#|$)/i.test(url) ? new Blob([blob], { type: "image/svg+xml" }) : blob;
16299
16299
  const image = new Image();
16300
- image.src = URL.createObjectURL(typed);
16301
- await image.decode();
16302
- return image;
16300
+ const objectUrl = URL.createObjectURL(typed);
16301
+ try {
16302
+ image.src = objectUrl;
16303
+ await image.decode();
16304
+ return image;
16305
+ } finally {
16306
+ URL.revokeObjectURL(objectUrl);
16307
+ }
16303
16308
  })()
16304
16309
  ).then((image) => {
16305
16310
  entry.value = image;
@@ -17932,11 +17937,13 @@ var _pq = new THREE67__namespace.Quaternion();
17932
17937
  var _IKSystem = class _IKSystem {
17933
17938
  constructor() {
17934
17939
  this.runtimes = /* @__PURE__ */ new Map();
17935
- this.reach = /* @__PURE__ */ new Map();
17936
17940
  }
17937
- /** How far a limb's end stayed from its target last frame, in metres (0 = reached). */
17941
+ /**
17942
+ * How far a limb's end stayed from its target last frame, in metres
17943
+ * (0 = reached), or null if the limb's chain didn't run.
17944
+ */
17938
17945
  getReachError(entityId, limb) {
17939
- return this.reach.get(`${entityId}:${limb}`) ?? null;
17946
+ return this.runtimes.get(entityId)?.reach.get(limb) ?? null;
17940
17947
  }
17941
17948
  restore(runtime) {
17942
17949
  for (const [bone, w] of runtime.written) {
@@ -17962,13 +17969,14 @@ var _IKSystem = class _IKSystem {
17962
17969
  let runtime = this.runtimes.get(id);
17963
17970
  if (!runtime || runtime.rootUuid !== root.uuid) {
17964
17971
  if (runtime) this.restore(runtime);
17965
- runtime = { rootUuid: root.uuid, limbs: /* @__PURE__ */ new Map(), written: /* @__PURE__ */ new Map() };
17972
+ runtime = { rootUuid: root.uuid, limbs: /* @__PURE__ */ new Map(), written: /* @__PURE__ */ new Map(), reach: /* @__PURE__ */ new Map() };
17966
17973
  this.runtimes.set(id, runtime);
17967
17974
  }
17968
17975
  for (const [bone, w] of runtime.written) {
17969
17976
  if (bone.quaternion.equals(w.written)) bone.quaternion.copy(w.before);
17970
17977
  }
17971
17978
  runtime.written.clear();
17979
+ runtime.reach.clear();
17972
17980
  if (!ik.enabled) continue;
17973
17981
  const active = ik.chains.filter((c) => c.enabled && c.weight > 0 && typeof c.target === "number");
17974
17982
  if (active.length === 0) continue;
@@ -17998,7 +18006,7 @@ var _IKSystem = class _IKSystem {
17998
18006
  if (poleObject) poleObject.getWorldPosition(_p2);
17999
18007
  else lower.getWorldPosition(_p2);
18000
18008
  const miss = twoBoneIK(upper, lower, end, _t, _p2);
18001
- this.reach.set(`${id}:${chain.limb}`, Math.max(0, miss));
18009
+ runtime.reach.set(chain.limb, Math.max(0, miss));
18002
18010
  if (chain.matchRotation) {
18003
18011
  target.getWorldQuaternion(_q3);
18004
18012
  end.parent?.getWorldQuaternion(_pq);