@relu-interactives/spatial-ecs 0.2.2

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 (308) hide show
  1. package/README.md +125 -0
  2. package/dist/System-rXAmagXA.d.cts +659 -0
  3. package/dist/System-rXAmagXA.d.ts +659 -0
  4. package/dist/Video-CDemv74U.d.cts +1261 -0
  5. package/dist/Video-ChKV1UI7.d.ts +1261 -0
  6. package/dist/assets/draco/draco_decoder.js +34 -0
  7. package/dist/assets/draco/draco_decoder.wasm +0 -0
  8. package/dist/assets/draco/draco_wasm_wrapper.js +117 -0
  9. package/dist/chunk-AYEF3X2P.js +223 -0
  10. package/dist/chunk-AYEF3X2P.js.map +1 -0
  11. package/dist/chunk-MAWBTMCG.js +1722 -0
  12. package/dist/chunk-MAWBTMCG.js.map +1 -0
  13. package/dist/chunk-NFDTIYR4.js +248 -0
  14. package/dist/chunk-NFDTIYR4.js.map +1 -0
  15. package/dist/chunk-OY7ZODZP.js +16 -0
  16. package/dist/chunk-OY7ZODZP.js.map +1 -0
  17. package/dist/chunk-P2YDX5DB.js +3304 -0
  18. package/dist/chunk-P2YDX5DB.js.map +1 -0
  19. package/dist/chunk-QHILSPT4.js +3 -0
  20. package/dist/chunk-QHILSPT4.js.map +1 -0
  21. package/dist/chunk-XWIEEJ7Z.js +1315 -0
  22. package/dist/chunk-XWIEEJ7Z.js.map +1 -0
  23. package/dist/components/index.cjs +1745 -0
  24. package/dist/components/index.cjs.map +1 -0
  25. package/dist/components/index.d.cts +4 -0
  26. package/dist/components/index.d.ts +4 -0
  27. package/dist/components/index.js +4 -0
  28. package/dist/components/index.js.map +1 -0
  29. package/dist/docs/api/Behaviour/classes/Behaviour.md +554 -0
  30. package/dist/docs/api/Behaviour/index.md +15 -0
  31. package/dist/docs/api/Component/classes/Component.md +57 -0
  32. package/dist/docs/api/Component/index.md +15 -0
  33. package/dist/docs/api/components/classes/AnimationComponent.md +318 -0
  34. package/dist/docs/api/components/classes/AudioComponent.md +114 -0
  35. package/dist/docs/api/components/classes/CameraComponent.md +59 -0
  36. package/dist/docs/api/components/classes/EntityType.md +48 -0
  37. package/dist/docs/api/components/classes/Environment.md +47 -0
  38. package/dist/docs/api/components/classes/ImageComponent.md +57 -0
  39. package/dist/docs/api/components/classes/ImageTarget.md +60 -0
  40. package/dist/docs/api/components/classes/ImageTargetAnchor.md +48 -0
  41. package/dist/docs/api/components/classes/LightComponent.md +70 -0
  42. package/dist/docs/api/components/classes/MaterialComponent.md +181 -0
  43. package/dist/docs/api/components/classes/MeshComponent.md +48 -0
  44. package/dist/docs/api/components/classes/MeshGeometryComponent.md +64 -0
  45. package/dist/docs/api/components/classes/ModelComponent.md +49 -0
  46. package/dist/docs/api/components/classes/Name.md +46 -0
  47. package/dist/docs/api/components/classes/Object3DRef.md +54 -0
  48. package/dist/docs/api/components/classes/ParentId.md +47 -0
  49. package/dist/docs/api/components/classes/PhysicsComponent.md +82 -0
  50. package/dist/docs/api/components/classes/Postprocessing.md +49 -0
  51. package/dist/docs/api/components/classes/ScriptComponent.md +54 -0
  52. package/dist/docs/api/components/classes/Selectable.md +46 -0
  53. package/dist/docs/api/components/classes/SelectionTransformState.md +54 -0
  54. package/dist/docs/api/components/classes/SpriteComponent.md +55 -0
  55. package/dist/docs/api/components/classes/TransformComponent.md +197 -0
  56. package/dist/docs/api/components/classes/VideoComponent.md +123 -0
  57. package/dist/docs/api/components/functions/normalizePhysicsState.md +23 -0
  58. package/dist/docs/api/components/index.md +94 -0
  59. package/dist/docs/api/components/type-aliases/AnimationComponentOptions.md +42 -0
  60. package/dist/docs/api/components/type-aliases/CameraComponentOptions.md +45 -0
  61. package/dist/docs/api/components/type-aliases/CameraProjection.md +15 -0
  62. package/dist/docs/api/components/type-aliases/CameraRuntimeType.md +15 -0
  63. package/dist/docs/api/components/type-aliases/ColliderShape.md +15 -0
  64. package/dist/docs/api/components/type-aliases/ColliderState.md +62 -0
  65. package/dist/docs/api/components/type-aliases/CubeMeshParameters.md +27 -0
  66. package/dist/docs/api/components/type-aliases/EditableMeshObjectKind.md +15 -0
  67. package/dist/docs/api/components/type-aliases/EnvironmentFogState.md +37 -0
  68. package/dist/docs/api/components/type-aliases/EnvironmentFogType.md +15 -0
  69. package/dist/docs/api/components/type-aliases/EnvironmentGradientEffect.md +15 -0
  70. package/dist/docs/api/components/type-aliases/EnvironmentSkyboxState.md +34 -0
  71. package/dist/docs/api/components/type-aliases/EnvironmentSkyboxType.md +15 -0
  72. package/dist/docs/api/components/type-aliases/EnvironmentState.md +29 -0
  73. package/dist/docs/api/components/type-aliases/ImageTargetAnchorOptions.md +25 -0
  74. package/dist/docs/api/components/type-aliases/ImageTargetReference.md +33 -0
  75. package/dist/docs/api/components/type-aliases/LightValueState.md +41 -0
  76. package/dist/docs/api/components/type-aliases/MaterialTypeValue.md +15 -0
  77. package/dist/docs/api/components/type-aliases/MaterialValueState.md +75 -0
  78. package/dist/docs/api/components/type-aliases/MeshGeometryParameters.md +13 -0
  79. package/dist/docs/api/components/type-aliases/MeshGeometryParametersByKind.md +33 -0
  80. package/dist/docs/api/components/type-aliases/PhysicsState.md +25 -0
  81. package/dist/docs/api/components/type-aliases/PlaneMeshParameters.md +25 -0
  82. package/dist/docs/api/components/type-aliases/PostprocessingState.md +164 -0
  83. package/dist/docs/api/components/type-aliases/RadiusHeightMeshParameters.md +25 -0
  84. package/dist/docs/api/components/type-aliases/RadiusMeshParameters.md +23 -0
  85. package/dist/docs/api/components/type-aliases/RigidbodyState.md +53 -0
  86. package/dist/docs/api/components/type-aliases/RigidbodyType.md +19 -0
  87. package/dist/docs/api/components/type-aliases/ScriptEntry.md +38 -0
  88. package/dist/docs/api/components/type-aliases/TextureFilteringValue.md +15 -0
  89. package/dist/docs/api/components/type-aliases/TransformData.md +27 -0
  90. package/dist/docs/api/components/type-aliases/TransformModeValue.md +15 -0
  91. package/dist/docs/api/components/type-aliases/TransformSpaceValue.md +15 -0
  92. package/dist/docs/api/components/type-aliases/Vec3.md +27 -0
  93. package/dist/docs/api/components/variables/DEFAULT_COLLIDER_STATE.md +13 -0
  94. package/dist/docs/api/components/variables/DEFAULT_ENVIRONMENT_STATE.md +13 -0
  95. package/dist/docs/api/components/variables/DEFAULT_MESH_GEOMETRY_PARAMETERS.md +13 -0
  96. package/dist/docs/api/components/variables/DEFAULT_PHYSICS_STATE.md +13 -0
  97. package/dist/docs/api/components/variables/DEFAULT_POSTPROCESSING_STATE.md +13 -0
  98. package/dist/docs/api/components/variables/DEFAULT_RIGIDBODY_STATE.md +13 -0
  99. package/dist/docs/api/index/classes/AnimationStateMachine.md +201 -0
  100. package/dist/docs/api/index/classes/AnimationStateManager.md +253 -0
  101. package/dist/docs/api/index/classes/AnimationSystem.md +68 -0
  102. package/dist/docs/api/index/classes/AudioSystem.md +98 -0
  103. package/dist/docs/api/index/classes/CameraSyncSystem.md +49 -0
  104. package/dist/docs/api/index/classes/EnvironmentSyncSystem.md +75 -0
  105. package/dist/docs/api/index/classes/InputSystem.md +449 -0
  106. package/dist/docs/api/index/classes/LightSyncSystem.md +49 -0
  107. package/dist/docs/api/index/classes/MaterialSyncSystem.md +67 -0
  108. package/dist/docs/api/index/classes/MeshGeometrySystem.md +49 -0
  109. package/dist/docs/api/index/classes/ObjectManagementSystem.md +298 -0
  110. package/dist/docs/api/index/classes/ObjectVisibilitySystem.md +49 -0
  111. package/dist/docs/api/index/classes/PhysicsSyncSystem.md +83 -0
  112. package/dist/docs/api/index/classes/PostprocessingSyncSystem.md +80 -0
  113. package/dist/docs/api/index/classes/RenderSystem.md +64 -0
  114. package/dist/docs/api/index/classes/ScriptBehaviourSystem.md +83 -0
  115. package/dist/docs/api/index/classes/TransformSyncSystem.md +49 -0
  116. package/dist/docs/api/index/classes/VideoSystem.md +97 -0
  117. package/dist/docs/api/index/classes/World.md +1405 -0
  118. package/dist/docs/api/index/functions/createAnimationComponent.md +28 -0
  119. package/dist/docs/api/index/functions/createAudioComponent.md +32 -0
  120. package/dist/docs/api/index/functions/createCameraComponent.md +28 -0
  121. package/dist/docs/api/index/functions/createEntityTypeComponent.md +28 -0
  122. package/dist/docs/api/index/functions/createEnvironmentComponent.md +28 -0
  123. package/dist/docs/api/index/functions/createImageComponent.md +28 -0
  124. package/dist/docs/api/index/functions/createImageTargetAnchorComponent.md +28 -0
  125. package/dist/docs/api/index/functions/createImageTargetComponent.md +28 -0
  126. package/dist/docs/api/index/functions/createLightComponent.md +28 -0
  127. package/dist/docs/api/index/functions/createMaterialComponent.md +28 -0
  128. package/dist/docs/api/index/functions/createMeshComponent.md +28 -0
  129. package/dist/docs/api/index/functions/createMeshGeometryComponent.md +28 -0
  130. package/dist/docs/api/index/functions/createModelComponent.md +28 -0
  131. package/dist/docs/api/index/functions/createNameComponent.md +28 -0
  132. package/dist/docs/api/index/functions/createObject3DRefComponent.md +28 -0
  133. package/dist/docs/api/index/functions/createParentIdComponent.md +28 -0
  134. package/dist/docs/api/index/functions/createPhysicsComponent.md +30 -0
  135. package/dist/docs/api/index/functions/createPostprocessingComponent.md +28 -0
  136. package/dist/docs/api/index/functions/createScriptComponent.md +28 -0
  137. package/dist/docs/api/index/functions/createSelectableComponent.md +28 -0
  138. package/dist/docs/api/index/functions/createSelectionTransformStateComponent.md +28 -0
  139. package/dist/docs/api/index/functions/createSpriteComponent.md +28 -0
  140. package/dist/docs/api/index/functions/createTransformComponent.md +28 -0
  141. package/dist/docs/api/index/functions/createVideoComponent.md +28 -0
  142. package/dist/docs/api/index/functions/hydrateWorldFromSnapshot.md +28 -0
  143. package/dist/docs/api/index/functions/hydrateWorldFromSnapshotDetailed.md +28 -0
  144. package/dist/docs/api/index/functions/registerDefaultComponentFactories.md +23 -0
  145. package/dist/docs/api/index/functions/registerDefaultFactories.md +23 -0
  146. package/dist/docs/api/index/index.md +249 -0
  147. package/dist/docs/api/index/interfaces/EcsSystem.md +50 -0
  148. package/dist/docs/api/index/interfaces/StateMachine.md +26 -0
  149. package/dist/docs/api/index/type-aliases/AnimationStateCallbacks.md +25 -0
  150. package/dist/docs/api/index/type-aliases/ComponentFactory.md +25 -0
  151. package/dist/docs/api/index/type-aliases/EcsComponentFactoryKind.md +37 -0
  152. package/dist/docs/api/index/type-aliases/EcsWorldComponentSnapshot.md +26 -0
  153. package/dist/docs/api/index/type-aliases/EcsWorldStateSnapshotLike.md +25 -0
  154. package/dist/docs/api/index/type-aliases/HydrateWorldFromSnapshotResult.md +23 -0
  155. package/dist/docs/api/index/type-aliases/KeyboardKey.md +13 -0
  156. package/dist/docs/api/index/type-aliases/MouseButton.md +13 -0
  157. package/dist/docs/api/index/type-aliases/SelectionContext.md +31 -0
  158. package/dist/docs/api/index/variables/HYDRATABLE_ENTITY_KINDS.md +13 -0
  159. package/dist/docs/api/index/variables/KeyboardKeys.md +195 -0
  160. package/dist/docs/api/index.md +15 -0
  161. package/dist/docs/api/typedoc-sidebar.json +1 -0
  162. package/dist/docs/api/types/index.md +34 -0
  163. package/dist/docs/api/types/type-aliases/AssetInput.md +23 -0
  164. package/dist/docs/api/types/type-aliases/CheckboxInput.md +13 -0
  165. package/dist/docs/api/types/type-aliases/ColorInput.md +13 -0
  166. package/dist/docs/api/types/type-aliases/ComponentInput.md +52 -0
  167. package/dist/docs/api/types/type-aliases/ComponentKind.md +37 -0
  168. package/dist/docs/api/types/type-aliases/DropdownInput.md +23 -0
  169. package/dist/docs/api/types/type-aliases/DropdownOption.md +23 -0
  170. package/dist/docs/api/types/type-aliases/EcsEntityEditorKind.md +15 -0
  171. package/dist/docs/api/types/type-aliases/EcsEntityKind.md +35 -0
  172. package/dist/docs/api/types/type-aliases/EntityId.md +16 -0
  173. package/dist/docs/api/types/type-aliases/EntityInput.md +23 -0
  174. package/dist/docs/api/types/type-aliases/FloatInput.md +13 -0
  175. package/dist/docs/api/types/type-aliases/IntersectionResult.md +29 -0
  176. package/dist/docs/api/types/type-aliases/ParentLookup.md +26 -0
  177. package/dist/docs/api/types/type-aliases/SelectionListener.md +25 -0
  178. package/dist/docs/api/types/type-aliases/SliderInput.md +27 -0
  179. package/dist/docs/api/types/type-aliases/TextInput.md +13 -0
  180. package/dist/docs/api/types/type-aliases/ToggleInput.md +13 -0
  181. package/dist/docs/api/types/type-aliases/Vec3.md +23 -0
  182. package/dist/docs/api/types/type-aliases/Vector2Input.md +23 -0
  183. package/dist/docs/api/types/type-aliases/Vector3Input.md +25 -0
  184. package/dist/docs/api/types/type-aliases/WorldEntityView.md +17 -0
  185. package/dist/docs/guide/accessing-components.md +399 -0
  186. package/dist/docs/guide/authoring-a-behaviour.md +166 -0
  187. package/dist/docs/guide/behaviour-lifecycle.md +43 -0
  188. package/dist/docs/guide/component-catalog.md +59 -0
  189. package/dist/docs/guide/components/_sidebar.json +78 -0
  190. package/dist/docs/guide/components/animation.md +171 -0
  191. package/dist/docs/guide/components/audio.md +181 -0
  192. package/dist/docs/guide/components/camera.md +179 -0
  193. package/dist/docs/guide/components/entity-type.md +141 -0
  194. package/dist/docs/guide/components/image-target-anchor.md +103 -0
  195. package/dist/docs/guide/components/image-target.md +122 -0
  196. package/dist/docs/guide/components/image.md +146 -0
  197. package/dist/docs/guide/components/light.md +157 -0
  198. package/dist/docs/guide/components/material.md +161 -0
  199. package/dist/docs/guide/components/mesh-geometry.md +153 -0
  200. package/dist/docs/guide/components/mesh.md +151 -0
  201. package/dist/docs/guide/components/model.md +96 -0
  202. package/dist/docs/guide/components/name.md +121 -0
  203. package/dist/docs/guide/components/object3d-ref.md +115 -0
  204. package/dist/docs/guide/components/parent-id.md +108 -0
  205. package/dist/docs/guide/components/physics.md +163 -0
  206. package/dist/docs/guide/components/script.md +142 -0
  207. package/dist/docs/guide/components/sprite.md +155 -0
  208. package/dist/docs/guide/components/transform.md +155 -0
  209. package/dist/docs/guide/components/video.md +153 -0
  210. package/dist/docs/guide/concepts.md +34 -0
  211. package/dist/docs/guide/getting-started/creating-objects.md +50 -0
  212. package/dist/docs/guide/getting-started/editing-objects.md +62 -0
  213. package/dist/docs/guide/getting-started/editor/assets-browser.md +55 -0
  214. package/dist/docs/guide/getting-started/editor/hierarchy.md +47 -0
  215. package/dist/docs/guide/getting-started/editor/index.md +16 -0
  216. package/dist/docs/guide/getting-started/editor/inspector.md +36 -0
  217. package/dist/docs/guide/getting-started/editor/modules.md +35 -0
  218. package/dist/docs/guide/getting-started/editor/scene-inspector.md +64 -0
  219. package/dist/docs/guide/getting-started/editor/toolbar.md +39 -0
  220. package/dist/docs/guide/getting-started/editor/viewport.md +43 -0
  221. package/dist/docs/guide/getting-started/first-launch.md +17 -0
  222. package/dist/docs/guide/getting-started/index.md +37 -0
  223. package/dist/docs/guide/getting-started/installation.md +59 -0
  224. package/dist/docs/guide/getting-started/preview-and-test.md +55 -0
  225. package/dist/docs/guide/getting-started/project-types/3d.md +30 -0
  226. package/dist/docs/guide/getting-started/project-types/ar.md +6 -0
  227. package/dist/docs/guide/getting-started/project-types/face-tracking.md +6 -0
  228. package/dist/docs/guide/getting-started/project-types/image-tracking.md +42 -0
  229. package/dist/docs/guide/getting-started/project-types/index.md +25 -0
  230. package/dist/docs/guide/getting-started/project-types/vr.md +6 -0
  231. package/dist/docs/guide/getting-started/projects.md +53 -0
  232. package/dist/docs/guide/getting-started/shortcuts.md +43 -0
  233. package/dist/docs/guide/inspector-data-binding.md +367 -0
  234. package/dist/docs/guide/reading-input.md +202 -0
  235. package/dist/docs/guide/scene/environment.md +101 -0
  236. package/dist/docs/guide/scene/index.md +36 -0
  237. package/dist/docs/guide/scene/postprocessing.md +108 -0
  238. package/dist/docs/guide/spawning/ambient-light.md +28 -0
  239. package/dist/docs/guide/spawning/area-light.md +32 -0
  240. package/dist/docs/guide/spawning/audio.md +42 -0
  241. package/dist/docs/guide/spawning/camera.md +50 -0
  242. package/dist/docs/guide/spawning/capsule.md +29 -0
  243. package/dist/docs/guide/spawning/cube.md +31 -0
  244. package/dist/docs/guide/spawning/cylinder.md +29 -0
  245. package/dist/docs/guide/spawning/directional-light.md +32 -0
  246. package/dist/docs/guide/spawning/empty.md +31 -0
  247. package/dist/docs/guide/spawning/image-target.md +48 -0
  248. package/dist/docs/guide/spawning/image.md +33 -0
  249. package/dist/docs/guide/spawning/index.md +79 -0
  250. package/dist/docs/guide/spawning/model.md +31 -0
  251. package/dist/docs/guide/spawning/plane.md +31 -0
  252. package/dist/docs/guide/spawning/point-light.md +32 -0
  253. package/dist/docs/guide/spawning/sphere.md +29 -0
  254. package/dist/docs/guide/spawning/spot-light.md +32 -0
  255. package/dist/docs/guide/spawning/sprite.md +31 -0
  256. package/dist/docs/guide/spawning/video.md +53 -0
  257. package/dist/docs/guide/system-overview.md +73 -0
  258. package/dist/docs/guide/systems/_sidebar.json +66 -0
  259. package/dist/docs/guide/systems/animation-system.md +32 -0
  260. package/dist/docs/guide/systems/audio-system.md +28 -0
  261. package/dist/docs/guide/systems/camera-sync-system.md +31 -0
  262. package/dist/docs/guide/systems/environment-sync-system.md +31 -0
  263. package/dist/docs/guide/systems/input-system.md +217 -0
  264. package/dist/docs/guide/systems/light-sync-system.md +29 -0
  265. package/dist/docs/guide/systems/material-sync-system.md +32 -0
  266. package/dist/docs/guide/systems/mesh-geometry-system.md +40 -0
  267. package/dist/docs/guide/systems/object-management-system.md +38 -0
  268. package/dist/docs/guide/systems/object-visibility-system.md +26 -0
  269. package/dist/docs/guide/systems/physics-sync-system.md +56 -0
  270. package/dist/docs/guide/systems/postprocessing-sync-system.md +43 -0
  271. package/dist/docs/guide/systems/render-system.md +22 -0
  272. package/dist/docs/guide/systems/script-behaviour-system.md +59 -0
  273. package/dist/docs/guide/systems/transform-sync-system.md +29 -0
  274. package/dist/docs/guide/systems/video-system.md +30 -0
  275. package/dist/docs/guide/world-api.md +405 -0
  276. package/dist/factories/index.cjs +3077 -0
  277. package/dist/factories/index.cjs.map +1 -0
  278. package/dist/factories/index.d.cts +69 -0
  279. package/dist/factories/index.d.ts +69 -0
  280. package/dist/factories/index.js +6 -0
  281. package/dist/factories/index.js.map +1 -0
  282. package/dist/index-B4-YyUNR.d.cts +73 -0
  283. package/dist/index-BZUOKeTO.d.ts +73 -0
  284. package/dist/index.cjs +8584 -0
  285. package/dist/index.cjs.map +1 -0
  286. package/dist/index.d.cts +283 -0
  287. package/dist/index.d.ts +283 -0
  288. package/dist/index.js +1729 -0
  289. package/dist/index.js.map +1 -0
  290. package/dist/systems/index.cjs +5119 -0
  291. package/dist/systems/index.cjs.map +1 -0
  292. package/dist/systems/index.d.cts +200 -0
  293. package/dist/systems/index.d.ts +200 -0
  294. package/dist/systems/index.js +6 -0
  295. package/dist/systems/index.js.map +1 -0
  296. package/dist/types.cjs +4 -0
  297. package/dist/types.cjs.map +1 -0
  298. package/dist/types.d.cts +3 -0
  299. package/dist/types.d.ts +3 -0
  300. package/dist/types.js +3 -0
  301. package/dist/types.js.map +1 -0
  302. package/dist/worldSnapshotUtils.cjs +259 -0
  303. package/dist/worldSnapshotUtils.cjs.map +1 -0
  304. package/dist/worldSnapshotUtils.d.cts +3 -0
  305. package/dist/worldSnapshotUtils.d.ts +3 -0
  306. package/dist/worldSnapshotUtils.js +4 -0
  307. package/dist/worldSnapshotUtils.js.map +1 -0
  308. package/package.json +80 -0
@@ -0,0 +1,367 @@
1
+ # Inspector Data Binding
2
+
3
+ The `ScriptComponent.data` field is the bridge between the editor inspector and your `Behaviour` subclass. Anything you place on `data` is:
4
+
5
+ 1. Saved with the project.
6
+ 2. Rendered as a live inspector control in the editor.
7
+ 3. Available at runtime as `this.data` inside the script.
8
+
9
+ The **type annotation** on each field tells the editor which control to render. Import the input types from `@relu-interactives/spatial-ecs` and use them as `as` casts on the initial values in your data object.
10
+
11
+ ## Input types reference
12
+
13
+ | Type | Import | Inspector control | Runtime value |
14
+ | --- | --- | --- | --- |
15
+ | `FloatInput` | ✓ | Number input | `number` |
16
+ | `TextInput` | ✓ | Text input | `string` |
17
+ | `ColorInput` | ✓ | Color picker | `string` (hex, e.g. `"#ff0000"`) |
18
+ | `Vector2Input` | ✓ | XY number pair | `{ x: number; y: number }` |
19
+ | `Vector3Input` | ✓ | XYZ number triple | `{ x: number; y: number; z: number }` |
20
+ | `SliderInput` | ✓ | Range slider | `{ min, max, step, value }` (read `field.value` at runtime) |
21
+ | `DropdownInput` | ✓ | Select dropdown | `{ options: DropdownOption[]; value: string }` (read `field.value`) |
22
+ | `CheckboxInput` | ✓ | Checkbox | `boolean` |
23
+ | `ToggleInput` | ✓ | Toggle switch | `boolean` |
24
+ | `AssetInput` | ✓ | Asset file picker | `{ path: string; type: string }` — read `field.path`; `.value` is always `null` |
25
+ | `EntityInput` | ✓ | Entity picker | `{ type: "entity"; value: WorldEntityView \| null }` — read `field.value` |
26
+ | `ComponentInput` | ✓ | Entity + component picker | `{ type: "component"; componentKind?: ComponentKind; value: Component \| null }` — read `field.value` |
27
+
28
+ ## Declaring inspector fields
29
+
30
+ Import the input types you need alongside `Behaviour`, then declare them directly on the `data` class property using `as` casts:
31
+
32
+ ```ts
33
+ import {
34
+ Behaviour,
35
+ type FloatInput,
36
+ type TextInput,
37
+ type ColorInput,
38
+ type Vector2Input,
39
+ type Vector3Input,
40
+ type SliderInput,
41
+ type DropdownInput,
42
+ type CheckboxInput,
43
+ type ToggleInput,
44
+ type AssetInput,
45
+ type EntityInput,
46
+ type ComponentInput,
47
+ } from "@relu-interactives/spatial-ecs";
48
+
49
+ export default class Demo extends Behaviour {
50
+ data = {
51
+ speed: 1 as FloatInput,
52
+ label: "Hello" as TextInput,
53
+ tint: "#ffffff" as ColorInput,
54
+ offset: { x: 0, y: 0 } as Vector2Input,
55
+ origin: { x: 0, y: 0, z: 0 } as Vector3Input,
56
+ range: { min: 0, max: 10, step: 0.1, value: 5 } as SliderInput,
57
+ axis: {
58
+ value: "y",
59
+ options: [
60
+ { label: "X", value: "x" },
61
+ { label: "Y", value: "y" },
62
+ { label: "Z", value: "z" },
63
+ ],
64
+ } as DropdownInput,
65
+ active: true as ToggleInput,
66
+ visible: true as CheckboxInput,
67
+ texture: { path: "", type: "texture" } as AssetInput,
68
+ target: { type: "entity", value: null } as EntityInput,
69
+ camera: { type: "component", componentKind: "Camera", value: null } as ComponentInput,
70
+ };
71
+ }
72
+ ```
73
+
74
+ ## Reading values at runtime
75
+
76
+ Most types map directly to their underlying primitive. The exceptions are `SliderInput`, `DropdownInput`, `AssetInput`, `EntityInput`, and `ComponentInput`, which are objects — read the nested value:
77
+
78
+ ```ts
79
+ export default class Demo extends Behaviour {
80
+ data = {
81
+ speed: 1 as FloatInput,
82
+ active: true as ToggleInput,
83
+ range: { min: 0, max: 1, step: 0.1, value: 0.8 } as SliderInput,
84
+ axis: { value: "y", options: [{ label: "X", value: "x" }, { label: "Y", value: "y" }, { label: "Z", value: "z" }] } as DropdownInput,
85
+ texture: { path: "", type: "texture" } as AssetInput,
86
+ target: { type: "entity", value: null } as EntityInput,
87
+ camera: { type: "component", componentKind: "Camera", value: null } as ComponentInput,
88
+ };
89
+
90
+ onUpdate() {
91
+ // FloatInput / TextInput / ColorInput / CheckboxInput / ToggleInput
92
+ // → use directly
93
+ this.transform.rotation.y += this.data.speed * this.deltaTime;
94
+ const isOn = this.data.active;
95
+
96
+ // SliderInput → read .value
97
+ const volume = this.data.range.value;
98
+
99
+ // DropdownInput → read .value
100
+ const axis = this.data.axis.value as "x" | "y" | "z";
101
+ this.transform.rotation[axis] += this.data.speed * this.deltaTime;
102
+
103
+ // AssetInput → read .path (see AssetInput section below)
104
+ const src = this.data.texture.path;
105
+
106
+ // EntityInput → cast to WorldEntityView | null
107
+ const entity = this.data.target.value as WorldEntityView | null;
108
+
109
+ // ComponentInput → cast to the concrete component type
110
+ const cam = this.data.camera.value as CameraComponent | null;
111
+ }
112
+ }
113
+ ```
114
+
115
+ ## EntityInput — picking and using scene entities
116
+
117
+ `EntityInput` lets the editor user pick any entity from the scene. Declare it with `{ type: "entity", value: null }` as the default (no entity selected).
118
+
119
+ ```ts
120
+ import {
121
+ Behaviour,
122
+ type EntityInput,
123
+ } from "@relu-interactives/spatial-ecs";
124
+
125
+ export default class Follower extends Behaviour {
126
+ data = {
127
+ target: { type: "entity", value: null } as EntityInput,
128
+ };
129
+ }
130
+ ```
131
+
132
+ At runtime, `this.data.target.value` is resolved to a **`WorldEntityView`** — not a raw ID. You can import and use this type directly:
133
+
134
+ ```ts
135
+ import { type WorldEntityView } from "@relu-interactives/spatial-ecs";
136
+ ```
137
+
138
+ `WorldEntityView` has the following shape:
139
+
140
+ ```ts
141
+ type WorldEntityView = {
142
+ name: string; // entity name from the NameComponent
143
+ entityId: number; // runtime entity ID
144
+ type: string; // entity type ("mesh", "camera", "light", …)
145
+ object: THREE.Object3D | null; // live three.js scene object
146
+ components: Component[]; // all components attached to this entity
147
+ };
148
+ ```
149
+
150
+ ### Reading entity data
151
+
152
+ ```ts
153
+ onUpdate() {
154
+ const target = this.data.target.value as WorldEntityView | null;
155
+ if (!target) return; // no entity assigned in the inspector
156
+
157
+ // Name and ID
158
+ console.log(target.name); // e.g. "Camera"
159
+ console.log(target.entityId); // runtime numeric ID
160
+
161
+ // Access the three.js object directly
162
+ const obj = target.object;
163
+ if (obj) {
164
+ console.log(obj.position); // THREE.Vector3
165
+ }
166
+ }
167
+ ```
168
+
169
+ ### Moving another entity from a script
170
+
171
+ Use `getEntity()` on `WorldEntityView` to get the entity's transform and mutate it:
172
+
173
+ ```ts
174
+ import {
175
+ Behaviour,
176
+ TransformComponent,
177
+ type EntityInput,
178
+ type WorldEntityView,
179
+ } from "@relu-interactives/spatial-ecs";
180
+
181
+ export default class Mover extends Behaviour {
182
+ data = {
183
+ target: { type: "entity", value: null } as EntityInput,
184
+ speed: 5 as FloatInput,
185
+ };
186
+
187
+ onUpdate() {
188
+ const target = this.data.target.value as WorldEntityView | null;
189
+ if (!target) return;
190
+
191
+ // Find the TransformComponent on the picked entity
192
+ const transform = target.components.find(
193
+ (c) => c instanceof TransformComponent,
194
+ ) as TransformComponent | undefined;
195
+
196
+ if (transform) {
197
+ transform.position.x += this.data.speed * this.deltaTime;
198
+ }
199
+ }
200
+ }
201
+ ```
202
+
203
+ > [!TIP]
204
+ > Always guard with `if (!target) return;` — the field is `null` until the user picks an entity in the inspector, and may be `null` in new scenes.
205
+
206
+ ## ComponentInput — picking and using a specific component
207
+
208
+ `ComponentInput` lets the user pick an entity **and** a specific component kind from that entity. Use this when you want to read or drive a particular component (e.g. a `CameraComponent`, `AudioComponent`, or `AnimationComponent`).
209
+
210
+ ```ts
211
+ import {
212
+ Behaviour,
213
+ type ComponentInput,
214
+ } from "@relu-interactives/spatial-ecs";
215
+
216
+ export default class CameraController extends Behaviour {
217
+ data = {
218
+ cam: { type: "component", componentKind: "CameraComponent", value: null } as ComponentInput,
219
+ };
220
+ }
221
+ ```
222
+
223
+ At runtime, `this.data.cam.value` is resolved to the **live component instance** — the actual class instance that the ECS manages each frame.
224
+
225
+ ### Reading component properties
226
+
227
+ ```ts
228
+ import {
229
+ Behaviour,
230
+ CameraComponent,
231
+ type ComponentInput,
232
+ } from "@relu-interactives/spatial-ecs";
233
+
234
+ export default class FovAnimator extends Behaviour {
235
+ data = {
236
+ camera: { type: "component", componentKind: "CameraComponent", value: null } as ComponentInput,
237
+ targetFov: 90 as FloatInput,
238
+ };
239
+
240
+ onUpdate() {
241
+ const cam = this.data.camera.value as CameraComponent | null;
242
+ if (!cam) return; // no component assigned
243
+
244
+ // Read a property
245
+ console.log(cam.fov); // current field of view in degrees
246
+ }
247
+ }
248
+ ```
249
+
250
+ ### Changing component properties
251
+
252
+ Mutate the instance directly — the system that owns the component will pick up the change next frame:
253
+
254
+ ```ts
255
+ import {
256
+ Behaviour,
257
+ CameraComponent,
258
+ type ComponentInput,
259
+ type FloatInput,
260
+ } from "@relu-interactives/spatial-ecs";
261
+
262
+ export default class FovAnimator extends Behaviour {
263
+ data = {
264
+ camera: { type: "component", componentKind: "CameraComponent", value: null } as ComponentInput,
265
+ targetFov: 90 as FloatInput,
266
+ speed: 30 as FloatInput,
267
+ };
268
+
269
+ onUpdate() {
270
+ const cam = this.data.camera.value as CameraComponent | null;
271
+ if (!cam) return;
272
+
273
+ // Lerp the field of view toward targetFov
274
+ cam.fov += (this.data.targetFov - cam.fov) * this.data.speed * this.deltaTime;
275
+ }
276
+ }
277
+ ```
278
+
279
+ > [!TIP]
280
+ > Cast the resolved value to the concrete component type (e.g. `as CameraComponent | null`) to get full TypeScript autocompletion on its properties. Always guard the null case — the field is `null` until the user picks both an entity and a component in the inspector.
281
+
282
+ ## AssetInput — referencing project assets
283
+
284
+ `AssetInput` exposes a file picker in the inspector. The user selects a file from the project's `assets/` folder. The field stores the relative path to that file.
285
+
286
+ ```ts
287
+ import {
288
+ Behaviour,
289
+ type AssetInput,
290
+ } from "@relu-interactives/spatial-ecs";
291
+
292
+ export default class AudioPlayer extends Behaviour {
293
+ data = {
294
+ clip: { path: "", type: "audio" } as AssetInput,
295
+ };
296
+ }
297
+ ```
298
+
299
+ At runtime, **`this.data.clip.value` is always `null`** — `AssetInput` does not resolve to a loaded asset object. Use `this.data.clip.path` to get the relative file path, then load the asset yourself if needed:
300
+
301
+ ```ts
302
+ onUpdate() {
303
+ const path = this.data.clip.path;
304
+ if (!path) return;
305
+
306
+ // path is the relative asset path, e.g. "./assets/sounds/click.mp3"
307
+ console.log(path);
308
+ }
309
+ ```
310
+
311
+ The `type` field on the default value (`"audio"`, `"texture"`, `"model"`, etc.) is used by the editor to filter the file picker to relevant asset types.
312
+
313
+ ## Practical example — spinner with inspector controls
314
+
315
+ ```ts
316
+ import {
317
+ Behaviour,
318
+ type FloatInput,
319
+ type ColorInput,
320
+ type DropdownInput,
321
+ type ToggleInput,
322
+ } from "@relu-interactives/spatial-ecs";
323
+
324
+ export default class Spinner extends Behaviour {
325
+ data = {
326
+ speed: 1 as FloatInput,
327
+ color: "#00aaff" as ColorInput,
328
+ enabled: true as ToggleInput,
329
+ axis: {
330
+ value: "y",
331
+ options: [
332
+ { label: "X", value: "x" },
333
+ { label: "Y", value: "y" },
334
+ { label: "Z", value: "z" },
335
+ ],
336
+ } as DropdownInput,
337
+ };
338
+
339
+ onUpdate() {
340
+ if (!this.data.enabled) return;
341
+ const axis = this.data.axis.value as "x" | "y" | "z";
342
+ this.transform.rotation[axis] += this.data.speed * this.deltaTime;
343
+ }
344
+ }
345
+ ```
346
+
347
+ ## Defaulting fields
348
+
349
+ 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:
350
+
351
+ - Adding a new field with an inline default is safe — existing saves will pick it up on next load.
352
+ - The inspector always has a valid initial value when the script is first attached.
353
+ - For `SliderInput` and `DropdownInput`, the full object (including `options`) must be present in the inline default — the editor reads `options` to build the control.
354
+
355
+ ## Persistence
356
+
357
+ `ScriptComponent.data` is serialized and saved with the project. On reload, your `data` payload is restored verbatim. If you rename or restructure a field, migrate it inside `init()`:
358
+
359
+ ```ts
360
+ init() {
361
+ // migrate renamed field
362
+ if ((this.data as any).oldSpeed !== undefined) {
363
+ this.data.speed = (this.data as any).oldSpeed;
364
+ delete (this.data as any).oldSpeed;
365
+ }
366
+ }
367
+ ```
@@ -0,0 +1,202 @@
1
+ # Reading Input
2
+
3
+ Call input methods directly on `this.world` inside `onUpdate()` to query keyboard and mouse state each frame. There is no `world.input` accessor — all methods are on the `World` instance itself.
4
+
5
+ ```ts
6
+ import { Behaviour, KeyboardKeys } from "@relu-interactives/spatial-ecs";
7
+
8
+ export default class Example extends Behaviour {
9
+ onUpdate() {
10
+ // held this frame
11
+ if (this.world.getKey(KeyboardKeys.Space)) { /* … */ }
12
+
13
+ // only true on the first frame the key goes down
14
+ if (this.world.getKeyDown(KeyboardKeys.E)) { /* … */ }
15
+
16
+ // only true on the frame the key is released
17
+ if (this.world.getKeyUp(KeyboardKeys.E)) { /* … */ }
18
+ }
19
+ }
20
+ ```
21
+
22
+ ## API
23
+
24
+ All methods are called directly on `this.world`:
25
+
26
+ | Method | Description |
27
+ | --- | --- |
28
+ | `this.world.getKey(key)` | `true` while the key is held. |
29
+ | `this.world.getKeyDown(key)` | `true` only on the first frame the key is pressed. |
30
+ | `this.world.getKeyUp(key)` | `true` only on the frame the key is released. |
31
+ | `this.world.getMouse(button)` | `true` while the mouse button is held. `"left"` / `"middle"` / `"right"`. |
32
+ | `this.world.getMouseDown(button)` | `true` only on the first frame the button is pressed. |
33
+ | `this.world.getMouseUp(button)` | `true` only on the frame the button is released. |
34
+ | `this.world.getMousePosition()` | `{ x, y }` in viewport pixels. |
35
+ | `this.world.getMouseDelta()` | `{ x, y }` pointer movement since the last frame. |
36
+ | `this.world.consumeMouseDelta()` | `{ x, y }` movement since last frame; zeroes the delta after reading. |
37
+ | `this.world.getScrollDelta()` | `{ x, y }` scroll wheel delta since the last frame. |
38
+
39
+ ## KeyboardKeys reference
40
+
41
+ All constants are available from the `KeyboardKeys` import. Pass any of them to `getKey` / `getKeyDown` / `getKeyUp`.
42
+
43
+ ```ts
44
+ import { KeyboardKeys } from "@relu-interactives/spatial-ecs";
45
+ ```
46
+
47
+ ### Letters
48
+
49
+ `KeyboardKeys.A` through `KeyboardKeys.Z`
50
+
51
+ ### Digits
52
+
53
+ `KeyboardKeys.Digit0` through `KeyboardKeys.Digit9`
54
+
55
+ ### Navigation & editing
56
+
57
+ | Constant | Key |
58
+ | --- | --- |
59
+ | `KeyboardKeys.ArrowUp` | ↑ Arrow |
60
+ | `KeyboardKeys.ArrowDown` | ↓ Arrow |
61
+ | `KeyboardKeys.ArrowLeft` | ← Arrow |
62
+ | `KeyboardKeys.ArrowRight` | → Arrow |
63
+ | `KeyboardKeys.Space` | Space |
64
+ | `KeyboardKeys.Enter` | Enter / Return |
65
+ | `KeyboardKeys.Escape` | Escape |
66
+ | `KeyboardKeys.Tab` | Tab |
67
+ | `KeyboardKeys.Backspace` | Backspace |
68
+ | `KeyboardKeys.Delete` | Delete |
69
+ | `KeyboardKeys.Insert` | Insert |
70
+ | `KeyboardKeys.Home` | Home |
71
+ | `KeyboardKeys.End` | End |
72
+ | `KeyboardKeys.PageUp` | Page Up |
73
+ | `KeyboardKeys.PageDown` | Page Down |
74
+
75
+ ### Modifier keys
76
+
77
+ Generic variants match either the left or right physical key. Use the specific variant when the side matters.
78
+
79
+ | Constant | Physical key |
80
+ | --- | --- |
81
+ | `KeyboardKeys.Shift` | Either Shift key |
82
+ | `KeyboardKeys.ShiftLeft` | Left Shift |
83
+ | `KeyboardKeys.ShiftRight` | Right Shift |
84
+ | `KeyboardKeys.Control` | Either Ctrl key |
85
+ | `KeyboardKeys.ControlLeft` | Left Ctrl |
86
+ | `KeyboardKeys.ControlRight` | Right Ctrl |
87
+ | `KeyboardKeys.Alt` | Alt / Option |
88
+ | `KeyboardKeys.Meta` | Cmd (macOS) / Win key |
89
+ | `KeyboardKeys.CapsLock` | Caps Lock |
90
+
91
+ ### Function keys
92
+
93
+ `KeyboardKeys.F1` through `KeyboardKeys.F12`
94
+
95
+ ### Punctuation & symbols
96
+
97
+ | Constant | Key |
98
+ | --- | --- |
99
+ | `KeyboardKeys.Minus` | `-` |
100
+ | `KeyboardKeys.Equal` | `=` |
101
+ | `KeyboardKeys.BracketLeft` | `[` |
102
+ | `KeyboardKeys.BracketRight` | `]` |
103
+ | `KeyboardKeys.Backslash` | `\` |
104
+ | `KeyboardKeys.Semicolon` | `;` |
105
+ | `KeyboardKeys.Quote` | `'` |
106
+ | `KeyboardKeys.Backquote` | `` ` `` |
107
+ | `KeyboardKeys.Comma` | `,` |
108
+ | `KeyboardKeys.Period` | `.` |
109
+ | `KeyboardKeys.Slash` | `/` |
110
+
111
+ ### Other
112
+
113
+ | Constant | Key |
114
+ | --- | --- |
115
+ | `KeyboardKeys.NumLock` | Num Lock |
116
+ | `KeyboardKeys.ScrollLock` | Scroll Lock |
117
+ | `KeyboardKeys.Pause` | Pause / Break |
118
+ | `KeyboardKeys.PrintScreen` | Print Screen |
119
+ | `KeyboardKeys.ContextMenu` | Context Menu |
120
+
121
+ ## Examples
122
+
123
+ ### WASD movement with sprint
124
+
125
+ ```ts
126
+ import { Behaviour, KeyboardKeys } from "@relu-interactives/spatial-ecs";
127
+
128
+ export default class Movement extends Behaviour {
129
+ speed = 5;
130
+ sprintMultiplier = 2;
131
+
132
+ onUpdate() {
133
+ const step = this.speed * (this.world.getKey(KeyboardKeys.Shift) ? this.sprintMultiplier : 1) * this.deltaTime;
134
+
135
+ if (this.world.getKey(KeyboardKeys.W)) this.transform.position.z -= step;
136
+ if (this.world.getKey(KeyboardKeys.S)) this.transform.position.z += step;
137
+ if (this.world.getKey(KeyboardKeys.A)) this.transform.position.x -= step;
138
+ if (this.world.getKey(KeyboardKeys.D)) this.transform.position.x += step;
139
+ }
140
+ }
141
+ ```
142
+
143
+ ### One-shot action on key press and mouse click
144
+
145
+ `getKeyDown` fires only on the frame the key transitions from up to down, so it is safe to use for one-shot actions.
146
+
147
+ ```ts
148
+ import { Behaviour, KeyboardKeys } from "@relu-interactives/spatial-ecs";
149
+
150
+ export default class ActionHandler extends Behaviour {
151
+ onUpdate() {
152
+ if (this.world.getKeyDown(KeyboardKeys.Space)) {
153
+ console.log("Jump!");
154
+ }
155
+
156
+ if (this.world.getMouseDown("left")) {
157
+ const pos = this.world.getMousePosition();
158
+ console.log("Fired at", pos.x, pos.y);
159
+ }
160
+ }
161
+ }
162
+ ```
163
+
164
+ ### Distinguishing left vs right modifier
165
+
166
+ ```ts
167
+ import { Behaviour, KeyboardKeys } from "@relu-interactives/spatial-ecs";
168
+
169
+ export default class ModifierDemo extends Behaviour {
170
+ onUpdate() {
171
+ if (this.world.getKeyDown(KeyboardKeys.ControlLeft)) {
172
+ console.log("Left Ctrl");
173
+ }
174
+ if (this.world.getKeyDown(KeyboardKeys.ControlRight)) {
175
+ console.log("Right Ctrl");
176
+ }
177
+
178
+ // Matches either Shift key
179
+ if (this.world.getKey(KeyboardKeys.Shift)) {
180
+ console.log("Shift held");
181
+ }
182
+ }
183
+ }
184
+ ```
185
+
186
+ ### Mouse-delta camera look
187
+
188
+ ```ts
189
+ import { Behaviour } from "@relu-interactives/spatial-ecs";
190
+
191
+ export default class CameraLook extends Behaviour {
192
+ sensitivity = 0.002;
193
+
194
+ onUpdate() {
195
+ const { x, y } = this.world.consumeMouseDelta();
196
+ this.transform.rotation.y -= x * this.sensitivity;
197
+ this.transform.rotation.x -= y * this.sensitivity;
198
+ }
199
+ }
200
+ ```
201
+
202
+ For `InputSystem` internals and pointer-lock details, see the [InputSystem guide](./systems/input-system).
@@ -0,0 +1,101 @@
1
+ # Environment
2
+
3
+ The `Environment` component holds scene-wide settings:
4
+
5
+ - **Skybox:** gradient, solid color, equirectangular image, or none.
6
+ - **Fog:** linear, exponential, or none.
7
+ - **Gravity:** the world gravity vector applied by the physics system (in m/s²).
8
+
9
+ It is a **singleton** there is exactly one `Environment` entity per scene, owned by the editor.
10
+
11
+ > **Managed by:** [`EnvironmentSyncSystem`](../systems/environment-sync-system)
12
+
13
+ ## Get the component from the world
14
+
15
+ ```ts
16
+ import { Behaviour, Environment } from "@relu-interactives/spatial-ecs";
17
+
18
+ export default class ReadEnvironment extends Behaviour {
19
+ init() {
20
+ const [entityId] = this.world.query(Environment);
21
+ if (entityId === undefined) return;
22
+
23
+ const env = this.world.getComponent(entityId, Environment);
24
+ if (!env) return;
25
+
26
+ console.log("skybox type", env.values.skybox.type);
27
+ console.log("gravity", env.values.gravity);
28
+ }
29
+ }
30
+ ```
31
+
32
+ `env.values` is the live state object. Mutating fields on it is enough, the `EnvironmentSyncSystem` reads it every frame and pushes changes into the three.js scene.
33
+
34
+ ## Change values at runtime
35
+
36
+ ### Switch the skybox
37
+
38
+ ```ts
39
+ env.values.skybox.type = "gradient";
40
+ env.values.skybox.gradient.colors = ["#0b1026", "#3b6dd6", "#f7d488"];
41
+ env.values.skybox.gradient.effect = "linear"; // "linear" | "radial" | "angular"
42
+
43
+ // Or use a solid color:
44
+ env.values.skybox.type = "color";
45
+ env.values.skybox.color = "#101010";
46
+
47
+ // Or an equirectangular image:
48
+ env.values.skybox.type = "image";
49
+ env.values.skybox.imageUrl = "/assets/skies/studio.hdr";
50
+
51
+ // Or disable it:
52
+ env.values.skybox.type = "none";
53
+ ```
54
+
55
+ ### Configure fog
56
+
57
+ ```ts
58
+ // Linear fog
59
+ env.values.fog.type = "linear";
60
+ env.values.fog.color = "#aabbcc";
61
+ env.values.fog.linear.near = 1;
62
+ env.values.fog.linear.far = 50;
63
+
64
+ // Exponential fog
65
+ env.values.fog.type = "exponential";
66
+ env.values.fog.exponential.density = 0.05;
67
+
68
+ // Off
69
+ env.values.fog.type = "none";
70
+ ```
71
+
72
+ ### Change physics gravity
73
+
74
+ ```ts
75
+ // Moon-like gravity
76
+ env.values.gravity = { x: 0, y: -1.62, z: 0 };
77
+
78
+ // Zero-G
79
+ env.values.gravity = { x: 0, y: 0, z: 0 };
80
+ ```
81
+
82
+ ## Authorable values
83
+
84
+ | Path | Type | Default | Notes |
85
+ | --- | --- | --- | --- |
86
+ | `skybox.type` | `"gradient" \| "color" \| "image" \| "none"` | `"none"` | Active skybox mode. |
87
+ | `skybox.color` | `string` (hex) | `"#1e1e1e"` | Used when `type` is `"color"`. |
88
+ | `skybox.imageUrl` | `string` | `""` | Used when `type` is `"image"`. |
89
+ | `skybox.gradient.colors` | `string[]` | `["#464766", "#657ea6", "#0f0e1a"]` | Hex color stops. |
90
+ | `skybox.gradient.effect` | `"linear" \| "radial" \| "angular"` | `"linear"` | Gradient distribution. |
91
+ | `fog.type` | `"linear" \| "exponential" \| "none"` | `"none"` | Fog model. |
92
+ | `fog.color` | `string` (hex) | `"#1e1e1e"` | Fog color. |
93
+ | `fog.linear.near` | `number` | `1` | Distance where fog starts. |
94
+ | `fog.linear.far` | `number` | `100` | Distance where fog reaches full opacity. |
95
+ | `fog.exponential.density` | `number` | `0.002` | Higher = thicker fog. |
96
+ | `gravity` | `{ x, y, z }` | `(0, -9.81, 0)` | World units per second squared. |
97
+
98
+ ## API reference
99
+
100
+ - Class: [`Environment`](../../api/components/classes/Environment.md)
101
+ - Source: [`core/components/Environment.ts`](https://github.com/Relu-Interactives/relu-spatial-ecs-engine/blob/main/core/components/Environment.ts)
@@ -0,0 +1,36 @@
1
+ # Scene
2
+
3
+ Some settings live on the **scene** rather than on a single object the skybox, fog, gravity, and the post-processing stack. They are stored on a singleton entity so you can read and mutate them from any `Behaviour`.
4
+
5
+ | Page | What it covers |
6
+ | --- | --- |
7
+ | [Environment](./environment) | Skybox (gradient / color / image), fog (linear / exponential), and physics gravity. |
8
+ | [Postprocessing](./postprocessing) | Bloom, vignette, depth-of-field, tone mapping, and other full-screen effects. |
9
+
10
+ ## Pattern
11
+
12
+ Both components follow the same access pattern from a script:
13
+
14
+ ```ts
15
+ import { Behaviour, Environment, Postprocessing } from "@relu-interactives/spatial-ecs";
16
+
17
+ export default class TweakScene extends Behaviour {
18
+ init() {
19
+ // 1. Find the singleton entity that owns the component.
20
+ const [entityId] = this.world.query(Environment);
21
+ if (entityId === undefined) return;
22
+
23
+ // 2. Read the component instance.
24
+ const env = this.world.getComponent(entityId, Environment);
25
+ if (!env) return;
26
+
27
+ // 3. Mutate `env.values` — sync systems pick the change up next frame.
28
+ env.values.fog.type = "linear";
29
+ env.values.fog.color = "#88aaff";
30
+ env.values.fog.linear.near = 5;
31
+ env.values.fog.linear.far = 60;
32
+ }
33
+ }
34
+ ```
35
+
36
+ The same shape works for `Postprocessing` — see each page for the full set of authorable values.