murow 0.0.70 → 0.0.71

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 (439) hide show
  1. package/README.md +52 -37
  2. package/dist/cjs/core/binary-codec/binary-codec.js +1 -0
  3. package/dist/cjs/core/binary-codec/index.js +1 -0
  4. package/dist/cjs/core/driver/driver.js +1 -0
  5. package/dist/cjs/core/driver/drivers/immediate.js +1 -0
  6. package/dist/cjs/core/driver/drivers/index.js +1 -0
  7. package/dist/cjs/core/driver/drivers/raf.js +1 -0
  8. package/dist/cjs/core/driver/drivers/timeout.js +1 -0
  9. package/dist/cjs/core/driver/index.js +1 -0
  10. package/dist/cjs/core/events/event-system.js +1 -0
  11. package/dist/cjs/core/events/index.js +1 -0
  12. package/dist/cjs/core/fixed-ticker/fixed-ticker.js +1 -0
  13. package/dist/cjs/core/fixed-ticker/index.js +1 -0
  14. package/dist/cjs/core/free-list/free-list.js +1 -0
  15. package/dist/cjs/core/free-list/index.js +1 -0
  16. package/dist/cjs/core/generate-id/generate-id.js +1 -0
  17. package/dist/cjs/core/generate-id/index.js +1 -0
  18. package/dist/cjs/core/index.js +1 -0
  19. package/dist/cjs/core/input/index.js +1 -0
  20. package/dist/cjs/core/input/manager.js +1 -0
  21. package/dist/cjs/core/input/sources/browser.js +1 -0
  22. package/dist/cjs/core/input/sources/index.js +1 -0
  23. package/dist/cjs/core/input/types.js +1 -0
  24. package/dist/cjs/core/lerp/index.js +1 -0
  25. package/dist/cjs/core/lerp/lerp.js +1 -0
  26. package/dist/cjs/core/navmesh/index.js +1 -0
  27. package/dist/cjs/core/navmesh/navmesh-worker-pool.js +1 -0
  28. package/dist/cjs/core/navmesh/navmesh.js +1 -0
  29. package/dist/cjs/core/navmesh/navmesh.worker.js +1 -0
  30. package/dist/cjs/core/pooled-codec/index.js +1 -0
  31. package/dist/cjs/core/pooled-codec/pooled-codec.js +1 -0
  32. package/dist/cjs/core/prediction/index.js +1 -0
  33. package/dist/cjs/core/prediction/prediction.js +1 -0
  34. package/dist/cjs/core/ray/index.js +1 -0
  35. package/dist/cjs/core/ray/ray-2d.js +1 -0
  36. package/dist/cjs/core/ray/ray-3d.js +1 -0
  37. package/dist/cjs/core/simple-rng/index.js +1 -0
  38. package/dist/cjs/core/simple-rng/simple-rng.js +1 -0
  39. package/dist/cjs/core/sparse-batcher/index.js +1 -0
  40. package/dist/cjs/core/sparse-batcher/sparse-batcher.js +1 -0
  41. package/dist/cjs/ecs/component-store.js +1 -0
  42. package/dist/cjs/ecs/component.js +1 -0
  43. package/dist/cjs/ecs/entity-handle.js +1 -0
  44. package/dist/cjs/ecs/index.js +1 -0
  45. package/dist/cjs/ecs/system-builder.js +1 -0
  46. package/dist/cjs/ecs/world-systems.js +1 -0
  47. package/dist/cjs/ecs/world.js +1 -0
  48. package/dist/cjs/game/index.js +1 -0
  49. package/dist/cjs/game/loop/index.js +1 -0
  50. package/dist/cjs/game/loop/loop.js +1 -0
  51. package/dist/cjs/index.js +1 -0
  52. package/dist/cjs/net/adapters/browser-websocket.js +1 -0
  53. package/dist/cjs/net/adapters/bun-websocket.js +1 -0
  54. package/dist/cjs/net/buffer-pool.js +1 -0
  55. package/dist/cjs/net/client.js +1 -0
  56. package/dist/cjs/net/index.js +1 -0
  57. package/dist/cjs/net/server.js +1 -0
  58. package/dist/cjs/net/types.js +1 -0
  59. package/dist/cjs/net/validators.js +1 -0
  60. package/dist/cjs/protocol/index.js +1 -0
  61. package/dist/cjs/protocol/intent/define-intent.js +1 -0
  62. package/dist/cjs/protocol/intent/index.js +1 -0
  63. package/dist/cjs/protocol/intent/intent-registry.js +1 -0
  64. package/dist/cjs/protocol/intent/intent.js +1 -0
  65. package/dist/cjs/protocol/rpc/define-rpc.js +1 -0
  66. package/dist/cjs/protocol/rpc/index.js +1 -0
  67. package/dist/cjs/protocol/rpc/rpc-registry.js +1 -0
  68. package/dist/cjs/protocol/rpc/rpc.js +1 -0
  69. package/dist/cjs/protocol/snapshot/index.js +1 -0
  70. package/dist/cjs/protocol/snapshot/snapshot-codec.js +1 -0
  71. package/dist/cjs/protocol/snapshot/snapshot-registry.js +1 -0
  72. package/dist/cjs/protocol/snapshot/snapshot.js +1 -0
  73. package/dist/cjs/renderer/base-2d-renderer.js +1 -0
  74. package/dist/cjs/renderer/base-3d-renderer.js +1 -0
  75. package/dist/cjs/renderer/base-renderer.js +1 -0
  76. package/dist/cjs/renderer/index.js +1 -0
  77. package/dist/cjs/renderer/types.js +1 -0
  78. package/dist/esm/core/binary-codec/binary-codec.js +1 -0
  79. package/dist/esm/core/binary-codec/index.js +1 -0
  80. package/dist/esm/core/driver/driver.js +1 -0
  81. package/dist/esm/core/driver/drivers/immediate.js +1 -0
  82. package/dist/esm/core/driver/drivers/index.js +1 -0
  83. package/dist/esm/core/driver/drivers/raf.js +1 -0
  84. package/dist/esm/core/driver/drivers/timeout.js +1 -0
  85. package/dist/esm/core/driver/index.js +1 -0
  86. package/dist/esm/core/events/event-system.js +1 -0
  87. package/dist/esm/core/events/index.js +1 -0
  88. package/dist/esm/core/fixed-ticker/fixed-ticker.js +1 -0
  89. package/dist/esm/core/fixed-ticker/index.js +1 -0
  90. package/dist/esm/core/free-list/free-list.js +1 -0
  91. package/dist/esm/core/free-list/index.js +1 -0
  92. package/dist/esm/core/generate-id/generate-id.js +1 -0
  93. package/dist/esm/core/generate-id/index.js +1 -0
  94. package/dist/esm/core/index.js +1 -0
  95. package/dist/esm/core/input/index.js +1 -0
  96. package/dist/esm/core/input/manager.js +1 -0
  97. package/dist/esm/core/input/sources/browser.js +1 -0
  98. package/dist/esm/core/input/sources/index.js +1 -0
  99. package/dist/esm/core/input/types.js +0 -0
  100. package/dist/esm/core/lerp/index.js +1 -0
  101. package/dist/esm/core/lerp/lerp.js +1 -0
  102. package/dist/esm/core/navmesh/index.js +1 -0
  103. package/dist/esm/core/navmesh/navmesh-worker-pool.js +1 -0
  104. package/dist/esm/core/navmesh/navmesh.js +1 -0
  105. package/dist/esm/core/navmesh/navmesh.worker.js +1 -0
  106. package/dist/esm/core/pooled-codec/index.js +1 -0
  107. package/dist/esm/core/pooled-codec/pooled-codec.js +1 -0
  108. package/dist/esm/core/prediction/index.js +1 -0
  109. package/dist/esm/core/prediction/prediction.js +1 -0
  110. package/dist/esm/core/ray/index.js +1 -0
  111. package/dist/esm/core/ray/ray-2d.js +1 -0
  112. package/dist/esm/core/ray/ray-3d.js +1 -0
  113. package/dist/esm/core/simple-rng/index.js +1 -0
  114. package/dist/esm/core/simple-rng/simple-rng.js +1 -0
  115. package/dist/esm/core/sparse-batcher/index.js +1 -0
  116. package/dist/esm/core/sparse-batcher/sparse-batcher.js +1 -0
  117. package/dist/esm/ecs/component-store.js +1 -0
  118. package/dist/esm/ecs/component.js +1 -0
  119. package/dist/esm/ecs/entity-handle.js +1 -0
  120. package/dist/esm/ecs/index.js +1 -0
  121. package/dist/esm/ecs/system-builder.js +1 -0
  122. package/dist/esm/ecs/world-systems.js +1 -0
  123. package/dist/esm/ecs/world.js +1 -0
  124. package/dist/esm/game/index.js +1 -0
  125. package/dist/esm/game/loop/index.js +1 -0
  126. package/dist/esm/game/loop/loop.js +1 -0
  127. package/dist/esm/index.js +1 -0
  128. package/dist/esm/net/adapters/browser-websocket.js +1 -0
  129. package/dist/esm/net/adapters/bun-websocket.js +1 -0
  130. package/dist/esm/net/buffer-pool.js +1 -0
  131. package/dist/esm/net/client.js +1 -0
  132. package/dist/esm/net/index.js +1 -0
  133. package/dist/esm/net/server.js +1 -0
  134. package/dist/esm/net/types.js +1 -0
  135. package/dist/esm/net/validators.js +1 -0
  136. package/dist/esm/protocol/index.js +1 -0
  137. package/dist/esm/protocol/intent/define-intent.js +1 -0
  138. package/dist/esm/protocol/intent/index.js +1 -0
  139. package/dist/esm/protocol/intent/intent-registry.js +1 -0
  140. package/dist/esm/protocol/intent/intent.js +0 -0
  141. package/dist/esm/protocol/rpc/define-rpc.js +1 -0
  142. package/dist/esm/protocol/rpc/index.js +1 -0
  143. package/dist/esm/protocol/rpc/rpc-registry.js +1 -0
  144. package/dist/esm/protocol/rpc/rpc.js +0 -0
  145. package/dist/esm/protocol/snapshot/index.js +1 -0
  146. package/dist/esm/protocol/snapshot/snapshot-codec.js +1 -0
  147. package/dist/esm/protocol/snapshot/snapshot-registry.js +1 -0
  148. package/dist/esm/protocol/snapshot/snapshot.js +1 -0
  149. package/dist/esm/renderer/base-2d-renderer.js +1 -0
  150. package/dist/esm/renderer/base-3d-renderer.js +1 -0
  151. package/dist/esm/renderer/base-renderer.js +1 -0
  152. package/dist/esm/renderer/index.js +1 -0
  153. package/dist/esm/renderer/types.js +0 -0
  154. package/dist/{core → types/core}/binary-codec/binary-codec.d.ts +4 -0
  155. package/dist/{core → types/core}/events/event-system.d.ts +14 -33
  156. package/dist/types/core/free-list/free-list.d.ts +31 -0
  157. package/dist/types/core/free-list/index.d.ts +1 -0
  158. package/dist/{core → types/core}/index.d.ts +5 -0
  159. package/dist/{core → types/core}/input/index.d.ts +1 -0
  160. package/dist/{core → types/core}/input/manager.d.ts +2 -0
  161. package/dist/{core → types/core}/navmesh/navmesh.d.ts +1 -21
  162. package/dist/types/core/ray/index.d.ts +2 -0
  163. package/dist/types/core/ray/ray-2d.d.ts +37 -0
  164. package/dist/types/core/ray/ray-3d.d.ts +42 -0
  165. package/dist/types/core/simple-rng/index.d.ts +1 -0
  166. package/dist/types/core/simple-rng/simple-rng.d.ts +36 -0
  167. package/dist/types/core/sparse-batcher/index.d.ts +1 -0
  168. package/dist/types/core/sparse-batcher/sparse-batcher.d.ts +55 -0
  169. package/dist/{ecs → types/ecs}/world.d.ts +11 -0
  170. package/dist/{game → types/game}/loop/loop.d.ts +33 -29
  171. package/dist/{index.d.ts → types/index.d.ts} +1 -0
  172. package/dist/{net → types/net}/index.d.ts +2 -2
  173. package/dist/types/renderer/base-2d-renderer.d.ts +13 -0
  174. package/dist/types/renderer/base-3d-renderer.d.ts +10 -0
  175. package/dist/types/renderer/base-renderer.d.ts +21 -0
  176. package/dist/types/renderer/index.d.ts +4 -0
  177. package/dist/types/renderer/types.d.ts +79 -0
  178. package/dist/webgpu/cjs/index.js +6004 -0
  179. package/dist/webgpu/esm/index.js +5972 -0
  180. package/dist/webgpu/types/2d/animation.d.ts +97 -0
  181. package/dist/webgpu/types/2d/renderer.d.ts +55 -0
  182. package/dist/webgpu/types/2d/shader.d.ts +61 -0
  183. package/dist/webgpu/types/2d/sprite-accessor.d.ts +47 -0
  184. package/dist/webgpu/types/3d/gltf-skin-parser.d.ts +101 -0
  185. package/dist/webgpu/types/3d/morph-animation.d.ts +69 -0
  186. package/dist/webgpu/types/3d/morph-animation.test.d.ts +1 -0
  187. package/dist/webgpu/types/3d/renderer.d.ts +216 -0
  188. package/dist/webgpu/types/3d/shader.d.ts +136 -0
  189. package/dist/webgpu/types/3d/skeletal-animation-compute/index.d.ts +2 -0
  190. package/dist/webgpu/types/3d/skeletal-animation-compute/kernel.d.ts +8 -0
  191. package/dist/webgpu/types/3d/skeletal-animation-compute/packer.d.ts +32 -0
  192. package/dist/webgpu/types/3d/skeletal-animation.d.ts +90 -0
  193. package/dist/webgpu/types/camera/camera-2d.d.ts +53 -0
  194. package/dist/webgpu/types/camera/camera-2d.test.d.ts +1 -0
  195. package/dist/webgpu/types/camera/camera-3d.d.ts +81 -0
  196. package/dist/webgpu/types/camera/camera-3d.test.d.ts +1 -0
  197. package/dist/webgpu/types/camera/index.d.ts +2 -0
  198. package/dist/webgpu/types/compute/compute-builder.d.ts +123 -0
  199. package/dist/webgpu/types/compute/compute-builder.test.d.ts +1 -0
  200. package/dist/webgpu/types/core/constants.d.ts +59 -0
  201. package/dist/webgpu/types/core/constants.test.d.ts +1 -0
  202. package/dist/webgpu/types/core/index.d.ts +2 -0
  203. package/dist/webgpu/types/core/math.d.ts +37 -0
  204. package/dist/webgpu/types/core/types.d.ts +125 -0
  205. package/dist/webgpu/types/core/types.test.d.ts +1 -0
  206. package/dist/webgpu/types/geometry/built-in.d.ts +58 -0
  207. package/dist/webgpu/types/geometry/built-in.test.d.ts +1 -0
  208. package/dist/webgpu/types/geometry/geometry-builder.d.ts +281 -0
  209. package/dist/webgpu/types/geometry/geometry-builder.test.d.ts +1 -0
  210. package/dist/webgpu/types/geometry/index.d.ts +2 -0
  211. package/dist/webgpu/types/index.d.ts +32 -0
  212. package/dist/webgpu/types/particle/emitter.d.ts +36 -0
  213. package/dist/webgpu/types/shaders/index.d.ts +2 -0
  214. package/dist/webgpu/types/shaders/runtime-transpile.d.ts +18 -0
  215. package/dist/webgpu/types/shaders/sprite-2d.wgsl.d.ts +10 -0
  216. package/dist/webgpu/types/shaders/typegpu.d.ts +9 -0
  217. package/dist/webgpu/types/shaders/utils.d.ts +28 -0
  218. package/dist/webgpu/types/shaders/utils.test.d.ts +1 -0
  219. package/dist/webgpu/types/spritesheet/index.d.ts +1 -0
  220. package/dist/webgpu/types/spritesheet/spritesheet.d.ts +57 -0
  221. package/dist/webgpu/types/spritesheet/spritesheet.test.d.ts +1 -0
  222. package/package.json +96 -26
  223. package/dist/core/binary-codec/binary-codec.js +0 -354
  224. package/dist/core/binary-codec/index.js +0 -1
  225. package/dist/core/driver/driver.js +0 -47
  226. package/dist/core/driver/drivers/immediate.js +0 -61
  227. package/dist/core/driver/drivers/index.js +0 -3
  228. package/dist/core/driver/drivers/raf.js +0 -62
  229. package/dist/core/driver/drivers/timeout.js +0 -71
  230. package/dist/core/driver/index.js +0 -2
  231. package/dist/core/events/event-system.js +0 -88
  232. package/dist/core/events/index.js +0 -1
  233. package/dist/core/fixed-ticker/fixed-ticker.js +0 -105
  234. package/dist/core/fixed-ticker/index.js +0 -1
  235. package/dist/core/generate-id/generate-id.js +0 -25
  236. package/dist/core/generate-id/index.js +0 -1
  237. package/dist/core/index.js +0 -10
  238. package/dist/core/input/index.js +0 -2
  239. package/dist/core/input/manager.js +0 -211
  240. package/dist/core/input/sources/browser.js +0 -29
  241. package/dist/core/input/sources/index.js +0 -1
  242. package/dist/core/lerp/index.js +0 -1
  243. package/dist/core/lerp/lerp.js +0 -42
  244. package/dist/core/navmesh/index.js +0 -1
  245. package/dist/core/navmesh/navmesh-worker-pool.js +0 -180
  246. package/dist/core/navmesh/navmesh.js +0 -799
  247. package/dist/core/navmesh/navmesh.worker.js +0 -79
  248. package/dist/core/pooled-codec/index.js +0 -1
  249. package/dist/core/pooled-codec/pooled-codec.js +0 -410
  250. package/dist/core/prediction/index.js +0 -1
  251. package/dist/core/prediction/prediction.js +0 -99
  252. package/dist/core.esm.js +0 -1
  253. package/dist/core.js +0 -1
  254. package/dist/ecs/component-store.js +0 -175
  255. package/dist/ecs/component.js +0 -43
  256. package/dist/ecs/entity-handle.js +0 -515
  257. package/dist/ecs/example.js +0 -125
  258. package/dist/ecs/index.js +0 -4
  259. package/dist/ecs/system-builder.js +0 -249
  260. package/dist/ecs/world-systems.js +0 -79
  261. package/dist/ecs/world.js +0 -767
  262. package/dist/game/index.js +0 -1
  263. package/dist/game/loop/index.js +0 -1
  264. package/dist/game/loop/loop.js +0 -108
  265. package/dist/index.js +0 -26
  266. package/dist/net/adapters/browser-websocket.js +0 -74
  267. package/dist/net/adapters/bun-websocket.js +0 -245
  268. package/dist/net/buffer-pool.js +0 -89
  269. package/dist/net/client.js +0 -586
  270. package/dist/net/index.js +0 -58
  271. package/dist/net/server.js +0 -974
  272. package/dist/net/types.js +0 -31
  273. package/dist/net/validators.js +0 -88
  274. package/dist/protocol/index.js +0 -92
  275. package/dist/protocol/intent/define-intent.js +0 -125
  276. package/dist/protocol/intent/index.js +0 -91
  277. package/dist/protocol/intent/intent-registry.js +0 -91
  278. package/dist/protocol/rpc/define-rpc.js +0 -84
  279. package/dist/protocol/rpc/index.js +0 -3
  280. package/dist/protocol/rpc/rpc-registry.js +0 -159
  281. package/dist/protocol/rpc/rpc.js +0 -12
  282. package/dist/protocol/snapshot/index.js +0 -43
  283. package/dist/protocol/snapshot/snapshot-codec.js +0 -67
  284. package/dist/protocol/snapshot/snapshot-registry.js +0 -168
  285. package/dist/protocol/snapshot/snapshot.js +0 -30
  286. package/src/core/binary-codec/README.md +0 -60
  287. package/src/core/binary-codec/binary-codec.test.ts +0 -300
  288. package/src/core/binary-codec/binary-codec.ts +0 -448
  289. package/src/core/binary-codec/index.ts +0 -1
  290. package/src/core/driver/README.md +0 -97
  291. package/src/core/driver/driver.test.ts +0 -414
  292. package/src/core/driver/driver.ts +0 -71
  293. package/src/core/driver/drivers/immediate.ts +0 -66
  294. package/src/core/driver/drivers/index.ts +0 -3
  295. package/src/core/driver/drivers/raf.ts +0 -67
  296. package/src/core/driver/drivers/timeout.ts +0 -77
  297. package/src/core/driver/index.ts +0 -2
  298. package/src/core/events/README.md +0 -47
  299. package/src/core/events/event-system.test.ts +0 -243
  300. package/src/core/events/event-system.ts +0 -140
  301. package/src/core/events/index.ts +0 -1
  302. package/src/core/fixed-ticker/README.md +0 -77
  303. package/src/core/fixed-ticker/fixed-ticker.test.ts +0 -151
  304. package/src/core/fixed-ticker/fixed-ticker.ts +0 -174
  305. package/src/core/fixed-ticker/index.ts +0 -1
  306. package/src/core/generate-id/README.md +0 -18
  307. package/src/core/generate-id/generate-id.test.ts +0 -79
  308. package/src/core/generate-id/generate-id.ts +0 -37
  309. package/src/core/generate-id/index.ts +0 -1
  310. package/src/core/index.ts +0 -10
  311. package/src/core/input/README.md +0 -24
  312. package/src/core/input/index.ts +0 -2
  313. package/src/core/input/manager.ts +0 -259
  314. package/src/core/input/sources/browser.ts +0 -39
  315. package/src/core/input/sources/index.ts +0 -1
  316. package/src/core/input/types.ts +0 -40
  317. package/src/core/lerp/README.md +0 -79
  318. package/src/core/lerp/index.ts +0 -1
  319. package/src/core/lerp/lerp.test.ts +0 -90
  320. package/src/core/lerp/lerp.ts +0 -42
  321. package/src/core/navmesh/README.md +0 -164
  322. package/src/core/navmesh/index.ts +0 -1
  323. package/src/core/navmesh/navmesh-worker-pool.ts +0 -236
  324. package/src/core/navmesh/navmesh-workers.test.ts +0 -356
  325. package/src/core/navmesh/navmesh.test.ts +0 -344
  326. package/src/core/navmesh/navmesh.ts +0 -1047
  327. package/src/core/navmesh/navmesh.worker.ts +0 -147
  328. package/src/core/pooled-codec/README.md +0 -70
  329. package/src/core/pooled-codec/index.ts +0 -1
  330. package/src/core/pooled-codec/pooled-codec.test.ts +0 -862
  331. package/src/core/pooled-codec/pooled-codec.ts +0 -504
  332. package/src/core/prediction/README.md +0 -64
  333. package/src/core/prediction/index.ts +0 -1
  334. package/src/core/prediction/prediction.test.ts +0 -423
  335. package/src/core/prediction/prediction.ts +0 -112
  336. package/src/ecs/README.md +0 -427
  337. package/src/ecs/benchmark.test.ts +0 -1645
  338. package/src/ecs/component-store.ts +0 -198
  339. package/src/ecs/component.ts +0 -90
  340. package/src/ecs/entity-handle.test.ts +0 -393
  341. package/src/ecs/entity-handle.ts +0 -563
  342. package/src/ecs/example.ts +0 -152
  343. package/src/ecs/index.ts +0 -4
  344. package/src/ecs/system-builder.ts +0 -404
  345. package/src/ecs/world-systems.ts +0 -83
  346. package/src/ecs/world.test.ts +0 -310
  347. package/src/ecs/world.ts +0 -904
  348. package/src/game/index.ts +0 -1
  349. package/src/game/loop/README.md +0 -32
  350. package/src/game/loop/index.ts +0 -1
  351. package/src/game/loop/loop.ts +0 -236
  352. package/src/index.ts +0 -32
  353. package/src/net/README.md +0 -474
  354. package/src/net/adapters/browser-websocket.ts +0 -86
  355. package/src/net/adapters/bun-websocket.ts +0 -292
  356. package/src/net/buffer-pool.ts +0 -106
  357. package/src/net/client.test.ts +0 -807
  358. package/src/net/client.ts +0 -695
  359. package/src/net/index.ts +0 -60
  360. package/src/net/server.test.ts +0 -799
  361. package/src/net/server.ts +0 -1152
  362. package/src/net/types.ts +0 -228
  363. package/src/net/validators.ts +0 -104
  364. package/src/protocol/README.md +0 -469
  365. package/src/protocol/index.ts +0 -93
  366. package/src/protocol/intent/define-intent.test.ts +0 -397
  367. package/src/protocol/intent/define-intent.ts +0 -201
  368. package/src/protocol/intent/index.ts +0 -94
  369. package/src/protocol/intent/intent-registry.test.ts +0 -198
  370. package/src/protocol/intent/intent-registry.ts +0 -112
  371. package/src/protocol/intent/intent.ts +0 -12
  372. package/src/protocol/rpc/define-rpc.test.ts +0 -141
  373. package/src/protocol/rpc/define-rpc.ts +0 -113
  374. package/src/protocol/rpc/index.ts +0 -3
  375. package/src/protocol/rpc/rpc-registry.test.ts +0 -168
  376. package/src/protocol/rpc/rpc-registry.ts +0 -176
  377. package/src/protocol/rpc/rpc.ts +0 -37
  378. package/src/protocol/snapshot/index.ts +0 -45
  379. package/src/protocol/snapshot/snapshot-codec.test.ts +0 -138
  380. package/src/protocol/snapshot/snapshot-codec.ts +0 -87
  381. package/src/protocol/snapshot/snapshot-registry.test.ts +0 -310
  382. package/src/protocol/snapshot/snapshot-registry.ts +0 -201
  383. package/src/protocol/snapshot/snapshot.test.ts +0 -76
  384. package/src/protocol/snapshot/snapshot.ts +0 -41
  385. /package/dist/{core → types/core}/binary-codec/index.d.ts +0 -0
  386. /package/dist/{core → types/core}/driver/driver.d.ts +0 -0
  387. /package/dist/{core → types/core}/driver/drivers/immediate.d.ts +0 -0
  388. /package/dist/{core → types/core}/driver/drivers/index.d.ts +0 -0
  389. /package/dist/{core → types/core}/driver/drivers/raf.d.ts +0 -0
  390. /package/dist/{core → types/core}/driver/drivers/timeout.d.ts +0 -0
  391. /package/dist/{core → types/core}/driver/index.d.ts +0 -0
  392. /package/dist/{core → types/core}/events/index.d.ts +0 -0
  393. /package/dist/{core → types/core}/fixed-ticker/fixed-ticker.d.ts +0 -0
  394. /package/dist/{core → types/core}/fixed-ticker/index.d.ts +0 -0
  395. /package/dist/{core → types/core}/generate-id/generate-id.d.ts +0 -0
  396. /package/dist/{core → types/core}/generate-id/index.d.ts +0 -0
  397. /package/dist/{core → types/core}/input/sources/browser.d.ts +0 -0
  398. /package/dist/{core → types/core}/input/sources/index.d.ts +0 -0
  399. /package/dist/{core → types/core}/input/types.d.ts +0 -0
  400. /package/dist/{core → types/core}/lerp/index.d.ts +0 -0
  401. /package/dist/{core → types/core}/lerp/lerp.d.ts +0 -0
  402. /package/dist/{core → types/core}/navmesh/index.d.ts +0 -0
  403. /package/dist/{core → types/core}/navmesh/navmesh-worker-pool.d.ts +0 -0
  404. /package/dist/{core → types/core}/navmesh/navmesh.worker.d.ts +0 -0
  405. /package/dist/{core → types/core}/pooled-codec/index.d.ts +0 -0
  406. /package/dist/{core → types/core}/pooled-codec/pooled-codec.d.ts +0 -0
  407. /package/dist/{core → types/core}/prediction/index.d.ts +0 -0
  408. /package/dist/{core → types/core}/prediction/prediction.d.ts +0 -0
  409. /package/dist/{ecs → types/ecs}/component-store.d.ts +0 -0
  410. /package/dist/{ecs → types/ecs}/component.d.ts +0 -0
  411. /package/dist/{ecs → types/ecs}/entity-handle.d.ts +0 -0
  412. /package/dist/{ecs → types/ecs}/example.d.ts +0 -0
  413. /package/dist/{ecs → types/ecs}/index.d.ts +0 -0
  414. /package/dist/{ecs → types/ecs}/system-builder.d.ts +0 -0
  415. /package/dist/{ecs → types/ecs}/world-systems.d.ts +0 -0
  416. /package/dist/{game → types/game}/index.d.ts +0 -0
  417. /package/dist/{game → types/game}/loop/index.d.ts +0 -0
  418. /package/dist/{net → types/net}/adapters/browser-websocket.d.ts +0 -0
  419. /package/dist/{net → types/net}/adapters/bun-websocket.d.ts +0 -0
  420. /package/dist/{net → types/net}/buffer-pool.d.ts +0 -0
  421. /package/dist/{net → types/net}/client.d.ts +0 -0
  422. /package/dist/{net → types/net}/server.d.ts +0 -0
  423. /package/dist/{net → types/net}/types.d.ts +0 -0
  424. /package/dist/{net → types/net}/validators.d.ts +0 -0
  425. /package/dist/{protocol → types/protocol}/index.d.ts +0 -0
  426. /package/dist/{protocol → types/protocol}/intent/define-intent.d.ts +0 -0
  427. /package/dist/{protocol → types/protocol}/intent/index.d.ts +0 -0
  428. /package/dist/{protocol → types/protocol}/intent/intent-registry.d.ts +0 -0
  429. /package/dist/{protocol → types/protocol}/intent/intent.d.ts +0 -0
  430. /package/dist/{protocol → types/protocol}/rpc/define-rpc.d.ts +0 -0
  431. /package/dist/{protocol → types/protocol}/rpc/index.d.ts +0 -0
  432. /package/dist/{protocol → types/protocol}/rpc/rpc-registry.d.ts +0 -0
  433. /package/dist/{protocol → types/protocol}/rpc/rpc.d.ts +0 -0
  434. /package/dist/{protocol → types/protocol}/snapshot/index.d.ts +0 -0
  435. /package/dist/{protocol → types/protocol}/snapshot/snapshot-codec.d.ts +0 -0
  436. /package/dist/{protocol → types/protocol}/snapshot/snapshot-registry.d.ts +0 -0
  437. /package/dist/{protocol → types/protocol}/snapshot/snapshot.d.ts +0 -0
  438. /package/dist/{core/input/types.js → webgpu/types/2d/animation.test.d.ts} +0 -0
  439. /package/dist/{protocol/intent/intent.js → webgpu/types/2d/sprite-accessor.test.d.ts} +0 -0
@@ -1,799 +0,0 @@
1
- /* ---------------------------------- */
2
- /* Utils */
3
- /* ---------------------------------- */
4
- const dirs = [
5
- { x: 1, y: 0 },
6
- { x: -1, y: 0 },
7
- { x: 0, y: 1 },
8
- { x: 0, y: -1 },
9
- ];
10
- /**
11
- * Converts world coordinates to grid cell coordinates (floor).
12
- */
13
- const toCell = (v) => ({
14
- x: Math.floor(v.x),
15
- y: Math.floor(v.y),
16
- });
17
- /**
18
- * Converts grid cell coordinates to world coordinates (cell center).
19
- */
20
- const fromCell = (v) => ({
21
- x: v.x + 0.5,
22
- y: v.y + 0.5
23
- });
24
- /**
25
- * Generates unique sequential IDs for obstacles.
26
- */
27
- const genId = (() => {
28
- let i = 1;
29
- return () => i++;
30
- })();
31
- /**
32
- * Encodes grid coordinates as a single integer for use as Map/Set keys.
33
- * Uses 32-bit safe packing: lower 16 bits = x, upper 16 bits = y.
34
- * Supports coordinates in range [-32768, 32767].
35
- */
36
- const encodeCell = (x, y) => (x & 0xffff) | ((y & 0xffff) << 16);
37
- /**
38
- * Decodes an encoded cell back to {x, y}.
39
- * Properly handles sign extension for negative coordinates.
40
- */
41
- const decodeCell = (n) => ({
42
- x: (n << 16) >> 16,
43
- y: n >> 16,
44
- });
45
- /* ---------------------------------- */
46
- /* Binary Heap (Priority Queue) */
47
- /* ---------------------------------- */
48
- /**
49
- * Min-heap priority queue for A*.
50
- * Supports O(log n) insert and extract-min operations.
51
- */
52
- class BinaryHeap {
53
- constructor(scoreFn) {
54
- this.scoreFn = scoreFn;
55
- this.heap = [];
56
- }
57
- push(item) {
58
- this.heap.push(item);
59
- this.bubbleUp(this.heap.length - 1);
60
- }
61
- pop() {
62
- const result = this.heap[0];
63
- const end = this.heap.pop();
64
- if (this.heap.length > 0 && end !== undefined) {
65
- this.heap[0] = end;
66
- this.sinkDown(0);
67
- }
68
- return result;
69
- }
70
- get size() {
71
- return this.heap.length;
72
- }
73
- bubbleUp(n) {
74
- const element = this.heap[n];
75
- const score = this.scoreFn(element);
76
- while (n > 0) {
77
- const parentN = ((n + 1) >> 1) - 1;
78
- const parent = this.heap[parentN];
79
- if (score >= this.scoreFn(parent))
80
- break;
81
- this.heap[parentN] = element;
82
- this.heap[n] = parent;
83
- n = parentN;
84
- }
85
- }
86
- sinkDown(n) {
87
- const length = this.heap.length;
88
- const element = this.heap[n];
89
- const elemScore = this.scoreFn(element);
90
- while (true) {
91
- const child2N = (n + 1) << 1;
92
- const child1N = child2N - 1;
93
- let swap = null;
94
- let child1Score;
95
- if (child1N < length) {
96
- const child1 = this.heap[child1N];
97
- child1Score = this.scoreFn(child1);
98
- if (child1Score < elemScore) {
99
- swap = child1N;
100
- }
101
- }
102
- if (child2N < length) {
103
- const child2 = this.heap[child2N];
104
- const child2Score = this.scoreFn(child2);
105
- if (child2Score < (swap === null ? elemScore : child1Score)) {
106
- swap = child2N;
107
- }
108
- }
109
- if (swap === null)
110
- break;
111
- this.heap[n] = this.heap[swap];
112
- this.heap[swap] = element;
113
- n = swap;
114
- }
115
- }
116
- }
117
- /* ---------------------------------- */
118
- /* Spatial Hash */
119
- /* ---------------------------------- */
120
- /**
121
- * Spatial hash for fast obstacle queries.
122
- * Divides space into fixed-size cells and indexes obstacles by cell.
123
- * Provides O(1) average case lookup instead of O(n) linear scan.
124
- *
125
- * Cell size = 1 matches grid pathfinding unit cells.
126
- */
127
- class SpatialHash {
128
- constructor(cellSize = 1) {
129
- this.grid = new Map();
130
- this.obstacleCells = new Map();
131
- this.cellSize = cellSize;
132
- }
133
- /**
134
- * Returns hash key for a world position.
135
- */
136
- hash(x, y) {
137
- const cx = Math.floor(x / this.cellSize);
138
- const cy = Math.floor(y / this.cellSize);
139
- return encodeCell(cx, cy);
140
- }
141
- /**
142
- * Adds an obstacle to the spatial hash.
143
- */
144
- add(id, obstacle) {
145
- const cells = this.getCellsForObstacle(obstacle);
146
- for (const cell of cells) {
147
- if (!this.grid.has(cell)) {
148
- this.grid.set(cell, new Set());
149
- }
150
- this.grid.get(cell).add(id);
151
- }
152
- this.obstacleCells.set(id, cells);
153
- }
154
- /**
155
- * Removes an obstacle from the spatial hash.
156
- */
157
- remove(id) {
158
- const cells = this.obstacleCells.get(id);
159
- if (!cells)
160
- return;
161
- for (const cell of cells) {
162
- const bucket = this.grid.get(cell);
163
- if (bucket) {
164
- bucket.delete(id);
165
- if (bucket.size === 0) {
166
- this.grid.delete(cell);
167
- }
168
- }
169
- }
170
- this.obstacleCells.delete(id);
171
- }
172
- /**
173
- * Returns obstacle IDs that might contain the given point.
174
- */
175
- query(pos) {
176
- const cell = this.hash(pos.x, pos.y);
177
- return this.grid.get(cell) || new Set();
178
- }
179
- /**
180
- * Clears the entire spatial hash.
181
- */
182
- clear() {
183
- this.grid.clear();
184
- this.obstacleCells.clear();
185
- }
186
- /**
187
- * Determines which cells an obstacle overlaps.
188
- */
189
- getCellsForObstacle(o) {
190
- const cells = new Set();
191
- if (o.type === 'circle') {
192
- const r = o.radius;
193
- const minX = Math.floor((o.pos.x - r) / this.cellSize);
194
- const maxX = Math.floor((o.pos.x + r) / this.cellSize);
195
- const minY = Math.floor((o.pos.y - r) / this.cellSize);
196
- const maxY = Math.floor((o.pos.y + r) / this.cellSize);
197
- for (let x = minX; x <= maxX; x++) {
198
- for (let y = minY; y <= maxY; y++) {
199
- cells.add(encodeCell(x, y));
200
- }
201
- }
202
- }
203
- else if (o.type === 'rect') {
204
- const cx = o.pos.x + o.size.x / 2;
205
- const cy = o.pos.y + o.size.y / 2;
206
- const hw = o.size.x / 2;
207
- const hh = o.size.y / 2;
208
- const diagonal = Math.sqrt(hw * hw + hh * hh);
209
- const minX = Math.floor((cx - diagonal) / this.cellSize);
210
- const maxX = Math.floor((cx + diagonal) / this.cellSize);
211
- const minY = Math.floor((cy - diagonal) / this.cellSize);
212
- const maxY = Math.floor((cy + diagonal) / this.cellSize);
213
- for (let x = minX; x <= maxX; x++) {
214
- for (let y = minY; y <= maxY; y++) {
215
- cells.add(encodeCell(x, y));
216
- }
217
- }
218
- }
219
- else if (o.type === 'polygon') {
220
- const bounds = getPolygonBounds(o);
221
- const minX = Math.floor(bounds.minX / this.cellSize);
222
- const maxX = Math.floor(bounds.maxX / this.cellSize);
223
- const minY = Math.floor(bounds.minY / this.cellSize);
224
- const maxY = Math.floor(bounds.maxY / this.cellSize);
225
- for (let x = minX; x <= maxX; x++) {
226
- for (let y = minY; y <= maxY; y++) {
227
- cells.add(encodeCell(x, y));
228
- }
229
- }
230
- }
231
- return cells;
232
- }
233
- }
234
- /* ---------------------------------- */
235
- /* Geometry helpers */
236
- /* ---------------------------------- */
237
- /**
238
- * Tests if a point is inside a circle obstacle.
239
- */
240
- function pointInCircle(p, c) {
241
- const dx = p.x - c.pos.x;
242
- const dy = p.y - c.pos.y;
243
- return dx * dx + dy * dy <= c.radius * c.radius;
244
- }
245
- /**
246
- * Tests if a point is inside a rectangle obstacle.
247
- * Handles rotation around the rectangle's center.
248
- */
249
- function pointInRect(p, r) {
250
- const cx = r.pos.x + r.size.x / 2;
251
- const cy = r.pos.y + r.size.y / 2;
252
- if (r.rotation) {
253
- const cos = Math.cos(-r.rotation);
254
- const sin = Math.sin(-r.rotation);
255
- const dx = p.x - cx;
256
- const dy = p.y - cy;
257
- const localX = dx * cos - dy * sin;
258
- const localY = dx * sin + dy * cos;
259
- return Math.abs(localX) <= r.size.x / 2 &&
260
- Math.abs(localY) <= r.size.y / 2;
261
- }
262
- return (p.x >= r.pos.x &&
263
- p.y >= r.pos.y &&
264
- p.x <= r.pos.x + r.size.x &&
265
- p.y <= r.pos.y + r.size.y);
266
- }
267
- /**
268
- * Tests if a point is inside a polygon obstacle using ray casting.
269
- * REQUIRES: polygon.points are defined relative to local origin (0,0).
270
- * Uses numerically stable intersection test.
271
- */
272
- function pointInPolygon(p, poly) {
273
- let inside = false;
274
- const pts = poly.points;
275
- const cos = poly.rotation ? Math.cos(poly.rotation) : 1;
276
- const sin = poly.rotation ? Math.sin(poly.rotation) : 0;
277
- for (let i = 0, j = pts.length - 1; i < pts.length; j = i++) {
278
- let xi = pts[i].x;
279
- let yi = pts[i].y;
280
- let xj = pts[j].x;
281
- let yj = pts[j].y;
282
- if (poly.rotation) {
283
- const tempXi = xi * cos - yi * sin;
284
- const tempYi = xi * sin + yi * cos;
285
- const tempXj = xj * cos - yj * sin;
286
- const tempYj = xj * sin + yj * cos;
287
- xi = tempXi;
288
- yi = tempYi;
289
- xj = tempXj;
290
- yj = tempYj;
291
- }
292
- xi += poly.pos.x;
293
- yi += poly.pos.y;
294
- xj += poly.pos.x;
295
- yj += poly.pos.y;
296
- // Stable ray casting test
297
- const intersect = (yi > p.y) !== (yj > p.y) &&
298
- p.x < ((xj - xi) * (p.y - yi)) / (yj - yi) + xi;
299
- if (intersect)
300
- inside = !inside;
301
- }
302
- return inside;
303
- }
304
- /**
305
- * Computes axis-aligned bounding box for a transformed polygon.
306
- */
307
- function getPolygonBounds(poly) {
308
- let minX = Infinity, minY = Infinity;
309
- let maxX = -Infinity, maxY = -Infinity;
310
- const cos = poly.rotation ? Math.cos(poly.rotation) : 1;
311
- const sin = poly.rotation ? Math.sin(poly.rotation) : 0;
312
- for (const p of poly.points) {
313
- let x = p.x;
314
- let y = p.y;
315
- if (poly.rotation) {
316
- const tx = x * cos - y * sin;
317
- const ty = x * sin + y * cos;
318
- x = tx;
319
- y = ty;
320
- }
321
- x += poly.pos.x;
322
- y += poly.pos.y;
323
- minX = Math.min(minX, x);
324
- minY = Math.min(minY, y);
325
- maxX = Math.max(maxX, x);
326
- maxY = Math.max(maxY, y);
327
- }
328
- return { minX, minY, maxX, maxY };
329
- }
330
- /* ---------------------------------- */
331
- /* Obstacles */
332
- /* ---------------------------------- */
333
- /**
334
- * Manages obstacles with spatial hashing for fast queries.
335
- * Version tracking prevents unnecessary rebuilds.
336
- */
337
- class Obstacles {
338
- constructor() {
339
- this.items = new Map();
340
- this.spatial = new SpatialHash(1); // Match grid cell size
341
- this._cachedItems = [];
342
- this.dirty = true;
343
- this.version = 0;
344
- }
345
- add(obstacle) {
346
- const id = genId();
347
- const newObstacle = { ...obstacle, id };
348
- this.items.set(id, newObstacle);
349
- this.spatial.add(id, newObstacle);
350
- this.dirty = true;
351
- this.version++;
352
- return id;
353
- }
354
- move(id, pos) {
355
- const o = this.items.get(id);
356
- if (!o)
357
- return;
358
- // Remove from old position in spatial hash
359
- this.spatial.remove(id);
360
- // Create updated obstacle
361
- const updated = {
362
- ...o,
363
- pos: { ...pos },
364
- };
365
- this.items.set(id, updated);
366
- this.spatial.add(id, updated);
367
- this.dirty = true;
368
- this.version++;
369
- }
370
- remove(id) {
371
- this.spatial.remove(id);
372
- this.items.delete(id);
373
- this.dirty = true;
374
- this.version++;
375
- }
376
- /**
377
- * Fast spatial query using hash grid.
378
- * O(1) average case instead of O(n) linear scan.
379
- */
380
- at(pos) {
381
- const candidates = this.spatial.query(pos);
382
- for (const id of candidates) {
383
- const o = this.items.get(id);
384
- if (!o || o.solid === false)
385
- continue;
386
- if (o.type === 'circle' && pointInCircle(pos, o))
387
- return o;
388
- if (o.type === 'rect' && pointInRect(pos, o))
389
- return o;
390
- if (o.type === 'polygon' && pointInPolygon(pos, o))
391
- return o;
392
- }
393
- }
394
- get values() {
395
- if (!this.dirty)
396
- return this._cachedItems;
397
- this._cachedItems = [...this.items.values()];
398
- this.dirty = false;
399
- return this._cachedItems;
400
- }
401
- }
402
- /* ---------------------------------- */
403
- /* Grid Nav */
404
- /* ---------------------------------- */
405
- /**
406
- * Grid navigation with simple full rebuild.
407
- * Fast enough for most games (< 1000 obstacles).
408
- *
409
- * Performance: O(n * area) where n = obstacle count.
410
- * Typical rebuild time: < 1ms for 100 obstacles on 100x100 grid.
411
- */
412
- class GridNav {
413
- constructor(obstacles) {
414
- this.obstacles = obstacles;
415
- this.blocked = new Set();
416
- }
417
- /**
418
- * Rebuilds the entire blocked cell set.
419
- * Simple and correct - no incremental complexity.
420
- */
421
- rebuild() {
422
- this.blocked.clear();
423
- for (const o of this.obstacles.values) {
424
- if (o.solid === false)
425
- continue;
426
- if (o.type === 'circle') {
427
- const r = Math.ceil(o.radius);
428
- const cx = Math.floor(o.pos.x);
429
- const cy = Math.floor(o.pos.y);
430
- for (let dx = -r; dx <= r; dx++) {
431
- for (let dy = -r; dy <= r; dy++) {
432
- const cellX = cx + dx;
433
- const cellY = cy + dy;
434
- const cellCenter = { x: cellX + 0.5, y: cellY + 0.5 };
435
- if (pointInCircle(cellCenter, o)) {
436
- this.blocked.add(encodeCell(cellX, cellY));
437
- }
438
- }
439
- }
440
- }
441
- else if (o.type === 'rect') {
442
- const cx = o.pos.x + o.size.x / 2;
443
- const cy = o.pos.y + o.size.y / 2;
444
- const hw = o.size.x / 2;
445
- const hh = o.size.y / 2;
446
- const diagonal = Math.sqrt(hw * hw + hh * hh);
447
- const minX = Math.floor(cx - diagonal);
448
- const maxX = Math.ceil(cx + diagonal);
449
- const minY = Math.floor(cy - diagonal);
450
- const maxY = Math.ceil(cy + diagonal);
451
- for (let x = minX; x <= maxX; x++) {
452
- for (let y = minY; y <= maxY; y++) {
453
- const cellCenter = { x: x + 0.5, y: y + 0.5 };
454
- if (pointInRect(cellCenter, o)) {
455
- this.blocked.add(encodeCell(x, y));
456
- }
457
- }
458
- }
459
- }
460
- else if (o.type === 'polygon') {
461
- const bounds = getPolygonBounds(o);
462
- const minX = Math.floor(bounds.minX);
463
- const maxX = Math.ceil(bounds.maxX);
464
- const minY = Math.floor(bounds.minY);
465
- const maxY = Math.ceil(bounds.maxY);
466
- for (let x = minX; x <= maxX; x++) {
467
- for (let y = minY; y <= maxY; y++) {
468
- const cellCenter = { x: x + 0.5, y: y + 0.5 };
469
- if (pointInPolygon(cellCenter, o)) {
470
- this.blocked.add(encodeCell(x, y));
471
- }
472
- }
473
- }
474
- }
475
- }
476
- }
477
- findPath(from, to) {
478
- return aStar(toCell(from), toCell(to), (x, y) => !this.blocked.has(encodeCell(x, y))).map(fromCell);
479
- }
480
- }
481
- /* ---------------------------------- */
482
- /* Graph Nav */
483
- /* ---------------------------------- */
484
- /**
485
- * Line-of-sight navigation with grid fallback.
486
- * Not a true navmesh - use GridNav for production.
487
- */
488
- class GraphNav {
489
- constructor(obstacles) {
490
- this.obstacles = obstacles;
491
- }
492
- rebuild() { }
493
- findPath(from, to) {
494
- // Uniform sampling along path for LOS check
495
- const steps = Math.ceil(Math.hypot(to.x - from.x, to.y - from.y) * 2);
496
- let blocked = false;
497
- for (let i = 1; i <= steps; i++) {
498
- const t = i / steps;
499
- const p = {
500
- x: from.x + (to.x - from.x) * t,
501
- y: from.y + (to.y - from.y) * t,
502
- };
503
- if (this.obstacles.at(p)) {
504
- blocked = true;
505
- break;
506
- }
507
- }
508
- if (!blocked) {
509
- return [from, to];
510
- }
511
- // Fallback to grid A*
512
- const cellPath = aStar(toCell(from), toCell(to), (x, y) => {
513
- const p = { x: x + 0.5, y: y + 0.5 };
514
- return !this.obstacles.at(p);
515
- });
516
- return cellPath.map(fromCell);
517
- }
518
- }
519
- /**
520
- * Navigation mesh with spatial hashing and smart rebuild.
521
- *
522
- * Features:
523
- * - Spatial hash: O(1) obstacle queries
524
- * - Version tracking: zero unnecessary rebuilds
525
- * - Binary heap A*: handles 10k+ node searches
526
- * - Simple full rebuild: correct and fast enough
527
- * - Optional Web Workers: 3-4.5x speedup for parallel pathfinding
528
- *
529
- * Performance characteristics:
530
- * - Obstacle query: O(1) average via spatial hash
531
- * - Grid rebuild: O(n * area), < 1ms for typical games
532
- * - Pathfinding: O(b^d * log n) with binary heap
533
- * - Worker overhead: ~0.5ms per request (use for 20+ concurrent paths)
534
- *
535
- * Production ready for:
536
- * - Grid-based games
537
- * - RTS with < 1000 dynamic obstacles
538
- * - Turn-based games
539
- * - Moderate map sizes (< 1M cells)
540
- *
541
- * @example
542
- * ```ts
543
- * // Simple usage (synchronous) - typed as Vec2[]
544
- * const navmesh = new NavMesh('grid');
545
- * const path = navmesh.findPath({ from: {x:0, y:0}, to: {x:10, y:10} });
546
- *
547
- * // With workers (automatic) - typed as Vec2[] | Promise<Vec2[]>
548
- * const navmesh = new NavMesh('grid', { workers: 'auto' });
549
- * const path = await navmesh.findPath({ from: {x:0, y:0}, to: {x:10, y:10} });
550
- *
551
- * // With workers (always) - typed as Promise<Vec2[]>
552
- * const navmesh = new NavMesh('grid', { workers: true });
553
- * const path = await navmesh.findPath({ from: {x:0, y:0}, to: {x:10, y:10} });
554
- * ```
555
- */
556
- export class NavMesh {
557
- constructor(type, options) {
558
- this.type = type;
559
- this.lastVersion = -1;
560
- this.pendingPaths = 0;
561
- this.AUTO_WORKER_THRESHOLD = 20; // Use workers when >= 20 pending paths
562
- this.obstacles = new Obstacles();
563
- // Set defaults - cast to any to avoid complex type gymnastics
564
- this.options = {
565
- workers: (options?.workers ?? false),
566
- workerPoolSize: options?.workerPoolSize ?? 4,
567
- workerPath: options?.workerPath ?? './navmesh.worker.js',
568
- };
569
- // Initialize sync navigation
570
- if (type === 'grid')
571
- this.grid = new GridNav(this.obstacles);
572
- if (type === 'graph')
573
- this.graph = new GraphNav(this.obstacles);
574
- // Initialize worker pool if workers = true
575
- if (this.options.workers === true) {
576
- this.initWorkerPool();
577
- }
578
- }
579
- /**
580
- * Lazy initialize worker pool
581
- */
582
- async initWorkerPool() {
583
- if (this.workerPool)
584
- return;
585
- try {
586
- // Dynamic import to avoid bundling worker pool if not needed
587
- const { NavMeshWorkerPool } = await import('./navmesh-worker-pool');
588
- this.workerPool = new NavMeshWorkerPool(this.options.workerPoolSize, this.options.workerPath, this.type, this.obstacles.values);
589
- await this.workerPool.init();
590
- }
591
- catch (error) {
592
- console.warn('Failed to initialize worker pool, falling back to sync:', error);
593
- this.options.workers = false; // Disable workers on failure
594
- }
595
- }
596
- /**
597
- * Check if we should use workers for this request
598
- */
599
- shouldUseWorkers() {
600
- if (this.options.workers === false)
601
- return false;
602
- if (this.options.workers === true)
603
- return true;
604
- // Auto mode: use workers if we have many pending paths
605
- return this.pendingPaths >= this.AUTO_WORKER_THRESHOLD;
606
- }
607
- /**
608
- * Adds an obstacle and returns its unique ID.
609
- * For polygons: ensure points are defined relative to (0,0).
610
- */
611
- addObstacle(obstacle) {
612
- return this.obstacles.add(obstacle);
613
- }
614
- /**
615
- * Moves an existing obstacle to a new position.
616
- */
617
- moveObstacle(id, pos) {
618
- this.obstacles.move(id, pos);
619
- }
620
- /**
621
- * Removes an obstacle by ID.
622
- */
623
- removeObstacle(id) {
624
- this.obstacles.remove(id);
625
- }
626
- /**
627
- * Returns all current obstacles.
628
- */
629
- getObstacles() {
630
- return this.obstacles.values;
631
- }
632
- /**
633
- * Finds a path from start to goal.
634
- * Automatically rebuilds navigation data if obstacles changed.
635
- * Returns empty array if no path exists.
636
- *
637
- * @remarks
638
- * - If workers are disabled (false): Returns Vec2[] synchronously
639
- * - If workers are enabled (true): Returns Promise<Vec2[]>
640
- * - If workers are 'auto': Returns Vec2[] | Promise<Vec2[]> based on load
641
- *
642
- * @example
643
- * ```ts
644
- * // Synchronous (no workers) - typed as Vec2[]
645
- * const navmesh = new NavMesh('grid');
646
- * const path = navmesh.findPath({ from, to });
647
- *
648
- * // Asynchronous (with workers) - typed as Promise<Vec2[]>
649
- * const navmesh = new NavMesh('grid', { workers: true });
650
- * const path = await navmesh.findPath({ from, to });
651
- *
652
- * // Auto mode - typed as Vec2[] | Promise<Vec2[]>
653
- * const navmesh = new NavMesh('grid', { workers: 'auto' });
654
- * const result = navmesh.findPath({ from, to });
655
- * const path = result instanceof Promise ? await result : result;
656
- * ```
657
- */
658
- findPath({ from, to }) {
659
- // Check if we should use workers
660
- if (this.shouldUseWorkers() && this.workerPool) {
661
- // Async path (with workers)
662
- this.pendingPaths++;
663
- return this.findPathAsync(from, to).finally(() => {
664
- this.pendingPaths--;
665
- });
666
- }
667
- // Sync path (no workers)
668
- this.rebuild();
669
- return (this.type === 'grid'
670
- ? this.grid.findPath(from, to)
671
- : this.graph.findPath(from, to));
672
- }
673
- /**
674
- * Async pathfinding using worker pool
675
- */
676
- async findPathAsync(from, to) {
677
- // Lazy init for 'auto' mode
678
- if (this.options.workers === 'auto' && !this.workerPool) {
679
- await this.initWorkerPool();
680
- }
681
- if (!this.workerPool) {
682
- // Fallback to sync if workers failed to init
683
- this.rebuild();
684
- return this.type === 'grid'
685
- ? this.grid.findPath(from, to)
686
- : this.graph.findPath(from, to);
687
- }
688
- return this.workerPool.findPath(from, to);
689
- }
690
- /**
691
- * Smart rebuild - only rebuilds if obstacles changed.
692
- * Version checking eliminates unnecessary work.
693
- */
694
- rebuild() {
695
- if (this.lastVersion === this.obstacles.version)
696
- return;
697
- this.grid?.rebuild();
698
- this.graph?.rebuild();
699
- this.lastVersion = this.obstacles.version;
700
- }
701
- /**
702
- * Cleanup resources (terminate worker pool if active)
703
- * Call this when you're done with the NavMesh instance.
704
- *
705
- * @example
706
- * ```ts
707
- * const navmesh = new NavMesh('grid', { workers: true });
708
- * // ... use navmesh ...
709
- * navmesh.dispose(); // Cleanup workers
710
- * ```
711
- */
712
- dispose() {
713
- if (this.workerPool) {
714
- this.workerPool.terminate();
715
- this.workerPool = undefined;
716
- }
717
- }
718
- /**
719
- * Get current worker status for debugging/monitoring
720
- */
721
- getWorkerStatus() {
722
- return {
723
- workersEnabled: this.options.workers,
724
- workerPoolActive: !!this.workerPool,
725
- pendingPaths: this.pendingPaths,
726
- usingWorkersNow: this.shouldUseWorkers(),
727
- };
728
- }
729
- }
730
- /* ---------------------------------- */
731
- /* A* */
732
- /* ---------------------------------- */
733
- /**
734
- * A* pathfinding with binary heap and proper open set tracking.
735
- *
736
- * Optimizations:
737
- * - Binary heap: O(log n) operations
738
- * - Open set tracking: prevents duplicate nodes
739
- * - Integer cell encoding: eliminates string allocation
740
- * - Closed set: avoids reprocessing
741
- *
742
- * Performance: Handles 10k+ node searches efficiently.
743
- * Time: O(b^d * log n) where b = branching, d = depth, n = nodes.
744
- */
745
- function aStar(start, goal, walkable) {
746
- const cameFrom = new Map();
747
- const g = new Map();
748
- const closed = new Set();
749
- const openSet = new Set();
750
- const key = (p) => encodeCell(p.x, p.y);
751
- const h = (a, b) => Math.abs(a.x - b.x) + Math.abs(a.y - b.y);
752
- const open = new BinaryHeap((nodeKey) => {
753
- const pos = decodeCell(nodeKey);
754
- return g.get(nodeKey) + h(pos, goal);
755
- });
756
- const startKey = key(start);
757
- g.set(startKey, 0);
758
- open.push(startKey);
759
- openSet.add(startKey);
760
- while (open.size > 0) {
761
- const currentKey = open.pop();
762
- openSet.delete(currentKey);
763
- const current = decodeCell(currentKey);
764
- if (current.x === goal.x && current.y === goal.y) {
765
- return reconstruct(cameFrom, current);
766
- }
767
- closed.add(currentKey);
768
- for (const d of dirs) {
769
- const n = { x: current.x + d.x, y: current.y + d.y };
770
- if (!walkable(n.x, n.y))
771
- continue;
772
- const nk = key(n);
773
- if (closed.has(nk))
774
- continue;
775
- const ng = g.get(currentKey) + 1;
776
- if (ng < (g.get(nk) ?? Infinity)) {
777
- g.set(nk, ng);
778
- cameFrom.set(nk, currentKey);
779
- if (!openSet.has(nk)) {
780
- open.push(nk);
781
- openSet.add(nk);
782
- }
783
- }
784
- }
785
- }
786
- return [];
787
- }
788
- /**
789
- * Reconstructs path from A* came-from map.
790
- */
791
- function reconstruct(cameFrom, current) {
792
- const path = [current];
793
- let k = encodeCell(current.x, current.y);
794
- while (cameFrom.has(k)) {
795
- k = cameFrom.get(k);
796
- path.push(decodeCell(k));
797
- }
798
- return path.reverse();
799
- }