@relu-interactives/spatial-ecs 0.5.3 → 0.9.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 (512) hide show
  1. package/dist/{System-V_mv07le.d.cts → System-8D-XBDKZ.d.cts} +734 -8
  2. package/dist/{System-V_mv07le.d.ts → System-DPMAW30g.d.ts} +734 -8
  3. package/dist/{XRHandPose-CU3vNFuS.d.ts → XRHandPose-CWSrsnYN.d.ts} +236 -3
  4. package/dist/{XRHandPose-CQTLGxFC.d.cts → XRHandPose-Dn2yiALk.d.cts} +236 -3
  5. package/dist/animation/index.cjs +252 -0
  6. package/dist/animation/index.cjs.map +1 -0
  7. package/dist/animation/index.d.cts +100 -0
  8. package/dist/animation/index.d.ts +100 -0
  9. package/dist/animation/index.js +4 -0
  10. package/dist/animation/index.js.map +1 -0
  11. package/dist/chunk-CKTHDXPS.js +11 -0
  12. package/dist/chunk-CKTHDXPS.js.map +1 -0
  13. package/dist/chunk-GSWC6LLD.js +241 -0
  14. package/dist/chunk-GSWC6LLD.js.map +1 -0
  15. package/dist/chunk-JEPUCLZX.js +1237 -0
  16. package/dist/chunk-JEPUCLZX.js.map +1 -0
  17. package/dist/{chunk-BUEKOSR5.js → chunk-JNYPJB55.js} +435 -14
  18. package/dist/chunk-JNYPJB55.js.map +1 -0
  19. package/dist/{chunk-RXBLOO5B.js → chunk-NXASMBDS.js} +105 -715
  20. package/dist/chunk-NXASMBDS.js.map +1 -0
  21. package/dist/chunk-OHCNPPMX.js +334 -0
  22. package/dist/chunk-OHCNPPMX.js.map +1 -0
  23. package/dist/{chunk-DF5SSRN6.js → chunk-VYIWOXAY.js} +2574 -3381
  24. package/dist/chunk-VYIWOXAY.js.map +1 -0
  25. package/dist/chunk-WWP46AEF.js +2878 -0
  26. package/dist/chunk-WWP46AEF.js.map +1 -0
  27. package/dist/{chunk-OY7ZODZP.js → chunk-XE4OXN2W.js} +3 -9
  28. package/dist/chunk-XE4OXN2W.js.map +1 -0
  29. package/dist/{chunk-OWQSESTO.js → chunk-XU2DVWCP.js} +4 -3
  30. package/dist/chunk-XU2DVWCP.js.map +1 -0
  31. package/dist/components/index.cjs +334 -10
  32. package/dist/components/index.cjs.map +1 -1
  33. package/dist/components/index.d.cts +5 -3
  34. package/dist/components/index.d.ts +5 -3
  35. package/dist/components/index.js +3 -2
  36. package/dist/docs/api/Behaviour/classes/Behaviour.md +366 -79
  37. package/dist/docs/api/Behaviour/index.md +7 -3
  38. package/dist/docs/api/Behaviour/type-aliases/UiInteractionEvent.md +35 -0
  39. package/dist/docs/api/Component/classes/Component.md +14 -1
  40. package/dist/docs/api/components/classes/AnimationComponent.md +26 -26
  41. package/dist/docs/api/components/classes/AudioComponent.md +19 -19
  42. package/dist/docs/api/components/classes/CameraComponent.md +14 -14
  43. package/dist/docs/api/components/classes/EntityType.md +4 -4
  44. package/dist/docs/api/components/classes/Environment.md +5 -4
  45. package/dist/docs/api/components/classes/ImageComponent.md +7 -7
  46. package/dist/docs/api/components/classes/ImageTarget.md +8 -8
  47. package/dist/docs/api/components/classes/ImageTargetAnchor.md +4 -4
  48. package/dist/docs/api/components/classes/InstanceSlotComponent.md +4 -4
  49. package/dist/docs/api/components/classes/InstancedMeshComponent.md +10 -10
  50. package/dist/docs/api/components/classes/LightComponent.md +6 -6
  51. package/dist/docs/api/components/classes/MaterialComponent.md +16 -16
  52. package/dist/docs/api/components/classes/MeshComponent.md +3 -3
  53. package/dist/docs/api/components/classes/MeshGeometryComponent.md +9 -9
  54. package/dist/docs/api/components/classes/ModelComponent.md +8 -5
  55. package/dist/docs/api/components/classes/Name.md +3 -3
  56. package/dist/docs/api/components/classes/Object3DRef.md +4 -4
  57. package/dist/docs/api/components/classes/ParentId.md +3 -3
  58. package/dist/docs/api/components/classes/PhysicsComponent.md +7 -6
  59. package/dist/docs/api/components/classes/Postprocessing.md +3 -3
  60. package/dist/docs/api/components/classes/PrefabInstance.md +5 -5
  61. package/dist/docs/api/components/classes/PrefabNode.md +3 -3
  62. package/dist/docs/api/components/classes/ScriptComponent.md +5 -5
  63. package/dist/docs/api/components/classes/ScriptObjectComponent.md +9 -9
  64. package/dist/docs/api/components/classes/Selectable.md +3 -3
  65. package/dist/docs/api/components/classes/SelectionTransformState.md +5 -5
  66. package/dist/docs/api/components/classes/SpriteComponent.md +7 -7
  67. package/dist/docs/api/components/classes/TransformComponent.md +12 -12
  68. package/dist/docs/api/components/classes/UIButtonComponent.md +63 -0
  69. package/dist/docs/api/components/classes/UIPanelComponent.md +62 -0
  70. package/dist/docs/api/components/classes/UISliderComponent.md +59 -0
  71. package/dist/docs/api/components/classes/UITextComponent.md +59 -0
  72. package/dist/docs/api/components/classes/UIToggleComponent.md +56 -0
  73. package/dist/docs/api/components/classes/VRTeleportAreaComponent.md +53 -0
  74. package/dist/docs/api/components/classes/VideoComponent.md +28 -28
  75. package/dist/docs/api/components/classes/XRAnchorComponent.md +64 -0
  76. package/dist/docs/api/components/classes/XREnvironmentComponent.md +64 -0
  77. package/dist/docs/api/components/classes/XRHandPoseComponent.md +50 -0
  78. package/dist/docs/api/components/classes/XRInteractableComponent.md +74 -0
  79. package/dist/docs/api/components/classes/XRInteractorComponent.md +57 -0
  80. package/dist/docs/api/components/classes/XRInteractorSideComponent.md +50 -0
  81. package/dist/docs/api/components/classes/XRRigComponent.md +68 -0
  82. package/dist/docs/api/components/functions/createAttachPoint.md +25 -0
  83. package/dist/docs/api/components/functions/createHandPoseEntry.md +25 -0
  84. package/dist/docs/api/components/functions/defaultMaterialValue.md +1 -1
  85. package/dist/docs/api/components/functions/handPoseDefinitionFor.md +33 -0
  86. package/dist/docs/api/components/functions/normalizeEnvironmentLighting.md +30 -0
  87. package/dist/docs/api/components/functions/normalizePhysicsState.md +1 -1
  88. package/dist/docs/api/components/functions/setModelLoadState.md +33 -0
  89. package/dist/docs/api/components/functions/setPhysicsLiveRef.md +3 -9
  90. package/dist/docs/api/components/index.md +61 -4
  91. package/dist/docs/api/components/type-aliases/AnimationComponentOptions.md +9 -9
  92. package/dist/docs/api/components/type-aliases/CameraComponentOptions.md +13 -13
  93. package/dist/docs/api/components/type-aliases/CameraProjection.md +1 -1
  94. package/dist/docs/api/components/type-aliases/CameraRuntimeType.md +5 -3
  95. package/dist/docs/api/components/type-aliases/ColliderShape.md +1 -1
  96. package/dist/docs/api/components/type-aliases/ColliderState.md +20 -20
  97. package/dist/docs/api/components/type-aliases/CubeMeshParameters.md +4 -4
  98. package/dist/docs/api/components/type-aliases/EditableMeshObjectKind.md +1 -1
  99. package/dist/docs/api/components/type-aliases/EnvironmentFogState.md +8 -8
  100. package/dist/docs/api/components/type-aliases/EnvironmentFogType.md +1 -1
  101. package/dist/docs/api/components/type-aliases/EnvironmentGradientEffect.md +1 -1
  102. package/dist/docs/api/components/type-aliases/EnvironmentLightingState.md +40 -0
  103. package/dist/docs/api/components/type-aliases/EnvironmentSkyboxImageProjection.md +22 -0
  104. package/dist/docs/api/components/type-aliases/EnvironmentSkyboxState.md +9 -7
  105. package/dist/docs/api/components/type-aliases/EnvironmentSkyboxType.md +1 -1
  106. package/dist/docs/api/components/type-aliases/EnvironmentState.md +7 -5
  107. package/dist/docs/api/components/type-aliases/EnvironmentToneMapping.md +16 -0
  108. package/dist/docs/api/components/type-aliases/ImageTargetAnchorOptions.md +3 -3
  109. package/dist/docs/api/components/type-aliases/ImageTargetReference.md +7 -7
  110. package/dist/docs/api/components/type-aliases/InstanceTransform.md +13 -13
  111. package/dist/docs/api/components/type-aliases/InstancedMeshKind.md +1 -1
  112. package/dist/docs/api/components/type-aliases/LightShadowState.md +37 -0
  113. package/dist/docs/api/components/type-aliases/LightValueState.md +13 -11
  114. package/dist/docs/api/components/type-aliases/MaterialTypeValue.md +1 -1
  115. package/dist/docs/api/components/type-aliases/MaterialValueState.md +28 -28
  116. package/dist/docs/api/components/type-aliases/MeshGeometryParameters.md +1 -1
  117. package/dist/docs/api/components/type-aliases/MeshGeometryParametersByKind.md +7 -7
  118. package/dist/docs/api/components/type-aliases/ModelLoadState.md +15 -0
  119. package/dist/docs/api/components/type-aliases/PhysicsState.md +3 -3
  120. package/dist/docs/api/components/type-aliases/PlaneMeshParameters.md +3 -3
  121. package/dist/docs/api/components/type-aliases/PostprocessingState.md +62 -62
  122. package/dist/docs/api/components/type-aliases/RadiusHeightMeshParameters.md +3 -3
  123. package/dist/docs/api/components/type-aliases/RadiusMeshParameters.md +2 -2
  124. package/dist/docs/api/components/type-aliases/RigidbodyState.md +17 -17
  125. package/dist/docs/api/components/type-aliases/RigidbodyType.md +1 -1
  126. package/dist/docs/api/components/type-aliases/ScriptEntry.md +8 -8
  127. package/dist/docs/api/components/type-aliases/ScriptObjectComponentInput.md +1 -1
  128. package/dist/docs/api/components/type-aliases/ScriptObjectRuntimeState.md +1 -1
  129. package/dist/docs/api/components/type-aliases/TextureFilteringValue.md +1 -1
  130. package/dist/docs/api/components/type-aliases/TransformData.md +4 -4
  131. package/dist/docs/api/components/type-aliases/TransformModeValue.md +1 -1
  132. package/dist/docs/api/components/type-aliases/TransformSpaceValue.md +1 -1
  133. package/dist/docs/api/components/type-aliases/UIButtonOptions.md +45 -0
  134. package/dist/docs/api/components/type-aliases/UIPanelOptions.md +39 -0
  135. package/dist/docs/api/components/type-aliases/UISliderOptions.md +39 -0
  136. package/dist/docs/api/components/type-aliases/UITextOptions.md +41 -0
  137. package/dist/docs/api/components/type-aliases/UIToggleOptions.md +35 -0
  138. package/dist/docs/api/components/type-aliases/UiFollowMode.md +15 -0
  139. package/dist/docs/api/components/type-aliases/UiTextAlign.md +13 -0
  140. package/dist/docs/api/components/type-aliases/UiTextVAlign.md +13 -0
  141. package/dist/docs/api/components/type-aliases/VRTeleportAreaOptions.md +29 -0
  142. package/dist/docs/api/components/type-aliases/Vec3.md +4 -4
  143. package/dist/docs/api/components/type-aliases/VrTeleportShape.md +15 -0
  144. package/dist/docs/api/components/type-aliases/XRAnchorOptions.md +23 -0
  145. package/dist/docs/api/components/type-aliases/XRHandPoseOptions.md +23 -0
  146. package/dist/docs/api/components/type-aliases/XRInteractableOptions.md +75 -0
  147. package/dist/docs/api/components/type-aliases/XRInteractorOptions.md +37 -0
  148. package/dist/docs/api/components/type-aliases/XRRigOptions.md +51 -0
  149. package/dist/docs/api/components/type-aliases/XrAttachPoint.md +53 -0
  150. package/dist/docs/api/components/type-aliases/XrDistanceGrabBehavior.md +19 -0
  151. package/dist/docs/api/components/type-aliases/XrEnvironmentKind.md +15 -0
  152. package/dist/docs/api/components/type-aliases/XrEnvironmentOrientation.md +15 -0
  153. package/dist/docs/api/components/type-aliases/XrEnvironmentPhysics.md +25 -0
  154. package/dist/docs/api/components/type-aliases/XrGrabGesture.md +19 -0
  155. package/dist/docs/api/components/type-aliases/XrGrabHands.md +20 -0
  156. package/dist/docs/api/components/type-aliases/XrGrabReach.md +20 -0
  157. package/dist/docs/api/components/type-aliases/XrHandPoseEntry.md +49 -0
  158. package/dist/docs/api/components/type-aliases/XrHandPreset.md +19 -0
  159. package/dist/docs/api/components/type-aliases/XrInteractorSide.md +15 -0
  160. package/dist/docs/api/components/type-aliases/XrInteractorType.md +13 -0
  161. package/dist/docs/api/components/type-aliases/XrLocomotionMode.md +15 -0
  162. package/dist/docs/api/components/type-aliases/XrTrackingOrigin.md +24 -0
  163. package/dist/docs/api/components/type-aliases/XrTwoHandRotation.md +15 -0
  164. package/dist/docs/api/components/variables/DEFAULT_COLLIDER_STATE.md +1 -1
  165. package/dist/docs/api/components/variables/DEFAULT_ENVIRONMENT_LIGHTING.md +15 -0
  166. package/dist/docs/api/components/variables/DEFAULT_ENVIRONMENT_STATE.md +1 -1
  167. package/dist/docs/api/components/variables/DEFAULT_INSTANCED_MESH_PARAMETERS.md +1 -1
  168. package/dist/docs/api/components/variables/DEFAULT_INSTANCE_TRANSFORM.md +1 -1
  169. package/dist/docs/api/components/variables/DEFAULT_MESH_GEOMETRY_PARAMETERS.md +1 -1
  170. package/dist/docs/api/components/variables/DEFAULT_PHYSICS_STATE.md +1 -1
  171. package/dist/docs/api/components/variables/DEFAULT_POSE_CURLS.md +13 -0
  172. package/dist/docs/api/components/variables/DEFAULT_POSE_DIRECTIONS.md +13 -0
  173. package/dist/docs/api/components/variables/DEFAULT_POSTPROCESSING_STATE.md +1 -1
  174. package/dist/docs/api/components/variables/DEFAULT_RIGIDBODY_STATE.md +1 -1
  175. package/dist/docs/api/components/variables/MODEL_NO_PATH_MESSAGE.md +15 -0
  176. package/dist/docs/api/index/classes/AnimationStateMachine.md +16 -16
  177. package/dist/docs/api/index/classes/AnimationStateManager.md +13 -13
  178. package/dist/docs/api/index/classes/AnimationSystem.md +3 -3
  179. package/dist/docs/api/index/classes/AudioSystem.md +4 -4
  180. package/dist/docs/api/index/classes/CameraSyncSystem.md +2 -2
  181. package/dist/docs/api/index/classes/EnvironmentSyncSystem.md +19 -4
  182. package/dist/docs/api/index/classes/HandPoseTracker.md +114 -0
  183. package/dist/docs/api/index/classes/InputSystem.md +33 -33
  184. package/dist/docs/api/index/classes/InstancedMeshSystem.md +2 -2
  185. package/dist/docs/api/index/classes/LightSyncSystem.md +2 -2
  186. package/dist/docs/api/index/classes/MaterialSyncSystem.md +3 -3
  187. package/dist/docs/api/index/classes/MeshGeometrySystem.md +2 -2
  188. package/dist/docs/api/index/classes/ObjectManagementSystem.md +14 -14
  189. package/dist/docs/api/index/classes/ObjectVisibilitySystem.md +2 -2
  190. package/dist/docs/api/index/classes/PhysicsSyncSystem.md +4 -4
  191. package/dist/docs/api/index/classes/PostprocessingSyncSystem.md +34 -10
  192. package/dist/docs/api/index/classes/RenderSystem.md +13 -4
  193. package/dist/docs/api/index/classes/ScriptBehaviourSystem.md +9 -5
  194. package/dist/docs/api/index/classes/ScriptObject.md +10 -10
  195. package/dist/docs/api/index/classes/ScriptObjectSystem.md +6 -6
  196. package/dist/docs/api/index/classes/TeleportAimGate.md +114 -0
  197. package/dist/docs/api/index/classes/ThrowVelocityTracker.md +89 -0
  198. package/dist/docs/api/index/classes/TransformSyncSystem.md +2 -2
  199. package/dist/docs/api/index/classes/UIInteractionSystem.md +60 -0
  200. package/dist/docs/api/index/classes/UIPanelSystem.md +79 -0
  201. package/dist/docs/api/index/classes/VRTeleportAreaSystem.md +49 -0
  202. package/dist/docs/api/index/classes/VideoSystem.md +8 -6
  203. package/dist/docs/api/index/classes/World.md +282 -100
  204. package/dist/docs/api/index/classes/XRAnchorSystem.md +90 -0
  205. package/dist/docs/api/index/classes/XRControllerVisualSystem.md +77 -0
  206. package/dist/docs/api/index/classes/XREnvironmentSystem.md +137 -0
  207. package/dist/docs/api/index/classes/XRHandPoseSystem.md +107 -0
  208. package/dist/docs/api/index/classes/XRHitTestSystem.md +93 -0
  209. package/dist/docs/api/index/classes/XRHoverVisualSystem.md +76 -0
  210. package/dist/docs/api/index/classes/XRInputSystem.md +189 -0
  211. package/dist/docs/api/index/classes/XRInteractionSystem.md +323 -0
  212. package/dist/docs/api/index/classes/XRLocomotionSystem.md +128 -0
  213. package/dist/docs/api/index/classes/XRSessionSystem.md +116 -0
  214. package/dist/docs/api/index/classes/XRTeleportVisualSystem.md +75 -0
  215. package/dist/docs/api/index/functions/angularVelocityFrom.md +33 -0
  216. package/dist/docs/api/index/functions/applyHandMaterial.md +26 -0
  217. package/dist/docs/api/index/functions/applyPrefabToSnapshotInstances.md +1 -1
  218. package/dist/docs/api/index/functions/arcGroundCrossing.md +30 -0
  219. package/dist/docs/api/index/functions/buildComponentValueMaps.md +1 -1
  220. package/dist/docs/api/index/functions/buildNodeKeyMapsFromSnapshot.md +1 -1
  221. package/dist/docs/api/index/functions/buildNodeMapsFromSnapshot.md +1 -1
  222. package/dist/docs/api/index/functions/canonicalizeComponentValue.md +1 -1
  223. package/dist/docs/api/index/functions/clearModelCache.md +1 -1
  224. package/dist/docs/api/index/functions/clearPrefabCache.md +1 -1
  225. package/dist/docs/api/index/functions/cloneHandPose.md +23 -0
  226. package/dist/docs/api/index/functions/collectDiffPaths.md +1 -1
  227. package/dist/docs/api/index/functions/collectDirectPrefabDependencies.md +1 -1
  228. package/dist/docs/api/index/functions/collectEntitySubtree.md +1 -1
  229. package/dist/docs/api/index/functions/collectSnapshotSubtreeIds.md +1 -1
  230. package/dist/docs/api/index/functions/computeFingerCurl.md +29 -0
  231. package/dist/docs/api/index/functions/computeHandShape.md +29 -0
  232. package/dist/docs/api/index/functions/computeInstanceOverrides.md +1 -1
  233. package/dist/docs/api/index/functions/computePalmPose.md +30 -0
  234. package/dist/docs/api/index/functions/computePalmWidth.md +25 -0
  235. package/dist/docs/api/index/functions/computePinch.md +29 -0
  236. package/dist/docs/api/index/functions/computeSpread.md +33 -0
  237. package/dist/docs/api/index/functions/createAnimationComponent.md +1 -1
  238. package/dist/docs/api/index/functions/createAudioComponent.md +1 -1
  239. package/dist/docs/api/index/functions/createCameraComponent.md +1 -1
  240. package/dist/docs/api/index/functions/createEntityTypeComponent.md +2 -2
  241. package/dist/docs/api/index/functions/createEnvironmentComponent.md +1 -1
  242. package/dist/docs/api/index/functions/createHandMaterial.md +30 -0
  243. package/dist/docs/api/index/functions/createImageComponent.md +1 -1
  244. package/dist/docs/api/index/functions/createImageTargetAnchorComponent.md +1 -1
  245. package/dist/docs/api/index/functions/createImageTargetComponent.md +2 -2
  246. package/dist/docs/api/index/functions/createInstanceSlotComponent.md +1 -1
  247. package/dist/docs/api/index/functions/createInstancedMeshComponent.md +1 -1
  248. package/dist/docs/api/index/functions/createLightComponent.md +2 -2
  249. package/dist/docs/api/index/functions/createMaterialComponent.md +2 -2
  250. package/dist/docs/api/index/functions/createMeshComponent.md +1 -1
  251. package/dist/docs/api/index/functions/createMeshGeometryComponent.md +1 -1
  252. package/dist/docs/api/index/functions/createModelComponent.md +1 -1
  253. package/dist/docs/api/index/functions/createNameComponent.md +1 -1
  254. package/dist/docs/api/index/functions/createObject3DRefComponent.md +1 -1
  255. package/dist/docs/api/index/functions/createParentIdComponent.md +1 -1
  256. package/dist/docs/api/index/functions/createPhysicsComponent.md +1 -1
  257. package/dist/docs/api/index/functions/createPostprocessingComponent.md +1 -1
  258. package/dist/docs/api/index/functions/createScriptComponent.md +1 -1
  259. package/dist/docs/api/index/functions/createScriptObjectComponent.md +1 -1
  260. package/dist/docs/api/index/functions/createSelectableComponent.md +1 -1
  261. package/dist/docs/api/index/functions/createSelectionTransformStateComponent.md +1 -1
  262. package/dist/docs/api/index/functions/createSpriteComponent.md +1 -1
  263. package/dist/docs/api/index/functions/createTransformComponent.md +1 -1
  264. package/dist/docs/api/index/functions/createUIButtonComponent.md +28 -0
  265. package/dist/docs/api/index/functions/createUIPanelComponent.md +28 -0
  266. package/dist/docs/api/index/functions/createUISliderComponent.md +28 -0
  267. package/dist/docs/api/index/functions/createUITextComponent.md +28 -0
  268. package/dist/docs/api/index/functions/createUIToggleComponent.md +28 -0
  269. package/dist/docs/api/index/functions/createVRTeleportAreaComponent.md +28 -0
  270. package/dist/docs/api/index/functions/createVideoComponent.md +1 -1
  271. package/dist/docs/api/index/functions/createXRAnchorComponent.md +28 -0
  272. package/dist/docs/api/index/functions/createXRHandPoseComponent.md +28 -0
  273. package/dist/docs/api/index/functions/createXRInteractableComponent.md +28 -0
  274. package/dist/docs/api/index/functions/createXRInteractorComponent.md +28 -0
  275. package/dist/docs/api/index/functions/createXRInteractorSideComponent.md +28 -0
  276. package/dist/docs/api/index/functions/createXRRigComponent.md +28 -0
  277. package/dist/docs/api/index/functions/decanonicalizeComponentValue.md +1 -1
  278. package/dist/docs/api/index/functions/despawnPrefab.md +1 -1
  279. package/dist/docs/api/index/functions/encodeOverride.md +1 -1
  280. package/dist/docs/api/index/functions/estimateHandScale.md +28 -0
  281. package/dist/docs/api/index/functions/findSnapshotRootEntityIds.md +1 -1
  282. package/dist/docs/api/index/functions/findTopLevelNestedRegions.md +1 -1
  283. package/dist/docs/api/index/functions/getHandPosePreset.md +31 -0
  284. package/dist/docs/api/index/functions/groupOverridePaths.md +1 -1
  285. package/dist/docs/api/index/functions/handPoseFromCurls.md +42 -0
  286. package/dist/docs/api/index/functions/hydrateWorldFromSnapshot.md +1 -1
  287. package/dist/docs/api/index/functions/hydrateWorldFromSnapshotDetailed.md +1 -1
  288. package/dist/docs/api/index/functions/indexSnapshotByEntity.md +1 -1
  289. package/dist/docs/api/index/functions/instantiateSubtree.md +1 -1
  290. package/dist/docs/api/index/functions/loadPrefab.md +1 -1
  291. package/dist/docs/api/index/functions/loadSharedGltf.md +1 -1
  292. package/dist/docs/api/index/functions/matchHandPose.md +34 -0
  293. package/dist/docs/api/index/functions/mergeComponentValue.md +1 -1
  294. package/dist/docs/api/index/functions/parseOverride.md +1 -1
  295. package/dist/docs/api/index/functions/parsePrefabAsset.md +1 -1
  296. package/dist/docs/api/index/functions/prefabFileVersionFor.md +1 -1
  297. package/dist/docs/api/index/functions/readXrCapabilities.md +30 -0
  298. package/dist/docs/api/index/functions/registerDefaultComponentFactories.md +1 -1
  299. package/dist/docs/api/index/functions/registerDefaultFactories.md +1 -1
  300. package/dist/docs/api/index/functions/remapSnapshotEntityIds.md +3 -3
  301. package/dist/docs/api/index/functions/resolveDracoDecoderPath.md +1 -1
  302. package/dist/docs/api/index/functions/restoreComponentState.md +1 -1
  303. package/dist/docs/api/index/functions/restorePostCreateComponents.md +1 -1
  304. package/dist/docs/api/index/functions/sampleTeleportArc.md +40 -0
  305. package/dist/docs/api/index/functions/serializeEntitySubtree.md +1 -1
  306. package/dist/docs/api/index/functions/setDracoDecoderPath.md +1 -1
  307. package/dist/docs/api/index/functions/setPrefabAssetUrlResolver.md +1 -1
  308. package/dist/docs/api/index/functions/spawnPrefab.md +1 -1
  309. package/dist/docs/api/index/index.md +116 -4
  310. package/dist/docs/api/index/interfaces/ChromaKeyOptions.md +20 -0
  311. package/dist/docs/api/index/interfaces/EcsSystem.md +3 -3
  312. package/dist/docs/api/index/interfaces/PostprocessingBuildContext.md +21 -0
  313. package/dist/docs/api/index/interfaces/PostprocessingPipeline.md +84 -0
  314. package/dist/docs/api/index/interfaces/RenderBackend.md +168 -0
  315. package/dist/docs/api/index/interfaces/StateMachine.md +13 -13
  316. package/dist/docs/api/index/type-aliases/AnimationStateCallbacks.md +4 -4
  317. package/dist/docs/api/index/type-aliases/ApplyPrefabToSnapshotResult.md +3 -3
  318. package/dist/docs/api/index/type-aliases/ComponentFactory.md +1 -1
  319. package/dist/docs/api/index/type-aliases/ComponentValueMaps.md +50 -26
  320. package/dist/docs/api/index/type-aliases/EcsComponentFactoryKind.md +14 -2
  321. package/dist/docs/api/index/type-aliases/EcsRenderer.md +17 -0
  322. package/dist/docs/api/index/type-aliases/EcsWorldComponentSnapshot.md +3 -3
  323. package/dist/docs/api/index/type-aliases/EcsWorldStateSnapshotLike.md +4 -4
  324. package/dist/docs/api/index/type-aliases/ExternalRefWarning.md +5 -5
  325. package/dist/docs/api/index/type-aliases/HandMaterialOptions.md +32 -0
  326. package/dist/docs/api/index/type-aliases/HandPoseTrackerOptions.md +27 -0
  327. package/dist/docs/api/index/type-aliases/HydrateOptions.md +3 -3
  328. package/dist/docs/api/index/type-aliases/HydrateWorldFromSnapshotResult.md +4 -4
  329. package/dist/docs/api/index/type-aliases/InstantiateSubtreeResult.md +3 -3
  330. package/dist/docs/api/index/type-aliases/KeyboardKey.md +1 -1
  331. package/dist/docs/api/index/type-aliases/ModuleLoader.md +1 -1
  332. package/dist/docs/api/index/type-aliases/MouseButton.md +1 -1
  333. package/dist/docs/api/index/type-aliases/NestedRegion.md +5 -5
  334. package/dist/docs/api/index/type-aliases/NodeKeyMaps.md +5 -5
  335. package/dist/docs/api/index/type-aliases/NodeMaps.md +4 -4
  336. package/dist/docs/api/index/type-aliases/PrefabAsset.md +5 -5
  337. package/dist/docs/api/index/type-aliases/RemapSnapshotOptions.md +2 -2
  338. package/dist/docs/api/index/type-aliases/RendererKind.md +15 -0
  339. package/dist/docs/api/index/type-aliases/ScriptBehaviourSystemOptions.md +23 -0
  340. package/dist/docs/api/index/type-aliases/ScriptErrorEvent.md +39 -0
  341. package/dist/docs/api/index/type-aliases/ScriptErrorListener.md +25 -0
  342. package/dist/docs/api/index/type-aliases/ScriptErrorPhase.md +28 -0
  343. package/dist/docs/api/index/type-aliases/ScriptErrorReport.md +31 -0
  344. package/dist/docs/api/index/type-aliases/ScriptErrorSource.md +15 -0
  345. package/dist/docs/api/index/type-aliases/SelectionContext.md +4 -4
  346. package/dist/docs/api/index/type-aliases/SerializeEntitySubtreeResult.md +4 -4
  347. package/dist/docs/api/index/type-aliases/SpawnPrefabOptions.md +5 -5
  348. package/dist/docs/api/index/type-aliases/SpawnPrefabSource.md +1 -1
  349. package/dist/docs/api/index/type-aliases/SubtreeSnapshot.md +3 -3
  350. package/dist/docs/api/index/type-aliases/UiCanvasLike.md +46 -0
  351. package/dist/docs/api/index/type-aliases/VelocitySample.md +23 -0
  352. package/dist/docs/api/index/type-aliases/XrCapabilities.md +41 -0
  353. package/dist/docs/api/index/type-aliases/XrFinger.md +13 -0
  354. package/dist/docs/api/index/type-aliases/XrFingerCurl.md +27 -0
  355. package/dist/docs/api/index/type-aliases/XrFingerTarget.md +31 -0
  356. package/dist/docs/api/index/type-aliases/XrHandJointName.md +40 -0
  357. package/dist/docs/api/index/type-aliases/XrHandJoints.md +18 -0
  358. package/dist/docs/api/index/type-aliases/XrHandPoseAxis.md +15 -0
  359. package/dist/docs/api/index/type-aliases/XrHandPoseContext.md +23 -0
  360. package/dist/docs/api/index/type-aliases/XrHandPoseDefinition.md +47 -0
  361. package/dist/docs/api/index/type-aliases/XrHandPoseDirection.md +21 -0
  362. package/dist/docs/api/index/type-aliases/XrHandPoseEvent.md +13 -0
  363. package/dist/docs/api/index/type-aliases/XrHandPoseEventDetail.md +27 -0
  364. package/dist/docs/api/index/type-aliases/XrHandPoseMatch.md +25 -0
  365. package/dist/docs/api/index/type-aliases/XrHandPoseOrientation.md +25 -0
  366. package/dist/docs/api/index/type-aliases/XrHandShape.md +46 -0
  367. package/dist/docs/api/index/type-aliases/XrHandedness.md +15 -0
  368. package/dist/docs/api/index/type-aliases/XrHitResult.md +25 -0
  369. package/dist/docs/api/index/type-aliases/XrInputKind.md +19 -0
  370. package/dist/docs/api/index/type-aliases/XrInputState.md +60 -0
  371. package/dist/docs/api/index/type-aliases/XrPalmPose.md +31 -0
  372. package/dist/docs/api/index/variables/ADDED_NODE_MARKER_COMPONENT.md +2 -2
  373. package/dist/docs/api/index/variables/ARC_GRAVITY.md +15 -0
  374. package/dist/docs/api/index/variables/ARC_MAX_TIME.md +15 -0
  375. package/dist/docs/api/index/variables/ARC_SPEED.md +15 -0
  376. package/dist/docs/api/index/variables/ARC_STEPS.md +15 -0
  377. package/dist/docs/api/index/variables/CURLED_COS.md +13 -0
  378. package/dist/docs/api/index/variables/DEFAULT_DIRECTION_TOLERANCE.md +15 -0
  379. package/dist/docs/api/index/variables/DEFAULT_ENTER_CONFIDENCE.md +13 -0
  380. package/dist/docs/api/index/variables/DEFAULT_EXIT_CONFIDENCE.md +13 -0
  381. package/dist/docs/api/index/variables/DEFAULT_LOST_GRACE_SECONDS.md +13 -0
  382. package/dist/docs/api/index/variables/DEFAULT_MIN_HOLD_SECONDS.md +13 -0
  383. package/dist/docs/api/index/variables/DEFAULT_SCRIPT_ERROR_RETRY_DELAY.md +17 -0
  384. package/dist/docs/api/index/variables/FALLBACK_HAND_SCALE.md +15 -0
  385. package/dist/docs/api/index/variables/HAND_POSE_PRESETS.md +19 -0
  386. package/dist/docs/api/index/variables/HAND_POSE_PRESET_IDS.md +15 -0
  387. package/dist/docs/api/index/variables/HYDRATABLE_ENTITY_KINDS.md +1 -1
  388. package/dist/docs/api/index/variables/KeyboardKeys.md +89 -89
  389. package/dist/docs/api/index/variables/MATCH_FALLOFF.md +15 -0
  390. package/dist/docs/api/index/variables/MAX_PLAUSIBLE_SPEED.md +25 -0
  391. package/dist/docs/api/index/variables/MAX_SAMPLE_AGE_SECONDS.md +18 -0
  392. package/dist/docs/api/index/variables/NODE_KEY_SEPARATOR.md +1 -1
  393. package/dist/docs/api/index/variables/NO_XR_CAPABILITIES.md +15 -0
  394. package/dist/docs/api/index/variables/OVERRIDE_DIFF_EXCLUDED_COMPONENTS.md +1 -1
  395. package/dist/docs/api/index/variables/OVERRIDE_ROOT_EXCLUDED_COMPONENTS.md +1 -1
  396. package/dist/docs/api/index/variables/PINCH_FINGERS.md +15 -0
  397. package/dist/docs/api/index/variables/PREFAB_FILE_VERSION.md +1 -1
  398. package/dist/docs/api/index/variables/PREFAB_FILE_VERSION_NESTED.md +1 -1
  399. package/dist/docs/api/index/variables/SCRIPT_OBJECT_ROOT_FLAG.md +1 -1
  400. package/dist/docs/api/index/variables/SHARED_MODEL_RESOURCE_FLAG.md +1 -1
  401. package/dist/docs/api/index/variables/STRAIGHT_COS.md +19 -0
  402. package/dist/docs/api/index/variables/VELOCITY_SAMPLES.md +15 -0
  403. package/dist/docs/api/index/variables/XR_FINGERS.md +13 -0
  404. package/dist/docs/api/index/variables/XR_HOVER_SHELL_FLAG.md +15 -0
  405. package/dist/docs/api/index/variables/webglBackend.md +16 -0
  406. package/dist/docs/api/typedoc-sidebar.json +1 -1
  407. package/dist/docs/api/types/type-aliases/AssetInput.md +3 -3
  408. package/dist/docs/api/types/type-aliases/CheckboxInput.md +3 -3
  409. package/dist/docs/api/types/type-aliases/ColorInput.md +1 -1
  410. package/dist/docs/api/types/type-aliases/ComponentInput.md +4 -4
  411. package/dist/docs/api/types/type-aliases/ComponentKind.md +1 -1
  412. package/dist/docs/api/types/type-aliases/DropdownInput.md +3 -3
  413. package/dist/docs/api/types/type-aliases/DropdownOption.md +3 -3
  414. package/dist/docs/api/types/type-aliases/EcsEntityEditorKind.md +1 -1
  415. package/dist/docs/api/types/type-aliases/EcsEntityKind.md +10 -2
  416. package/dist/docs/api/types/type-aliases/EntityId.md +1 -1
  417. package/dist/docs/api/types/type-aliases/EntityInput.md +3 -3
  418. package/dist/docs/api/types/type-aliases/FloatInput.md +1 -1
  419. package/dist/docs/api/types/type-aliases/IntersectionResult.md +3 -3
  420. package/dist/docs/api/types/type-aliases/ParentLookup.md +3 -3
  421. package/dist/docs/api/types/type-aliases/SelectionListener.md +1 -1
  422. package/dist/docs/api/types/type-aliases/SliderInput.md +5 -5
  423. package/dist/docs/api/types/type-aliases/TextInput.md +1 -1
  424. package/dist/docs/api/types/type-aliases/ToggleInput.md +1 -1
  425. package/dist/docs/api/types/type-aliases/Vec3.md +1 -1
  426. package/dist/docs/api/types/type-aliases/Vector2Input.md +3 -3
  427. package/dist/docs/api/types/type-aliases/Vector3Input.md +4 -4
  428. package/dist/docs/api/types/type-aliases/WorldEntityView.md +1 -1
  429. package/dist/docs/guide/audio-mixing-and-sound-banks.md +71 -0
  430. package/dist/docs/guide/authoring-a-behaviour.md +3 -3
  431. package/dist/docs/guide/authoring-a-script-object.md +12 -9
  432. package/dist/docs/guide/behaviour-data-binding/index.md +11 -11
  433. package/dist/docs/guide/behaviour-lifecycle.md +9 -0
  434. package/dist/docs/guide/bone-attachments-and-ik.md +128 -0
  435. package/dist/docs/guide/component-catalog.md +10 -2
  436. package/dist/docs/guide/components/light.md +42 -0
  437. package/dist/docs/guide/components/model.md +32 -3
  438. package/dist/docs/guide/concepts.md +2 -2
  439. package/dist/docs/guide/getting-started/creating-objects.md +2 -2
  440. package/dist/docs/guide/getting-started/editing-objects.md +2 -2
  441. package/dist/docs/guide/getting-started/editor/ai-agent.md +227 -0
  442. package/dist/docs/guide/getting-started/editor/hierarchy.md +2 -2
  443. package/dist/docs/guide/getting-started/editor/index.md +3 -2
  444. package/dist/docs/guide/getting-started/editor/inspector.md +2 -2
  445. package/dist/docs/guide/getting-started/editor/scene-inspector.md +3 -3
  446. package/dist/docs/guide/getting-started/editor/toolbar.md +11 -11
  447. package/dist/docs/guide/getting-started/editor/viewport.md +17 -9
  448. package/dist/docs/guide/getting-started/index.md +1 -1
  449. package/dist/docs/guide/getting-started/installation.md +1 -1
  450. package/dist/docs/guide/getting-started/preview-and-test.md +7 -7
  451. package/dist/docs/guide/getting-started/project-types/image-tracking.md +23 -11
  452. package/dist/docs/guide/getting-started/project-types/index.md +4 -4
  453. package/dist/docs/guide/getting-started/project-types/vr.md +270 -2
  454. package/dist/docs/guide/getting-started/projects.md +4 -5
  455. package/dist/docs/guide/getting-started/shortcuts.md +5 -4
  456. package/dist/docs/guide/multiplayer.md +92 -0
  457. package/dist/docs/guide/scene/environment.md +101 -4
  458. package/dist/docs/guide/scene/index.md +4 -4
  459. package/dist/docs/guide/scene/postprocessing.md +67 -5
  460. package/dist/docs/guide/spatial-ui.md +83 -7
  461. package/dist/docs/guide/spawning/area-light.md +2 -0
  462. package/dist/docs/guide/systems/environment-sync-system.md +11 -6
  463. package/dist/docs/guide/systems/light-sync-system.md +5 -3
  464. package/dist/docs/guide/systems/postprocessing-sync-system.md +16 -6
  465. package/dist/docs/guide/systems/render-system.md +7 -6
  466. package/dist/docs/guide/systems/script-behaviour-system.md +7 -5
  467. package/dist/docs/guide/systems/script-object-system.md +3 -1
  468. package/dist/docs/guide/systems/video-system.md +1 -1
  469. package/dist/docs/guide/webgpu-and-tsl.md +415 -0
  470. package/dist/docs/guide/world-api.md +52 -2
  471. package/dist/factories/index.cjs +921 -283
  472. package/dist/factories/index.cjs.map +1 -1
  473. package/dist/factories/index.d.cts +14 -3
  474. package/dist/factories/index.d.ts +14 -3
  475. package/dist/factories/index.js +7 -4
  476. package/dist/{index-C3ik3sA1.d.ts → index-CAZHrh0q.d.cts} +28 -3
  477. package/dist/{index-Dlr-7-4m.d.cts → index-CLtSMf2M.d.ts} +28 -3
  478. package/dist/{index-D2Jt_JzH.d.ts → index-D5MmJNyj.d.ts} +161 -43
  479. package/dist/{index-DaG03vyN.d.cts → index-DiIjV2lm.d.cts} +161 -43
  480. package/dist/index.cjs +4959 -1414
  481. package/dist/index.cjs.map +1 -1
  482. package/dist/index.d.cts +113 -11
  483. package/dist/index.d.ts +113 -11
  484. package/dist/index.js +187 -12
  485. package/dist/index.js.map +1 -1
  486. package/dist/network/index.cjs +5069 -0
  487. package/dist/network/index.cjs.map +1 -0
  488. package/dist/network/index.d.cts +98 -0
  489. package/dist/network/index.d.ts +98 -0
  490. package/dist/network/index.js +493 -0
  491. package/dist/network/index.js.map +1 -0
  492. package/dist/systems/index.cjs +5319 -1957
  493. package/dist/systems/index.cjs.map +1 -1
  494. package/dist/systems/index.d.cts +4 -2
  495. package/dist/systems/index.d.ts +4 -2
  496. package/dist/systems/index.js +8 -4
  497. package/dist/types.d.cts +3 -1
  498. package/dist/types.d.ts +3 -1
  499. package/dist/webgpu/index.d.ts +113 -0
  500. package/dist/webgpu/index.js +302 -0
  501. package/dist/webgpu/index.js.map +1 -0
  502. package/dist/worldSnapshotUtils.d.cts +3 -1
  503. package/dist/worldSnapshotUtils.d.ts +3 -1
  504. package/dist/worldSnapshotUtils.js +3 -2
  505. package/package.json +19 -3
  506. package/dist/chunk-BUEKOSR5.js.map +0 -1
  507. package/dist/chunk-DF5SSRN6.js.map +0 -1
  508. package/dist/chunk-OWQSESTO.js.map +0 -1
  509. package/dist/chunk-OY7ZODZP.js.map +0 -1
  510. package/dist/chunk-RXBLOO5B.js.map +0 -1
  511. package/dist/chunk-WJD2VKEH.js +0 -315
  512. package/dist/chunk-WJD2VKEH.js.map +0 -1
@@ -0,0 +1,71 @@
1
+ # Mixing and sound banks
2
+
3
+ Every sound plays through a **bus**: `sfx`, `voice` or `music`. A bus has its own volume, so a game can offer a music slider without touching a single sound, and music dips by itself while a voice plays.
4
+
5
+ ## Buses
6
+
7
+ An `AudioComponent` picks its bus in `options.bus` (default `sfx`). To set a volume at runtime:
8
+
9
+ ```ts
10
+ import { Behaviour } from "@relu-interactives/spatial-ecs";
11
+
12
+ export class VolumeMenu extends Behaviour {
13
+ setMusic(volume: number) {
14
+ this.world.getAudioSystem()?.setBusVolume("music", volume);
15
+ }
16
+ }
17
+ ```
18
+
19
+ ## Sound banks
20
+
21
+ A game usually wants a *kind* of sound ("hit", "footstep"), not one file: a few takes so it doesn't repeat, a chance so it doesn't fire every time, a cooldown so a flurry doesn't stack. A `.soundbank.json` asset holds that:
22
+
23
+ ```json
24
+ {
25
+ "version": 1,
26
+ "slots": {
27
+ "hit": {
28
+ "bus": "sfx",
29
+ "takes": [{ "file": "assets/sfx/hit-1.mp3" }, { "file": "assets/sfx/hit-2.mp3", "volume": 0.8 }],
30
+ "cooldownMs": 80
31
+ },
32
+ "taunt": {
33
+ "bus": "voice",
34
+ "chance": 0.5,
35
+ "priority": 1,
36
+ "takes": [{ "file": "assets/voice/taunt.mp3" }]
37
+ }
38
+ }
39
+ }
40
+ ```
41
+
42
+ `file` paths start at `assets/`. Files a bank names ship with a publish.
43
+
44
+ | Field | Default | Description |
45
+ |---|---|---|
46
+ | `takes` | | The recordings. The same take never plays twice running when there's another. |
47
+ | `bus` | `sfx` | The volume group. |
48
+ | `chance` | `1` | Probability it plays at all. |
49
+ | `cooldownMs` | `0` | Asks within this long of the last play are ignored. |
50
+ | `volume` | `1` | Linear gain; a take's `volume` multiplies it. |
51
+ | `priority` | `0` | On the voice bus, a lower priority stays quiet while a higher one speaks, and an equal or higher one cuts in. |
52
+
53
+ Load a bank once, then play slots by name. `playSlot` says whether it sounded; a slot kept quiet by its chance or cooldown isn't an error.
54
+
55
+ ```ts
56
+ import { Behaviour } from "@relu-interactives/spatial-ecs";
57
+
58
+ export class Fighter extends Behaviour {
59
+ data = { sounds: { path: "", type: "file" as const } };
60
+
61
+ protected init() {
62
+ void this.loadSoundBank(this.data.sounds);
63
+ }
64
+
65
+ takeHit() {
66
+ this.playSlot("hit", { position: this.transform.position });
67
+ }
68
+ }
69
+ ```
70
+
71
+ Without `position`, a slot plays evenly everywhere. Audio needs a user gesture before a browser will play it, so play from input, not from `init`.
@@ -87,7 +87,7 @@ In a Relu Spatial project, scripts live under the project's `assets/` directory.
87
87
 
88
88
  ## Inspector data binding
89
89
 
90
- The `data` object is the bridge between the editor inspector and your script. Use typed input annotations — `FloatInput`, `ColorInput`, `DropdownInput`, etc. — to control which inspector control renders for each field:
90
+ The `data` object is the bridge between the editor inspector and your script. Use typed input annotations `FloatInput`, `ColorInput`, `DropdownInput`, etc. to control which inspector control renders for each field:
91
91
 
92
92
  ```ts
93
93
  import {
@@ -124,6 +124,6 @@ See [Reading Input](./reading-input) for the full keyboard and mouse input API,
124
124
 
125
125
  ## Behaviours run at preview/runtime only
126
126
 
127
- `Behaviour` scripts execute **only** at preview and runtime — never inside the editor. Gameplay logic, input handling, physics, and anything that should not run while authoring belongs in a Behaviour.
127
+ `Behaviour` scripts execute **only** at preview and runtime, never inside the editor. Gameplay logic, input handling, physics, and anything that should not run while authoring belongs in a Behaviour.
128
128
 
129
- For a visual that must render and animate **inside the editor** (custom shaders, procedural geometry, grass, particle systems — anything the object palette can't produce), use a [Script Object](./authoring-a-script-object) instead. A `ScriptObject` builds a `THREE.Object3D` that renders in the editor AND at runtime.
129
+ For a visual that must render and animate **inside the editor** (custom shaders, procedural geometry, grass, particle systems, anything the object palette can't produce), use a [Script Object](./authoring-a-script-object) instead. A `ScriptObject` builds a `THREE.Object3D` that renders in the editor AND at runtime.
@@ -1,6 +1,6 @@
1
1
  # Authoring a Script Object
2
2
 
3
- A **Script Object** is an entity whose THREE.js visual is built entirely by your code — custom shaders, procedural geometry, particle systems, anything the editor's object palette can't produce. Unlike a [Behaviour](./authoring-a-behaviour), a Script Object runs in the **editor AND at runtime**: `build()` and `update()` execute identically in both, so what you see while authoring is exactly what ships.
3
+ A **Script Object** is an entity whose THREE.js visual is built entirely by your code, for example custom shaders, procedural geometry, particle systems, anything the editor's object palette can't produce. Unlike a [Behaviour](./authoring-a-behaviour), a Script Object runs in the **editor AND at runtime**: `build()` and `update()` execute identically in both, so what you see while authoring is exactly what ships.
4
4
 
5
5
  > [!IMPORTANT]
6
6
  > **Do NOT gate anything on `world.isEditorMode()`.** Running everywhere is the whole point of a Script Object. Use a [Behaviour](./authoring-a-behaviour) for gameplay logic that must NOT run in the editor.
@@ -15,14 +15,14 @@ import * as THREE from "three";
15
15
 
16
16
  export default class WavePlane extends ScriptObject {
17
17
  // Inspector fields: an INLINE `data = { … }` literal (same envelopes as
18
- // Behaviours). NEVER `declare data` — that is a type-only annotation with no
18
+ // Behaviours). NEVER `declare data` that is a type-only annotation with no
19
19
  // runtime object, so the editor can't discover your fields and the inspector
20
20
  // shows nothing to edit.
21
21
  data = { color: "#3aa0ff" as ColorInput };
22
22
 
23
23
  private mat!: THREE.ShaderMaterial;
24
24
 
25
- // REQUIRED — build and return the visual root.
25
+ // REQUIRED build and return the visual root.
26
26
  build(): THREE.Object3D {
27
27
  this.mat = new THREE.ShaderMaterial({
28
28
  uniforms: {
@@ -60,6 +60,9 @@ export default class WavePlane extends ScriptObject {
60
60
  }
61
61
  ```
62
62
 
63
+ > [!NOTE]
64
+ > GLSL (`ShaderMaterial`, `RawShaderMaterial`, `onBeforeCompile`) only renders on a `WebGLRenderer`. When the world runs on `WebGPURenderer` (`this.world.getRendererKind() === "webgpu"`), write the material in TSL instead: see [WebGPU and TSL](./webgpu-and-tsl#tsl-in-script-objects) for pulse, displacement, fresnel, dissolve and scrolling-UV recipes.
65
+
63
66
  `ScriptObjectSystem` calls `build()` once, attaches the returned object under the entity's Object3D (so it inherits the entity's transform, selection, and visibility), then calls `update(deltaTime)` every frame. `dispose()` runs on removal, disable, or hot-reload.
64
67
 
65
68
  ## Members available
@@ -68,12 +71,12 @@ export default class WavePlane extends ScriptObject {
68
71
  | --- | --- | --- |
69
72
  | `this.world` | `World` | The owning ECS world. |
70
73
  | `this.entityId` | `number` | The entity this script is bound to. |
71
- | `this.data` | `Record<string, unknown>` | Inspector-bound payload. Declare it with an INLINE literal (`data = { … }`) — never `declare data` (a type-only annotation with no runtime object → no inspector fields). |
74
+ | `this.data` | `Record<string, unknown>` | Inspector-bound payload. Declare it with an INLINE literal (`data = { … }`), never use `declare data` (a type-only annotation with no runtime object → no inspector fields). |
72
75
  | `this.root` | `THREE.Object3D \| null` | The object `build()` returned (set after build). |
73
76
 
74
77
  ## Data fields (inspector)
75
78
 
76
- Declare `data` as an **inline literal** (`data = { … }`) with the same input envelopes as Behaviours. **Never use `declare data`** — it is a type-only annotation that produces no runtime object, so the editor can't discover the fields and the inspector shows nothing to edit. (Likewise, don't set defaults with `this.data.x ??= …` inside `build()` — put the default in the literal.)
79
+ Declare `data` as an **inline literal** (`data = { … }`) with the same input envelopes as Behaviours. **Never use `declare data`** it is a type-only annotation that produces no runtime object, so the editor can't discover the fields and the inspector shows nothing to edit. (Likewise, don't set defaults with `this.data.x ??= …` inside `build()` put the default in the literal.)
77
80
 
78
81
  Simple scalars take a value plus an `as <Input>` cast and are read directly:
79
82
 
@@ -98,12 +101,12 @@ See [Data binding](./behaviour-data-binding/) for the full envelope catalog. Edi
98
101
 
99
102
  ## Rules
100
103
 
101
- - **`build()` must return a `THREE.Object3D`** — a `Group`, `Mesh`, `Points`, etc. Returning anything else marks the object as errored.
104
+ - **`build()` must return a `THREE.Object3D`**, a `Group`, `Mesh`, `Points`, etc. Returning anything else marks the object as errored.
102
105
  - **Do NOT gate on `world.isEditorMode()`.** Build and animate unconditionally.
103
- - **`dispose()` must free what you allocated** — geometries, materials, textures, render targets. THREE `dispose()` is idempotent, so it's safe to over-dispose. The engine removes the built subtree from the scene for you; freeing GPU memory is yours.
104
- - **Keep per-frame work in local THREE state / uniforms.** Do NOT write ECS components every frame from `update()` — that churns the editor's undo history.
106
+ - **`dispose()` must free what you allocated**, geometries, materials, textures, render targets. THREE `dispose()` is idempotent, so it's safe to over-dispose. The engine removes the built subtree from the scene for you; freeing GPU memory is yours.
107
+ - **Keep per-frame work in local THREE state / uniforms.** Do NOT write ECS components every frame from `update()`, that churns the editor's undo history.
105
108
  - **Pivot at the origin, meters for scale.** The built object rides the entity's transform, so build it centered on `(0,0,0)` at real-world scale.
106
- - **Imports**: only `three` (and `three/examples/jsm/*`) and `@relu-interactives/spatial-ecs`. Other bare imports won't resolve.
109
+ - **Imports**: only `three` (and `three/examples/jsm/*`) and `@relu-interactives/spatial-ecs`. Other bare imports won't resolve. TSL Script Objects also import `three/tsl` and `three/webgpu`.
107
110
 
108
111
  ## Behaviour vs Script Object
109
112
 
@@ -17,13 +17,13 @@ The **type annotation** on each field tells the editor which control to render.
17
17
  | [`ColorInput`](./color-input) | Color picker | `string` (hex, e.g. `"#ff0000"`) |
18
18
  | [`Vector2Input`](./vector2-input) | XY number pair | `{ x: number; y: number }` |
19
19
  | [`Vector3Input`](./vector3-input) | XYZ number triple | `{ x: number; y: number; z: number }` |
20
- | [`SliderInput`](./slider-input) | Range slider | `{ min, max, step, value }` — read `field.value` at runtime |
21
- | [`DropdownInput`](./dropdown-input) | Select dropdown | `{ options: DropdownOption[]; value: string }` — read `field.value` |
22
- | [`CheckboxInput`](./checkbox-input) | Checkbox | `{ type: "checkbox"; value: boolean }` — read `.value` |
20
+ | [`SliderInput`](./slider-input) | Range slider | `{ min, max, step, value }` - read `field.value` at runtime |
21
+ | [`DropdownInput`](./dropdown-input) | Select dropdown | `{ options: DropdownOption[]; value: string }` - read `field.value` |
22
+ | [`CheckboxInput`](./checkbox-input) | Checkbox | `{ type: "checkbox"; value: boolean }` - read `.value` |
23
23
  | [`ToggleInput`](./toggle-input) | Toggle switch | `boolean` |
24
- | [`AssetInput`](./asset-input) | Asset file picker | `{ path: string; type: string }` — read `field.path` |
25
- | [`EntityInput`](./entity-input) | Entity picker | `{ type: "entity"; value: WorldEntityView \| null }` — read `field.value` |
26
- | [`ComponentInput`](./component-input) | Entity + component picker | `{ type: "component"; componentKind?: ComponentKind; value: Component \| null }` — read `field.value` |
24
+ | [`AssetInput`](./asset-input) | Asset file picker | `{ path: string; type: string }` - read `field.path` |
25
+ | [`EntityInput`](./entity-input) | Entity picker | `{ type: "entity"; value: WorldEntityView \| null }` - read `field.value` |
26
+ | [`ComponentInput`](./component-input) | Entity + component picker | `{ type: "component"; componentKind?: ComponentKind; value: Component \| null }` - read `field.value` |
27
27
 
28
28
  ## Declaring inspector fields
29
29
 
@@ -77,7 +77,7 @@ Each field in `data` maps directly to a live inspector control. The script above
77
77
 
78
78
  ## Reading values at runtime
79
79
 
80
- Most types map directly to their underlying primitive. The exceptions are `SliderInput`, `DropdownInput`, `AssetInput`, `EntityInput`, and `ComponentInput` — read the nested value:
80
+ Most types map directly to their underlying primitive. The exceptions are `SliderInput`, `DropdownInput`, `AssetInput`, `EntityInput`, and `ComponentInput` - read the nested value:
81
81
 
82
82
  ```ts
83
83
  onUpdate() {
@@ -101,7 +101,7 @@ onUpdate() {
101
101
  }
102
102
  ```
103
103
 
104
- ## Practical example — spinner with inspector controls
104
+ ## Practical example (spinner with inspector controls)
105
105
 
106
106
  ```ts
107
107
  import {
@@ -137,11 +137,11 @@ export default class Spinner extends Behaviour {
137
137
 
138
138
  ## Defaulting fields
139
139
 
140
- Defaults are set inline on the `data` property. When a saved project reloads, saved values take precedence — the inline defaults only apply when a field has never been saved. This means:
140
+ Defaults are set inline on the `data` property. When a saved project reloads, saved values take precedence, the inline defaults only apply when a field has never been saved. This means:
141
141
 
142
- - Adding a new field with an inline default is safe — existing saves will pick it up on next load.
142
+ - Adding a new field with an inline default is safe, existing saves will pick it up on next load.
143
143
  - The inspector always has a valid initial value when the script is first attached.
144
- - For `SliderInput` and `DropdownInput`, the full object (including `options`) must be present in the inline default — the editor reads `options` to build the control.
144
+ - For `SliderInput` and `DropdownInput`, the full object (including `options`) must be present in the inline default, the editor reads `options` to build the control.
145
145
 
146
146
  ## Persistence
147
147
 
@@ -36,6 +36,15 @@ This ordering means:
36
36
 
37
37
  Behaviours never run in the editor. For a visual that must render and animate in the editor, use a [Script Object](./authoring-a-script-object).
38
38
 
39
+ ## When a hook throws
40
+
41
+ The engine catches the error, so one broken script never stops the frame or other scripts. What happens next depends on the hook:
42
+
43
+ - **Load, `init()` or `onUpdate()`**: the engine disposes the instance, sets the entry's `runtimeState` to `"error"` with the message in `runtimeMessage`, and waits about one second before it loads and initialises the script again. A script that throws on every frame therefore restarts about once a second, not 60 times.
44
+ - **Event hooks** (`onSelect`, `onUiPress`, `onGrab`, `onXRSessionStart` and the rest): the instance keeps running and the next event calls the hook again.
45
+
46
+ Either way the engine logs the first occurrence of each distinct error with `console.error`, naming the entity, class and phase. Subscribe with [`world.onScriptError`](./world-api#catch-script-errors) to receive the same reports in code.
47
+
39
48
  <!-- ## Tips
40
49
 
41
50
  - **Do not** capture `this.threeRef.object` outside hooks; the underlying `Object3D` may be replaced during hot reload.
@@ -0,0 +1,128 @@
1
+ # Bone attachments and IK
2
+
3
+ Two components make characters hold and touch things:
4
+
5
+ - **`BoneAttachmentComponent`** fixes an entity to one bone of its parent's model: a sword in a hand, a hat on the head, a backpack on the chest. It then moves with every animation.
6
+ - **`IKComponent`** bends a character's arms or legs after the animation so a hand or foot reaches a target entity: the second hand on a rifle's grip, a hand on a door handle, a foot on a step.
7
+
8
+ Both find bones by **humanoid name** (`rightHand`, `head`, `leftFoot` …) as well as by node name, so they work on Mixamo rigs, generated auto-rigs, Unreal/UAL rigs and VRM models alike.
9
+
10
+ > **Managed by:** `ObjectManagementSystem` (attachments) and `IKSystem` (IK, right after the `AnimationSystem`).
11
+
12
+ ## Attach an object to a bone
13
+
14
+ The attached entity stays a CHILD of the character (`ParentId`); the component names the bone. Its Transform becomes its **offset from the bone**: position in the character's units (metres for an unscaled character, whatever scale the rig itself uses inside), rotation relative to the bone.
15
+
16
+ Attach from a script with `ObjectManagementSystem.attachToBone`. By default the entity keeps its current place in the world, so place it in the hand first and then attach:
17
+
18
+ ```ts
19
+ import { Behaviour, type EntityInput } from "@relu-interactives/spatial-ecs";
20
+
21
+ export default class EquipSword extends Behaviour {
22
+ data = {
23
+ sword: { type: "entity", value: null } as EntityInput,
24
+ };
25
+
26
+ init() {
27
+ const swordId = this.data.sword.value;
28
+ if (swordId === null) return;
29
+ const oms = this.world.getObjectManagementSystem();
30
+ // keep the sword where it is, now riding on the right hand
31
+ const result = oms.attachToBone(this.world, swordId, this.entityId, { humanoid: "rightHand" });
32
+ if (!result.resolved) console.log("the model is still loading; the sword will attach when it has");
33
+ }
34
+ }
35
+ ```
36
+
37
+ Pass `{ preserveWorldTransform: false }` to snap the entity onto the bone (zero offset) instead, then set its Transform as the offset.
38
+
39
+ `attachToBone` accepts `{ bone: "<node name>" }` or `{ humanoid: "<humanoid name>" }`; it fills in the other half so the attachment also resolves if the character's model is swapped for another rig. List the bones of a loaded model with `listModelBones`:
40
+
41
+ ```ts
42
+ import { Behaviour } from "@relu-interactives/spatial-ecs";
43
+
44
+ export default class LogBones extends Behaviour {
45
+ init() {
46
+ const bones = this.world.getObjectManagementSystem().listModelBones(this.world, this.entityId);
47
+ for (const b of bones) console.log(b.name, b.humanoid ?? "-", "depth", b.depth);
48
+ }
49
+ }
50
+ ```
51
+
52
+ ### Detach
53
+
54
+ ```ts
55
+ import { Behaviour, type EntityInput } from "@relu-interactives/spatial-ecs";
56
+
57
+ export default class DropSword extends Behaviour {
58
+ data = {
59
+ sword: { type: "entity", value: null } as EntityInput,
60
+ };
61
+
62
+ // a "Drop" button in a spatial UI panel under this character
63
+ onUiPress() {
64
+ const swordId = this.data.sword.value;
65
+ if (swordId === null) return;
66
+ // stays where it is in the world; toRoot also unparents it from the character
67
+ this.world.getObjectManagementSystem().detachFromBone(this.world, swordId, { toRoot: true });
68
+ }
69
+ }
70
+ ```
71
+
72
+ Moving an attached entity to another parent (`setParent`) also ends its attachment.
73
+
74
+ ### What happens until the model loads
75
+
76
+ Until the parent's model has loaded, or when the named bone doesn't exist in it, the entity sits under the character as an ordinary child. The attachment is kept and takes effect as soon as the bone appears.
77
+
78
+ ## Reach for targets with IK
79
+
80
+ Add an `IKComponent` to the CHARACTER (the entity with the model) and give it one chain per limb. Each chain names the hand or foot (`limb`) and a `target` entity whose world position it reaches:
81
+
82
+ ```ts
83
+ import { Behaviour, type EntityInput } from "@relu-interactives/spatial-ecs";
84
+ import { IKComponent } from "@relu-interactives/spatial-ecs/components";
85
+
86
+ export default class TwoHandedGrip extends Behaviour {
87
+ data = {
88
+ foregrip: { type: "entity", value: null } as EntityInput,
89
+ };
90
+
91
+ init() {
92
+ const grip = this.data.foregrip.value;
93
+ if (grip === null) return;
94
+ this.world.addComponent(
95
+ this.entityId,
96
+ new IKComponent({ chains: [{ limb: "leftHand", target: grip, weight: 1 }] }),
97
+ );
98
+ }
99
+ }
100
+ ```
101
+
102
+ A typical rifle: the rifle is attached to the right hand, an empty child entity of the rifle marks the foregrip, and the left hand's chain targets that child, so the left hand stays on the gun through every animation.
103
+
104
+ Chain fields:
105
+
106
+ | Field | Meaning |
107
+ | --- | --- |
108
+ | `limb` | `"leftHand"`, `"rightHand"`, `"leftFoot"` or `"rightFoot"`. |
109
+ | `target` | Entity id the hand/foot reaches. |
110
+ | `pole` | Entity the elbow/knee bends toward; `null` keeps the animation's own bend. |
111
+ | `weight` | 0 = the animation, 1 = the target; blend in between (fade a grip in or out by animating it). |
112
+ | `matchRotation` | Also turn the hand/foot to the target's rotation. |
113
+ | `enabled` | Turn one chain off. |
114
+
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
+
117
+ Targets out of reach are reached for as far as the limb allows. Ask the system how far a limb fell short:
118
+
119
+ ```ts
120
+ import { Behaviour } from "@relu-interactives/spatial-ecs";
121
+
122
+ export default class ReachCheck extends Behaviour {
123
+ onUpdate() {
124
+ const miss = this.world.getIKSystem()?.getReachError(this.entityId, "leftHand") ?? 0;
125
+ if (miss > 0.05) console.log(`the left hand is ${miss.toFixed(2)} m short of its target`);
126
+ }
127
+ }
128
+ ```
@@ -26,20 +26,25 @@ Every entity in `@relu-interactives/spatial-ecs` is a bag of components. This ca
26
26
  - [Image](./components/image) — 2D image rendered as a textured quad.
27
27
  - [Sprite](./components/sprite) — camera-facing billboard.
28
28
  - [Video](./components/video) — video texture with optional green-screen keying.
29
- - [Model](./components/model) — GLTF/GLB asset reference loaded asynchronously.
29
+ - [Model](./components/model) — GLTF/GLB asset reference loaded asynchronously; `loadState` reports progress.
30
30
  - [Instanced Mesh](./components/instanced-mesh) — groups instance-slot entities into a single GPU-instanced draw call for high-count identical objects.
31
31
  - [Instance Slot](./components/instance-slot) — marks an entity as a single instance within an `InstancedMeshComponent` group.
32
32
 
33
33
  ## Lighting & atmosphere
34
34
 
35
35
  - [Light](./components/light) — directional, point, spot, ambient, hemisphere, or rect-area light.
36
- - [Environment](./scene/environment) — singleton skybox, fog, and gravity state.
36
+ - [Environment](./scene/environment) — singleton skybox, fog, gravity, and HDRI lighting / tone mapping state.
37
37
  - [Postprocessing](./scene/postprocessing) — singleton postprocessing stack (bloom, DoF, vignette, tonemap, etc.).
38
38
  - [Camera](./components/camera) — perspective/orthographic camera with `3d`/`ar` runtime modes.
39
39
 
40
40
  ## Audio
41
41
 
42
42
  - [Audio](./components/audio) — audio clip with positional/listener options.
43
+ - [Mixing and sound banks](./audio-mixing-and-sound-banks.md) — volume buses, music ducking, named random-take sounds.
44
+
45
+ ## Multiplayer
46
+
47
+ - [Multiplayer](./multiplayer.md) — shared entities, who owns what, `this.network`, server rules.
43
48
 
44
49
  ## Physics
45
50
 
@@ -58,4 +63,7 @@ Every entity in `@relu-interactives/spatial-ecs` is a bag of components. This ca
58
63
 
59
64
  - [Script](./components/script) — authored behaviour scripts attached to an entity.
60
65
 
66
+ ## Characters
61
67
 
68
+ - `BoneAttachmentComponent`: fixes an entity to a bone of its parent's model. See [Bone attachments and IK](./bone-attachments-and-ik).
69
+ - `IKComponent`: makes a character's hands and feet reach target entities after the animation. See [Bone attachments and IK](./bone-attachments-and-ik).
@@ -96,6 +96,48 @@ export default class LightColorCycle extends Behaviour {
96
96
  }
97
97
  ```
98
98
 
99
+ ### Tune shadow quality
100
+
101
+ three's shadow defaults suit a small demo: a 512 × 512 shadow map, and for a directional light a shadow camera that only covers a 10 m square around the light's target. In a larger level, shadows past that square vanish and the ones inside look blocky. Set `values.shadow` to fix both:
102
+
103
+ ```typescript
104
+ import { Behaviour } from "@relu-interactives/spatial-ecs";
105
+ import { LightComponent } from "@relu-interactives/spatial-ecs/components";
106
+
107
+ export default class SunShadows extends Behaviour {
108
+ init() {
109
+ const light = this.getComponent(LightComponent);
110
+ if (!light) return;
111
+
112
+ light.setValues({
113
+ castShadow: true,
114
+ shadow: {
115
+ mapSize: 2048, // texels per side; sharper but costs GPU memory
116
+ cameraSize: 25, // directional only: covers a 50 m square
117
+ near: 0.5,
118
+ far: 120,
119
+ bias: -0.0005, // removes "shadow acne" stripes
120
+ normalBias: 0.02, // helps on large flat floors
121
+ radius: 2, // softer edges (PCF shadow maps)
122
+ },
123
+ });
124
+ }
125
+ }
126
+ ```
127
+
128
+ `LightSyncSystem` writes only the fields you provide and leaves the rest at three's defaults. A light with no `shadow` block keeps every default. If you remove a field later, it returns to its default.
129
+
130
+ | Field | Applies to | Notes |
131
+ | --- | --- | --- |
132
+ | `mapSize` | directional, spot, point | Square shadow map size, clamped to 16 to 8192. Changing it frees the old map; three rebuilds it next frame. |
133
+ | `bias` | directional, spot, point | Small negative values such as `-0.0005` remove acne. Too large and shadows detach from objects. |
134
+ | `normalBias` | directional, spot, point | Offsets along the surface normal. `0.02` to `0.05` works for big flat surfaces. |
135
+ | `radius` | directional, spot, point | Edge blur for PCF shadow maps. |
136
+ | `cameraSize` | directional | Half-width of the orthographic shadow box. Make it just large enough to cover the play area; a bigger box spreads the same texels thinner. |
137
+ | `near`, `far` | directional, spot, point | Shadow camera clip planes. A spot light with a non-zero `distance` uses that distance as its far plane. |
138
+
139
+ The light must also have `castShadow: true`, and the meshes need `castShadow` / `receiveShadow` on their `MeshGeometryComponent`. Directional lights spawn with `castShadow` on.
140
+
99
141
  ::: tip Live light access
100
142
  Mutate `light.light.intensity` and `light.light.color` directly for immediate per-frame changes. For changes that should survive a save/reload cycle, also update `light.values.intensity` / `light.values.color` so the authoring state stays in sync.
101
143
  :::
@@ -8,6 +8,8 @@ References a GLTF/GLB asset loaded from `path`. The model loading system resolve
8
8
  | --- | --- | --- |
9
9
  | `path` | `string` | Source URL or `localasset://` path of the GLTF/GLB asset. |
10
10
  | `object` | `THREE.Object3D \| null` | Loaded model object, populated asynchronously by the model loader. `null` until loaded. |
11
+ | `loadState` | `ModelLoadState` | `"loading"` while the asset is being fetched and parsed, `"loaded"` once it is attached to the entity, `"error"` when it failed (see `loadError`). A model with an empty `path` reports `"error"`. Runtime-only: never saved. |
12
+ | `loadError` | `string` | Why the load failed, when `loadState` is `"error"`. Runtime-only. |
11
13
 
12
14
  ## API reference
13
15
 
@@ -33,7 +35,7 @@ if (other) {
33
35
 
34
36
  ### Fade the model in after it loads
35
37
 
36
- Wait for the async model load to complete, then animate opacity to 1 over one second.
38
+ Wait for the async model load to complete (`loadState === "loaded"`), then animate opacity to 1 over one second.
37
39
 
38
40
  ```typescript
39
41
  import { Behaviour } from "@relu-interactives/spatial-ecs";
@@ -45,7 +47,8 @@ export default class ModelFadeIn extends Behaviour {
45
47
 
46
48
  protected onUpdate() {
47
49
  const model = this.getComponent(ModelComponent);
48
- if (!model?.object) return; // wait for async load to complete
50
+ // `object` is an empty anchor until the GLB arrives, so wait on loadState.
51
+ if (!model?.object || model.loadState !== "loaded") return;
49
52
 
50
53
  if (!this.started) {
51
54
  this.started = true;
@@ -68,6 +71,32 @@ export default class ModelFadeIn extends Behaviour {
68
71
  }
69
72
  ```
70
73
 
74
+ ### Check whether the model loaded
75
+
76
+ `loadState` starts as `"loading"`, then becomes `"loaded"` once the GLB is attached to the entity, or `"error"` if the fetch or parse failed. `loadError` holds the reason. A model entity with an empty `path` reports `"error"` with the message `"No model path set."`. Neither field is saved with the project.
77
+
78
+ ```typescript
79
+ import { Behaviour } from "@relu-interactives/spatial-ecs";
80
+ import { ModelComponent } from "@relu-interactives/spatial-ecs/components";
81
+
82
+ export default class ModelLoadWatcher extends Behaviour {
83
+ private reported = false;
84
+
85
+ onUpdate() {
86
+ const model = this.getComponent(ModelComponent);
87
+ if (!model || this.reported) return;
88
+
89
+ if (model.loadState === "loaded") {
90
+ this.reported = true;
91
+ console.log("model ready", model.path);
92
+ } else if (model.loadState === "error") {
93
+ this.reported = true;
94
+ console.warn(`model failed: ${model.path}: ${model.loadError}`);
95
+ }
96
+ }
97
+ }
98
+ ```
99
+
71
100
  ### Toggle model visibility
72
101
 
73
102
  Show or hide the loaded model at runtime using the `Object3DRef` visibility flag.
@@ -93,6 +122,6 @@ export default class ModelVisibility extends Behaviour {
93
122
  ```
94
123
 
95
124
  ::: tip Async loading
96
- Always guard with `model?.object` before traversing or mutating sub-meshes. The `object` property is `null` until the GLTF/GLB asset finishes loading.
125
+ Always guard before traversing or mutating sub-meshes. Check `model.loadState === "loaded"`, or guard with `model?.object`. `object` starts as the empty anchor group, or `null` on a bare component, until the GLTF/GLB asset finishes loading.
97
126
  :::
98
127
 
@@ -17,13 +17,13 @@ See the [Component Catalog](./component-catalog) for an alphabetical list with f
17
17
 
18
18
  ## System
19
19
 
20
- A **system** queries entities by component shape and applies side effects each frame. Built-in systems handle object management, geometry, transforms, animation, rendering, and so on. As a script author you rarely interact with systems directly — you read and mutate components, and the systems do the rest.
20
+ A **system** queries entities by component shape and applies side effects each frame. Built-in systems handle object management, geometry, transforms, animation, rendering, and so on. As a script author you rarely interact with systems directly, you read and mutate components, and the systems do the rest.
21
21
 
22
22
  ## Behaviour (Scripting)
23
23
 
24
24
  A **Behaviour** is a user-authored class that runs per-frame logic on a single entity. It has full access to `world`, the entity's `transform`, its three.js `Object3D`, and helpers for hierarchy and math.
25
25
 
26
- By default, Behaviours only execute at preview or runtime. Enable the **Execute in editor** toggle on a script entry in the inspector to run the full lifecycle inside the editor as well. This gives direct access to `this.world.getScene()`, `getCamera()`, and `getRenderer()` — useful for custom shaders, procedural geometry, grass, and other Three.js features the editor palette does not expose.
26
+ By default, Behaviours only execute at preview or runtime. Enable the **Execute in editor** toggle on a script entry in the inspector to run the full lifecycle inside the editor as well. This gives direct access to `this.world.getScene()`, `getCamera()`, and `getRenderer()`, useful for custom shaders, procedural geometry, grass, and other Three.js features the editor palette does not expose.
27
27
 
28
28
  See [Custom Behaviours](./authoring-a-behaviour) and [Running scripts in the editor](./authoring-a-behaviour#running-scripts-in-the-editor).
29
29
 
@@ -46,5 +46,5 @@ Drag any asset from the [assets browser](./editor/assets-browser) into the viewp
46
46
 
47
47
  ## Next
48
48
 
49
- - [Editing inspector values](./editing-objects) — fine-tune components on selected entities.
50
- - [Spawning](../spawning/) — full reference of every spawnable kind.
49
+ - [Editing inspector values](./editing-objects) - fine-tune components on selected entities.
50
+ - [Spawning](../spawning/) - full reference of every spawnable kind.
@@ -47,7 +47,7 @@ See [Custom Behaviours](../authoring-a-behaviour) for how to declare exposed fie
47
47
 
48
48
  ## Adding components
49
49
 
50
- Click **`+ Add component`** at the bottom of the inspector to attach additional components — collider, rigidbody, audio, animation, custom script, etc.
50
+ Click **`+ Add component`** at the bottom of the inspector to attach additional components (collider, rigidbody, audio, animation, custom script, etc).
51
51
 
52
52
  ![Add Component Inspector Gif](/images/getting-started/editing-objects/editing-objects-add-component.png)
53
53
 
@@ -59,4 +59,4 @@ Every inspector edit pushes onto the undo stack. Use **⌘Z / Ctrl+Z** to revert
59
59
  ## Related
60
60
 
61
61
  - [Inspector reference](./editor/inspector).
62
- - [Component Catalog](../component-catalog) — every component and field.
62
+ - [Component Catalog](../component-catalog) - every component and field.