lecodes-sdk 0.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (367) hide show
  1. package/README.md +114 -0
  2. package/dist/global.d.ts +503 -0
  3. package/dist/host.d.ts +61 -0
  4. package/dist/inject.js +4730 -0
  5. package/dist/types/animate/animate.d.ts +20 -0
  6. package/dist/types/animate/bezier.d.ts +2 -0
  7. package/dist/types/animate/easings.d.ts +21 -0
  8. package/dist/types/canvas/Canvas.d.ts +168 -0
  9. package/dist/types/core/Aspect.d.ts +171 -0
  10. package/dist/types/core/InspectorUI.d.ts +88 -0
  11. package/dist/types/core/StateMachine.d.ts +81 -0
  12. package/dist/types/core/color.d.ts +13 -0
  13. package/dist/types/core/compWrite.d.ts +11 -0
  14. package/dist/types/core/events.d.ts +11 -0
  15. package/dist/types/core/fields.d.ts +58 -0
  16. package/dist/types/core/registry.d.ts +7 -0
  17. package/dist/types/core/signals.d.ts +29 -0
  18. package/dist/types/core/time.d.ts +31 -0
  19. package/dist/types/g2/Camera2D.d.ts +19 -0
  20. package/dist/types/g2/CharacterController2D.d.ts +134 -0
  21. package/dist/types/g2/Node2D.d.ts +91 -0
  22. package/dist/types/g2/OneWay2D.d.ts +24 -0
  23. package/dist/types/g2/Physics2D.d.ts +147 -0
  24. package/dist/types/g2/Scene2D.d.ts +72 -0
  25. package/dist/types/g2/Shape2D.d.ts +58 -0
  26. package/dist/types/g2/Sprite.d.ts +51 -0
  27. package/dist/types/g2/SpriteAnimation.d.ts +50 -0
  28. package/dist/types/g2/SpriteSheet.d.ts +69 -0
  29. package/dist/types/g2/Texture2D.d.ts +16 -0
  30. package/dist/types/g2/Tilemap.d.ts +20 -0
  31. package/dist/types/g2/Tileset.d.ts +32 -0
  32. package/dist/types/g2/Trigger2D.d.ts +20 -0
  33. package/dist/types/g2/autotile.d.ts +133 -0
  34. package/dist/types/g2/cells.d.ts +14 -0
  35. package/dist/types/g2/defineScene2d.d.ts +141 -0
  36. package/dist/types/g2/groups2d.d.ts +16 -0
  37. package/dist/types/g2/loop.d.ts +4 -0
  38. package/dist/types/g2/scenarios2d.d.ts +30 -0
  39. package/dist/types/g2/touch.d.ts +2 -0
  40. package/dist/types/gl/Camera.d.ts +79 -0
  41. package/dist/types/gl/CameraPlace.d.ts +26 -0
  42. package/dist/types/gl/CharacterController.d.ts +98 -0
  43. package/dist/types/gl/Gearbox.d.ts +86 -0
  44. package/dist/types/gl/Geometry.d.ts +39 -0
  45. package/dist/types/gl/IK.d.ts +53 -0
  46. package/dist/types/gl/InstancedMesh.d.ts +46 -0
  47. package/dist/types/gl/Light.d.ts +73 -0
  48. package/dist/types/gl/Lightmap.d.ts +85 -0
  49. package/dist/types/gl/Locomotion.d.ts +279 -0
  50. package/dist/types/gl/Material.d.ts +100 -0
  51. package/dist/types/gl/Mesh.d.ts +33 -0
  52. package/dist/types/gl/Model.d.ts +53 -0
  53. package/dist/types/gl/NavAgent.d.ts +99 -0
  54. package/dist/types/gl/NavMesh.d.ts +169 -0
  55. package/dist/types/gl/Node.d.ts +99 -0
  56. package/dist/types/gl/Noise.d.ts +20 -0
  57. package/dist/types/gl/Particles.d.ts +277 -0
  58. package/dist/types/gl/Physics.d.ts +91 -0
  59. package/dist/types/gl/Plane.d.ts +19 -0
  60. package/dist/types/gl/Ragdoll.d.ts +86 -0
  61. package/dist/types/gl/Ray.d.ts +8 -0
  62. package/dist/types/gl/Scene.d.ts +221 -0
  63. package/dist/types/gl/Shape.d.ts +122 -0
  64. package/dist/types/gl/Terrain.d.ts +280 -0
  65. package/dist/types/gl/Texture.d.ts +27 -0
  66. package/dist/types/gl/Trigger.d.ts +10 -0
  67. package/dist/types/gl/Vehicle.d.ts +191 -0
  68. package/dist/types/gl/Wheel.d.ts +95 -0
  69. package/dist/types/gl/animation/AnimationClip.d.ts +60 -0
  70. package/dist/types/gl/animation/Animator.d.ts +219 -0
  71. package/dist/types/gl/animation/Layer.d.ts +31 -0
  72. package/dist/types/gl/animation/Loop.d.ts +17 -0
  73. package/dist/types/gl/animation/Playback.d.ts +36 -0
  74. package/dist/types/gl/animation/core.d.ts +367 -0
  75. package/dist/types/gl/controls.d.ts +19 -0
  76. package/dist/types/gl/physicsEvents.d.ts +1 -0
  77. package/dist/types/gl/scenarios.d.ts +98 -0
  78. package/dist/types/gl/state.d.ts +5 -0
  79. package/dist/types/gl/terrainMesh.d.ts +46 -0
  80. package/dist/types/gl/touch.d.ts +2 -0
  81. package/dist/types/inject.d.ts +123 -0
  82. package/dist/types/math/Mathf.d.ts +39 -0
  83. package/dist/types/math/mat4.d.ts +66 -0
  84. package/dist/types/math/quat.d.ts +53 -0
  85. package/dist/types/math/vec.d.ts +129 -0
  86. package/dist/types/net/codec.d.ts +25 -0
  87. package/dist/types/net/core.d.ts +106 -0
  88. package/dist/types/net/index.d.ts +80 -0
  89. package/dist/types/net/replication.d.ts +101 -0
  90. package/dist/types/plugins/camera.d.ts +25 -0
  91. package/dist/types/plugins/geolocation.d.ts +39 -0
  92. package/dist/types/plugins/oauth.d.ts +25 -0
  93. package/dist/types/plugins/permission.d.ts +1 -0
  94. package/dist/types/plugins/push.d.ts +46 -0
  95. package/dist/types/plugins/qr.d.ts +21 -0
  96. package/dist/types/plugins/service.d.ts +33 -0
  97. package/dist/types/runtime/app.d.ts +67 -0
  98. package/dist/types/runtime/appEvents.d.ts +7 -0
  99. package/dist/types/runtime/channel.d.ts +1 -0
  100. package/dist/types/runtime/clipboard.d.ts +7 -0
  101. package/dist/types/runtime/datetime.d.ts +80 -0
  102. package/dist/types/runtime/device.d.ts +126 -0
  103. package/dist/types/runtime/fetch.d.ts +31 -0
  104. package/dist/types/runtime/files.d.ts +33 -0
  105. package/dist/types/runtime/input.d.ts +121 -0
  106. package/dist/types/runtime/media.d.ts +46 -0
  107. package/dist/types/runtime/misc.d.ts +11 -0
  108. package/dist/types/runtime/net.d.ts +15 -0
  109. package/dist/types/runtime/rpc.d.ts +44 -0
  110. package/dist/types/runtime/service.d.ts +1 -0
  111. package/dist/types/runtime/share.d.ts +2 -0
  112. package/dist/types/runtime/storage.d.ts +5 -0
  113. package/dist/types/runtime/touch.d.ts +56 -0
  114. package/dist/types/scene/defineScene.d.ts +296 -0
  115. package/dist/types/scene/editorPlugins.d.ts +82 -0
  116. package/dist/types/scene/gizmos.d.ts +56 -0
  117. package/dist/types/scene/grammar.d.ts +56 -0
  118. package/dist/types/scene/level.d.ts +98 -0
  119. package/dist/types/scene/material.d.ts +76 -0
  120. package/dist/types/server/auth/appConfig.d.ts +16 -0
  121. package/dist/types/server/auth/global.d.ts +56 -0
  122. package/dist/types/server/auth/models.d.ts +164 -0
  123. package/dist/types/server/auth/types.d.ts +56 -0
  124. package/dist/types/server/channel.d.ts +28 -0
  125. package/dist/types/server/context.d.ts +27 -0
  126. package/dist/types/server/db/defineDb.d.ts +36 -0
  127. package/dist/types/server/db/fields.d.ts +146 -0
  128. package/dist/types/server/db/index.d.ts +6 -0
  129. package/dist/types/server/db/marci/query.d.ts +326 -0
  130. package/dist/types/server/db/types.d.ts +163 -0
  131. package/dist/types/server/errors.d.ts +8 -0
  132. package/dist/types/server/inject.d.ts +5 -0
  133. package/dist/types/ui/NativeView.d.ts +38 -0
  134. package/dist/types/ui/UI.d.ts +27 -0
  135. package/dist/types/ui/UIBottomSheet.d.ts +71 -0
  136. package/dist/types/ui/UIButton.d.ts +30 -0
  137. package/dist/types/ui/UIContainer.d.ts +33 -0
  138. package/dist/types/ui/UIImage.d.ts +35 -0
  139. package/dist/types/ui/UIInput.d.ts +110 -0
  140. package/dist/types/ui/UIModal.d.ts +70 -0
  141. package/dist/types/ui/UINode.d.ts +363 -0
  142. package/dist/types/ui/UIPager.d.ts +123 -0
  143. package/dist/types/ui/UIPopover.d.ts +39 -0
  144. package/dist/types/ui/UIScreen.d.ts +57 -0
  145. package/dist/types/ui/UIScrollable.d.ts +40 -0
  146. package/dist/types/ui/UISpacer.d.ts +9 -0
  147. package/dist/types/ui/UITabs.d.ts +96 -0
  148. package/dist/types/ui/UIText.d.ts +19 -0
  149. package/dist/types/ui/UIVideo.d.ts +28 -0
  150. package/dist/types/ui/UIVirtualizedList.d.ts +97 -0
  151. package/dist/types/ui/UIWidget.d.ts +65 -0
  152. package/dist/types/ui/fonts.d.ts +9 -0
  153. package/dist/types/ui/presentable.d.ts +68 -0
  154. package/dist/types/ui/router.d.ts +40 -0
  155. package/dist/types/ui/theme.d.ts +26 -0
  156. package/dist/types.json +1 -0
  157. package/package.json +46 -0
  158. package/prompts/2d.md +395 -0
  159. package/prompts/3d-scene-files.md +113 -0
  160. package/prompts/3d-scene.md +119 -0
  161. package/prompts/3d.md +303 -0
  162. package/prompts/README.md +142 -0
  163. package/prompts/ar.md +109 -0
  164. package/prompts/canvas.md +27 -0
  165. package/prompts/compose.ts +46 -0
  166. package/prompts/concept.md +49 -0
  167. package/prompts/core-design.md +75 -0
  168. package/prompts/core.md +264 -0
  169. package/prompts/design.md +218 -0
  170. package/prompts/dist/2d-game.md +1530 -0
  171. package/prompts/dist/3d-app.md +1672 -0
  172. package/prompts/dist/ar-app.md +1548 -0
  173. package/prompts/dist/concept.md +49 -0
  174. package/prompts/dist/design.md +498 -0
  175. package/prompts/dist/ui-app.md +1134 -0
  176. package/prompts/index.md +37 -0
  177. package/prompts/intake-prompt.md +33 -0
  178. package/prompts/namer-prompt.md +12 -0
  179. package/prompts/router-prompt.md +50 -0
  180. package/prompts/select.ts +111 -0
  181. package/prompts/ui-design.md +203 -0
  182. package/prompts/ui.md +803 -0
  183. package/src/animate/animate.ts +238 -0
  184. package/src/animate/bezier.ts +138 -0
  185. package/src/animate/easings.ts +126 -0
  186. package/src/bridges.d.ts +1345 -0
  187. package/src/canvas/Canvas.ts +305 -0
  188. package/src/compile/__tests__/assetIconMacro.test.ts +219 -0
  189. package/src/compile/__tests__/assetMacro.test.ts +74 -0
  190. package/src/compile/__tests__/assetName.test.ts +55 -0
  191. package/src/compile/__tests__/compile.test.ts +287 -0
  192. package/src/compile/__tests__/detectEntry.test.ts +132 -0
  193. package/src/compile/__tests__/fontMacro.test.ts +199 -0
  194. package/src/compile/aspectMacro.ts +86 -0
  195. package/src/compile/assetIconMacro.ts +384 -0
  196. package/src/compile/assetMacro.ts +146 -0
  197. package/src/compile/assetName.ts +50 -0
  198. package/src/compile/bundler.ts +287 -0
  199. package/src/compile/compileProject.ts +127 -0
  200. package/src/compile/detectEntry.ts +128 -0
  201. package/src/compile/fontMacro.ts +459 -0
  202. package/src/compile/fontRegistry.ts +78 -0
  203. package/src/compile/header.ts +67 -0
  204. package/src/compile/index.ts +100 -0
  205. package/src/compile/libraryImports.ts +52 -0
  206. package/src/compile/liteMaterial.ts +247 -0
  207. package/src/compile/sceneEditor.ts +88 -0
  208. package/src/compile/serverSplit.ts +233 -0
  209. package/src/compile/serverTypes.ts +227 -0
  210. package/src/compile/sfnt.ts +98 -0
  211. package/src/compile/shaderSchema.ts +202 -0
  212. package/src/compile/shaderTargets.ts +77 -0
  213. package/src/compile/sourcemap.ts +25 -0
  214. package/src/core/Aspect.ts +568 -0
  215. package/src/core/InspectorUI.ts +212 -0
  216. package/src/core/StateMachine.ts +308 -0
  217. package/src/core/__tests__/stateMachine.test.ts +132 -0
  218. package/src/core/color.ts +66 -0
  219. package/src/core/compWrite.ts +42 -0
  220. package/src/core/events.ts +38 -0
  221. package/src/core/fields.ts +120 -0
  222. package/src/core/registry.ts +23 -0
  223. package/src/core/signals.ts +277 -0
  224. package/src/core/time.ts +84 -0
  225. package/src/g2/Camera2D.ts +40 -0
  226. package/src/g2/CharacterController2D.ts +276 -0
  227. package/src/g2/Node2D.ts +267 -0
  228. package/src/g2/OneWay2D.ts +66 -0
  229. package/src/g2/Physics2D.ts +346 -0
  230. package/src/g2/Scene2D.ts +209 -0
  231. package/src/g2/Shape2D.ts +259 -0
  232. package/src/g2/Sprite.ts +89 -0
  233. package/src/g2/SpriteAnimation.ts +171 -0
  234. package/src/g2/SpriteSheet.ts +166 -0
  235. package/src/g2/Texture2D.ts +47 -0
  236. package/src/g2/Tilemap.ts +41 -0
  237. package/src/g2/Tileset.ts +71 -0
  238. package/src/g2/Trigger2D.ts +77 -0
  239. package/src/g2/autotile.ts +433 -0
  240. package/src/g2/cells.ts +91 -0
  241. package/src/g2/defineScene2d.ts +381 -0
  242. package/src/g2/groups2d.ts +106 -0
  243. package/src/g2/loop.ts +50 -0
  244. package/src/g2/scenarios2d.ts +69 -0
  245. package/src/g2/touch.ts +83 -0
  246. package/src/gl/Camera.ts +160 -0
  247. package/src/gl/CameraPlace.ts +52 -0
  248. package/src/gl/CharacterController.ts +238 -0
  249. package/src/gl/Gearbox.ts +212 -0
  250. package/src/gl/Geometry.ts +279 -0
  251. package/src/gl/IK.ts +193 -0
  252. package/src/gl/InstancedMesh.ts +132 -0
  253. package/src/gl/Light.ts +135 -0
  254. package/src/gl/Lightmap.ts +402 -0
  255. package/src/gl/Locomotion.ts +498 -0
  256. package/src/gl/Material.ts +279 -0
  257. package/src/gl/Mesh.ts +83 -0
  258. package/src/gl/Model.ts +124 -0
  259. package/src/gl/NavAgent.ts +337 -0
  260. package/src/gl/NavMesh.ts +397 -0
  261. package/src/gl/Node.ts +350 -0
  262. package/src/gl/Noise.ts +30 -0
  263. package/src/gl/Particles.ts +676 -0
  264. package/src/gl/Physics.ts +222 -0
  265. package/src/gl/Plane.ts +53 -0
  266. package/src/gl/Ragdoll.ts +270 -0
  267. package/src/gl/Ray.ts +16 -0
  268. package/src/gl/Scene.ts +505 -0
  269. package/src/gl/Shape.ts +409 -0
  270. package/src/gl/Terrain.ts +1092 -0
  271. package/src/gl/Texture.ts +63 -0
  272. package/src/gl/Trigger.ts +45 -0
  273. package/src/gl/Vehicle.ts +473 -0
  274. package/src/gl/Wheel.ts +240 -0
  275. package/src/gl/animation/AnimationClip.ts +204 -0
  276. package/src/gl/animation/Animator.ts +329 -0
  277. package/src/gl/animation/Layer.ts +39 -0
  278. package/src/gl/animation/Loop.ts +31 -0
  279. package/src/gl/animation/Playback.ts +52 -0
  280. package/src/gl/animation/core.ts +670 -0
  281. package/src/gl/controls.ts +95 -0
  282. package/src/gl/physicsEvents.ts +20 -0
  283. package/src/gl/scenarios.ts +291 -0
  284. package/src/gl/state.ts +6 -0
  285. package/src/gl/terrainMesh.ts +219 -0
  286. package/src/gl/touch.ts +68 -0
  287. package/src/host.d.ts +61 -0
  288. package/src/inject.ts +203 -0
  289. package/src/math/Mathf.ts +118 -0
  290. package/src/math/mat4.ts +278 -0
  291. package/src/math/quat.ts +232 -0
  292. package/src/math/vec.ts +255 -0
  293. package/src/net/codec.ts +119 -0
  294. package/src/net/core.ts +384 -0
  295. package/src/net/index.ts +181 -0
  296. package/src/net/replication.ts +622 -0
  297. package/src/plugins/camera.ts +81 -0
  298. package/src/plugins/geolocation.ts +123 -0
  299. package/src/plugins/oauth.ts +61 -0
  300. package/src/plugins/permission.ts +7 -0
  301. package/src/plugins/push.ts +132 -0
  302. package/src/plugins/qr.ts +73 -0
  303. package/src/plugins/service.ts +47 -0
  304. package/src/runtime/app.ts +101 -0
  305. package/src/runtime/appEvents.ts +54 -0
  306. package/src/runtime/channel.ts +61 -0
  307. package/src/runtime/clipboard.ts +20 -0
  308. package/src/runtime/datetime.ts +329 -0
  309. package/src/runtime/device.ts +293 -0
  310. package/src/runtime/fetch.ts +77 -0
  311. package/src/runtime/files.ts +108 -0
  312. package/src/runtime/input.ts +175 -0
  313. package/src/runtime/media.ts +111 -0
  314. package/src/runtime/misc.ts +16 -0
  315. package/src/runtime/net.ts +36 -0
  316. package/src/runtime/rpc.ts +218 -0
  317. package/src/runtime/service.ts +83 -0
  318. package/src/runtime/share.ts +9 -0
  319. package/src/runtime/storage.ts +13 -0
  320. package/src/runtime/touch.ts +76 -0
  321. package/src/scene/defineScene.ts +1396 -0
  322. package/src/scene/editorPlugins.ts +110 -0
  323. package/src/scene/gizmos.ts +148 -0
  324. package/src/scene/grammar.ts +120 -0
  325. package/src/scene/level.ts +296 -0
  326. package/src/scene/material.ts +188 -0
  327. package/src/server/auth/appConfig.ts +12 -0
  328. package/src/server/auth/global.ts +80 -0
  329. package/src/server/auth/host.ts +318 -0
  330. package/src/server/auth/models.ts +83 -0
  331. package/src/server/auth/types.ts +50 -0
  332. package/src/server/channel.ts +56 -0
  333. package/src/server/context.ts +36 -0
  334. package/src/server/db/defineDb.ts +237 -0
  335. package/src/server/db/fields.ts +132 -0
  336. package/src/server/db/httpTransport.ts +93 -0
  337. package/src/server/db/index.ts +7 -0
  338. package/src/server/db/marci/query.ts +412 -0
  339. package/src/server/db/types.ts +202 -0
  340. package/src/server/errors.ts +12 -0
  341. package/src/server/host.ts +74 -0
  342. package/src/server/inject.ts +13 -0
  343. package/src/server/runtime.ts +133 -0
  344. package/src/server/validate.ts +87 -0
  345. package/src/ui/NativeView.ts +142 -0
  346. package/src/ui/UI.ts +39 -0
  347. package/src/ui/UIBottomSheet.ts +139 -0
  348. package/src/ui/UIButton.ts +101 -0
  349. package/src/ui/UIContainer.ts +60 -0
  350. package/src/ui/UIImage.ts +83 -0
  351. package/src/ui/UIInput.ts +185 -0
  352. package/src/ui/UIModal.ts +139 -0
  353. package/src/ui/UINode.ts +830 -0
  354. package/src/ui/UIPager.ts +362 -0
  355. package/src/ui/UIPopover.ts +100 -0
  356. package/src/ui/UIScreen.ts +123 -0
  357. package/src/ui/UIScrollable.ts +87 -0
  358. package/src/ui/UISpacer.ts +14 -0
  359. package/src/ui/UITabs.ts +236 -0
  360. package/src/ui/UIText.ts +51 -0
  361. package/src/ui/UIVideo.ts +88 -0
  362. package/src/ui/UIVirtualizedList.ts +241 -0
  363. package/src/ui/UIWidget.ts +127 -0
  364. package/src/ui/fonts.ts +13 -0
  365. package/src/ui/presentable.ts +117 -0
  366. package/src/ui/router.ts +132 -0
  367. package/src/ui/theme.ts +84 -0
@@ -0,0 +1,255 @@
1
+ // Fluent 2D / 3D vectors — the SDK's user-facing vector math (no gl-matrix, no out-params, no imports).
2
+ //
3
+ // Design (see PLAN.md): a vector is a *mutable little struct* — `v.x = 3`, `v.set(x, y, z)` mutate in
4
+ // place — but every *method* is PURE: `a.add(b)` returns a NEW vector and never touches `a`. So chains
5
+ // (`dir.normalize().scale(s)`) can't clobber their source, and the immutable-method style is the most
6
+ // amenable to a future escape-analysis / scalar-replacement compiler pass. Backing is plain number
7
+ // fields (not a Float32Array), which the optimizer can trivially scalar-replace.
8
+ //
9
+ // "Never wrap away the metal": vectors expose `.x/.y/.z`, are iterable (`const [x, y] = v`, `[...v]`),
10
+ // and every method / constructor accepts a raw tuple just as well as a wrapper. Reads off a `*Like`
11
+ // input go through the `cx/cy/cz` helpers below, which work uniformly on a wrapper (`.x`) or an
12
+ // array-like (`[0]`), so callers can always pass `[0, 1, 0]` where a vector is expected.
13
+
14
+ export type Vec2Like = Vec2 | readonly [number, number] | number[] | Float32Array
15
+ export type Vec3Like = Vec3 | readonly [number, number, number] | number[] | Float32Array
16
+
17
+ /** Read the x / first component of any vector-like (wrapper, tuple, or typed array). `?? ` is safe on
18
+ * 0 and NaN — it only falls through on `undefined` (i.e. a non-wrapper that has no `.x`). */
19
+ export const cx = (v: { x?: number } | ArrayLike<number>): number => (v as { x?: number }).x ?? (v as ArrayLike<number>)[0]
20
+ export const cy = (v: { y?: number } | ArrayLike<number>): number => (v as { y?: number }).y ?? (v as ArrayLike<number>)[1]
21
+ export const cz = (v: { z?: number } | ArrayLike<number>): number => (v as { z?: number }).z ?? (v as ArrayLike<number>)[2]
22
+
23
+ /** Relative-epsilon compare (matches gl-matrix's `equals`), so the oracle tests agree to the bit. */
24
+ const approx = (a: number, b: number, eps: number): boolean => Math.abs(a - b) <= eps * Math.max(1, Math.abs(a), Math.abs(b))
25
+
26
+ // ---------------------------------------------------------------------------------------------------
27
+ // Vec2
28
+ // ---------------------------------------------------------------------------------------------------
29
+
30
+ export class Vec2 {
31
+ x: number
32
+ y: number
33
+
34
+ constructor(x: number | Vec2Like = 0, y = 0) {
35
+ if (typeof x === "number") { this.x = x; this.y = y }
36
+ else { this.x = cx(x); this.y = cy(x) }
37
+ }
38
+
39
+ // --- mutation (the only methods that change `this`) ---
40
+ /** Mutate the components in place. Returns `this`. */
41
+ set(x: number, y: number): this { this.x = x; this.y = y; return this }
42
+ /** Copy another vector's components into this one. Returns `this`. */
43
+ copy(v: Vec2Like): this { this.x = cx(v); this.y = cy(v); return this }
44
+
45
+ // --- pure arithmetic (each returns a NEW Vec2) ---
46
+ add(v: Vec2Like): Vec2 { return new Vec2(this.x + cx(v), this.y + cy(v)) }
47
+ sub(v: Vec2Like): Vec2 { return new Vec2(this.x - cx(v), this.y - cy(v)) }
48
+ mul(v: Vec2Like): Vec2 { return new Vec2(this.x * cx(v), this.y * cy(v)) }
49
+ div(v: Vec2Like): Vec2 { return new Vec2(this.x / cx(v), this.y / cy(v)) }
50
+ scale(s: number): Vec2 { return new Vec2(this.x * s, this.y * s) }
51
+ /** `this + v * s` (fused multiply-add). */
52
+ scaleAndAdd(v: Vec2Like, s: number): Vec2 { return new Vec2(this.x + cx(v) * s, this.y + cy(v) * s) }
53
+ negate(): Vec2 { return new Vec2(-this.x, -this.y) }
54
+
55
+ // --- products / measures ---
56
+ dot(v: Vec2Like): number { return this.x * cx(v) + this.y * cy(v) }
57
+ /** 2D cross product → the scalar z of the 3D cross (signed parallelogram area). */
58
+ cross(v: Vec2Like): number { return this.x * cy(v) - this.y * cx(v) }
59
+ length(): number { return Math.hypot(this.x, this.y) }
60
+ lengthSq(): number { return this.x * this.x + this.y * this.y }
61
+ distanceTo(v: Vec2Like): number { return Math.hypot(this.x - cx(v), this.y - cy(v)) }
62
+ distanceSqTo(v: Vec2Like): number { const dx = this.x - cx(v), dy = this.y - cy(v); return dx * dx + dy * dy }
63
+
64
+ normalize(): Vec2 {
65
+ const l = Math.hypot(this.x, this.y)
66
+ return l === 0 ? new Vec2(0, 0) : new Vec2(this.x / l, this.y / l)
67
+ }
68
+ lerp(v: Vec2Like, t: number): Vec2 { return new Vec2(this.x + (cx(v) - this.x) * t, this.y + (cy(v) - this.y) * t) }
69
+ clamp(min: Vec2Like, max: Vec2Like): Vec2 {
70
+ return new Vec2(clampN(this.x, cx(min), cx(max)), clampN(this.y, cy(min), cy(max)))
71
+ }
72
+ min(v: Vec2Like): Vec2 { return new Vec2(Math.min(this.x, cx(v)), Math.min(this.y, cy(v))) }
73
+ max(v: Vec2Like): Vec2 { return new Vec2(Math.max(this.x, cx(v)), Math.max(this.y, cy(v))) }
74
+ /** Left-hand perpendicular: (-y, x), a 90° CCW turn. */
75
+ perp(): Vec2 { return new Vec2(-this.y, this.x) }
76
+ /** Rotate by `rad` (CCW) around `origin` (default 0). */
77
+ rotate(rad: number, origin: Vec2Like = ZERO2): Vec2 {
78
+ const ox = cx(origin), oy = cy(origin)
79
+ const c = Math.cos(rad), s = Math.sin(rad)
80
+ const dx = this.x - ox, dy = this.y - oy
81
+ return new Vec2(ox + dx * c - dy * s, oy + dx * s + dy * c)
82
+ }
83
+ /** The vector's heading in radians: `atan2(y, x)`. */
84
+ heading(): number { return Math.atan2(this.y, this.x) }
85
+ /** Angle (radians) between this and `v`. */
86
+ angle(v: Vec2Like): number {
87
+ const mag = Math.sqrt(this.lengthSq() * (cx(v) * cx(v) + cy(v) * cy(v)))
88
+ return mag === 0 ? 0 : Math.acos(clampN(this.dot(v) / mag, -1, 1))
89
+ }
90
+
91
+ withX(x: number): Vec2 { return new Vec2(x, this.y) }
92
+ withY(y: number): Vec2 { return new Vec2(this.x, y) }
93
+
94
+ // --- interop ---
95
+ equals(v: Vec2Like, eps = 1e-6): boolean { return approx(this.x, cx(v), eps) && approx(this.y, cy(v), eps) }
96
+ clone(): Vec2 { return new Vec2(this.x, this.y) }
97
+ toArray(): [number, number] { return [ this.x, this.y ] }
98
+ *[Symbol.iterator](): Iterator<number> { yield this.x; yield this.y }
99
+
100
+ static from(v: Vec2Like): Vec2 { return new Vec2(cx(v), cy(v)) }
101
+ static get zero(): Vec2 { return new Vec2(0, 0) }
102
+ static get one(): Vec2 { return new Vec2(1, 1) }
103
+ static get up(): Vec2 { return new Vec2(0, 1) }
104
+ static get down(): Vec2 { return new Vec2(0, -1) }
105
+ static get left(): Vec2 { return new Vec2(-1, 0) }
106
+ static get right(): Vec2 { return new Vec2(1, 0) }
107
+ }
108
+
109
+ // ---------------------------------------------------------------------------------------------------
110
+ // Vec3
111
+ // ---------------------------------------------------------------------------------------------------
112
+
113
+ export class Vec3 {
114
+ x: number
115
+ y: number
116
+ z: number
117
+
118
+ constructor(x: number | Vec3Like = 0, y = 0, z = 0) {
119
+ if (typeof x === "number") { this.x = x; this.y = y; this.z = z }
120
+ else { this.x = cx(x); this.y = cy(x); this.z = cz(x) }
121
+ }
122
+
123
+ // --- mutation ---
124
+ set(x: number, y: number, z: number): this { this.x = x; this.y = y; this.z = z; return this }
125
+ copy(v: Vec3Like): this { this.x = cx(v); this.y = cy(v); this.z = cz(v); return this }
126
+
127
+ // --- pure arithmetic ---
128
+ add(v: Vec3Like): Vec3 { return new Vec3(this.x + cx(v), this.y + cy(v), this.z + cz(v)) }
129
+ sub(v: Vec3Like): Vec3 { return new Vec3(this.x - cx(v), this.y - cy(v), this.z - cz(v)) }
130
+ mul(v: Vec3Like): Vec3 { return new Vec3(this.x * cx(v), this.y * cy(v), this.z * cz(v)) }
131
+ div(v: Vec3Like): Vec3 { return new Vec3(this.x / cx(v), this.y / cy(v), this.z / cz(v)) }
132
+ scale(s: number): Vec3 { return new Vec3(this.x * s, this.y * s, this.z * s) }
133
+ /** `this + v * s` (fused multiply-add). */
134
+ scaleAndAdd(v: Vec3Like, s: number): Vec3 { return new Vec3(this.x + cx(v) * s, this.y + cy(v) * s, this.z + cz(v) * s) }
135
+ negate(): Vec3 { return new Vec3(-this.x, -this.y, -this.z) }
136
+
137
+ // --- products / measures ---
138
+ dot(v: Vec3Like): number { return this.x * cx(v) + this.y * cy(v) + this.z * cz(v) }
139
+ cross(v: Vec3Like): Vec3 {
140
+ const bx = cx(v), by = cy(v), bz = cz(v)
141
+ return new Vec3(this.y * bz - this.z * by, this.z * bx - this.x * bz, this.x * by - this.y * bx)
142
+ }
143
+ length(): number { return Math.hypot(this.x, this.y, this.z) }
144
+ lengthSq(): number { return this.x * this.x + this.y * this.y + this.z * this.z }
145
+ distanceTo(v: Vec3Like): number { return Math.hypot(this.x - cx(v), this.y - cy(v), this.z - cz(v)) }
146
+ distanceSqTo(v: Vec3Like): number {
147
+ const dx = this.x - cx(v), dy = this.y - cy(v), dz = this.z - cz(v)
148
+ return dx * dx + dy * dy + dz * dz
149
+ }
150
+
151
+ normalize(): Vec3 {
152
+ const l = Math.hypot(this.x, this.y, this.z)
153
+ return l === 0 ? new Vec3(0, 0, 0) : new Vec3(this.x / l, this.y / l, this.z / l)
154
+ }
155
+ lerp(v: Vec3Like, t: number): Vec3 {
156
+ return new Vec3(this.x + (cx(v) - this.x) * t, this.y + (cy(v) - this.y) * t, this.z + (cz(v) - this.z) * t)
157
+ }
158
+ clamp(min: Vec3Like, max: Vec3Like): Vec3 {
159
+ return new Vec3(clampN(this.x, cx(min), cx(max)), clampN(this.y, cy(min), cy(max)), clampN(this.z, cz(min), cz(max)))
160
+ }
161
+ min(v: Vec3Like): Vec3 { return new Vec3(Math.min(this.x, cx(v)), Math.min(this.y, cy(v)), Math.min(this.z, cz(v))) }
162
+ max(v: Vec3Like): Vec3 { return new Vec3(Math.max(this.x, cx(v)), Math.max(this.y, cy(v)), Math.max(this.z, cz(v))) }
163
+ /** Reflect this vector about a (unit) `normal`: `v - 2·(v·n)·n`. */
164
+ reflect(normal: Vec3Like): Vec3 {
165
+ const d = 2 * this.dot(normal)
166
+ return new Vec3(this.x - d * cx(normal), this.y - d * cy(normal), this.z - d * cz(normal))
167
+ }
168
+ /** Vector projection of this onto `onto`. */
169
+ project(onto: Vec3Like): Vec3 {
170
+ const ox = cx(onto), oy = cy(onto), oz = cz(onto)
171
+ const denom = ox * ox + oy * oy + oz * oz
172
+ if (denom === 0) return new Vec3(0, 0, 0)
173
+ const k = this.dot(onto) / denom
174
+ return new Vec3(ox * k, oy * k, oz * k)
175
+ }
176
+ /** Angle (radians) between this and `v`. */
177
+ angle(v: Vec3Like): number {
178
+ const bx = cx(v), by = cy(v), bz = cz(v)
179
+ const mag = Math.sqrt(this.lengthSq() * (bx * bx + by * by + bz * bz))
180
+ return mag === 0 ? 0 : Math.acos(clampN(this.dot(v) / mag, -1, 1))
181
+ }
182
+
183
+ // --- rotation ---
184
+ /** Rotate this point around the X axis through `origin` (default 0) by `rad`. */
185
+ rotateX(rad: number, origin: Vec3Like = ZERO3): Vec3 {
186
+ const ox = cx(origin), oy = cy(origin), oz = cz(origin)
187
+ const py = this.y - oy, pz = this.z - oz, c = Math.cos(rad), s = Math.sin(rad)
188
+ return new Vec3(this.x, oy + py * c - pz * s, oz + py * s + pz * c)
189
+ }
190
+ rotateY(rad: number, origin: Vec3Like = ZERO3): Vec3 {
191
+ const ox = cx(origin), oy = cy(origin), oz = cz(origin)
192
+ const px = this.x - ox, pz = this.z - oz, c = Math.cos(rad), s = Math.sin(rad)
193
+ return new Vec3(ox + pz * s + px * c, this.y, oz + pz * c - px * s)
194
+ }
195
+ rotateZ(rad: number, origin: Vec3Like = ZERO3): Vec3 {
196
+ const ox = cx(origin), oy = cy(origin), oz = cz(origin)
197
+ const px = this.x - ox, py = this.y - oy, c = Math.cos(rad), s = Math.sin(rad)
198
+ return new Vec3(ox + px * c - py * s, oy + px * s + py * c, this.z)
199
+ }
200
+ /** Rotate this vector by a quaternion (x, y, z, w). Accepts a `Quat` or a raw `[x,y,z,w]`. */
201
+ rotate(q: ArrayLike<number> | { x: number, y: number, z: number, w: number }): Vec3 {
202
+ const qx = cx(q as Vec3Like), qy = cy(q as Vec3Like), qz = cz(q as Vec3Like)
203
+ const qw = (q as { w?: number }).w ?? (q as ArrayLike<number>)[3]
204
+ const vx = this.x, vy = this.y, vz = this.z
205
+ // t = 2 * (q.xyz × v)
206
+ let tx = qy * vz - qz * vy, ty = qz * vx - qx * vz, tz = qx * vy - qy * vx
207
+ tx += tx; ty += ty; tz += tz
208
+ // v + w·t + q.xyz × t
209
+ return new Vec3(
210
+ vx + qw * tx + qy * tz - qz * ty,
211
+ vy + qw * ty + qz * tx - qx * tz,
212
+ vz + qw * tz + qx * ty - qy * tx,
213
+ )
214
+ }
215
+ /** Transform this point by a column-major mat4 (a `Mat4`, its `.m`, or a raw length-16 array),
216
+ * applying translation and the perspective divide. */
217
+ transform(m: ArrayLike<number> | { m: ArrayLike<number> }): Vec3 {
218
+ const a = (m as { m?: ArrayLike<number> }).m ?? (m as ArrayLike<number>)
219
+ const x = this.x, y = this.y, z = this.z
220
+ let w = a[3] * x + a[7] * y + a[11] * z + a[15]
221
+ w = w || 1
222
+ return new Vec3(
223
+ (a[0] * x + a[4] * y + a[8] * z + a[12]) / w,
224
+ (a[1] * x + a[5] * y + a[9] * z + a[13]) / w,
225
+ (a[2] * x + a[6] * y + a[10] * z + a[14]) / w,
226
+ )
227
+ }
228
+
229
+ withX(x: number): Vec3 { return new Vec3(x, this.y, this.z) }
230
+ withY(y: number): Vec3 { return new Vec3(this.x, y, this.z) }
231
+ withZ(z: number): Vec3 { return new Vec3(this.x, this.y, z) }
232
+
233
+ // --- interop ---
234
+ equals(v: Vec3Like, eps = 1e-6): boolean {
235
+ return approx(this.x, cx(v), eps) && approx(this.y, cy(v), eps) && approx(this.z, cz(v), eps)
236
+ }
237
+ clone(): Vec3 { return new Vec3(this.x, this.y, this.z) }
238
+ toArray(): [number, number, number] { return [ this.x, this.y, this.z ] }
239
+ *[Symbol.iterator](): Iterator<number> { yield this.x; yield this.y; yield this.z }
240
+
241
+ static from(v: Vec3Like): Vec3 { return new Vec3(cx(v), cy(v), cz(v)) }
242
+ static get zero(): Vec3 { return new Vec3(0, 0, 0) }
243
+ static get one(): Vec3 { return new Vec3(1, 1, 1) }
244
+ static get up(): Vec3 { return new Vec3(0, 1, 0) }
245
+ static get down(): Vec3 { return new Vec3(0, -1, 0) }
246
+ static get left(): Vec3 { return new Vec3(-1, 0, 0) }
247
+ static get right(): Vec3 { return new Vec3(1, 0, 0) }
248
+ /** Forward is −Z (the engine's cameras look down −Z; `node.forward` is −Z at identity). */
249
+ static get forward(): Vec3 { return new Vec3(0, 0, -1) }
250
+ static get back(): Vec3 { return new Vec3(0, 0, 1) }
251
+ }
252
+
253
+ const clampN = (v: number, lo: number, hi: number): number => (v < lo ? lo : v > hi ? hi : v)
254
+ const ZERO2 = new Vec2(0, 0)
255
+ const ZERO3 = new Vec3(0, 0, 0)
@@ -0,0 +1,119 @@
1
+ // Defaults → wire layout (docs/multiplayer-plan.md §4 "input: defaults object = layout"). The hot
2
+ // stream — inputs and snapshot states — is binary and its shape comes from a plain defaults object:
3
+ // number → f32
4
+ // boolean → 1 bit (packed after the floats)
5
+ // number[] → f32 × length, fixed
6
+ // Nothing else: no strings, no nesting, no optionals — snapshot fields are flat and fixed-size by
7
+ // design. Both sides run the same bundle, so the layout is derived, never transmitted; the `sig`
8
+ // feeds the schema hash the handshake compares.
9
+
10
+ export type FieldKind = 0 | 1 | 2 // f32 · bool · f32[]
11
+ export type Field = { key: string; kind: FieldKind; len: number }
12
+ export type Layout = { fields: Field[]; floats: number; bools: number; bytes: number; sig: string }
13
+
14
+ const describe = (v: unknown): string => Array.isArray(v) ? `array of ${v.length}` : v === null ? "null" : typeof v
15
+
16
+ export const makeLayout = (defaults: Record<string, unknown>, what: string): Layout => {
17
+ const fields: Field[] = []
18
+ let floats = 0
19
+ let bools = 0
20
+ for (const key of Object.keys(defaults)) {
21
+ const v = defaults[key]
22
+ if (typeof v === "number") { fields.push({ key, kind: 0, len: 1 }); floats++ }
23
+ else if (typeof v === "boolean") { fields.push({ key, kind: 1, len: 1 }); bools++ }
24
+ else if (Array.isArray(v) && v.length > 0 && v.length <= 64 && v.every((n) => typeof n === "number")) {
25
+ fields.push({ key, kind: 2, len: v.length }); floats += v.length
26
+ } else {
27
+ throw new Error(`${what}: field '${key}' must be a number, a boolean or a fixed-length number[] (got ${describe(v)})`)
28
+ }
29
+ }
30
+ const sig = fields.map((f) => `${f.key}:${f.kind}${f.len > 1 ? f.len : ""}`).join(",")
31
+ return { fields, floats, bools, bytes: floats * 4 + Math.ceil(bools / 8), sig }
32
+ }
33
+
34
+ /** A fresh state object shaped like the defaults (arrays copied, never shared). */
35
+ export const cloneDefaults = <T extends object>(defaults: T): T => {
36
+ const out: Record<string, unknown> = {}
37
+ for (const key of Object.keys(defaults)) {
38
+ const v = (defaults as Record<string, unknown>)[key]
39
+ out[key] = Array.isArray(v) ? v.slice() : v
40
+ }
41
+ return out as T
42
+ }
43
+
44
+ /** Copy the layout's fields from `from` into `into` (array elements copied in place; unknown keys
45
+ * ignored — a JSON spawn state or a partial `setInput`). */
46
+ export const assignState = (layout: Layout, into: any, from: any): void => {
47
+ if (!from) return
48
+ for (const f of layout.fields) {
49
+ const v = from[f.key]
50
+ if (v === undefined) continue
51
+ if (f.kind === 2) {
52
+ const a = into[f.key] as number[]
53
+ for (let i = 0; i < f.len; i++) a[i] = +(v[i] ?? 0)
54
+ } else if (f.kind === 1) into[f.key] = !!v
55
+ else into[f.key] = +v
56
+ }
57
+ }
58
+
59
+ export const packInto = (view: DataView, offset: number, layout: Layout, s: any): number => {
60
+ let o = offset
61
+ for (const f of layout.fields) {
62
+ if (f.kind === 0) { view.setFloat32(o, s[f.key], true); o += 4 }
63
+ else if (f.kind === 2) {
64
+ const a = s[f.key] as number[]
65
+ for (let i = 0; i < f.len; i++) { view.setFloat32(o, a[i] ?? 0, true); o += 4 }
66
+ }
67
+ }
68
+ let bits = 0
69
+ let n = 0
70
+ for (const f of layout.fields) {
71
+ if (f.kind !== 1) continue
72
+ if (s[f.key]) bits |= 1 << (n & 7)
73
+ n++
74
+ if ((n & 7) === 0) { view.setUint8(o++, bits); bits = 0 }
75
+ }
76
+ if (n & 7) view.setUint8(o++, bits)
77
+ return o
78
+ }
79
+
80
+ export const unpackFrom = (view: DataView, offset: number, layout: Layout, into: any): number => {
81
+ let o = offset
82
+ for (const f of layout.fields) {
83
+ if (f.kind === 0) { into[f.key] = view.getFloat32(o, true); o += 4 }
84
+ else if (f.kind === 2) {
85
+ const a = into[f.key] as number[]
86
+ for (let i = 0; i < f.len; i++) { a[i] = view.getFloat32(o, true); o += 4 }
87
+ }
88
+ }
89
+ let bits = 0
90
+ let n = 0
91
+ for (const f of layout.fields) {
92
+ if (f.kind !== 1) continue
93
+ if ((n & 7) === 0) bits = view.getUint8(o++)
94
+ into[f.key] = (bits & (1 << (n & 7))) !== 0
95
+ n++
96
+ }
97
+ return o
98
+ }
99
+
100
+ /** `out = a + (b − a) · t` for the numeric fields; booleans take `b`'s. */
101
+ export const lerpState = (layout: Layout, a: any, b: any, t: number, out: any): void => {
102
+ for (const f of layout.fields) {
103
+ if (f.kind === 0) out[f.key] = a[f.key] + (b[f.key] - a[f.key]) * t
104
+ else if (f.kind === 2) {
105
+ const pa = a[f.key] as number[], pb = b[f.key] as number[], po = out[f.key] as number[]
106
+ for (let i = 0; i < f.len; i++) po[i] = pa[i] + (pb[i] - pa[i]) * t
107
+ } else out[f.key] = b[f.key]
108
+ }
109
+ }
110
+
111
+ /** FNV-1a over a string → 8 hex chars. Enough to tell two bundles' schemas apart. */
112
+ export const hashString = (s: string): string => {
113
+ let h = 0x811c9dc5
114
+ for (let i = 0; i < s.length; i++) {
115
+ h ^= s.charCodeAt(i)
116
+ h = Math.imul(h, 0x01000193)
117
+ }
118
+ return (h >>> 0).toString(16).padStart(8, "0")
119
+ }