@needle-tools/engine 4.12.5 → 4.13.0-next.1eca7a7

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 (322) hide show
  1. package/CHANGELOG.md +5 -0
  2. package/README.md +38 -1
  3. package/components.needle.json +1 -1
  4. package/custom-elements.json +156 -5
  5. package/dist/{gltf-progressive-BqUnxvCx.umd.cjs → gltf-progressive-BURrJW0U.umd.cjs} +1 -1
  6. package/dist/{gltf-progressive-CSaX5HQb.min.js → gltf-progressive-DHLDFNvQ.min.js} +1 -1
  7. package/dist/{gltf-progressive-ChnIhDXx.js → gltf-progressive-eiJCrjLb.js} +3 -3
  8. package/dist/materialx-B9ddsHcF.min.js +90 -0
  9. package/dist/materialx-BF23AVE8.umd.cjs +90 -0
  10. package/dist/materialx-fkoFuRh3.js +4636 -0
  11. package/dist/{needle-engine.bundle-Cnemui9H.umd.cjs → needle-engine.bundle-BfrDWglE.umd.cjs} +124 -124
  12. package/dist/{needle-engine.bundle-B_IGIr6Z.min.js → needle-engine.bundle-Bx_Lq_3v.min.js} +131 -131
  13. package/dist/{needle-engine.bundle-Cj66livk.js → needle-engine.bundle-MQyZGnMF.js} +3754 -3374
  14. package/dist/needle-engine.d.ts +2791 -309
  15. package/dist/needle-engine.js +415 -414
  16. package/dist/needle-engine.min.js +1 -1
  17. package/dist/needle-engine.umd.cjs +1 -1
  18. package/dist/{postprocessing-12-UW7je.min.js → postprocessing-BVNrgYZK.min.js} +1 -1
  19. package/dist/{postprocessing-B3Hu0Ryi.umd.cjs → postprocessing-CI2TjWpu.umd.cjs} +1 -1
  20. package/dist/{postprocessing-R535krvT.js → postprocessing-DdM-tz1j.js} +2 -2
  21. package/dist/{three-BzxwLtUE.umd.cjs → three-BW2s1Yl-.umd.cjs} +25 -25
  22. package/dist/{three-DMvLgxja.min.js → three-I__hSXzr.min.js} +26 -26
  23. package/dist/{three-D9pcFbxc.js → three-VvRoMeIN.js} +22 -0
  24. package/dist/{three-examples-F0MJj0vr.js → three-examples-BhfOE7NG.js} +1 -1
  25. package/dist/{three-examples-CjSwCv_b.umd.cjs → three-examples-Bpfu6ke_.umd.cjs} +1 -1
  26. package/dist/{three-examples-CIv2roOA.min.js → three-examples-D8zAE_7t.min.js} +1 -1
  27. package/dist/{three-mesh-ui-BLnJQzMl.umd.cjs → three-mesh-ui-BU55xDxJ.umd.cjs} +1 -1
  28. package/dist/{three-mesh-ui-BllgajJz.min.js → three-mesh-ui-C3QbemOV.min.js} +1 -1
  29. package/dist/{three-mesh-ui-DYyiRn5Y.js → three-mesh-ui-CcMp-FQm.js} +1 -1
  30. package/dist/{vendor-BIFy-gRe.js → vendor-BiyIZ61v.js} +1 -1
  31. package/dist/{vendor-BFgQSG2m.umd.cjs → vendor-COVQl0b8.umd.cjs} +1 -1
  32. package/dist/{vendor-ChgmXMYr.min.js → vendor-DW7zqjuT.min.js} +1 -1
  33. package/lib/engine/engine_context.d.ts +16 -0
  34. package/lib/engine/engine_context.js +16 -0
  35. package/lib/engine/engine_context.js.map +1 -1
  36. package/lib/engine/engine_gameobject.d.ts +72 -0
  37. package/lib/engine/engine_gameobject.js +38 -0
  38. package/lib/engine/engine_gameobject.js.map +1 -1
  39. package/lib/engine/engine_input.d.ts +80 -4
  40. package/lib/engine/engine_input.js +78 -2
  41. package/lib/engine/engine_input.js.map +1 -1
  42. package/lib/engine/engine_loaders.js +7 -1
  43. package/lib/engine/engine_loaders.js.map +1 -1
  44. package/lib/engine/engine_math.d.ts +81 -2
  45. package/lib/engine/engine_math.js +68 -2
  46. package/lib/engine/engine_math.js.map +1 -1
  47. package/lib/engine/engine_modules.d.ts +9 -0
  48. package/lib/engine/engine_modules.js +25 -0
  49. package/lib/engine/engine_modules.js.map +1 -1
  50. package/lib/engine/engine_networking.d.ts +181 -14
  51. package/lib/engine/engine_networking.js +181 -14
  52. package/lib/engine/engine_networking.js.map +1 -1
  53. package/lib/engine/engine_networking_auto.d.ts +35 -8
  54. package/lib/engine/engine_networking_auto.js +35 -8
  55. package/lib/engine/engine_networking_auto.js.map +1 -1
  56. package/lib/engine/engine_physics.d.ts +35 -1
  57. package/lib/engine/engine_physics.js +35 -1
  58. package/lib/engine/engine_physics.js.map +1 -1
  59. package/lib/engine/engine_physics_rapier.d.ts +76 -0
  60. package/lib/engine/engine_physics_rapier.js +76 -0
  61. package/lib/engine/engine_physics_rapier.js.map +1 -1
  62. package/lib/engine/engine_serialization_decorator.d.ts +28 -2
  63. package/lib/engine/engine_serialization_decorator.js +28 -2
  64. package/lib/engine/engine_serialization_decorator.js.map +1 -1
  65. package/lib/engine/engine_time.d.ts +23 -3
  66. package/lib/engine/engine_time.js +23 -3
  67. package/lib/engine/engine_time.js.map +1 -1
  68. package/lib/engine/engine_util_decorator.d.ts +31 -1
  69. package/lib/engine/engine_util_decorator.js +31 -1
  70. package/lib/engine/engine_util_decorator.js.map +1 -1
  71. package/lib/engine/engine_utils.d.ts +21 -5
  72. package/lib/engine/engine_utils.js +21 -5
  73. package/lib/engine/engine_utils.js.map +1 -1
  74. package/lib/engine/engine_utils_format.d.ts +1 -1
  75. package/lib/engine/engine_utils_format.js +4 -1
  76. package/lib/engine/engine_utils_format.js.map +1 -1
  77. package/lib/engine/extensions/NEEDLE_materialx.d.ts +29 -0
  78. package/lib/engine/extensions/NEEDLE_materialx.js +115 -0
  79. package/lib/engine/extensions/NEEDLE_materialx.js.map +1 -0
  80. package/lib/engine/extensions/extensions.js +2 -0
  81. package/lib/engine/extensions/extensions.js.map +1 -1
  82. package/lib/engine/extensions/index.d.ts +1 -0
  83. package/lib/engine/extensions/index.js +1 -0
  84. package/lib/engine/extensions/index.js.map +1 -1
  85. package/lib/engine-components/AlignmentConstraint.d.ts +23 -3
  86. package/lib/engine-components/AlignmentConstraint.js +23 -3
  87. package/lib/engine-components/AlignmentConstraint.js.map +1 -1
  88. package/lib/engine-components/Animation.d.ts +42 -0
  89. package/lib/engine-components/Animation.js +36 -0
  90. package/lib/engine-components/Animation.js.map +1 -1
  91. package/lib/engine-components/Animator.d.ts +37 -4
  92. package/lib/engine-components/Animator.js +37 -4
  93. package/lib/engine-components/Animator.js.map +1 -1
  94. package/lib/engine-components/AudioSource.d.ts +32 -10
  95. package/lib/engine-components/AudioSource.js +32 -10
  96. package/lib/engine-components/AudioSource.js.map +1 -1
  97. package/lib/engine-components/AxesHelper.d.ts +22 -3
  98. package/lib/engine-components/AxesHelper.js +22 -3
  99. package/lib/engine-components/AxesHelper.js.map +1 -1
  100. package/lib/engine-components/BasicIKConstraint.d.ts +27 -4
  101. package/lib/engine-components/BasicIKConstraint.js +27 -4
  102. package/lib/engine-components/BasicIKConstraint.js.map +1 -1
  103. package/lib/engine-components/Camera.d.ts +31 -1
  104. package/lib/engine-components/Camera.js +31 -1
  105. package/lib/engine-components/Camera.js.map +1 -1
  106. package/lib/engine-components/CharacterController.d.ts +67 -3
  107. package/lib/engine-components/CharacterController.js +67 -3
  108. package/lib/engine-components/CharacterController.js.map +1 -1
  109. package/lib/engine-components/Collider.d.ts +69 -12
  110. package/lib/engine-components/Collider.js +69 -12
  111. package/lib/engine-components/Collider.js.map +1 -1
  112. package/lib/engine-components/ContactShadows.d.ts +26 -6
  113. package/lib/engine-components/ContactShadows.js +46 -8
  114. package/lib/engine-components/ContactShadows.js.map +1 -1
  115. package/lib/engine-components/DeleteBox.d.ts +43 -2
  116. package/lib/engine-components/DeleteBox.js +43 -2
  117. package/lib/engine-components/DeleteBox.js.map +1 -1
  118. package/lib/engine-components/DeviceFlag.d.ts +21 -2
  119. package/lib/engine-components/DeviceFlag.js +21 -2
  120. package/lib/engine-components/DeviceFlag.js.map +1 -1
  121. package/lib/engine-components/DragControls.d.ts +32 -2
  122. package/lib/engine-components/DragControls.js +32 -2
  123. package/lib/engine-components/DragControls.js.map +1 -1
  124. package/lib/engine-components/DropListener.d.ts +33 -21
  125. package/lib/engine-components/DropListener.js +33 -21
  126. package/lib/engine-components/DropListener.js.map +1 -1
  127. package/lib/engine-components/Duplicatable.d.ts +36 -5
  128. package/lib/engine-components/Duplicatable.js +36 -5
  129. package/lib/engine-components/Duplicatable.js.map +1 -1
  130. package/lib/engine-components/EventList.d.ts +38 -10
  131. package/lib/engine-components/EventList.js +38 -10
  132. package/lib/engine-components/EventList.js.map +1 -1
  133. package/lib/engine-components/Fog.d.ts +23 -1
  134. package/lib/engine-components/Fog.js +23 -1
  135. package/lib/engine-components/Fog.js.map +1 -1
  136. package/lib/engine-components/GridHelper.d.ts +18 -2
  137. package/lib/engine-components/GridHelper.js +18 -2
  138. package/lib/engine-components/GridHelper.js.map +1 -1
  139. package/lib/engine-components/GroundProjection.d.ts +24 -2
  140. package/lib/engine-components/GroundProjection.js +24 -2
  141. package/lib/engine-components/GroundProjection.js.map +1 -1
  142. package/lib/engine-components/Interactable.d.ts +17 -2
  143. package/lib/engine-components/Interactable.js +17 -2
  144. package/lib/engine-components/Interactable.js.map +1 -1
  145. package/lib/engine-components/Joints.d.ts +50 -7
  146. package/lib/engine-components/Joints.js +50 -7
  147. package/lib/engine-components/Joints.js.map +1 -1
  148. package/lib/engine-components/LODGroup.d.ts +36 -14
  149. package/lib/engine-components/LODGroup.js +43 -11
  150. package/lib/engine-components/LODGroup.js.map +1 -1
  151. package/lib/engine-components/Light.d.ts +27 -5
  152. package/lib/engine-components/Light.js +27 -5
  153. package/lib/engine-components/Light.js.map +1 -1
  154. package/lib/engine-components/LookAtConstraint.d.ts +22 -7
  155. package/lib/engine-components/LookAtConstraint.js +22 -7
  156. package/lib/engine-components/LookAtConstraint.js.map +1 -1
  157. package/lib/engine-components/NeedleMenu.d.ts +27 -5
  158. package/lib/engine-components/NeedleMenu.js +27 -5
  159. package/lib/engine-components/NeedleMenu.js.map +1 -1
  160. package/lib/engine-components/NestedGltf.d.ts +39 -4
  161. package/lib/engine-components/NestedGltf.js +42 -4
  162. package/lib/engine-components/NestedGltf.js.map +1 -1
  163. package/lib/engine-components/OffsetConstraint.d.ts +27 -3
  164. package/lib/engine-components/OffsetConstraint.js +27 -3
  165. package/lib/engine-components/OffsetConstraint.js.map +1 -1
  166. package/lib/engine-components/OrbitControls.d.ts +41 -3
  167. package/lib/engine-components/OrbitControls.js +41 -3
  168. package/lib/engine-components/OrbitControls.js.map +1 -1
  169. package/lib/engine-components/ReflectionProbe.d.ts +17 -2
  170. package/lib/engine-components/ReflectionProbe.js +28 -10
  171. package/lib/engine-components/ReflectionProbe.js.map +1 -1
  172. package/lib/engine-components/Renderer.d.ts +34 -0
  173. package/lib/engine-components/Renderer.js +35 -2
  174. package/lib/engine-components/Renderer.js.map +1 -1
  175. package/lib/engine-components/SceneSwitcher.d.ts +11 -0
  176. package/lib/engine-components/SceneSwitcher.js +11 -0
  177. package/lib/engine-components/SceneSwitcher.js.map +1 -1
  178. package/lib/engine-components/ScreenCapture.d.ts +38 -6
  179. package/lib/engine-components/ScreenCapture.js +38 -6
  180. package/lib/engine-components/ScreenCapture.js.map +1 -1
  181. package/lib/engine-components/Skybox.js +1 -1
  182. package/lib/engine-components/Skybox.js.map +1 -1
  183. package/lib/engine-components/SmoothFollow.d.ts +66 -7
  184. package/lib/engine-components/SmoothFollow.js +66 -7
  185. package/lib/engine-components/SmoothFollow.js.map +1 -1
  186. package/lib/engine-components/SpatialTrigger.d.ts +48 -1
  187. package/lib/engine-components/SpatialTrigger.js +48 -1
  188. package/lib/engine-components/SpatialTrigger.js.map +1 -1
  189. package/lib/engine-components/SpectatorCamera.d.ts +21 -3
  190. package/lib/engine-components/SpectatorCamera.js +21 -3
  191. package/lib/engine-components/SpectatorCamera.js.map +1 -1
  192. package/lib/engine-components/SyncedRoom.d.ts +6 -0
  193. package/lib/engine-components/SyncedRoom.js +6 -0
  194. package/lib/engine-components/SyncedRoom.js.map +1 -1
  195. package/lib/engine-components/SyncedTransform.d.ts +55 -6
  196. package/lib/engine-components/SyncedTransform.js +55 -6
  197. package/lib/engine-components/SyncedTransform.js.map +1 -1
  198. package/lib/engine-components/TransformGizmo.d.ts +30 -3
  199. package/lib/engine-components/TransformGizmo.js +30 -3
  200. package/lib/engine-components/TransformGizmo.js.map +1 -1
  201. package/lib/engine-components/VideoPlayer.d.ts +33 -6
  202. package/lib/engine-components/VideoPlayer.js +45 -6
  203. package/lib/engine-components/VideoPlayer.js.map +1 -1
  204. package/lib/engine-components/Voip.d.ts +33 -2
  205. package/lib/engine-components/Voip.js +33 -2
  206. package/lib/engine-components/Voip.js.map +1 -1
  207. package/lib/engine-components/export/usdz/USDZExporter.d.ts +47 -13
  208. package/lib/engine-components/export/usdz/USDZExporter.js +47 -13
  209. package/lib/engine-components/export/usdz/USDZExporter.js.map +1 -1
  210. package/lib/engine-components/particlesystem/ParticleSystem.d.ts +82 -3
  211. package/lib/engine-components/particlesystem/ParticleSystem.js +82 -3
  212. package/lib/engine-components/particlesystem/ParticleSystem.js.map +1 -1
  213. package/lib/engine-components/timeline/PlayableDirector.d.ts +99 -14
  214. package/lib/engine-components/timeline/PlayableDirector.js +91 -25
  215. package/lib/engine-components/timeline/PlayableDirector.js.map +1 -1
  216. package/lib/engine-components/ui/Button.d.ts +29 -3
  217. package/lib/engine-components/ui/Button.js +29 -3
  218. package/lib/engine-components/ui/Button.js.map +1 -1
  219. package/lib/engine-components/ui/Canvas.d.ts +28 -3
  220. package/lib/engine-components/ui/Canvas.js +28 -3
  221. package/lib/engine-components/ui/Canvas.js.map +1 -1
  222. package/lib/engine-components/ui/Image.d.ts +22 -3
  223. package/lib/engine-components/ui/Image.js +22 -3
  224. package/lib/engine-components/ui/Image.js.map +1 -1
  225. package/lib/engine-components/ui/Raycaster.d.ts +55 -6
  226. package/lib/engine-components/ui/Raycaster.js +55 -6
  227. package/lib/engine-components/ui/Raycaster.js.map +1 -1
  228. package/lib/engine-components/ui/Text.d.ts +23 -1
  229. package/lib/engine-components/ui/Text.js +23 -1
  230. package/lib/engine-components/ui/Text.js.map +1 -1
  231. package/lib/engine-components/webxr/TeleportTarget.d.ts +21 -2
  232. package/lib/engine-components/webxr/TeleportTarget.js +21 -2
  233. package/lib/engine-components/webxr/TeleportTarget.js.map +1 -1
  234. package/lib/engine-components/webxr/WebXR.d.ts +10 -2
  235. package/lib/engine-components/webxr/WebXR.js +10 -2
  236. package/lib/engine-components/webxr/WebXR.js.map +1 -1
  237. package/lib/engine-components/webxr/WebXRAvatar.d.ts +39 -2
  238. package/lib/engine-components/webxr/WebXRAvatar.js +35 -3
  239. package/lib/engine-components/webxr/WebXRAvatar.js.map +1 -1
  240. package/lib/engine-components/webxr/WebXRImageTracking.d.ts +266 -30
  241. package/lib/engine-components/webxr/WebXRImageTracking.js +266 -30
  242. package/lib/engine-components/webxr/WebXRImageTracking.js.map +1 -1
  243. package/lib/engine-components/webxr/XRFlag.d.ts +29 -2
  244. package/lib/engine-components/webxr/XRFlag.js +29 -2
  245. package/lib/engine-components/webxr/XRFlag.js.map +1 -1
  246. package/package.json +3 -2
  247. package/plugins/vite/custom-element-data.js +128 -19
  248. package/plugins/vite/dependencies.js +9 -4
  249. package/plugins/vite/index.js +0 -2
  250. package/src/engine/engine_context.ts +16 -0
  251. package/src/engine/engine_gameobject.ts +73 -0
  252. package/src/engine/engine_input.ts +83 -7
  253. package/src/engine/engine_loaders.ts +9 -2
  254. package/src/engine/engine_math.ts +81 -2
  255. package/src/engine/engine_modules.ts +24 -0
  256. package/src/engine/engine_networking.ts +187 -17
  257. package/src/engine/engine_networking_auto.ts +36 -9
  258. package/src/engine/engine_physics.ts +37 -1
  259. package/src/engine/engine_physics_rapier.ts +77 -0
  260. package/src/engine/engine_serialization_decorator.ts +28 -2
  261. package/src/engine/engine_time.ts +23 -3
  262. package/src/engine/engine_util_decorator.ts +31 -1
  263. package/src/engine/engine_utils.ts +21 -5
  264. package/src/engine/engine_utils_format.ts +6 -2
  265. package/src/engine/extensions/NEEDLE_materialx.ts +143 -0
  266. package/src/engine/extensions/extensions.ts +2 -0
  267. package/src/engine/extensions/index.ts +1 -0
  268. package/src/engine-components/AlignmentConstraint.ts +24 -4
  269. package/src/engine-components/Animation.ts +44 -2
  270. package/src/engine-components/Animator.ts +40 -7
  271. package/src/engine-components/AudioSource.ts +37 -15
  272. package/src/engine-components/AxesHelper.ts +23 -4
  273. package/src/engine-components/BasicIKConstraint.ts +28 -5
  274. package/src/engine-components/Camera.ts +33 -3
  275. package/src/engine-components/CharacterController.ts +73 -6
  276. package/src/engine-components/Collider.ts +78 -21
  277. package/src/engine-components/ContactShadows.ts +51 -11
  278. package/src/engine-components/DeleteBox.ts +43 -2
  279. package/src/engine-components/DeviceFlag.ts +22 -3
  280. package/src/engine-components/DragControls.ts +32 -2
  281. package/src/engine-components/DropListener.ts +42 -29
  282. package/src/engine-components/Duplicatable.ts +37 -6
  283. package/src/engine-components/EventList.ts +41 -13
  284. package/src/engine-components/Fog.ts +23 -1
  285. package/src/engine-components/GridHelper.ts +18 -2
  286. package/src/engine-components/GroundProjection.ts +25 -3
  287. package/src/engine-components/Interactable.ts +17 -2
  288. package/src/engine-components/Joints.ts +51 -8
  289. package/src/engine-components/LODGroup.ts +45 -11
  290. package/src/engine-components/Light.ts +30 -8
  291. package/src/engine-components/LookAtConstraint.ts +26 -8
  292. package/src/engine-components/NeedleMenu.ts +29 -7
  293. package/src/engine-components/NestedGltf.ts +40 -4
  294. package/src/engine-components/OffsetConstraint.ts +27 -3
  295. package/src/engine-components/OrbitControls.ts +41 -3
  296. package/src/engine-components/ReflectionProbe.ts +31 -13
  297. package/src/engine-components/Renderer.ts +34 -1
  298. package/src/engine-components/SceneSwitcher.ts +11 -0
  299. package/src/engine-components/ScreenCapture.ts +41 -9
  300. package/src/engine-components/Skybox.ts +1 -1
  301. package/src/engine-components/SmoothFollow.ts +69 -7
  302. package/src/engine-components/SpatialTrigger.ts +51 -4
  303. package/src/engine-components/SpectatorCamera.ts +23 -5
  304. package/src/engine-components/SyncedRoom.ts +6 -0
  305. package/src/engine-components/SyncedTransform.ts +59 -10
  306. package/src/engine-components/TransformGizmo.ts +31 -4
  307. package/src/engine-components/VideoPlayer.ts +48 -6
  308. package/src/engine-components/Voip.ts +33 -2
  309. package/src/engine-components/export/usdz/USDZExporter.ts +47 -13
  310. package/src/engine-components/particlesystem/ParticleSystem.ts +84 -5
  311. package/src/engine-components/timeline/PlayableDirector.ts +104 -27
  312. package/src/engine-components/ui/Button.ts +29 -3
  313. package/src/engine-components/ui/Canvas.ts +28 -3
  314. package/src/engine-components/ui/Image.ts +22 -3
  315. package/src/engine-components/ui/Raycaster.ts +57 -8
  316. package/src/engine-components/ui/Text.ts +24 -2
  317. package/src/engine-components/webxr/TeleportTarget.ts +23 -4
  318. package/src/engine-components/webxr/WebXR.ts +11 -3
  319. package/src/engine-components/webxr/WebXRAvatar.ts +41 -4
  320. package/src/engine-components/webxr/WebXRImageTracking.ts +282 -38
  321. package/src/engine-components/webxr/XRFlag.ts +30 -3
  322. package/plugins/vite/materialx.js +0 -32
@@ -8,6 +8,30 @@
8
8
  */
9
9
  export namespace MODULES {
10
10
 
11
+ export namespace MaterialX {
12
+ export type TYPE = typeof import("@needle-tools/materialx");
13
+ export let MODULE: TYPE;
14
+ export let MAYBEMODULE: TYPE | null = null;
15
+
16
+ const callbacks: Array<(module: TYPE) => void> = [];
17
+ /** Wait for the module to be loaded (doesn't trigger a load) */
18
+ export function ready(): Promise<TYPE> {
19
+ if (MODULE) return Promise.resolve(MODULE);
20
+ return new Promise((resolve) => { callbacks.push(resolve); });
21
+ };
22
+ /** Load the module */
23
+ export async function load(): Promise<TYPE> {
24
+ if (MODULE) return MODULE;
25
+ const module = await import("@needle-tools/materialx");
26
+ MODULE = module;
27
+ MAYBEMODULE = module;
28
+ callbacks.forEach((callback) => callback(module));
29
+ callbacks.length = 0;
30
+ return module;
31
+ }
32
+
33
+ }
34
+
11
35
  export namespace RAPIER_PHYSICS {
12
36
  export type TYPE = typeof import("@dimforge/rapier3d-compat");
13
37
  export let MODULE: TYPE;
@@ -4,6 +4,9 @@ let networkingServerUrl: string | undefined = "wss://networking.needle.tools/soc
4
4
  import * as flatbuffers from 'flatbuffers';
5
5
  import { type Websocket } from 'websocket-ts';
6
6
 
7
+ import type { SyncedRoom } from "../engine-components/SyncedRoom.js";
8
+ import type { Networking } from "../engine-components/Networking.js";
9
+
7
10
  import * as schemes from "../engine-schemes/schemes.js";
8
11
  import { isDevEnvironment } from './debug/index.js';
9
12
  import { Telemetry } from './engine_license.js';
@@ -116,27 +119,95 @@ declare type OwnershipResponse = {
116
119
 
117
120
  declare type WebsocketSendType = IModel | object | boolean | null | string | number;
118
121
 
119
- /** Class for abstracting the concept of ownership regarding a networked object or component.
120
- * A component that is owned by another user can not be modified through networking (the server will reject changes) */
122
+ /**
123
+ * Manages ownership of networked objects or components.
124
+ *
125
+ * In multiplayer scenarios, ownership determines which client has authority to modify an object.
126
+ * The networking server rejects changes from clients that don't own an object. This prevents conflicts
127
+ * when multiple users try to manipulate the same object simultaneously.
128
+ *
129
+ * **Ownership states:**
130
+ * - `hasOwnership`: This client owns the object and can modify it
131
+ * - `isOwned`: Some client (could be local or remote) owns the object
132
+ * - `undefined`: Ownership state is unknown (not yet queried)
133
+ *
134
+ * **Typical workflow:**
135
+ * 1. Request ownership before modifying an object
136
+ * 2. Make your changes while you have ownership
137
+ * 3. Free ownership when done (or keep it if still interacting)
138
+ *
139
+ * @example Basic usage
140
+ * ```ts
141
+ * export class MyComponent extends Behaviour {
142
+ * private ownership?: OwnershipModel;
143
+ *
144
+ * awake() {
145
+ * this.ownership = new OwnershipModel(this.context.connection, this.guid);
146
+ * }
147
+ *
148
+ * onClick() {
149
+ * // Request ownership before modifying the object
150
+ * this.ownership.requestOwnership();
151
+ * }
152
+ *
153
+ * update() {
154
+ * if (this.ownership.hasOwnership) {
155
+ * // Safe to modify and sync the object
156
+ * this.gameObject.position.y += 0.01;
157
+ * }
158
+ * }
159
+ *
160
+ * onDisable() {
161
+ * // Release ownership when done
162
+ * this.ownership.freeOwnership();
163
+ * this.ownership.destroy();
164
+ * }
165
+ * }
166
+ * ```
167
+ *
168
+ * @example Async ownership
169
+ * ```ts
170
+ * async modifyObject() {
171
+ * try {
172
+ * await this.ownership.requestOwnershipAsync();
173
+ * // Now guaranteed to have ownership
174
+ * this.transform.position.x = 5;
175
+ * } catch(e) {
176
+ * console.log("Failed to gain ownership");
177
+ * }
178
+ * }
179
+ * ```
180
+ *
181
+ * @see {@link SyncedTransform} for a complete example of ownership in action
182
+ * @link https://engine.needle.tools/docs/networking.html
183
+ */
121
184
  export class OwnershipModel {
122
185
 
186
+ /** The unique identifier (GUID) of the object this ownership model manages */
123
187
  public guid: string;
124
188
  private connection: NetworkConnection;
125
189
 
190
+ /**
191
+ * Checks if the local client has ownership of this object.
192
+ * @returns `true` if this client owns the object and can modify it, `false` otherwise
193
+ */
126
194
  public get hasOwnership(): boolean {
127
195
  return this._hasOwnership;
128
196
  }
129
197
 
130
198
  // TODO: server should just send id to everyone
131
199
 
132
- /** @returns true of anyone has ownership */
200
+ /**
201
+ * Checks if anyone (local or remote client) has ownership of this object.
202
+ * @returns `true` if someone owns the object, `false` if no one owns it, `undefined` if unknown
203
+ */
133
204
  public get isOwned(): boolean | undefined {
134
205
  return this._isOwned;
135
206
  }
136
207
 
137
- /**
208
+ /**
138
209
  * Checks if Needle Engine networking is connected to a websocket. Note that this is **not equal** to being connected to a *room*. If you want to check if Needle Engine is connected to a networking room use the `isInRoom` property.
139
- * @returns true if connected to the websocket.
210
+ * @returns true if connected to the websocket.
140
211
  */
141
212
  public get isConnected(): boolean {
142
213
  return this.connection.isConnected;
@@ -162,6 +233,10 @@ export class OwnershipModel {
162
233
 
163
234
  private _isWaitingForOwnershipResponseCallback: Function | null = null;
164
235
 
236
+ /**
237
+ * Queries the server to update the `isOwned` state.
238
+ * Call this to check if anyone currently has ownership.
239
+ */
165
240
  public updateIsOwned() {
166
241
  this.connection.send(OwnershipEvent.RequestHasOwner, { guid: this.guid });
167
242
  }
@@ -172,6 +247,11 @@ export class OwnershipModel {
172
247
  }
173
248
  }
174
249
 
250
+ /**
251
+ * Requests ownership only if the object is not currently owned by anyone.
252
+ * Internally checks ownership state first, then requests ownership if free.
253
+ * @returns this OwnershipModel instance for method chaining
254
+ */
175
255
  public requestOwnershipIfNotOwned(): OwnershipModel {
176
256
  if (this._isWaitingForOwnershipResponseCallback !== null) return this;
177
257
  this._isWaitingForOwnershipResponseCallback = this.waitForHasOwnershipRequestResponse.bind(this);
@@ -197,6 +277,20 @@ export class OwnershipModel {
197
277
  }
198
278
 
199
279
 
280
+ /**
281
+ * Requests ownership and waits asynchronously until ownership is granted or timeout occurs.
282
+ * @returns Promise that resolves with this OwnershipModel when ownership is gained
283
+ * @throws Rejects with "Timeout" if ownership is not gained within ~1 second
284
+ * @example
285
+ * ```ts
286
+ * try {
287
+ * await ownership.requestOwnershipAsync();
288
+ * // Ownership granted, safe to modify object
289
+ * } catch(e) {
290
+ * console.warn("Could not gain ownership:", e);
291
+ * }
292
+ * ```
293
+ */
200
294
  public requestOwnershipAsync(): Promise<OwnershipModel> {
201
295
  return new Promise((resolve, reject) => {
202
296
  this.requestOwnership();
@@ -212,12 +306,22 @@ export class OwnershipModel {
212
306
  });
213
307
  }
214
308
 
309
+ /**
310
+ * Requests ownership of this object from the networking server.
311
+ * Ownership may not be granted immediately - check `hasOwnership` property or use `requestOwnershipAsync()`.
312
+ * @returns this OwnershipModel instance for method chaining
313
+ */
215
314
  public requestOwnership(): OwnershipModel {
216
315
  if (debugOwner) console.log("Request ownership", this.guid);
217
316
  this.connection.send(OwnershipEvent.RequestOwnership, { guid: this.guid });
218
317
  return this;
219
318
  }
220
319
 
320
+ /**
321
+ * Releases ownership of this object, allowing others to take control.
322
+ * Call this when you're done modifying an object to allow other users to interact with it.
323
+ * @returns this OwnershipModel instance for method chaining
324
+ */
221
325
  public freeOwnership(): OwnershipModel {
222
326
  // TODO: abort "requestOwnershipIfNotOwned"
223
327
  this.connection.send(OwnershipEvent.RemoveOwnership, { guid: this.guid });
@@ -228,6 +332,10 @@ export class OwnershipModel {
228
332
  return this;
229
333
  }
230
334
 
335
+ /**
336
+ * Cleans up event listeners and resources.
337
+ * Call this when the OwnershipModel is no longer needed (e.g., in `onDestroy()`).
338
+ */
231
339
  public destroy() {
232
340
  this.connection.stopListen(OwnershipEvent.GainedOwnership, this._gainSubscription);
233
341
  this.connection.stopListen(OwnershipEvent.LostOwnership, this._lostSubscription);
@@ -265,10 +373,46 @@ export declare type BinaryCallback = {
265
373
  (data: any | flatbuffers.ByteBuffer): void;
266
374
  }
267
375
 
268
- /** Main class to communicate with the networking backend
269
- * @link https://engine.needle.tools/docs/networking.html
270
- *
271
- */
376
+ /**
377
+ * Main class for multiuser networking. Access via `this.context.connection` from any component.
378
+ *
379
+ * **About GUIDs:**
380
+ * In Needle Engine networking, GUIDs (Globally Unique Identifiers) are used to identify objects and components across the network.
381
+ * Every GameObject and Component has a unique `guid` property that remains consistent across all clients.
382
+ * GUIDs are automatically assigned (e.g. during export from Unity/Blender) and are essential for:
383
+ * - Object ownership management (see {@link OwnershipModel})
384
+ * - State synchronization (storing and retrieving object state)
385
+ * - Identifying which object received a network message
386
+ *
387
+ * When working with networking, you'll typically use `this.guid` to identify your component or `this.gameObject.guid` for the GameObject.
388
+ *
389
+ * @example Joining a room
390
+ * ```ts
391
+ * this.context.connection.connect();
392
+ * this.context.connection.joinRoom("my-room");
393
+ * ```
394
+ * @example Listening to events
395
+ * ```ts
396
+ * this.context.connection.beginListen("my-event", (data) => {
397
+ * console.log("Received:", data);
398
+ * });
399
+ * ```
400
+ * @example Sending data
401
+ * ```ts
402
+ * this.context.connection.send("my-event", { message: "Hello" });
403
+ * ```
404
+ * @example Using GUIDs for object identification
405
+ * ```ts
406
+ * // Get state for a specific object by its GUID
407
+ * const state = this.context.connection.tryGetState(this.guid);
408
+ *
409
+ * // Delete remote state for an object
410
+ * this.context.connection.sendDeleteRemoteState(this.guid);
411
+ * ```
412
+ * @see {@link RoomEvents} for room lifecycle events
413
+ * @see {@link OwnershipModel} for object ownership
414
+ * @link https://engine.needle.tools/docs/how-to-guides/networking/
415
+ */
272
416
  export class NetworkConnection implements INetworkConnection {
273
417
 
274
418
  private context: Context;
@@ -287,7 +431,18 @@ export class NetworkConnection implements INetworkConnection {
287
431
  }
288
432
 
289
433
  /**
290
- * Returns the state of a given guid.
434
+ * Returns the cached network state for a given GUID.
435
+ * The state is stored locally whenever network updates are received for that object.
436
+ * @param guid The unique identifier of the object whose state you want to retrieve
437
+ * @returns The cached state object, or `null` if no state exists for this GUID
438
+ * @example
439
+ * ```ts
440
+ * // Get the last known state for this component
441
+ * const myState = this.context.connection.tryGetState(this.guid);
442
+ * if (myState) {
443
+ * console.log("Found cached state:", myState);
444
+ * }
445
+ * ```
291
446
  */
292
447
  public tryGetState(guid: string): IModel | null {
293
448
  if (guid === "invalid") return null;
@@ -307,7 +462,7 @@ export class NetworkConnection implements INetworkConnection {
307
462
  }
308
463
 
309
464
  /**
310
- * Checks if Needle Engine networking is connected to a websocket. Note that this is **not equal** to being connected to a *room*. If you want to check if Needle Engine is connected to a networking room use the `isInRoom` property.
465
+ * Checks if Needle Engine networking is connected to a websocket. Note that this is **not equal** to being connected to a *room*. If you want to check if Needle Engine is connected to a networking room use the `{@link isInRoom}` property.
311
466
  * @returns true if connected to the websocket.
312
467
  */
313
468
  public get isConnected(): boolean {
@@ -372,7 +527,7 @@ export class NetworkConnection implements INetworkConnection {
372
527
  return target;
373
528
  }
374
529
 
375
- /** Joins a networked room. If you don't want to manage a connection yourself you can use a `SyncedRoom` component as well */
530
+ /** Joins a networked room. If you don't want to manage a connection yourself you can use a `{@link SyncedRoom}` component as well */
376
531
  public joinRoom(room: string, viewOnly: boolean = false): boolean {
377
532
  if (!room) {
378
533
  console.error("Missing room name, can not join: \"" + room + "\"");
@@ -426,7 +581,18 @@ export class NetworkConnection implements INetworkConnection {
426
581
  return this.sendWithWebsocket(key, data, queue);
427
582
  }
428
583
 
429
- /** Use to delete state for a given guid on the server */
584
+ /**
585
+ * Deletes the network state for a specific object on the server.
586
+ * This removes the object's state from the room, preventing it from being sent to newly joining users.
587
+ * @param guid The unique identifier of the object whose state should be deleted
588
+ * @example
589
+ * ```ts
590
+ * // When destroying a networked object, clean up its server state
591
+ * onDestroy() {
592
+ * this.context.connection.sendDeleteRemoteState(this.guid);
593
+ * }
594
+ * ```
595
+ */
430
596
  public sendDeleteRemoteState(guid: string) {
431
597
  this.send("delete-state", { guid: guid, dontSave: true });
432
598
  delete this._state[guid];
@@ -469,7 +635,7 @@ export class NetworkConnection implements INetworkConnection {
469
635
  }
470
636
 
471
637
  /** Use to start listening to networking events.
472
- * To unsubscribe from events use the `stopListen` method.
638
+ * To unsubscribe from events use the `{@link stopListen}` method.
473
639
  * See the example below for typical usage:
474
640
  *
475
641
  * ### Component Example
@@ -501,7 +667,7 @@ export class NetworkConnection implements INetworkConnection {
501
667
  public stopListening(key: (string & {}) | OwnershipEvent | OwnershipEventNamesIncoming | RoomEventsIncoming | RoomEvents, callback: Function | null) { return this.stopListen(key, callback); }
502
668
 
503
669
  /** Use to stop listening to networking events
504
- * To subscribe to events use the `beginListen` method.
670
+ * To subscribe to events use the `{@link beginListen}` method.
505
671
  * See the example below for typical usage:
506
672
  *
507
673
  * ### Component Example
@@ -548,12 +714,16 @@ export class NetworkConnection implements INetworkConnection {
548
714
 
549
715
  private netWebSocketUrlProvider?: INetworkingWebsocketUrlProvider;
550
716
 
551
- /** Use to override the networking server backend url. This is what the `Networking` component uses to modify the backend url */
717
+ /** Use to override the networking server backend url.
718
+ * This is what the `{@link Networking}` component uses to modify the backend url.
719
+ **/
552
720
  public registerProvider(prov: INetworkingWebsocketUrlProvider) {
553
721
  this.netWebSocketUrlProvider = prov;
554
722
  }
555
723
 
556
- /** Used to connect to the networking server */
724
+ /** Used to connect to the networking server
725
+ * @param url Optional url to connect to. If not provided, it will use the url from the registered `INetworkingWebsocketUrlProvider` or the default backend networking url. If you want to change the url after connecting, you need to disconnect first and then connect again with the new url.
726
+ */
557
727
  public async connect(url?: string) {
558
728
  if (this.connected && url && url !== networkingServerUrl) {
559
729
  return Promise.reject("Can not connect to different server url. Please disconnect first.");
@@ -176,15 +176,42 @@ export declare type SyncFieldOptions = {
176
176
  export declare type FieldChangedCallbackFn = (newValue: any, previousValue: any) => void | boolean | any;
177
177
 
178
178
  /**
179
- * **Decorate a field to be automatically networked synced**
180
- * *Primitive* values are all automatically synced (like string, boolean, number).
181
- * For *arrays or objects* make sure to re-assign them (e.g. `this.mySyncField = this.mySyncField`) to trigger an update
182
- *
183
- * @param onFieldChanged name of a callback function that will be called when the field is changed.
184
- * You can also pass in a function like so: syncField(myClass.prototype.myFunctionToBeCalled)
185
- * Note: if you return `false` from this function you'll prevent the field from being synced with other clients
186
- * (for example a networked color is sent as a number and may be converted to a color in the receiver again)
187
- * Parameters: (newValue, previousValue)
179
+ * Marks a field for automatic network synchronization across connected clients.
180
+ * When a synced field changes, the new value is automatically broadcast to all users in the room.
181
+ *
182
+ * Primitives (string, number, boolean) sync automatically.
183
+ * For arrays/objects, reassign to trigger sync: `this.myArray = this.myArray`
184
+ *
185
+ * @param onFieldChanged Optional callback when the field changes (locally or from network).
186
+ * Return `false` to prevent syncing this change to others.
187
+ *
188
+ * @example Basic sync
189
+ * ```ts
190
+ * class MyComponent extends Behaviour {
191
+ * @syncField() playerScore: number = 0;
192
+ * }
193
+ * ```
194
+ * @example With change callback
195
+ * ```ts
196
+ * class MyComponent extends Behaviour {
197
+ * @syncField("onHealthChanged") health: number = 100;
198
+ *
199
+ * onHealthChanged(newValue: number, oldValue: number) {
200
+ * console.log(`Health: ${oldValue} → ${newValue}`);
201
+ * }
202
+ * }
203
+ * ```
204
+ * @example Preventing sync (one-way)
205
+ * ```ts
206
+ * class MyComponent extends Behaviour {
207
+ * @syncField(function(newVal, oldVal) {
208
+ * // Process incoming value but don't sync our changes
209
+ * return false;
210
+ * }) serverControlled: string = "";
211
+ * }
212
+ * ```
213
+ * @see {@link serializable} for editor serialization
214
+ * @link https://engine.needle.tools/docs/how-to-guides/networking/
188
215
  */
189
216
  export const syncField = function (onFieldChanged: string | FieldChangedCallbackFn | undefined | null = null) {
190
217
 
@@ -10,8 +10,10 @@ import { Context } from './engine_setup.js';
10
10
  import { getTempVector, getWorldPosition } from "./engine_three_utils.js"
11
11
  import type { ConstructorConcrete, Vec2, Vec3, } from './engine_types.js';
12
12
  import type { IPhysicsEngine } from './engine_types.js';
13
+ import type { RapierPhysics } from './engine_physics_rapier.js';
13
14
  import { getParam } from "./engine_utils.js"
14
15
 
16
+
15
17
  const debugPhysics = getParam("debugphysics");
16
18
  const debugWorker = getParam("debugworker");
17
19
  const layerMaskHelper: Layers = new Layers();
@@ -133,11 +135,45 @@ export class SphereIntersection implements Intersection {
133
135
  }
134
136
  }
135
137
 
138
+ /**
139
+ * Provides physics utilities including raycasting and overlap detection.
140
+ * Access via `this.context.physics` from any component.
141
+ *
142
+ * For physics engine features (rigidbodies, colliders, forces, etc.), use `this.context.physics.engine`.
143
+ * The physics engine is {@link RapierPhysics}, which uses the Rapier physics library for realistic simulation.
144
+ *
145
+ * **Performance - Automatic MeshBVH:**
146
+ * Needle Engine automatically uses [three-mesh-bvh](https://github.com/gkjohnson/three-mesh-bvh) to accelerate raycasting.
147
+ * MeshBVH structures are generated automatically on web workers in the background, making raycasts significantly faster
148
+ * without blocking the main thread. This happens transparently - you don't need to do anything to enable it.
149
+ * While the BVH is being generated, raycasts fall back to standard three.js raycasting (configurable via `allowSlowRaycastFallback`).
150
+ *
151
+ * @example Raycasting from mouse position
152
+ * ```ts
153
+ * const hits = this.context.physics.raycast();
154
+ * if (hits.length > 0) {
155
+ * console.log("Hit:", hits[0].object.name);
156
+ * }
157
+ * ```
158
+ * @example Raycasting with inline options
159
+ * ```ts
160
+ * const hits = this.context.physics.raycast({
161
+ * maxDistance: 100, // Only hit objects within 100 units
162
+ * layerMask: 1, // Only layer 0
163
+ * ignore: [this.gameObject] // Ignore self
164
+ * });
165
+ * ```
166
+ * @example Physics engine raycast (against colliders only)
167
+ * ```ts
168
+ * const hit = this.context.physics.engine?.raycast(origin, direction);
169
+ * ```
170
+ * @see {@link RapierPhysics} for physics engine implementation details
171
+ */
136
172
  export class Physics {
137
173
 
138
174
  private static _raycasting: number = 0;
139
175
  /**
140
- * Returns true if raycasting is currently happening
176
+ * Returns true if raycasting is currently in progress
141
177
  */
142
178
  public static get raycasting() {
143
179
  return this._raycasting > 0;
@@ -26,6 +26,7 @@ import type {
26
26
  import { Collision, ContactPoint } from './engine_types.js';
27
27
  import { ShapeOverlapResult } from './engine_types.js';
28
28
  import { CircularBuffer, getParam } from "./engine_utils.js"
29
+ import type { Physics } from './engine_physics.js';
29
30
 
30
31
  const debugPhysics = getParam("debugphysics");
31
32
  const debugColliderPlacement = getParam("debugcolliderplacement");
@@ -61,6 +62,82 @@ declare type PhysicsBody = {
61
62
  rotation(): { x: number, y: number, z: number, w: number }
62
63
  }
63
64
 
65
+ /**
66
+ * Rapier physics engine implementation for Needle Engine.
67
+ *
68
+ * Rapier is a fast, cross-platform physics engine that provides realistic physics simulation
69
+ * for rigidbodies, colliders, joints, and collision detection. It runs entirely in WebAssembly
70
+ * for high performance.
71
+ *
72
+ * **Features:**
73
+ * - Rigidbody simulation (dynamic, kinematic, static)
74
+ * - Multiple collider shapes (box, sphere, capsule, mesh, convex hull)
75
+ * - Raycasting and shape overlap queries against physics colliders
76
+ * - Collision and trigger events
77
+ * - Joints (fixed, hinge, etc.)
78
+ * - Continuous collision detection (CCD)
79
+ * - Physics materials (friction, bounciness)
80
+ *
81
+ * **Access:**
82
+ * The Rapier physics engine is accessible via `this.context.physics.engine` from any component.
83
+ * Rapier is automatically initialized when physics components are used.
84
+ *
85
+ * **Using the Rapier Module Directly:**
86
+ * Rapier is lazy-loaded for performance. You can access the raw Rapier module via {@link MODULES.RAPIER_PHYSICS}.
87
+ * Use `MODULES.RAPIER_PHYSICS.load()` to load the module, or `MODULES.RAPIER_PHYSICS.ready()` to wait for it without triggering a load.
88
+ * Once loaded, the module is available at `MODULES.RAPIER_PHYSICS.MODULE`.
89
+ *
90
+ * **Note:**
91
+ * This is the low-level physics engine implementation. For general raycasting (against all scene objects),
92
+ * use {@link Physics.raycast} instead. Use this class for physics-specific operations like applying forces,
93
+ * raycasting against colliders only, or accessing the Rapier world directly.
94
+ *
95
+ * @example Applying forces to a rigidbody
96
+ * ```ts
97
+ * const rb = this.gameObject.getComponent(Rigidbody);
98
+ * if (rb) {
99
+ * this.context.physics.engine?.addForce(rb, { x: 0, y: 10, z: 0 }, true);
100
+ * }
101
+ * ```
102
+ * @example Raycasting against physics colliders only
103
+ * ```ts
104
+ * const origin = { x: 0, y: 5, z: 0 };
105
+ * const direction = { x: 0, y: -1, z: 0 };
106
+ * const hit = this.context.physics.engine?.raycast(origin, direction);
107
+ * if (hit) {
108
+ * console.log("Hit collider:", hit.collider.name);
109
+ * }
110
+ * ```
111
+ * @example Accessing Rapier world directly
112
+ * ```ts
113
+ * const rapierWorld = this.context.physics.engine?.world;
114
+ * if (rapierWorld) {
115
+ * // Direct access to Rapier API
116
+ * console.log("Gravity:", rapierWorld.gravity);
117
+ * }
118
+ * ```
119
+ * @example Using the Rapier module directly
120
+ * ```ts
121
+ * import { MODULES } from "@needle-tools/engine";
122
+ *
123
+ * // Load the Rapier module
124
+ * const RAPIER = await MODULES.RAPIER_PHYSICS.load();
125
+ *
126
+ * // Now you can use Rapier types and create custom physics objects
127
+ * const rigidBodyDesc = RAPIER.RigidBodyDesc.dynamic()
128
+ * .setTranslation(0, 10, 0);
129
+ *
130
+ * // Or access the already-loaded module
131
+ * if (MODULES.RAPIER_PHYSICS.MODULE) {
132
+ * const colliderDesc = MODULES.RAPIER_PHYSICS.MODULE.ColliderDesc.ball(1.0);
133
+ * }
134
+ * ```
135
+ * @see {@link Physics} for general raycasting and physics utilities
136
+ * @see {@link MODULES.RAPIER_PHYSICS} for direct access to the Rapier module
137
+ * @link https://rapier.rs/docs/ for Rapier documentation
138
+ * @link https://engine.needle.tools/docs/reference/components.html#physics
139
+ * @link https://engine.needle.tools/docs/how-to-guides/scripting/use-physics.html
140
+ */
64
141
  export class RapierPhysics implements IPhysicsEngine {
65
142
 
66
143
  debugRenderColliders: boolean = false;
@@ -8,8 +8,34 @@ export const serializeable = function <T>(type?: Constructor<T> | null | Array<C
8
8
  }
9
9
 
10
10
  /**
11
- * The serializable attribute should be used to annotate all serialized fields / fields and members that should be serialized and exposed in an editor
12
- * @param type The type of the field. If not provided the type will be inferred from the constructor of the field. If the field is a primitive type (string, number, boolean) the type should be null.
11
+ * Marks a field for serialization and editor exposure. Required for fields that reference
12
+ * other objects, components, or assets. Primitive types (string, number, boolean) work without a type argument.
13
+ *
14
+ * @param type The constructor type for complex objects. Omit for primitives.
15
+ *
16
+ * @example Primitive types (no type needed)
17
+ * ```ts
18
+ * @serializable()
19
+ * speed: number = 1;
20
+ *
21
+ * @serializable()
22
+ * label: string = "Hello";
23
+ * ```
24
+ * @example Object references
25
+ * ```ts
26
+ * @serializable(Object3D)
27
+ * target: Object3D | null = null;
28
+ *
29
+ * @serializable(Renderer)
30
+ * myRenderer: Renderer | null = null;
31
+ * ```
32
+ * @example Arrays
33
+ * ```ts
34
+ * @serializable([Object3D])
35
+ * waypoints: Object3D[] = [];
36
+ * ```
37
+ * @see {@link syncField} for automatic network synchronization
38
+ * @link https://engine.needle.tools/docs/reference/typescript-decorators.html#serializable
13
39
  */
14
40
  export const serializable = function <T>(type?: Constructor<T> | null | Array<Constructor<any> | TypeResolver<T>> | TypeResolver<T>) {
15
41
  if (type === undefined) type = null;
@@ -8,8 +8,23 @@ let timeScale = 1;
8
8
  if (typeof timescaleUrl === "number") timeScale = timescaleUrl;
9
9
 
10
10
  /**
11
- * Time is a class that provides time-related information.
12
- * It is created and used within the Needle Engine Context.
11
+ * Provides time-related information for frame-based game logic.
12
+ * Access via `this.context.time` from any component.
13
+ *
14
+ * @example Using deltaTime for frame-rate independent movement
15
+ * ```ts
16
+ * update() {
17
+ * // Move 1 unit per second regardless of frame rate
18
+ * this.gameObject.position.x += 1 * this.context.time.deltaTime;
19
+ * }
20
+ * ```
21
+ * @example Checking elapsed time
22
+ * ```ts
23
+ * start() {
24
+ * console.log(`Time since start: ${this.context.time.time}s`);
25
+ * console.log(`Current frame: ${this.context.time.frameCount}`);
26
+ * }
27
+ * ```
13
28
  */
14
29
  export class Time implements ITime {
15
30
 
@@ -27,7 +42,12 @@ export class Time implements ITime {
27
42
  get deltaTimeUnscaled() { return this._deltaTimeUnscaled; }
28
43
  private _deltaTimeUnscaled = 0;
29
44
 
30
- /** The scale at which time passes. This can be used for slow motion effects or to speed up time. */
45
+ /**
46
+ * The scale at which time passes. Default is 1.
47
+ * - Values < 1 create slow motion (e.g. 0.5 = half speed)
48
+ * - Values > 1 speed up time (e.g. 2 = double speed)
49
+ * - Value of 0 effectively pauses time-dependent logic
50
+ */
31
51
  timeScale = 1;
32
52
 
33
53
  /** same as frameCount */
@@ -9,7 +9,37 @@ import { watchWrite } from "./engine_utils.js";
9
9
  declare type setter = (v: any) => void;
10
10
  declare type getter = () => any;
11
11
 
12
- /** create accessor callbacks for a field */
12
+ /**
13
+ * Marks a field to trigger the `onValidate` callback when its value changes.
14
+ * Useful for reacting to property changes from the editor or at runtime.
15
+ *
16
+ * Your component must implement `onValidate(property?: string)` to receive notifications.
17
+ *
18
+ * @param set Optional custom setter called before the value is assigned
19
+ * @param get Optional custom getter called when the value is read
20
+ *
21
+ * @example Basic usage
22
+ * ```ts
23
+ * export class MyComponent extends Behaviour {
24
+ * @serializable()
25
+ * @validate()
26
+ * color: Color = new Color(1, 0, 0);
27
+ *
28
+ * onValidate(property?: string) {
29
+ * if (property === "color") {
30
+ * console.log("Color changed to:", this.color);
31
+ * }
32
+ * }
33
+ * }
34
+ * ```
35
+ * @example With custom setter
36
+ * ```ts
37
+ * @validate(function(value) {
38
+ * console.log("Setting speed to", value);
39
+ * })
40
+ * speed: number = 1;
41
+ * ```
42
+ */
13
43
  export const validate = function (set?: setter, get?: getter) {
14
44
  // "descriptor : undefined" prevents @validate() to be added to property getters or setters
15
45
  return function (target: IComponent | any, propertyKey: string, descriptor?: undefined) {