murow 0.0.70 → 0.0.72

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 (470) hide show
  1. package/README.md +54 -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/renderer-2d.js +1 -0
  74. package/dist/cjs/renderer/base/renderer-3d.js +1 -0
  75. package/dist/cjs/renderer/base/renderer.js +1 -0
  76. package/dist/cjs/renderer/gltf/helpers.js +1 -0
  77. package/dist/cjs/renderer/gltf/parser.js +1 -0
  78. package/dist/cjs/renderer/gltf/skeletal-animation.js +1 -0
  79. package/dist/cjs/renderer/gltf/skin-parser.js +1 -0
  80. package/dist/cjs/renderer/index.js +1 -0
  81. package/dist/cjs/renderer/math.js +1 -0
  82. package/dist/cjs/renderer/prefab-bucket/concrete.js +1 -0
  83. package/dist/cjs/renderer/prefab-bucket/index.js +1 -0
  84. package/dist/cjs/renderer/prefab-bucket/parsers.js +1 -0
  85. package/dist/cjs/renderer/prefab-bucket/specs.js +1 -0
  86. package/dist/cjs/renderer/spritesheet/helpers.js +1 -0
  87. package/dist/cjs/renderer/spritesheet/parser.js +1 -0
  88. package/dist/cjs/renderer/types.js +1 -0
  89. package/dist/esm/core/binary-codec/binary-codec.js +1 -0
  90. package/dist/esm/core/binary-codec/index.js +1 -0
  91. package/dist/esm/core/driver/driver.js +1 -0
  92. package/dist/esm/core/driver/drivers/immediate.js +1 -0
  93. package/dist/esm/core/driver/drivers/index.js +1 -0
  94. package/dist/esm/core/driver/drivers/raf.js +1 -0
  95. package/dist/esm/core/driver/drivers/timeout.js +1 -0
  96. package/dist/esm/core/driver/index.js +1 -0
  97. package/dist/esm/core/events/event-system.js +1 -0
  98. package/dist/esm/core/events/index.js +1 -0
  99. package/dist/esm/core/fixed-ticker/fixed-ticker.js +1 -0
  100. package/dist/esm/core/fixed-ticker/index.js +1 -0
  101. package/dist/esm/core/free-list/free-list.js +1 -0
  102. package/dist/esm/core/free-list/index.js +1 -0
  103. package/dist/esm/core/generate-id/generate-id.js +1 -0
  104. package/dist/esm/core/generate-id/index.js +1 -0
  105. package/dist/esm/core/index.js +1 -0
  106. package/dist/esm/core/input/index.js +1 -0
  107. package/dist/esm/core/input/manager.js +1 -0
  108. package/dist/esm/core/input/sources/browser.js +1 -0
  109. package/dist/esm/core/input/sources/index.js +1 -0
  110. package/dist/esm/core/input/types.js +0 -0
  111. package/dist/esm/core/lerp/index.js +1 -0
  112. package/dist/esm/core/lerp/lerp.js +1 -0
  113. package/dist/esm/core/navmesh/index.js +1 -0
  114. package/dist/esm/core/navmesh/navmesh-worker-pool.js +1 -0
  115. package/dist/esm/core/navmesh/navmesh.js +1 -0
  116. package/dist/esm/core/navmesh/navmesh.worker.js +1 -0
  117. package/dist/esm/core/pooled-codec/index.js +1 -0
  118. package/dist/esm/core/pooled-codec/pooled-codec.js +1 -0
  119. package/dist/esm/core/prediction/index.js +1 -0
  120. package/dist/esm/core/prediction/prediction.js +1 -0
  121. package/dist/esm/core/ray/index.js +1 -0
  122. package/dist/esm/core/ray/ray-2d.js +1 -0
  123. package/dist/esm/core/ray/ray-3d.js +1 -0
  124. package/dist/esm/core/simple-rng/index.js +1 -0
  125. package/dist/esm/core/simple-rng/simple-rng.js +1 -0
  126. package/dist/esm/core/sparse-batcher/index.js +1 -0
  127. package/dist/esm/core/sparse-batcher/sparse-batcher.js +1 -0
  128. package/dist/esm/ecs/component-store.js +1 -0
  129. package/dist/esm/ecs/component.js +1 -0
  130. package/dist/esm/ecs/entity-handle.js +1 -0
  131. package/dist/esm/ecs/index.js +1 -0
  132. package/dist/esm/ecs/system-builder.js +1 -0
  133. package/dist/esm/ecs/world-systems.js +1 -0
  134. package/dist/esm/ecs/world.js +1 -0
  135. package/dist/esm/game/index.js +1 -0
  136. package/dist/esm/game/loop/index.js +1 -0
  137. package/dist/esm/game/loop/loop.js +1 -0
  138. package/dist/esm/index.js +1 -0
  139. package/dist/esm/net/adapters/browser-websocket.js +1 -0
  140. package/dist/esm/net/adapters/bun-websocket.js +1 -0
  141. package/dist/esm/net/buffer-pool.js +1 -0
  142. package/dist/esm/net/client.js +1 -0
  143. package/dist/esm/net/index.js +1 -0
  144. package/dist/esm/net/server.js +1 -0
  145. package/dist/esm/net/types.js +1 -0
  146. package/dist/esm/net/validators.js +1 -0
  147. package/dist/esm/protocol/index.js +1 -0
  148. package/dist/esm/protocol/intent/define-intent.js +1 -0
  149. package/dist/esm/protocol/intent/index.js +1 -0
  150. package/dist/esm/protocol/intent/intent-registry.js +1 -0
  151. package/dist/esm/protocol/intent/intent.js +0 -0
  152. package/dist/esm/protocol/rpc/define-rpc.js +1 -0
  153. package/dist/esm/protocol/rpc/index.js +1 -0
  154. package/dist/esm/protocol/rpc/rpc-registry.js +1 -0
  155. package/dist/esm/protocol/rpc/rpc.js +0 -0
  156. package/dist/esm/protocol/snapshot/index.js +1 -0
  157. package/dist/esm/protocol/snapshot/snapshot-codec.js +1 -0
  158. package/dist/esm/protocol/snapshot/snapshot-registry.js +1 -0
  159. package/dist/esm/protocol/snapshot/snapshot.js +1 -0
  160. package/dist/esm/renderer/base/renderer-2d.js +1 -0
  161. package/dist/esm/renderer/base/renderer-3d.js +1 -0
  162. package/dist/esm/renderer/base/renderer.js +1 -0
  163. package/dist/esm/renderer/gltf/helpers.js +1 -0
  164. package/dist/esm/renderer/gltf/parser.js +1 -0
  165. package/dist/esm/renderer/gltf/skeletal-animation.js +1 -0
  166. package/dist/esm/renderer/gltf/skin-parser.js +1 -0
  167. package/dist/esm/renderer/index.js +1 -0
  168. package/dist/esm/renderer/math.js +1 -0
  169. package/dist/esm/renderer/prefab-bucket/concrete.js +1 -0
  170. package/dist/esm/renderer/prefab-bucket/index.js +1 -0
  171. package/dist/esm/renderer/prefab-bucket/parsers.js +1 -0
  172. package/dist/esm/renderer/prefab-bucket/specs.js +0 -0
  173. package/dist/esm/renderer/spritesheet/helpers.js +1 -0
  174. package/dist/esm/renderer/spritesheet/parser.js +1 -0
  175. package/dist/esm/renderer/types.js +0 -0
  176. package/dist/{core → types/core}/binary-codec/binary-codec.d.ts +4 -0
  177. package/dist/{core → types/core}/events/event-system.d.ts +14 -33
  178. package/dist/types/core/free-list/free-list.d.ts +31 -0
  179. package/dist/types/core/free-list/index.d.ts +1 -0
  180. package/dist/{core → types/core}/index.d.ts +5 -0
  181. package/dist/{core → types/core}/input/index.d.ts +1 -0
  182. package/dist/{core → types/core}/input/manager.d.ts +2 -0
  183. package/dist/{core → types/core}/navmesh/navmesh.d.ts +1 -21
  184. package/dist/types/core/ray/index.d.ts +2 -0
  185. package/dist/types/core/ray/ray-2d.d.ts +37 -0
  186. package/dist/types/core/ray/ray-3d.d.ts +42 -0
  187. package/dist/types/core/simple-rng/index.d.ts +1 -0
  188. package/dist/types/core/simple-rng/simple-rng.d.ts +36 -0
  189. package/dist/types/core/sparse-batcher/index.d.ts +1 -0
  190. package/dist/types/core/sparse-batcher/sparse-batcher.d.ts +55 -0
  191. package/dist/{ecs → types/ecs}/world.d.ts +11 -0
  192. package/dist/{game → types/game}/loop/loop.d.ts +33 -29
  193. package/dist/{index.d.ts → types/index.d.ts} +1 -0
  194. package/dist/{net → types/net}/index.d.ts +2 -2
  195. package/dist/types/renderer/base/renderer-2d.d.ts +13 -0
  196. package/dist/types/renderer/base/renderer-3d.d.ts +10 -0
  197. package/dist/types/renderer/base/renderer.d.ts +21 -0
  198. package/dist/types/renderer/gltf/helpers.d.ts +43 -0
  199. package/dist/types/renderer/gltf/parser.d.ts +49 -0
  200. package/dist/types/renderer/gltf/skeletal-animation.d.ts +96 -0
  201. package/dist/types/renderer/gltf/skin-parser.d.ts +107 -0
  202. package/dist/types/renderer/index.d.ts +15 -0
  203. package/dist/types/renderer/math.d.ts +37 -0
  204. package/dist/types/renderer/prefab-bucket/concrete.d.ts +55 -0
  205. package/dist/types/renderer/prefab-bucket/index.d.ts +113 -0
  206. package/dist/types/renderer/prefab-bucket/parsers.d.ts +8 -0
  207. package/dist/types/renderer/prefab-bucket/specs.d.ts +166 -0
  208. package/dist/types/renderer/spritesheet/helpers.d.ts +38 -0
  209. package/dist/types/renderer/spritesheet/parser.d.ts +21 -0
  210. package/dist/types/renderer/types.d.ts +89 -0
  211. package/dist/webgpu/cjs/index.js +5401 -0
  212. package/dist/webgpu/esm/index.js +5378 -0
  213. package/dist/webgpu/types/2d/animation.d.ts +97 -0
  214. package/dist/webgpu/types/2d/renderer.d.ts +86 -0
  215. package/dist/webgpu/types/2d/shader.d.ts +61 -0
  216. package/dist/webgpu/types/2d/sprite-accessor.d.ts +47 -0
  217. package/dist/webgpu/types/3d/clip-resync-coordinator.d.ts +20 -0
  218. package/dist/webgpu/types/3d/morph-animation.d.ts +69 -0
  219. package/dist/webgpu/types/3d/morph-animation.test.d.ts +1 -0
  220. package/dist/webgpu/types/3d/renderer.d.ts +266 -0
  221. package/dist/webgpu/types/3d/shader.d.ts +136 -0
  222. package/dist/webgpu/types/3d/skeletal-animation-compute/index.d.ts +2 -0
  223. package/dist/webgpu/types/3d/skeletal-animation-compute/kernel.d.ts +25 -0
  224. package/dist/webgpu/types/3d/skeletal-animation-compute/packer.d.ts +32 -0
  225. package/dist/webgpu/types/camera/camera-2d.d.ts +53 -0
  226. package/dist/webgpu/types/camera/camera-2d.test.d.ts +1 -0
  227. package/dist/webgpu/types/camera/camera-3d.d.ts +81 -0
  228. package/dist/webgpu/types/camera/camera-3d.test.d.ts +1 -0
  229. package/dist/webgpu/types/camera/index.d.ts +2 -0
  230. package/dist/webgpu/types/compute/compute-builder.d.ts +123 -0
  231. package/dist/webgpu/types/compute/compute-builder.test.d.ts +1 -0
  232. package/dist/webgpu/types/core/constants.d.ts +59 -0
  233. package/dist/webgpu/types/core/constants.test.d.ts +1 -0
  234. package/dist/webgpu/types/core/index.d.ts +2 -0
  235. package/dist/webgpu/types/core/types.d.ts +125 -0
  236. package/dist/webgpu/types/core/types.test.d.ts +1 -0
  237. package/dist/webgpu/types/geometry/built-in.d.ts +58 -0
  238. package/dist/webgpu/types/geometry/built-in.test.d.ts +1 -0
  239. package/dist/webgpu/types/geometry/geometry-builder.d.ts +281 -0
  240. package/dist/webgpu/types/geometry/geometry-builder.test.d.ts +1 -0
  241. package/dist/webgpu/types/geometry/index.d.ts +2 -0
  242. package/dist/webgpu/types/index.d.ts +35 -0
  243. package/dist/webgpu/types/particle/emitter.d.ts +36 -0
  244. package/dist/webgpu/types/shaders/index.d.ts +2 -0
  245. package/dist/webgpu/types/shaders/runtime-transpile.d.ts +18 -0
  246. package/dist/webgpu/types/shaders/sprite-2d.wgsl.d.ts +10 -0
  247. package/dist/webgpu/types/shaders/typegpu.d.ts +9 -0
  248. package/dist/webgpu/types/shaders/utils.d.ts +28 -0
  249. package/dist/webgpu/types/shaders/utils.test.d.ts +1 -0
  250. package/dist/webgpu/types/spritesheet/index.d.ts +1 -0
  251. package/dist/webgpu/types/spritesheet/spritesheet.d.ts +28 -0
  252. package/dist/webgpu/types/spritesheet/spritesheet.test.d.ts +1 -0
  253. package/package.json +96 -26
  254. package/dist/core/binary-codec/binary-codec.js +0 -354
  255. package/dist/core/binary-codec/index.js +0 -1
  256. package/dist/core/driver/driver.js +0 -47
  257. package/dist/core/driver/drivers/immediate.js +0 -61
  258. package/dist/core/driver/drivers/index.js +0 -3
  259. package/dist/core/driver/drivers/raf.js +0 -62
  260. package/dist/core/driver/drivers/timeout.js +0 -71
  261. package/dist/core/driver/index.js +0 -2
  262. package/dist/core/events/event-system.js +0 -88
  263. package/dist/core/events/index.js +0 -1
  264. package/dist/core/fixed-ticker/fixed-ticker.js +0 -105
  265. package/dist/core/fixed-ticker/index.js +0 -1
  266. package/dist/core/generate-id/generate-id.js +0 -25
  267. package/dist/core/generate-id/index.js +0 -1
  268. package/dist/core/index.js +0 -10
  269. package/dist/core/input/index.js +0 -2
  270. package/dist/core/input/manager.js +0 -211
  271. package/dist/core/input/sources/browser.js +0 -29
  272. package/dist/core/input/sources/index.js +0 -1
  273. package/dist/core/lerp/index.js +0 -1
  274. package/dist/core/lerp/lerp.js +0 -42
  275. package/dist/core/navmesh/index.js +0 -1
  276. package/dist/core/navmesh/navmesh-worker-pool.js +0 -180
  277. package/dist/core/navmesh/navmesh.js +0 -799
  278. package/dist/core/navmesh/navmesh.worker.js +0 -79
  279. package/dist/core/pooled-codec/index.js +0 -1
  280. package/dist/core/pooled-codec/pooled-codec.js +0 -410
  281. package/dist/core/prediction/index.js +0 -1
  282. package/dist/core/prediction/prediction.js +0 -99
  283. package/dist/core.esm.js +0 -1
  284. package/dist/core.js +0 -1
  285. package/dist/ecs/component-store.js +0 -175
  286. package/dist/ecs/component.js +0 -43
  287. package/dist/ecs/entity-handle.js +0 -515
  288. package/dist/ecs/example.js +0 -125
  289. package/dist/ecs/index.js +0 -4
  290. package/dist/ecs/system-builder.js +0 -249
  291. package/dist/ecs/world-systems.js +0 -79
  292. package/dist/ecs/world.js +0 -767
  293. package/dist/game/index.js +0 -1
  294. package/dist/game/loop/index.js +0 -1
  295. package/dist/game/loop/loop.js +0 -108
  296. package/dist/index.js +0 -26
  297. package/dist/net/adapters/browser-websocket.js +0 -74
  298. package/dist/net/adapters/bun-websocket.js +0 -245
  299. package/dist/net/buffer-pool.js +0 -89
  300. package/dist/net/client.js +0 -586
  301. package/dist/net/index.js +0 -58
  302. package/dist/net/server.js +0 -974
  303. package/dist/net/types.js +0 -31
  304. package/dist/net/validators.js +0 -88
  305. package/dist/protocol/index.js +0 -92
  306. package/dist/protocol/intent/define-intent.js +0 -125
  307. package/dist/protocol/intent/index.js +0 -91
  308. package/dist/protocol/intent/intent-registry.js +0 -91
  309. package/dist/protocol/rpc/define-rpc.js +0 -84
  310. package/dist/protocol/rpc/index.js +0 -3
  311. package/dist/protocol/rpc/rpc-registry.js +0 -159
  312. package/dist/protocol/rpc/rpc.js +0 -12
  313. package/dist/protocol/snapshot/index.js +0 -43
  314. package/dist/protocol/snapshot/snapshot-codec.js +0 -67
  315. package/dist/protocol/snapshot/snapshot-registry.js +0 -168
  316. package/dist/protocol/snapshot/snapshot.js +0 -30
  317. package/src/core/binary-codec/README.md +0 -60
  318. package/src/core/binary-codec/binary-codec.test.ts +0 -300
  319. package/src/core/binary-codec/binary-codec.ts +0 -448
  320. package/src/core/binary-codec/index.ts +0 -1
  321. package/src/core/driver/README.md +0 -97
  322. package/src/core/driver/driver.test.ts +0 -414
  323. package/src/core/driver/driver.ts +0 -71
  324. package/src/core/driver/drivers/immediate.ts +0 -66
  325. package/src/core/driver/drivers/index.ts +0 -3
  326. package/src/core/driver/drivers/raf.ts +0 -67
  327. package/src/core/driver/drivers/timeout.ts +0 -77
  328. package/src/core/driver/index.ts +0 -2
  329. package/src/core/events/README.md +0 -47
  330. package/src/core/events/event-system.test.ts +0 -243
  331. package/src/core/events/event-system.ts +0 -140
  332. package/src/core/events/index.ts +0 -1
  333. package/src/core/fixed-ticker/README.md +0 -77
  334. package/src/core/fixed-ticker/fixed-ticker.test.ts +0 -151
  335. package/src/core/fixed-ticker/fixed-ticker.ts +0 -174
  336. package/src/core/fixed-ticker/index.ts +0 -1
  337. package/src/core/generate-id/README.md +0 -18
  338. package/src/core/generate-id/generate-id.test.ts +0 -79
  339. package/src/core/generate-id/generate-id.ts +0 -37
  340. package/src/core/generate-id/index.ts +0 -1
  341. package/src/core/index.ts +0 -10
  342. package/src/core/input/README.md +0 -24
  343. package/src/core/input/index.ts +0 -2
  344. package/src/core/input/manager.ts +0 -259
  345. package/src/core/input/sources/browser.ts +0 -39
  346. package/src/core/input/sources/index.ts +0 -1
  347. package/src/core/input/types.ts +0 -40
  348. package/src/core/lerp/README.md +0 -79
  349. package/src/core/lerp/index.ts +0 -1
  350. package/src/core/lerp/lerp.test.ts +0 -90
  351. package/src/core/lerp/lerp.ts +0 -42
  352. package/src/core/navmesh/README.md +0 -164
  353. package/src/core/navmesh/index.ts +0 -1
  354. package/src/core/navmesh/navmesh-worker-pool.ts +0 -236
  355. package/src/core/navmesh/navmesh-workers.test.ts +0 -356
  356. package/src/core/navmesh/navmesh.test.ts +0 -344
  357. package/src/core/navmesh/navmesh.ts +0 -1047
  358. package/src/core/navmesh/navmesh.worker.ts +0 -147
  359. package/src/core/pooled-codec/README.md +0 -70
  360. package/src/core/pooled-codec/index.ts +0 -1
  361. package/src/core/pooled-codec/pooled-codec.test.ts +0 -862
  362. package/src/core/pooled-codec/pooled-codec.ts +0 -504
  363. package/src/core/prediction/README.md +0 -64
  364. package/src/core/prediction/index.ts +0 -1
  365. package/src/core/prediction/prediction.test.ts +0 -423
  366. package/src/core/prediction/prediction.ts +0 -112
  367. package/src/ecs/README.md +0 -427
  368. package/src/ecs/benchmark.test.ts +0 -1645
  369. package/src/ecs/component-store.ts +0 -198
  370. package/src/ecs/component.ts +0 -90
  371. package/src/ecs/entity-handle.test.ts +0 -393
  372. package/src/ecs/entity-handle.ts +0 -563
  373. package/src/ecs/example.ts +0 -152
  374. package/src/ecs/index.ts +0 -4
  375. package/src/ecs/system-builder.ts +0 -404
  376. package/src/ecs/world-systems.ts +0 -83
  377. package/src/ecs/world.test.ts +0 -310
  378. package/src/ecs/world.ts +0 -904
  379. package/src/game/index.ts +0 -1
  380. package/src/game/loop/README.md +0 -32
  381. package/src/game/loop/index.ts +0 -1
  382. package/src/game/loop/loop.ts +0 -236
  383. package/src/index.ts +0 -32
  384. package/src/net/README.md +0 -474
  385. package/src/net/adapters/browser-websocket.ts +0 -86
  386. package/src/net/adapters/bun-websocket.ts +0 -292
  387. package/src/net/buffer-pool.ts +0 -106
  388. package/src/net/client.test.ts +0 -807
  389. package/src/net/client.ts +0 -695
  390. package/src/net/index.ts +0 -60
  391. package/src/net/server.test.ts +0 -799
  392. package/src/net/server.ts +0 -1152
  393. package/src/net/types.ts +0 -228
  394. package/src/net/validators.ts +0 -104
  395. package/src/protocol/README.md +0 -469
  396. package/src/protocol/index.ts +0 -93
  397. package/src/protocol/intent/define-intent.test.ts +0 -397
  398. package/src/protocol/intent/define-intent.ts +0 -201
  399. package/src/protocol/intent/index.ts +0 -94
  400. package/src/protocol/intent/intent-registry.test.ts +0 -198
  401. package/src/protocol/intent/intent-registry.ts +0 -112
  402. package/src/protocol/intent/intent.ts +0 -12
  403. package/src/protocol/rpc/define-rpc.test.ts +0 -141
  404. package/src/protocol/rpc/define-rpc.ts +0 -113
  405. package/src/protocol/rpc/index.ts +0 -3
  406. package/src/protocol/rpc/rpc-registry.test.ts +0 -168
  407. package/src/protocol/rpc/rpc-registry.ts +0 -176
  408. package/src/protocol/rpc/rpc.ts +0 -37
  409. package/src/protocol/snapshot/index.ts +0 -45
  410. package/src/protocol/snapshot/snapshot-codec.test.ts +0 -138
  411. package/src/protocol/snapshot/snapshot-codec.ts +0 -87
  412. package/src/protocol/snapshot/snapshot-registry.test.ts +0 -310
  413. package/src/protocol/snapshot/snapshot-registry.ts +0 -201
  414. package/src/protocol/snapshot/snapshot.test.ts +0 -76
  415. package/src/protocol/snapshot/snapshot.ts +0 -41
  416. /package/dist/{core → types/core}/binary-codec/index.d.ts +0 -0
  417. /package/dist/{core → types/core}/driver/driver.d.ts +0 -0
  418. /package/dist/{core → types/core}/driver/drivers/immediate.d.ts +0 -0
  419. /package/dist/{core → types/core}/driver/drivers/index.d.ts +0 -0
  420. /package/dist/{core → types/core}/driver/drivers/raf.d.ts +0 -0
  421. /package/dist/{core → types/core}/driver/drivers/timeout.d.ts +0 -0
  422. /package/dist/{core → types/core}/driver/index.d.ts +0 -0
  423. /package/dist/{core → types/core}/events/index.d.ts +0 -0
  424. /package/dist/{core → types/core}/fixed-ticker/fixed-ticker.d.ts +0 -0
  425. /package/dist/{core → types/core}/fixed-ticker/index.d.ts +0 -0
  426. /package/dist/{core → types/core}/generate-id/generate-id.d.ts +0 -0
  427. /package/dist/{core → types/core}/generate-id/index.d.ts +0 -0
  428. /package/dist/{core → types/core}/input/sources/browser.d.ts +0 -0
  429. /package/dist/{core → types/core}/input/sources/index.d.ts +0 -0
  430. /package/dist/{core → types/core}/input/types.d.ts +0 -0
  431. /package/dist/{core → types/core}/lerp/index.d.ts +0 -0
  432. /package/dist/{core → types/core}/lerp/lerp.d.ts +0 -0
  433. /package/dist/{core → types/core}/navmesh/index.d.ts +0 -0
  434. /package/dist/{core → types/core}/navmesh/navmesh-worker-pool.d.ts +0 -0
  435. /package/dist/{core → types/core}/navmesh/navmesh.worker.d.ts +0 -0
  436. /package/dist/{core → types/core}/pooled-codec/index.d.ts +0 -0
  437. /package/dist/{core → types/core}/pooled-codec/pooled-codec.d.ts +0 -0
  438. /package/dist/{core → types/core}/prediction/index.d.ts +0 -0
  439. /package/dist/{core → types/core}/prediction/prediction.d.ts +0 -0
  440. /package/dist/{ecs → types/ecs}/component-store.d.ts +0 -0
  441. /package/dist/{ecs → types/ecs}/component.d.ts +0 -0
  442. /package/dist/{ecs → types/ecs}/entity-handle.d.ts +0 -0
  443. /package/dist/{ecs → types/ecs}/example.d.ts +0 -0
  444. /package/dist/{ecs → types/ecs}/index.d.ts +0 -0
  445. /package/dist/{ecs → types/ecs}/system-builder.d.ts +0 -0
  446. /package/dist/{ecs → types/ecs}/world-systems.d.ts +0 -0
  447. /package/dist/{game → types/game}/index.d.ts +0 -0
  448. /package/dist/{game → types/game}/loop/index.d.ts +0 -0
  449. /package/dist/{net → types/net}/adapters/browser-websocket.d.ts +0 -0
  450. /package/dist/{net → types/net}/adapters/bun-websocket.d.ts +0 -0
  451. /package/dist/{net → types/net}/buffer-pool.d.ts +0 -0
  452. /package/dist/{net → types/net}/client.d.ts +0 -0
  453. /package/dist/{net → types/net}/server.d.ts +0 -0
  454. /package/dist/{net → types/net}/types.d.ts +0 -0
  455. /package/dist/{net → types/net}/validators.d.ts +0 -0
  456. /package/dist/{protocol → types/protocol}/index.d.ts +0 -0
  457. /package/dist/{protocol → types/protocol}/intent/define-intent.d.ts +0 -0
  458. /package/dist/{protocol → types/protocol}/intent/index.d.ts +0 -0
  459. /package/dist/{protocol → types/protocol}/intent/intent-registry.d.ts +0 -0
  460. /package/dist/{protocol → types/protocol}/intent/intent.d.ts +0 -0
  461. /package/dist/{protocol → types/protocol}/rpc/define-rpc.d.ts +0 -0
  462. /package/dist/{protocol → types/protocol}/rpc/index.d.ts +0 -0
  463. /package/dist/{protocol → types/protocol}/rpc/rpc-registry.d.ts +0 -0
  464. /package/dist/{protocol → types/protocol}/rpc/rpc.d.ts +0 -0
  465. /package/dist/{protocol → types/protocol}/snapshot/index.d.ts +0 -0
  466. /package/dist/{protocol → types/protocol}/snapshot/snapshot-codec.d.ts +0 -0
  467. /package/dist/{protocol → types/protocol}/snapshot/snapshot-registry.d.ts +0 -0
  468. /package/dist/{protocol → types/protocol}/snapshot/snapshot.d.ts +0 -0
  469. /package/dist/{core/input/types.js → webgpu/types/2d/animation.test.d.ts} +0 -0
  470. /package/dist/{protocol/intent/intent.js → webgpu/types/2d/sprite-accessor.test.d.ts} +0 -0
package/dist/ecs/world.js DELETED
@@ -1,767 +0,0 @@
1
- import { generateId } from "../core/generate-id";
2
- import { ComponentStore } from "./component-store";
3
- import { EntityHandle } from "./entity-handle";
4
- import { WorldSystems } from "./world-systems";
5
- /**
6
- * World manages entities and their components.
7
- * Provides efficient ECS storage using typed arrays.
8
- *
9
- * Performance optimizations:
10
- * - Array iteration instead of Set for 2-5x faster queries
11
- * - Query bitmask caching for repeated queries
12
- * - Array-indexed component stores for O(1) access
13
- * - Pre-allocated ring buffer for entity ID reuse
14
- *
15
- * @example
16
- * ```typescript
17
- * const world = new World({
18
- * maxEntities: 10000,
19
- * components: [Transform, Health, Velocity]
20
- * });
21
- *
22
- * const entity = world.spawn();
23
- * world.add(entity, Transform, { x: 100, y: 200, rotation: 0 });
24
- * world.add(entity, Health, { current: 100, max: 100 });
25
- *
26
- * // Query entities
27
- * for (const entity of world.query(Transform, Velocity)) {
28
- * const transform = world.get(entity, Transform);
29
- * const velocity = world.get(entity, Velocity);
30
- * // transform is readonly, use update() to modify
31
- * world.update(entity, Transform, {
32
- * x: transform.x + velocity.vx,
33
- * y: transform.y + velocity.vy
34
- * });
35
- * }
36
- * ```
37
- */
38
- export class World extends WorldSystems {
39
- constructor(config) {
40
- super();
41
- this.nextEntityId = 0;
42
- this.freeEntityHead = 0;
43
- this.freeEntityTail = 0;
44
- this.freeEntityCount = 0;
45
- this.freeEntityMask = 0; // Bitwise AND mask for power-of-2 modulo
46
- // Entity storage: Array for fast iteration, bitmask for O(1) alive checks
47
- this.aliveEntitiesArray = [];
48
- this.numMaskWords = 0; // Number of allocated mask words
49
- // Component registry (direct index stored on component - zero lookup cost!)
50
- this.components = [];
51
- // Query result cache (reusable buffers for zero allocations)
52
- this.queryResultBuffers = {}; // Now keyed by string hash
53
- // Persistent query cache (invalidated only on archetype changes)
54
- this.archetypeVersion = 0; // Increments on spawn/despawn/add/remove
55
- this.queryCacheVersions = {}; // Keyed by mask hash
56
- // Query mask cache (avoid recomputing masks for same component combinations)
57
- this.queryMaskCache = {};
58
- // Debug ID
59
- this.worldId = generateId({ prefix: "world_" });
60
- this.maxEntities = config.maxEntities ?? 10000;
61
- // Calculate number of mask words needed (1 word per 32 components)
62
- this.numMaskWords = Math.ceil(config.components.length / 32);
63
- // Allocate separate Uint32Array for each mask word
64
- this.componentMasks = [];
65
- for (let i = 0; i < this.numMaskWords; i++) {
66
- this.componentMasks.push(new Uint32Array(this.maxEntities));
67
- }
68
- // Cache first word for fast path (most games use <32 components)
69
- if (this.numMaskWords > 0) {
70
- this.componentMasks0 = this.componentMasks[0];
71
- }
72
- // Round up to next power of 2 for ring buffer (enables bitwise modulo)
73
- const ringBufferSize = Math.pow(2, Math.ceil(Math.log2(this.maxEntities)));
74
- this.freeEntityIds = new Uint32Array(ringBufferSize);
75
- this.freeEntityMask = ringBufferSize - 1; // For x % size → x & mask
76
- // Pre-allocate index lookup for O(1) despawn
77
- this.aliveEntitiesIndices = new Uint32Array(this.maxEntities);
78
- // Pre-allocate alive flags for O(1) alive checks
79
- this.aliveEntityFlags = new Uint8Array(this.maxEntities);
80
- // Pre-allocate arrays for component stores
81
- this.componentStoresArray = new Array(config.components.length);
82
- // Register components
83
- config.components.forEach((component, index) => {
84
- this.components.push(component);
85
- // Store index directly on component for O(1) access (no Map lookup!)
86
- component.__worldIndex = index;
87
- // Create component store with selected backend
88
- const store = new ComponentStore(component, this.maxEntities);
89
- this.componentStoresArray[index] = store;
90
- });
91
- }
92
- /**
93
- * Get component index (O(1) - stored directly on component)
94
- */
95
- getComponentIndex(component) {
96
- const index = component.__worldIndex;
97
- if (index === undefined) {
98
- const registered = this.components.map((c) => c.name).join(", ");
99
- throw new Error(`Component ${component.name} not registered in World[${this.worldId}]. ` +
100
- `Registered components: [${registered}]. ` +
101
- `Did you forget to include it in the WorldConfig?`);
102
- }
103
- return index;
104
- }
105
- /**
106
- * Set a bit in the bitmask for an entity
107
- */
108
- setComponentBit(entity, componentIndex) {
109
- const wordIndex = componentIndex >>> 5; // Which word (div 32)
110
- const bitIndex = componentIndex & 31; // Which bit in word (mod 32)
111
- this.componentMasks[wordIndex][entity] |= 1 << bitIndex;
112
- }
113
- /**
114
- * Clear a bit in the bitmask for an entity
115
- */
116
- clearComponentBit(entity, componentIndex) {
117
- const wordIndex = componentIndex >>> 5; // Which word (div 32)
118
- const bitIndex = componentIndex & 31; // Which bit in word (mod 32)
119
- this.componentMasks[wordIndex][entity] &= ~(1 << bitIndex);
120
- }
121
- /**
122
- * Check if a bit is set in the bitmask for an entity
123
- */
124
- hasComponentBit(entity, componentIndex) {
125
- const wordIndex = componentIndex >>> 5; // Which word (div 32)
126
- const bitIndex = componentIndex & 31; // Which bit in word (mod 32)
127
- return (this.componentMasks[wordIndex][entity] & (1 << bitIndex)) !== 0;
128
- }
129
- /**
130
- * Clear all component bits for an entity
131
- */
132
- clearAllComponentBits(entity) {
133
- // Fast paths for common cases (avoids loop overhead)
134
- if (this.numMaskWords === 1) {
135
- this.componentMasks0[entity] = 0;
136
- }
137
- else if (this.numMaskWords === 2) {
138
- this.componentMasks0[entity] = 0;
139
- this.componentMasks[1][entity] = 0;
140
- }
141
- else if (this.numMaskWords === 3) {
142
- this.componentMasks0[entity] = 0;
143
- this.componentMasks[1][entity] = 0;
144
- this.componentMasks[2][entity] = 0;
145
- }
146
- else {
147
- // General case for 4+ words
148
- for (let i = 0; i < this.numMaskWords; i++) {
149
- this.componentMasks[i][entity] = 0;
150
- }
151
- }
152
- }
153
- /**
154
- * Check if entity matches the required component mask
155
- * Returns true if entity has all required components
156
- *
157
- * Optimized for common case: most games use <32 components,
158
- * so we only need to check the first word
159
- */
160
- matchesComponentMask(entity, mask) {
161
- const len = mask.length;
162
- // Fast path: single word (most common - <32 components)
163
- if (len === 1) {
164
- return (this.componentMasks0[entity] & mask[0]) === mask[0];
165
- }
166
- // Unrolled for 2 words (32-63 components)
167
- if (len === 2) {
168
- return (this.componentMasks0[entity] & mask[0]) === mask[0] &&
169
- (this.componentMasks[1][entity] & mask[1]) === mask[1];
170
- }
171
- // Unrolled for 3 words (64-95 components)
172
- if (len === 3) {
173
- return (this.componentMasks0[entity] & mask[0]) === mask[0] &&
174
- (this.componentMasks[1][entity] & mask[1]) === mask[1] &&
175
- (this.componentMasks[2][entity] & mask[2]) === mask[2];
176
- }
177
- // Unrolled for 4 words (96-127 components)
178
- if (len === 4) {
179
- return (this.componentMasks0[entity] & mask[0]) === mask[0] &&
180
- (this.componentMasks[1][entity] & mask[1]) === mask[1] &&
181
- (this.componentMasks[2][entity] & mask[2]) === mask[2] &&
182
- (this.componentMasks[3][entity] & mask[3]) === mask[3];
183
- }
184
- // General case for 5+ words (rare)
185
- for (let i = 0; i < len; i++) {
186
- if ((this.componentMasks[i][entity] & mask[i]) !== mask[i]) {
187
- return false;
188
- }
189
- }
190
- return true;
191
- }
192
- /**
193
- * Get or compute query bitmask
194
- * Returns array of numbers (one 32-bit mask per word)
195
- *
196
- * Caches masks to avoid recomputation for frequently used component combinations
197
- */
198
- getQueryMask(components) {
199
- // Create cache key from component names (sorted for consistency)
200
- const cacheKey = components.map(c => c.name).sort().join(',');
201
- // Check cache first
202
- const cached = this.queryMaskCache[cacheKey];
203
- if (cached)
204
- return cached;
205
- // Find max component index to determine how many words we need
206
- let maxIndex = -1;
207
- const indices = [];
208
- for (const component of components) {
209
- const index = component.__worldIndex;
210
- if (index === undefined)
211
- return null; // Invalid mask sentinel
212
- indices.push(index);
213
- if (index > maxIndex)
214
- maxIndex = index;
215
- }
216
- // Calculate number of words needed
217
- const numWords = Math.floor(maxIndex / 32) + 1;
218
- const requiredMask = new Array(numWords).fill(0);
219
- // Set bits for each component (direct index access - no lookups!)
220
- for (const index of indices) {
221
- const wordIndex = index >>> 5; // div 32
222
- const bitIndex = index & 31; // mod 32
223
- requiredMask[wordIndex] |= 1 << bitIndex;
224
- }
225
- // Cache the mask for future queries
226
- this.queryMaskCache[cacheKey] = requiredMask;
227
- return requiredMask;
228
- }
229
- /**
230
- * Convert mask array to a hash key for caching
231
- */
232
- maskToKey(mask) {
233
- let key = '';
234
- for (let i = 0; i < mask.length; i++) {
235
- if (mask[i] !== 0) {
236
- key += `${i}:${mask[i].toString(36)},`;
237
- }
238
- }
239
- return key;
240
- }
241
- /**
242
- * Internal: Get query mask key for a set of components.
243
- * Used by SystemBuilder for precomputing query keys.
244
- * @internal
245
- */
246
- _getQueryMaskKey(components) {
247
- const mask = this.getQueryMask(components);
248
- return mask ? this.maskToKey(mask) : '';
249
- }
250
- /**
251
- * Internal: Query entities by precomputed mask key and mask.
252
- * Used by ExecutableSystem for fast queries without mask recomputation.
253
- * @internal
254
- */
255
- _queryByMaskKey(maskKey, requiredMask) {
256
- // Get or create reusable buffer for this query mask
257
- let buffer = this.queryResultBuffers[maskKey];
258
- if (!buffer) {
259
- buffer = [];
260
- this.queryResultBuffers[maskKey] = buffer;
261
- }
262
- // Check if cache is valid (persistent query caching)
263
- if (this.queryCacheVersions[maskKey] === this.archetypeVersion) {
264
- // Cache is valid! Return cached result (FAST PATH - no iteration!)
265
- return buffer;
266
- }
267
- // Cache is stale - rebuild by iterating alive entities
268
- const aliveEntities = this.aliveEntitiesArray;
269
- const length = aliveEntities.length;
270
- const numWords = requiredMask.length;
271
- let writeIdx = 0;
272
- // Fast path for single-word masks (most common case, <32 components)
273
- if (numWords === 1) {
274
- const mask0 = requiredMask[0];
275
- const componentMasks0 = this.componentMasks0;
276
- for (let i = 0; i < length; i++) {
277
- const entity = aliveEntities[i];
278
- if ((componentMasks0[entity] & mask0) === mask0) {
279
- buffer[writeIdx++] = entity;
280
- }
281
- }
282
- }
283
- else if (numWords === 2) {
284
- // Unrolled for 2 words (32-63 components)
285
- const mask0 = requiredMask[0];
286
- const mask1 = requiredMask[1];
287
- const masks0 = this.componentMasks0;
288
- const masks1 = this.componentMasks[1];
289
- for (let i = 0; i < length; i++) {
290
- const entity = aliveEntities[i];
291
- if ((masks0[entity] & mask0) === mask0 &&
292
- (masks1[entity] & mask1) === mask1) {
293
- buffer[writeIdx++] = entity;
294
- }
295
- }
296
- }
297
- else if (numWords === 3) {
298
- // Unrolled for 3 words (64-95 components)
299
- const mask0 = requiredMask[0];
300
- const mask1 = requiredMask[1];
301
- const mask2 = requiredMask[2];
302
- const masks0 = this.componentMasks0;
303
- const masks1 = this.componentMasks[1];
304
- const masks2 = this.componentMasks[2];
305
- for (let i = 0; i < length; i++) {
306
- const entity = aliveEntities[i];
307
- if ((masks0[entity] & mask0) === mask0 &&
308
- (masks1[entity] & mask1) === mask1 &&
309
- (masks2[entity] & mask2) === mask2) {
310
- buffer[writeIdx++] = entity;
311
- }
312
- }
313
- }
314
- else if (numWords === 4) {
315
- // Unrolled for 4 words (96-127 components)
316
- const mask0 = requiredMask[0];
317
- const mask1 = requiredMask[1];
318
- const mask2 = requiredMask[2];
319
- const mask3 = requiredMask[3];
320
- const masks0 = this.componentMasks0;
321
- const masks1 = this.componentMasks[1];
322
- const masks2 = this.componentMasks[2];
323
- const masks3 = this.componentMasks[3];
324
- for (let i = 0; i < length; i++) {
325
- const entity = aliveEntities[i];
326
- if ((masks0[entity] & mask0) === mask0 &&
327
- (masks1[entity] & mask1) === mask1 &&
328
- (masks2[entity] & mask2) === mask2 &&
329
- (masks3[entity] & mask3) === mask3) {
330
- buffer[writeIdx++] = entity;
331
- }
332
- }
333
- }
334
- else {
335
- // General case for 5+ words (rare)
336
- const componentMasks = this.componentMasks;
337
- outer: for (let i = 0; i < length; i++) {
338
- const entity = aliveEntities[i];
339
- for (let w = 0; w < numWords; w++) {
340
- if ((componentMasks[w][entity] & requiredMask[w]) !== requiredMask[w]) {
341
- continue outer;
342
- }
343
- }
344
- buffer[writeIdx++] = entity;
345
- }
346
- }
347
- // Truncate buffer to actual size (zero allocations)
348
- buffer.length = writeIdx;
349
- // Mark cache as valid for this archetype version
350
- this.queryCacheVersions[maskKey] = this.archetypeVersion;
351
- return buffer;
352
- }
353
- /**
354
- * Spawn a new entity.
355
- * Returns the entity ID.
356
- */
357
- spawn() {
358
- // Hot path: allocate new ID (most common case, no branching)
359
- let id = this.nextEntityId;
360
- // Cold path: reuse freed ID if available
361
- if (this.freeEntityCount > 0) {
362
- id = this.freeEntityIds[this.freeEntityTail];
363
- this.freeEntityTail = (this.freeEntityTail + 1) & this.freeEntityMask;
364
- this.freeEntityCount--;
365
- }
366
- else {
367
- this.nextEntityId++;
368
- }
369
- // Bounds check (unlikely to fail in normal operation)
370
- if (id >= this.maxEntities) {
371
- throw new Error(`Maximum entities (${this.maxEntities}) reached. ` +
372
- `Current alive: ${this.aliveEntitiesArray.length}, ` +
373
- `Free list: ${this.freeEntityCount}`);
374
- }
375
- // Fast path: setup entity (no branches)
376
- this.aliveEntityFlags[id] = 1;
377
- this.aliveEntitiesIndices[id] = this.aliveEntitiesArray.length;
378
- this.aliveEntitiesArray.push(id);
379
- this.clearAllComponentBits(id);
380
- // Invalidate query cache since entity count changed
381
- this.invalidateQueryCache();
382
- return id;
383
- }
384
- /**
385
- * Despawn an entity, removing all its components.
386
- * The entity ID will be reused.
387
- */
388
- despawn(entity) {
389
- if (this.aliveEntityFlags[entity] === 0) {
390
- return; // Already despawned
391
- }
392
- this.aliveEntityFlags[entity] = 0;
393
- // Remove from array (swap with last for O(1) removal)
394
- const idx = this.aliveEntitiesIndices[entity];
395
- const last = this.aliveEntitiesArray.length - 1;
396
- if (idx !== last) {
397
- // Swap with last element
398
- const lastEntity = this.aliveEntitiesArray[last];
399
- this.aliveEntitiesArray[idx] = lastEntity;
400
- this.aliveEntitiesIndices[lastEntity] = idx;
401
- }
402
- this.aliveEntitiesArray.pop();
403
- // Clear all components for this entity
404
- const stores = this.componentStoresArray;
405
- const componentCount = this.components.length;
406
- for (let i = 0; i < componentCount; i++) {
407
- if (this.hasComponentBit(entity, i)) {
408
- stores[i].clear(entity);
409
- }
410
- }
411
- this.clearAllComponentBits(entity);
412
- // Push to free list
413
- this.freeEntityIds[this.freeEntityHead] = entity;
414
- this.freeEntityHead = (this.freeEntityHead + 1) & this.freeEntityMask; // Bitwise AND instead of modulo
415
- this.freeEntityCount++;
416
- // Invalidate query cache since entity count changed
417
- this.invalidateQueryCache();
418
- }
419
- /**
420
- * Check if an entity is alive
421
- */
422
- isAlive(entity) {
423
- return this.aliveEntityFlags[entity] === 1;
424
- }
425
- /**
426
- * Invalidate all query caches (called on archetype changes).
427
- */
428
- invalidateQueryCache() {
429
- this.archetypeVersion++;
430
- }
431
- /**
432
- * Add a component to an entity with initial data.
433
- */
434
- add(entity, component, data) {
435
- if (this.aliveEntityFlags[entity] === 0) {
436
- throw new Error(`Cannot add component ${component.name} to entity ${entity}: ` +
437
- `entity is not alive (was it despawned?). ` +
438
- `Current alive entities: ${this.aliveEntitiesArray.length}`);
439
- }
440
- const index = this.getComponentIndex(component);
441
- const store = this.componentStoresArray[index];
442
- this.setComponentBit(entity, index);
443
- store.set(entity, data);
444
- // Invalidate query cache since archetype changed
445
- this.invalidateQueryCache();
446
- }
447
- /**
448
- * Remove a component from an entity.
449
- */
450
- remove(entity, component) {
451
- const index = component.__worldIndex;
452
- if (index === undefined)
453
- return;
454
- this.clearComponentBit(entity, index);
455
- const store = this.componentStoresArray[index];
456
- if (store) {
457
- store.clear(entity);
458
- }
459
- // Invalidate query cache since archetype changed
460
- this.invalidateQueryCache();
461
- }
462
- /**
463
- * Check if an entity has a component.
464
- */
465
- has(entity, component) {
466
- const index = component.__worldIndex;
467
- if (index === undefined)
468
- return false;
469
- return this.hasComponentBit(entity, index);
470
- }
471
- /**
472
- * Get a component's data for an entity.
473
- * Returns a READONLY reusable object (zero allocations).
474
- *
475
- * ⚠️ IMPORTANT: The returned object is reused and will be overwritten on the next get().
476
- * To modify, use set() or update() instead.
477
- * To keep multiple components, use getMutable() or spread operator.
478
- *
479
- * @example
480
- * // ✅ CORRECT: Use immediately
481
- * const t = world.get(entity, Transform);
482
- * console.log(t.x, t.y);
483
- *
484
- * // ❌ WRONG: Storing reference
485
- * const t1 = world.get(entity1, Transform);
486
- * const t2 = world.get(entity2, Transform); // t1 is now corrupted!
487
- *
488
- * // ✅ CORRECT: Copy if you need to keep
489
- * const t1 = { ...world.get(entity1, Transform) };
490
- * const t2 = { ...world.get(entity2, Transform) };
491
- */
492
- get(entity, component) {
493
- const index = this.getComponentIndex(component);
494
- if (!this.hasComponentBit(entity, index)) {
495
- const entityComponents = this.getEntityComponentNames(entity);
496
- throw new Error(`Cannot get component ${component.name} from entity ${entity}: ` +
497
- `entity does not have this component. ` +
498
- `Entity has: [${entityComponents.join(", ")}]. ` +
499
- `Did you forget to call world.add()?`);
500
- }
501
- return this.componentStoresArray[index].get(entity);
502
- }
503
- /**
504
- * Get a mutable copy of component data.
505
- * Use this when you need to modify and keep the data.
506
- *
507
- * Note: This allocates a new object. Use sparingly in hot paths.
508
- */
509
- getMutable(entity, component) {
510
- const index = this.getComponentIndex(component);
511
- if (!this.hasComponentBit(entity, index)) {
512
- throw new Error(`Entity ${entity} does not have component ${component.name}`);
513
- }
514
- return this.componentStoresArray[index].getMutable(entity);
515
- }
516
- /**
517
- * Set a component's data for an entity.
518
- * Overwrites all fields.
519
- */
520
- set(entity, component, data) {
521
- const index = this.getComponentIndex(component);
522
- if (!this.hasComponentBit(entity, index)) {
523
- throw new Error(`Cannot set component ${component.name} on entity ${entity}: ` +
524
- `entity does not have this component. Use add() first.`);
525
- }
526
- this.componentStoresArray[index].set(entity, data);
527
- }
528
- /**
529
- * Update specific fields of a component.
530
- * More efficient than get + modify + set.
531
- *
532
- * @example
533
- * // ✅ GOOD: Partial update
534
- * world.update(entity, Transform, { x: 150 });
535
- *
536
- * // ❌ BAD: Full get/set for single field
537
- * const t = world.getMutable(entity, Transform);
538
- * t.x = 150;
539
- * world.set(entity, Transform, t);
540
- */
541
- update(entity, component, partial) {
542
- const index = this.getComponentIndex(component);
543
- if (!this.hasComponentBit(entity, index)) {
544
- throw new Error(`Entity ${entity} does not have component ${component.name}`);
545
- }
546
- this.componentStoresArray[index].update(entity, partial);
547
- }
548
- /**
549
- * Query entities that have all specified components.
550
- * Returns a readonly array for zero-allocation iteration.
551
- *
552
- * Uses reusable buffers and direct bitmask checks for maximum performance.
553
- * The returned array is reused on subsequent queries with the same mask.
554
- *
555
- * @example
556
- * ```typescript
557
- * for (const entity of world.query(Transform, Velocity)) {
558
- * const t = world.get(entity, Transform);
559
- * const v = world.get(entity, Velocity);
560
- * world.update(entity, Transform, {
561
- * x: t.x + v.vx * dt,
562
- * y: t.y + v.vy * dt
563
- * });
564
- * }
565
- * ```
566
- */
567
- query(...components) {
568
- const requiredMask = this.getQueryMask(components);
569
- if (requiredMask === null)
570
- return []; // Component not registered
571
- const maskKey = this.maskToKey(requiredMask);
572
- // Get or create reusable buffer for this query mask
573
- let buffer = this.queryResultBuffers[maskKey];
574
- if (!buffer) {
575
- buffer = [];
576
- this.queryResultBuffers[maskKey] = buffer;
577
- }
578
- // Check if cache is valid (persistent query caching)
579
- if (this.queryCacheVersions[maskKey] === this.archetypeVersion) {
580
- // Cache is valid! Return cached result (FAST PATH - no iteration!)
581
- return buffer;
582
- }
583
- // Cache miss or stale - recompute query results
584
- const entities = this.aliveEntitiesArray;
585
- const length = entities.length;
586
- const numWords = requiredMask.length;
587
- // Use write cursor pattern instead of buffer.length = 0 + push
588
- let writeIdx = 0;
589
- // Inline fast path for single-word masks (avoids function call overhead)
590
- if (numWords === 1) {
591
- const mask0 = requiredMask[0];
592
- const masks0 = this.componentMasks0;
593
- for (let i = 0; i < length; i++) {
594
- const entity = entities[i];
595
- if ((masks0[entity] & mask0) === mask0) {
596
- buffer[writeIdx++] = entity;
597
- }
598
- }
599
- }
600
- else {
601
- // Fall back to matchesComponentMask for multi-word
602
- for (let i = 0; i < length; i++) {
603
- const entity = entities[i];
604
- if (this.matchesComponentMask(entity, requiredMask)) {
605
- buffer[writeIdx++] = entity;
606
- }
607
- }
608
- }
609
- // Truncate buffer to actual size
610
- buffer.length = writeIdx;
611
- // Mark cache as valid for this archetype version
612
- this.queryCacheVersions[maskKey] = this.archetypeVersion;
613
- return buffer;
614
- }
615
- /**
616
- * Get all alive entity IDs.
617
- *
618
- * ⚠️ WARNING: The returned array is a direct reference and should not be modified.
619
- * For a safe copy, use [...world.getEntities()].
620
- */
621
- getEntities() {
622
- return this.aliveEntitiesArray;
623
- }
624
- /**
625
- * Get the number of alive entities.
626
- */
627
- getEntityCount() {
628
- return this.aliveEntitiesArray.length;
629
- }
630
- /**
631
- * Get the maximum number of entities.
632
- */
633
- getMaxEntities() {
634
- return this.maxEntities;
635
- }
636
- /**
637
- * Get all registered components.
638
- */
639
- getComponents() {
640
- return this.components;
641
- }
642
- /**
643
- * Get component names for an entity (for debugging)
644
- */
645
- getEntityComponentNames(entity) {
646
- const result = [];
647
- for (let i = 0; i < this.components.length; i++) {
648
- if (this.hasComponentBit(entity, i)) {
649
- result.push(this.components[i].name);
650
- }
651
- }
652
- return result;
653
- }
654
- /**
655
- * Serialize entities with specific components to binary.
656
- * Uses PooledCodec internally for efficient encoding.
657
- *
658
- * @param components Components to include in the snapshot
659
- * @param entities Optional list of entities to serialize (defaults to all)
660
- * @returns Binary buffer with serialized data
661
- */
662
- serialize(components, entities) {
663
- const entityList = entities ?? Array.from(this.aliveEntitiesArray);
664
- // Build data structure for each component
665
- const componentArrays = [];
666
- for (const component of components) {
667
- const index = component.__worldIndex;
668
- if (index === undefined)
669
- continue;
670
- const store = this.componentStoresArray[index];
671
- if (!store)
672
- continue;
673
- const items = [];
674
- for (const entity of entityList) {
675
- if (this.has(entity, component)) {
676
- items.push({
677
- entity,
678
- ...store.getMutable(entity),
679
- });
680
- }
681
- }
682
- if (items.length > 0) {
683
- // Use the component's arrayCodec (PooledCodec.array) to encode
684
- const encoded = component.arrayCodec.encode(items);
685
- componentArrays.push(encoded);
686
- }
687
- }
688
- // Combine all buffers
689
- // TODO: Could optimize this with a proper multi-buffer format
690
- const totalSize = componentArrays.reduce((sum, buf) => sum + buf.length, 0);
691
- const result = new Uint8Array(totalSize);
692
- let offset = 0;
693
- for (const buf of componentArrays) {
694
- result.set(buf, offset);
695
- offset += buf.length;
696
- }
697
- return result;
698
- }
699
- /**
700
- * Deserialize binary data into entities.
701
- * Uses PooledCodec internally for efficient decoding.
702
- *
703
- * Note: This is a basic implementation. For production use,
704
- * you'd want a more sophisticated format with component IDs, etc.
705
- */
706
- deserialize(components, buffer) {
707
- // TODO: Implement proper deserialization with component IDs
708
- // For now, this is a placeholder
709
- throw new Error("Deserialization not yet implemented");
710
- }
711
- /**
712
- * Get direct access to a component field's TypedArray for maximum performance.
713
- * This bypasses the get/update API for ~3-4x faster access in hot paths.
714
- *
715
- * ⚠️ ADVANCED API: Use with caution!
716
- * - No bounds checking
717
- * - No type safety
718
- * - You must ensure entities have the component
719
- * - Direct array mutation bypasses any safety mechanisms
720
- *
721
- * @example
722
- * ```typescript
723
- * // High-performance system (bitECS-style)
724
- * const transformX = world.getFieldArray(Transform, 'x');
725
- * const transformY = world.getFieldArray(Transform, 'y');
726
- * const velocityVx = world.getFieldArray(Velocity, 'vx');
727
- * const velocityVy = world.getFieldArray(Velocity, 'vy');
728
- *
729
- * for (const entity of world.query(Transform, Velocity)) {
730
- * transformX[entity] += velocityVx[entity] * dt;
731
- * transformY[entity] += velocityVy[entity] * dt;
732
- * }
733
- * ```
734
- */
735
- getFieldArray(component, fieldName) {
736
- const index = this.getComponentIndex(component);
737
- return this.componentStoresArray[index].getFieldArray(fieldName);
738
- }
739
- /**
740
- * Create an EntityHandle wrapper for fluent API usage.
741
- *
742
- * EntityHandle provides a chainable interface for entity operations with zero runtime overhead.
743
- * Modern JIT compilers inline these simple method calls, making them identical to raw World API.
744
- *
745
- * @param entityId - Entity ID to wrap
746
- * @returns EntityHandle for fluent operations
747
- *
748
- * @example
749
- * ```typescript
750
- * // Fluent API with chaining
751
- * const player = world.entity(world.spawn())
752
- * .add(Transform, { x: 0, y: 0, rotation: 0 })
753
- * .add(Health, { current: 100, max: 100 })
754
- * .add(Velocity, { vx: 0, vy: 0 });
755
- *
756
- * // Use the handle
757
- * player.update(Transform, { x: 10 });
758
- * const health = player.get(Health);
759
- *
760
- * // Mix with raw API
761
- * world.add(player.id, Armor, { value: 50 });
762
- * ```
763
- */
764
- entity(entityId) {
765
- return new EntityHandle(this, entityId);
766
- }
767
- }