@thunderclap-engine/engine 0.0.0-stage → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (566) hide show
  1. package/CHANGELOG.md +390 -0
  2. package/LICENSE +21 -0
  3. package/README.md +333 -2
  4. package/dist/analytics/analytics.d.ts +80 -0
  5. package/dist/analytics/analytics.js +129 -0
  6. package/dist/analytics/index.d.ts +1 -0
  7. package/dist/analytics/index.js +1 -0
  8. package/dist/anim/aim.d.ts +43 -0
  9. package/dist/anim/aim.js +157 -0
  10. package/dist/anim/clip.d.ts +98 -0
  11. package/dist/anim/clip.js +282 -0
  12. package/dist/anim/compress.d.ts +65 -0
  13. package/dist/anim/compress.js +339 -0
  14. package/dist/anim/foot-ik.d.ts +74 -0
  15. package/dist/anim/foot-ik.js +241 -0
  16. package/dist/anim/graph.d.ts +153 -0
  17. package/dist/anim/graph.js +532 -0
  18. package/dist/anim/ik.d.ts +105 -0
  19. package/dist/anim/ik.js +435 -0
  20. package/dist/anim/index.d.ts +36 -0
  21. package/dist/anim/index.js +21 -0
  22. package/dist/anim/match.d.ts +66 -0
  23. package/dist/anim/match.js +153 -0
  24. package/dist/anim/mixer.d.ts +113 -0
  25. package/dist/anim/mixer.js +314 -0
  26. package/dist/anim/morph.d.ts +41 -0
  27. package/dist/anim/morph.js +94 -0
  28. package/dist/anim/pose.d.ts +74 -0
  29. package/dist/anim/pose.js +254 -0
  30. package/dist/anim/quat.d.ts +44 -0
  31. package/dist/anim/quat.js +187 -0
  32. package/dist/anim/retarget.d.ts +97 -0
  33. package/dist/anim/retarget.js +366 -0
  34. package/dist/anim/root-motion.d.ts +44 -0
  35. package/dist/anim/root-motion.js +224 -0
  36. package/dist/anim/skin-pose.d.ts +39 -0
  37. package/dist/anim/skin-pose.js +53 -0
  38. package/dist/anim/socket.d.ts +47 -0
  39. package/dist/anim/socket.js +84 -0
  40. package/dist/anim/spring-chain.d.ts +73 -0
  41. package/dist/anim/spring-chain.js +294 -0
  42. package/dist/assets/atlas.d.ts +90 -0
  43. package/dist/assets/atlas.js +212 -0
  44. package/dist/assets/baked.d.ts +33 -0
  45. package/dist/assets/baked.js +38 -0
  46. package/dist/assets/bundle.d.ts +88 -0
  47. package/dist/assets/bundle.js +464 -0
  48. package/dist/assets/cache.d.ts +56 -0
  49. package/dist/assets/cache.js +123 -0
  50. package/dist/assets/gltf-load.d.ts +252 -0
  51. package/dist/assets/gltf-load.js +661 -0
  52. package/dist/assets/gltf-skin.d.ts +36 -0
  53. package/dist/assets/gltf-skin.js +109 -0
  54. package/dist/assets/gltf.d.ts +706 -0
  55. package/dist/assets/gltf.js +1376 -0
  56. package/dist/assets/index.d.ts +20 -0
  57. package/dist/assets/index.js +10 -0
  58. package/dist/assets/ktx2.d.ts +71 -0
  59. package/dist/assets/ktx2.js +213 -0
  60. package/dist/assets/manifest.d.ts +79 -0
  61. package/dist/assets/manifest.js +7 -0
  62. package/dist/assets/meshopt.d.ts +23 -0
  63. package/dist/assets/meshopt.js +403 -0
  64. package/dist/audio/audio.d.ts +733 -0
  65. package/dist/audio/audio.js +2013 -0
  66. package/dist/audio/dsp.d.ts +61 -0
  67. package/dist/audio/dsp.js +159 -0
  68. package/dist/audio/duck.d.ts +44 -0
  69. package/dist/audio/duck.js +101 -0
  70. package/dist/audio/envelope.d.ts +53 -0
  71. package/dist/audio/envelope.js +106 -0
  72. package/dist/audio/index.d.ts +13 -0
  73. package/dist/audio/index.js +14 -0
  74. package/dist/audio/music.d.ts +113 -0
  75. package/dist/audio/music.js +548 -0
  76. package/dist/audio/occlusion.d.ts +55 -0
  77. package/dist/audio/occlusion.js +61 -0
  78. package/dist/audio/persist.d.ts +23 -0
  79. package/dist/audio/persist.js +27 -0
  80. package/dist/audio/recipes.d.ts +55 -0
  81. package/dist/audio/recipes.js +227 -0
  82. package/dist/audio/send.d.ts +41 -0
  83. package/dist/audio/send.js +118 -0
  84. package/dist/audio/sprites.d.ts +59 -0
  85. package/dist/audio/sprites.js +43 -0
  86. package/dist/audio/synth.d.ts +103 -0
  87. package/dist/audio/synth.js +197 -0
  88. package/dist/audio/variations.d.ts +25 -0
  89. package/dist/audio/variations.js +55 -0
  90. package/dist/audio/zones.d.ts +100 -0
  91. package/dist/audio/zones.js +167 -0
  92. package/dist/core/detached-surface.d.ts +44 -0
  93. package/dist/core/detached-surface.js +104 -0
  94. package/dist/core/events.d.ts +24 -0
  95. package/dist/core/events.js +43 -0
  96. package/dist/core/game.d.ts +409 -0
  97. package/dist/core/game.js +530 -0
  98. package/dist/core/hash.d.ts +24 -0
  99. package/dist/core/hash.js +49 -0
  100. package/dist/core/index.d.ts +17 -0
  101. package/dist/core/index.js +9 -0
  102. package/dist/core/loop.d.ts +113 -0
  103. package/dist/core/loop.js +185 -0
  104. package/dist/core/math.d.ts +58 -0
  105. package/dist/core/math.js +210 -0
  106. package/dist/core/noise.d.ts +40 -0
  107. package/dist/core/noise.js +247 -0
  108. package/dist/core/pool.d.ts +42 -0
  109. package/dist/core/pool.js +85 -0
  110. package/dist/core/random.d.ts +61 -0
  111. package/dist/core/random.js +199 -0
  112. package/dist/core/scene.d.ts +79 -0
  113. package/dist/core/scene.js +195 -0
  114. package/dist/core/timer.d.ts +66 -0
  115. package/dist/core/timer.js +286 -0
  116. package/dist/fx/billboard-wgsl.d.ts +29 -0
  117. package/dist/fx/billboard-wgsl.js +158 -0
  118. package/dist/fx/billboard.d.ts +249 -0
  119. package/dist/fx/billboard.js +702 -0
  120. package/dist/fx/debug-draw.d.ts +127 -0
  121. package/dist/fx/debug-draw.js +523 -0
  122. package/dist/fx/debug-wgsl.d.ts +7 -0
  123. package/dist/fx/debug-wgsl.js +32 -0
  124. package/dist/fx/decals-wgsl.d.ts +15 -0
  125. package/dist/fx/decals-wgsl.js +173 -0
  126. package/dist/fx/decals.d.ts +216 -0
  127. package/dist/fx/decals.js +607 -0
  128. package/dist/fx/effect.d.ts +129 -0
  129. package/dist/fx/effect.js +349 -0
  130. package/dist/fx/effects/hit-spark.json +48 -0
  131. package/dist/fx/effects/index.d.ts +8 -0
  132. package/dist/fx/effects/index.js +9 -0
  133. package/dist/fx/effects/magic-aura.json +47 -0
  134. package/dist/fx/effects/smoke-puff.json +34 -0
  135. package/dist/fx/emit-surface.d.ts +40 -0
  136. package/dist/fx/emit-surface.js +124 -0
  137. package/dist/fx/flicker.d.ts +30 -0
  138. package/dist/fx/flicker.js +42 -0
  139. package/dist/fx/index.d.ts +31 -0
  140. package/dist/fx/index.js +20 -0
  141. package/dist/fx/particles-wgsl.d.ts +57 -0
  142. package/dist/fx/particles-wgsl.js +828 -0
  143. package/dist/fx/particles.d.ts +566 -0
  144. package/dist/fx/particles.js +1533 -0
  145. package/dist/fx/random.d.ts +15 -0
  146. package/dist/fx/random.js +20 -0
  147. package/dist/fx/sky-wgsl.d.ts +23 -0
  148. package/dist/fx/sky-wgsl.js +127 -0
  149. package/dist/fx/sky.d.ts +96 -0
  150. package/dist/fx/sky.js +175 -0
  151. package/dist/fx/text-atlas.d.ts +143 -0
  152. package/dist/fx/text-atlas.js +327 -0
  153. package/dist/fx/trail-wgsl.d.ts +11 -0
  154. package/dist/fx/trail-wgsl.js +42 -0
  155. package/dist/fx/trail.d.ts +194 -0
  156. package/dist/fx/trail.js +555 -0
  157. package/dist/fx/water-wgsl.d.ts +34 -0
  158. package/dist/fx/water-wgsl.js +197 -0
  159. package/dist/fx/water.d.ts +176 -0
  160. package/dist/fx/water.js +371 -0
  161. package/dist/geom/collide/bvh.d.ts +151 -0
  162. package/dist/geom/collide/bvh.js +493 -0
  163. package/dist/geom/collide/debug.d.ts +14 -0
  164. package/dist/geom/collide/debug.js +74 -0
  165. package/dist/geom/collide/grid.d.ts +26 -0
  166. package/dist/geom/collide/grid.js +91 -0
  167. package/dist/geom/collide/index.d.ts +8 -0
  168. package/dist/geom/collide/index.js +8 -0
  169. package/dist/geom/collide/queries.d.ts +70 -0
  170. package/dist/geom/collide/queries.js +583 -0
  171. package/dist/geom/collide/serialize.d.ts +14 -0
  172. package/dist/geom/collide/serialize.js +145 -0
  173. package/dist/geom/collide/shapes.d.ts +161 -0
  174. package/dist/geom/collide/shapes.js +686 -0
  175. package/dist/geom/collide/slide.d.ts +66 -0
  176. package/dist/geom/collide/slide.js +375 -0
  177. package/dist/geom/collide/tile-slide.d.ts +88 -0
  178. package/dist/geom/collide/tile-slide.js +255 -0
  179. package/dist/geom/geometry.d.ts +95 -0
  180. package/dist/geom/geometry.js +322 -0
  181. package/dist/geom/heightfield.d.ts +72 -0
  182. package/dist/geom/heightfield.js +295 -0
  183. package/dist/geom/hull.d.ts +27 -0
  184. package/dist/geom/hull.js +279 -0
  185. package/dist/geom/index.d.ts +35 -0
  186. package/dist/geom/index.js +23 -0
  187. package/dist/geom/iso.d.ts +74 -0
  188. package/dist/geom/iso.js +89 -0
  189. package/dist/geom/lod.d.ts +29 -0
  190. package/dist/geom/lod.js +27 -0
  191. package/dist/geom/ops.d.ts +47 -0
  192. package/dist/geom/ops.js +285 -0
  193. package/dist/geom/primitives.d.ts +97 -0
  194. package/dist/geom/primitives.js +359 -0
  195. package/dist/geom/shapes.d.ts +43 -0
  196. package/dist/geom/shapes.js +88 -0
  197. package/dist/geom/simplify.d.ts +38 -0
  198. package/dist/geom/simplify.js +519 -0
  199. package/dist/geom/split.d.ts +37 -0
  200. package/dist/geom/split.js +413 -0
  201. package/dist/geom/sweep.d.ts +83 -0
  202. package/dist/geom/sweep.js +534 -0
  203. package/dist/geom/tangents.d.ts +16 -0
  204. package/dist/geom/tangents.js +124 -0
  205. package/dist/geom/triangulate.d.ts +19 -0
  206. package/dist/geom/triangulate.js +147 -0
  207. package/dist/host/default.d.ts +10 -0
  208. package/dist/host/default.js +10 -0
  209. package/dist/host/index.d.ts +4 -0
  210. package/dist/host/index.js +3 -0
  211. package/dist/host/types.d.ts +144 -0
  212. package/dist/host/types.js +1 -0
  213. package/dist/host/web-links.d.ts +38 -0
  214. package/dist/host/web-links.js +110 -0
  215. package/dist/host/web.d.ts +30 -0
  216. package/dist/host/web.js +216 -0
  217. package/dist/host/xr.d.ts +24 -0
  218. package/dist/host/xr.js +59 -0
  219. package/dist/i18n/i18n.d.ts +59 -0
  220. package/dist/i18n/i18n.js +241 -0
  221. package/dist/i18n/index.d.ts +3 -0
  222. package/dist/i18n/index.js +3 -0
  223. package/dist/i18n/message.d.ts +72 -0
  224. package/dist/i18n/message.js +369 -0
  225. package/dist/i18n/negotiate.d.ts +17 -0
  226. package/dist/i18n/negotiate.js +58 -0
  227. package/dist/index.d.ts +7 -0
  228. package/dist/index.js +1 -0
  229. package/dist/input/bindings.d.ts +31 -0
  230. package/dist/input/bindings.js +141 -0
  231. package/dist/input/clock.d.ts +44 -0
  232. package/dist/input/clock.js +49 -0
  233. package/dist/input/follow.d.ts +133 -0
  234. package/dist/input/follow.js +218 -0
  235. package/dist/input/gestures.d.ts +281 -0
  236. package/dist/input/gestures.js +662 -0
  237. package/dist/input/glyphs.d.ts +35 -0
  238. package/dist/input/glyphs.js +216 -0
  239. package/dist/input/gyro.d.ts +85 -0
  240. package/dist/input/gyro.js +140 -0
  241. package/dist/input/index.d.ts +19 -0
  242. package/dist/input/index.js +16 -0
  243. package/dist/input/input.d.ts +543 -0
  244. package/dist/input/input.js +1492 -0
  245. package/dist/input/look.d.ts +327 -0
  246. package/dist/input/look.js +681 -0
  247. package/dist/input/magnify.d.ts +177 -0
  248. package/dist/input/magnify.js +131 -0
  249. package/dist/input/pointer-dispatch.d.ts +138 -0
  250. package/dist/input/pointer-dispatch.js +180 -0
  251. package/dist/input/pointer-router.d.ts +204 -0
  252. package/dist/input/pointer-router.js +533 -0
  253. package/dist/input/pointer-sources.d.ts +164 -0
  254. package/dist/input/pointer-sources.js +306 -0
  255. package/dist/input/rays.d.ts +138 -0
  256. package/dist/input/rays.js +615 -0
  257. package/dist/input/record.d.ts +209 -0
  258. package/dist/input/record.js +601 -0
  259. package/dist/input/touch-zones.d.ts +147 -0
  260. package/dist/input/touch-zones.js +300 -0
  261. package/dist/input/types.d.ts +158 -0
  262. package/dist/input/types.js +1 -0
  263. package/dist/input/xr-source.d.ts +53 -0
  264. package/dist/input/xr-source.js +164 -0
  265. package/dist/nav/astar.d.ts +45 -0
  266. package/dist/nav/astar.js +182 -0
  267. package/dist/nav/corridor.d.ts +40 -0
  268. package/dist/nav/corridor.js +95 -0
  269. package/dist/nav/crowd.d.ts +94 -0
  270. package/dist/nav/crowd.js +624 -0
  271. package/dist/nav/flow.d.ts +61 -0
  272. package/dist/nav/flow.js +193 -0
  273. package/dist/nav/grid.d.ts +108 -0
  274. package/dist/nav/grid.js +210 -0
  275. package/dist/nav/heap.d.ts +22 -0
  276. package/dist/nav/heap.js +92 -0
  277. package/dist/nav/index.d.ts +37 -0
  278. package/dist/nav/index.js +19 -0
  279. package/dist/nav/mesh/areas.d.ts +44 -0
  280. package/dist/nav/mesh/areas.js +98 -0
  281. package/dist/nav/mesh/bake-options.d.ts +33 -0
  282. package/dist/nav/mesh/bake-options.js +76 -0
  283. package/dist/nav/mesh/contour.d.ts +22 -0
  284. package/dist/nav/mesh/contour.js +323 -0
  285. package/dist/nav/mesh/flow3.d.ts +35 -0
  286. package/dist/nav/mesh/flow3.js +229 -0
  287. package/dist/nav/mesh/links.d.ts +38 -0
  288. package/dist/nav/mesh/links.js +72 -0
  289. package/dist/nav/mesh/mesh-path.d.ts +152 -0
  290. package/dist/nav/mesh/mesh-path.js +643 -0
  291. package/dist/nav/mesh/mesh-reach.d.ts +78 -0
  292. package/dist/nav/mesh/mesh-reach.js +450 -0
  293. package/dist/nav/mesh/navmesh.d.ts +117 -0
  294. package/dist/nav/mesh/navmesh.js +647 -0
  295. package/dist/nav/mesh/polymesh.d.ts +24 -0
  296. package/dist/nav/mesh/polymesh.js +384 -0
  297. package/dist/nav/mesh/regions.d.ts +12 -0
  298. package/dist/nav/mesh/regions.js +367 -0
  299. package/dist/nav/mesh/serialize.d.ts +13 -0
  300. package/dist/nav/mesh/serialize.js +197 -0
  301. package/dist/nav/mesh/voxelize.d.ts +111 -0
  302. package/dist/nav/mesh/voxelize.js +552 -0
  303. package/dist/nav/obstacles.d.ts +75 -0
  304. package/dist/nav/obstacles.js +294 -0
  305. package/dist/nav/path.d.ts +59 -0
  306. package/dist/nav/path.js +177 -0
  307. package/dist/nav/query-queue.d.ts +46 -0
  308. package/dist/nav/query-queue.js +308 -0
  309. package/dist/nav/reach.d.ts +53 -0
  310. package/dist/nav/reach.js +148 -0
  311. package/dist/nav/steer.d.ts +36 -0
  312. package/dist/nav/steer.js +78 -0
  313. package/dist/platform/boot.d.ts +28 -0
  314. package/dist/platform/boot.js +43 -0
  315. package/dist/platform/device-mode.d.ts +40 -0
  316. package/dist/platform/device-mode.js +104 -0
  317. package/dist/platform/device.d.ts +31 -0
  318. package/dist/platform/device.js +91 -0
  319. package/dist/platform/environment.d.ts +42 -0
  320. package/dist/platform/environment.js +82 -0
  321. package/dist/platform/gpu.d.ts +40 -0
  322. package/dist/platform/gpu.js +57 -0
  323. package/dist/platform/index.d.ts +18 -0
  324. package/dist/platform/index.js +10 -0
  325. package/dist/platform/letterbox.d.ts +43 -0
  326. package/dist/platform/letterbox.js +57 -0
  327. package/dist/platform/links.d.ts +20 -0
  328. package/dist/platform/links.js +43 -0
  329. package/dist/platform/screens.d.ts +36 -0
  330. package/dist/platform/screens.js +138 -0
  331. package/dist/platform/surface.d.ts +72 -0
  332. package/dist/platform/surface.js +157 -0
  333. package/dist/platform/xr-fake.d.ts +168 -0
  334. package/dist/platform/xr-fake.js +434 -0
  335. package/dist/platform/xr-surface.d.ts +120 -0
  336. package/dist/platform/xr-surface.js +214 -0
  337. package/dist/platform/xr-types.d.ts +262 -0
  338. package/dist/post/ao.d.ts +12 -0
  339. package/dist/post/ao.js +136 -0
  340. package/dist/post/blend.d.ts +27 -0
  341. package/dist/post/blend.js +129 -0
  342. package/dist/post/depth-pass.d.ts +43 -0
  343. package/dist/post/depth-pass.js +118 -0
  344. package/dist/post/dof.d.ts +1 -0
  345. package/dist/post/dof.js +66 -0
  346. package/dist/post/exposure.d.ts +80 -0
  347. package/dist/post/exposure.js +322 -0
  348. package/dist/post/index.d.ts +12 -0
  349. package/dist/post/index.js +11 -0
  350. package/dist/post/lens-dirt.d.ts +13 -0
  351. package/dist/post/lens-dirt.js +91 -0
  352. package/dist/post/lut.d.ts +19 -0
  353. package/dist/post/lut.js +50 -0
  354. package/dist/post/motion-blur.d.ts +9 -0
  355. package/dist/post/motion-blur.js +78 -0
  356. package/dist/post/post-stack.d.ts +302 -0
  357. package/dist/post/post-stack.js +1137 -0
  358. package/dist/post/settings.d.ts +485 -0
  359. package/dist/post/settings.js +416 -0
  360. package/dist/post/shaders.d.ts +25 -0
  361. package/dist/post/shaders.js +410 -0
  362. package/dist/post/ssr.d.ts +16 -0
  363. package/dist/post/ssr.js +155 -0
  364. package/dist/post/taa.d.ts +74 -0
  365. package/dist/post/taa.js +235 -0
  366. package/dist/post/white-balance.d.ts +25 -0
  367. package/dist/post/white-balance.js +98 -0
  368. package/dist/render/bindings.d.ts +98 -0
  369. package/dist/render/bindings.js +281 -0
  370. package/dist/render/blend.d.ts +13 -0
  371. package/dist/render/blend.js +26 -0
  372. package/dist/render/camera-2d.d.ts +72 -0
  373. package/dist/render/camera-2d.js +92 -0
  374. package/dist/render/camera.d.ts +302 -0
  375. package/dist/render/camera.js +671 -0
  376. package/dist/render/color.d.ts +16 -0
  377. package/dist/render/color.js +41 -0
  378. package/dist/render/compressed.d.ts +104 -0
  379. package/dist/render/compressed.js +248 -0
  380. package/dist/render/diagnostics.d.ts +15 -0
  381. package/dist/render/diagnostics.js +43 -0
  382. package/dist/render/dynamic-resolution.d.ts +70 -0
  383. package/dist/render/dynamic-resolution.js +126 -0
  384. package/dist/render/fake-gpu.d.ts +204 -0
  385. package/dist/render/fake-gpu.js +426 -0
  386. package/dist/render/flipbook.d.ts +56 -0
  387. package/dist/render/flipbook.js +87 -0
  388. package/dist/render/frame.d.ts +278 -0
  389. package/dist/render/frame.js +174 -0
  390. package/dist/render/fullscreen.d.ts +54 -0
  391. package/dist/render/fullscreen.js +91 -0
  392. package/dist/render/gpu-timer.d.ts +73 -0
  393. package/dist/render/gpu-timer.js +186 -0
  394. package/dist/render/index.d.ts +53 -0
  395. package/dist/render/index.js +29 -0
  396. package/dist/render/instance-list.d.ts +185 -0
  397. package/dist/render/instance-list.js +547 -0
  398. package/dist/render/lights.d.ts +181 -0
  399. package/dist/render/lights.js +233 -0
  400. package/dist/render/lod.d.ts +54 -0
  401. package/dist/render/lod.js +52 -0
  402. package/dist/render/material.d.ts +165 -0
  403. package/dist/render/material.js +292 -0
  404. package/dist/render/mesh.d.ts +284 -0
  405. package/dist/render/mesh.js +472 -0
  406. package/dist/render/mipmap.d.ts +16 -0
  407. package/dist/render/mipmap.js +121 -0
  408. package/dist/render/parallax.d.ts +50 -0
  409. package/dist/render/parallax.js +47 -0
  410. package/dist/render/pbr-wgsl.d.ts +31 -0
  411. package/dist/render/pbr-wgsl.js +119 -0
  412. package/dist/render/ping-pong.d.ts +42 -0
  413. package/dist/render/ping-pong.js +74 -0
  414. package/dist/render/renderer.d.ts +741 -0
  415. package/dist/render/renderer.js +2486 -0
  416. package/dist/render/scene-pipelines.d.ts +44 -0
  417. package/dist/render/scene-pipelines.js +92 -0
  418. package/dist/render/scene-target.d.ts +170 -0
  419. package/dist/render/scene-target.js +450 -0
  420. package/dist/render/shadow.d.ts +74 -0
  421. package/dist/render/shadow.js +208 -0
  422. package/dist/render/skin.d.ts +112 -0
  423. package/dist/render/skin.js +240 -0
  424. package/dist/render/snapshot.d.ts +36 -0
  425. package/dist/render/snapshot.js +34 -0
  426. package/dist/render/standard.d.ts +162 -0
  427. package/dist/render/standard.js +263 -0
  428. package/dist/render/texture.d.ts +142 -0
  429. package/dist/render/texture.js +228 -0
  430. package/dist/render/tile-layer.d.ts +110 -0
  431. package/dist/render/tile-layer.js +304 -0
  432. package/dist/render/transform.d.ts +115 -0
  433. package/dist/render/transform.js +318 -0
  434. package/dist/render/wgsl.d.ts +131 -0
  435. package/dist/render/wgsl.js +528 -0
  436. package/dist/save/codec.d.ts +49 -0
  437. package/dist/save/codec.js +169 -0
  438. package/dist/save/index.d.ts +8 -0
  439. package/dist/save/index.js +8 -0
  440. package/dist/save/journal.d.ts +24 -0
  441. package/dist/save/journal.js +102 -0
  442. package/dist/save/migrate.d.ts +15 -0
  443. package/dist/save/migrate.js +37 -0
  444. package/dist/save/schema.d.ts +72 -0
  445. package/dist/save/schema.js +154 -0
  446. package/dist/save/settings.d.ts +28 -0
  447. package/dist/save/settings.js +59 -0
  448. package/dist/save/slots.d.ts +56 -0
  449. package/dist/save/slots.js +200 -0
  450. package/dist/save/storage.d.ts +35 -0
  451. package/dist/save/storage.js +62 -0
  452. package/dist/save/store.d.ts +114 -0
  453. package/dist/save/store.js +269 -0
  454. package/dist/testing/fake-host.d.ts +103 -0
  455. package/dist/testing/fake-host.js +163 -0
  456. package/dist/testing/fixed-clock.d.ts +25 -0
  457. package/dist/testing/fixed-clock.js +30 -0
  458. package/dist/testing/index.d.ts +4 -0
  459. package/dist/testing/index.js +5 -0
  460. package/dist/testing/test-game.d.ts +76 -0
  461. package/dist/testing/test-game.js +92 -0
  462. package/dist/tween/ease.d.ts +77 -0
  463. package/dist/tween/ease.js +192 -0
  464. package/dist/tween/index.d.ts +8 -0
  465. package/dist/tween/index.js +7 -0
  466. package/dist/tween/timeline.d.ts +78 -0
  467. package/dist/tween/timeline.js +269 -0
  468. package/dist/tween/tween.d.ts +168 -0
  469. package/dist/tween/tween.js +320 -0
  470. package/dist/ui/anchor.d.ts +206 -0
  471. package/dist/ui/anchor.js +307 -0
  472. package/dist/ui/caption.d.ts +122 -0
  473. package/dist/ui/caption.js +286 -0
  474. package/dist/ui/cursor.d.ts +105 -0
  475. package/dist/ui/cursor.js +261 -0
  476. package/dist/ui/dom.d.ts +30 -0
  477. package/dist/ui/dom.js +92 -0
  478. package/dist/ui/floats.d.ts +86 -0
  479. package/dist/ui/floats.js +260 -0
  480. package/dist/ui/hud.d.ts +198 -0
  481. package/dist/ui/hud.js +431 -0
  482. package/dist/ui/index.d.ts +37 -0
  483. package/dist/ui/index.js +34 -0
  484. package/dist/ui/inventory-card.d.ts +52 -0
  485. package/dist/ui/inventory-card.js +173 -0
  486. package/dist/ui/inventory-context.d.ts +29 -0
  487. package/dist/ui/inventory-context.js +125 -0
  488. package/dist/ui/inventory-drag.d.ts +63 -0
  489. package/dist/ui/inventory-drag.js +394 -0
  490. package/dist/ui/inventory-grid.d.ts +66 -0
  491. package/dist/ui/inventory-grid.js +625 -0
  492. package/dist/ui/inventory-radial.d.ts +39 -0
  493. package/dist/ui/inventory-radial.js +168 -0
  494. package/dist/ui/inventory.d.ts +128 -0
  495. package/dist/ui/inventory.js +154 -0
  496. package/dist/ui/layout.d.ts +356 -0
  497. package/dist/ui/layout.js +856 -0
  498. package/dist/ui/link.d.ts +64 -0
  499. package/dist/ui/link.js +155 -0
  500. package/dist/ui/loading.d.ts +40 -0
  501. package/dist/ui/loading.js +157 -0
  502. package/dist/ui/loupe.d.ts +74 -0
  503. package/dist/ui/loupe.js +164 -0
  504. package/dist/ui/menu-nav.d.ts +33 -0
  505. package/dist/ui/menu-nav.js +28 -0
  506. package/dist/ui/minimap-canvas.d.ts +145 -0
  507. package/dist/ui/minimap-canvas.js +460 -0
  508. package/dist/ui/notify.d.ts +40 -0
  509. package/dist/ui/notify.js +141 -0
  510. package/dist/ui/orb.d.ts +53 -0
  511. package/dist/ui/orb.js +304 -0
  512. package/dist/ui/overlay.d.ts +213 -0
  513. package/dist/ui/overlay.js +394 -0
  514. package/dist/ui/padnav.d.ts +53 -0
  515. package/dist/ui/padnav.js +146 -0
  516. package/dist/ui/perf.d.ts +130 -0
  517. package/dist/ui/perf.js +329 -0
  518. package/dist/ui/rotate-card.d.ts +54 -0
  519. package/dist/ui/rotate-card.js +97 -0
  520. package/dist/ui/stack.d.ts +128 -0
  521. package/dist/ui/stack.js +312 -0
  522. package/dist/ui/styles.d.ts +13 -0
  523. package/dist/ui/styles.js +200 -0
  524. package/dist/ui/text-scale.d.ts +67 -0
  525. package/dist/ui/text-scale.js +102 -0
  526. package/dist/ui/theme.d.ts +70 -0
  527. package/dist/ui/theme.js +98 -0
  528. package/dist/ui/toast.d.ts +23 -0
  529. package/dist/ui/toast.js +46 -0
  530. package/dist/ui/tooltip.d.ts +89 -0
  531. package/dist/ui/tooltip.js +333 -0
  532. package/dist/ui/widgets-2.d.ts +134 -0
  533. package/dist/ui/widgets-2.js +399 -0
  534. package/dist/ui/widgets-3.d.ts +91 -0
  535. package/dist/ui/widgets-3.js +212 -0
  536. package/dist/ui/widgets.d.ts +34 -0
  537. package/dist/ui/widgets.js +50 -0
  538. package/dist/ui/world-panel/index.d.ts +5 -0
  539. package/dist/ui/world-panel/index.js +5 -0
  540. package/dist/ui/world-panel/layout.d.ts +38 -0
  541. package/dist/ui/world-panel/layout.js +68 -0
  542. package/dist/ui/world-panel/paint.d.ts +96 -0
  543. package/dist/ui/world-panel/paint.js +136 -0
  544. package/dist/ui/world-panel/panel.d.ts +235 -0
  545. package/dist/ui/world-panel/panel.js +762 -0
  546. package/dist/ui/world-panel/wgsl.d.ts +10 -0
  547. package/dist/ui/world-panel/wgsl.js +52 -0
  548. package/dist/ui/world-panel/widgets.d.ts +207 -0
  549. package/dist/ui/world-panel/widgets.js +569 -0
  550. package/dist/voxel/chunks.d.ts +77 -0
  551. package/dist/voxel/chunks.js +149 -0
  552. package/dist/voxel/grid.d.ts +84 -0
  553. package/dist/voxel/grid.js +223 -0
  554. package/dist/voxel/index.d.ts +22 -0
  555. package/dist/voxel/index.js +7 -0
  556. package/dist/voxel/mesher-worker.d.ts +14 -0
  557. package/dist/voxel/mesher-worker.js +47 -0
  558. package/dist/voxel/mesher.d.ts +73 -0
  559. package/dist/voxel/mesher.js +306 -0
  560. package/dist/voxel/ray.d.ts +32 -0
  561. package/dist/voxel/ray.js +73 -0
  562. package/dist/voxel/wgsl.d.ts +16 -0
  563. package/dist/voxel/wgsl.js +28 -0
  564. package/dist/voxel/worker-client.d.ts +79 -0
  565. package/dist/voxel/worker-client.js +122 -0
  566. package/package.json +177 -3
@@ -0,0 +1,129 @@
1
+ /**
2
+ * Effects (ws/fx-3): a data-driven bundle of particle systems and emitters, played as
3
+ * instances at a point or attached to a moving one. A descriptor is plain JSON (textures by
4
+ * name), so an effect loads through the asset manifest as `{ kind: 'json', uri }` and is
5
+ * validated with `validateEffectDesc` before `createEffect`.
6
+ */
7
+ import type { Random } from '../core/random.js';
8
+ import type { Frame } from '../render/frame.js';
9
+ import type { Renderer } from '../render/renderer.js';
10
+ import type { TextureLike } from '../render/texture.js';
11
+ import { type EmitParams, ParticleSystem, type ParticleSystemOptions } from './particles.js';
12
+ /** One emitter of an effect system: continuous at `rate`, a `burst` at `delay`, or both. */
13
+ export interface EffectEmitterDesc {
14
+ params: EmitParams;
15
+ /** Particles per second while active. Default 0. */
16
+ rate?: number;
17
+ /** Seconds after `delay` the emitter stays active. Default: until the effect ends. */
18
+ duration?: number;
19
+ /** Seconds after the instance starts before this emitter begins. Default 0. */
20
+ delay?: number;
21
+ /** Particles emitted once at `delay`. Default 0. */
22
+ burst?: number;
23
+ }
24
+ /** A system's options in a descriptor: textures by name, no scene-target references. */
25
+ export type EffectSystemOptions = Omit<ParticleSystemOptions, 'texture' | 'depthTarget' | 'random'> & {
26
+ /** A key of the `textures` map given to `createEffect`. */
27
+ texture?: string;
28
+ };
29
+ export interface EffectSystemDesc {
30
+ name: string;
31
+ options?: EffectSystemOptions;
32
+ emitters: EffectEmitterDesc[];
33
+ }
34
+ export interface EffectDesc {
35
+ systems: EffectSystemDesc[];
36
+ /** Seconds an instance lives. Default: when the last emitter ends (forever if none ends). */
37
+ duration?: number;
38
+ /** Restart each instance at `duration` instead of finishing it. Default false. */
39
+ loop?: boolean;
40
+ }
41
+ /** Where an instance plays: a point, moved by `attach`. */
42
+ export interface EffectPoint {
43
+ x: number;
44
+ y: number;
45
+ z?: number;
46
+ }
47
+ /** Fills `out` (xyz) with where an attached instance should be this frame. */
48
+ export type EffectFollow = (out: Float32Array) => void;
49
+ /**
50
+ * Check a parsed effect JSON. Returns the problems found, each with its path (empty = valid).
51
+ * With `textures` (names, or the map `createEffect` will get) unknown texture names are errors.
52
+ */
53
+ export declare function validateEffectDesc(json: unknown, opts?: {
54
+ textures?: readonly string[] | Record<string, TextureLike>;
55
+ }): string[];
56
+ /** An emitter's per-instance state. */
57
+ interface EmitterState {
58
+ /** This instance's copy of the params (position overwritten each frame). */
59
+ params: EmitParams;
60
+ carry: number;
61
+ fired: boolean;
62
+ }
63
+ /** One playing of an effect: at a point, or following `attach`. */
64
+ export declare class EffectInstance {
65
+ /** World (or logical) position, xyz. */
66
+ readonly position: Float32Array<ArrayBuffer>;
67
+ /** Seconds since it started (wraps when the effect loops). */
68
+ time: number;
69
+ /** Set once it has finished emitting (or `stop()` was called); the effect drops it then. */
70
+ done: boolean;
71
+ /** @internal */
72
+ follow: EffectFollow | null;
73
+ /** @internal per system, per emitter. */
74
+ readonly states: EmitterState[][];
75
+ /** Keep the instance at wherever `getPosition` says each update. */
76
+ attach(getPosition: EffectFollow): this;
77
+ /** Stop emitting; the particles already born die on their own. */
78
+ stop(): void;
79
+ }
80
+ /**
81
+ * A playable effect built from an `EffectDesc`: its systems are created once; each `play` or
82
+ * `attach` adds an instance that drives the emitters. Call `update(dt)` once a frame, then
83
+ * `draw(frame)` to queue every system.
84
+ */
85
+ export declare class Effect {
86
+ readonly systems: ParticleSystem[];
87
+ /** The instances now playing. */
88
+ readonly instances: EffectInstance[];
89
+ /** Seconds an instance lives (Infinity: until stopped). */
90
+ readonly duration: number;
91
+ readonly loop: boolean;
92
+ /**
93
+ * The effect's stream (ws/fx-4): system `name` draws from `random.fork(name)`, so the same
94
+ * seed plays the same particles whatever else the game draws.
95
+ */
96
+ readonly random: Random;
97
+ private readonly desc;
98
+ private readonly pool;
99
+ constructor(renderer: Renderer, desc: EffectDesc, textures?: Record<string, TextureLike>, random?: Random);
100
+ /** Start an instance at `at` (default the origin). */
101
+ play(at?: EffectPoint): EffectInstance;
102
+ /** Start an instance that follows `getPosition`. */
103
+ attach(getPosition: EffectFollow): EffectInstance;
104
+ /** Stop every instance (particles already born die on their own). */
105
+ stop(): void;
106
+ /** Drive the instances' emitters and the systems. Call once per frame. */
107
+ update(dt: number): void;
108
+ private emitFor;
109
+ /** Queue every system for drawing (`frame.drawable`). */
110
+ draw(frame: Frame, order?: number): void;
111
+ destroy(): void;
112
+ private makeInstance;
113
+ }
114
+ /** `createEffect` options. */
115
+ export interface CreateEffectOptions {
116
+ /** Texture names the descriptor's systems refer to. */
117
+ textures?: Record<string, TextureLike>;
118
+ /**
119
+ * The effect's random stream (ws/fx-4; each system forks it by name). Default: a fork of the
120
+ * fx module default (`FX_DEFAULT_SEED`), named by creation order.
121
+ */
122
+ random?: Random;
123
+ }
124
+ /**
125
+ * Build an `Effect` from a descriptor, resolving texture names through `textures`. Throws a
126
+ * readable `Error` listing every problem `validateEffectDesc` finds.
127
+ */
128
+ export declare function createEffect(renderer: Renderer, desc: EffectDesc, opts?: CreateEffectOptions): Effect;
129
+ export {};
@@ -0,0 +1,349 @@
1
+ import { MAX_CURVE_STOPS, ParticleSystem, } from './particles.js';
2
+ import { defaultFxRandom } from './random.js';
3
+ const NUMBER_FIELDS = ['rate', 'duration', 'delay', 'burst'];
4
+ function isRecord(v) {
5
+ return typeof v === 'object' && v !== null && !Array.isArray(v);
6
+ }
7
+ function isColor(v) {
8
+ return (Array.isArray(v) &&
9
+ v.length >= 3 &&
10
+ v.length <= 4 &&
11
+ v.every((n) => typeof n === 'number' && Number.isFinite(n)));
12
+ }
13
+ function isPair(v) {
14
+ return Array.isArray(v) && v.length === 2 && v.every((n) => typeof n === 'number');
15
+ }
16
+ function validateParams(p, at, textures, out, depth) {
17
+ if (!isRecord(p)) {
18
+ out.push(`${at}: params must be an object`);
19
+ return;
20
+ }
21
+ if (typeof p.x !== 'number' || typeof p.y !== 'number')
22
+ out.push(`${at}: x and y must be numbers`);
23
+ if (!isColor(p.colorStart))
24
+ out.push(`${at}: colorStart must be [r, g, b] or [r, g, b, a]`);
25
+ if (p.colorEnd !== undefined && !isColor(p.colorEnd))
26
+ out.push(`${at}: colorEnd must be a colour`);
27
+ for (const k of ['speed', 'life', 'size', 'rotation', 'spin']) {
28
+ if (p[k] !== undefined && !isPair(p[k]))
29
+ out.push(`${at}: ${k} must be [min, max]`);
30
+ }
31
+ if (p.sizeCurve !== undefined) {
32
+ const c = p.sizeCurve;
33
+ if (!Array.isArray(c) || c.length < 2 || c.length > MAX_CURVE_STOPS) {
34
+ out.push(`${at}: sizeCurve needs 2..${MAX_CURVE_STOPS} stops`);
35
+ }
36
+ else if (!c.every((n) => typeof n === 'number'))
37
+ out.push(`${at}: sizeCurve stops must be numbers`);
38
+ }
39
+ if (p.colorCurve !== undefined) {
40
+ const c = p.colorCurve;
41
+ if (!Array.isArray(c) || c.length < 2 || c.length > MAX_CURVE_STOPS) {
42
+ out.push(`${at}: colorCurve needs 2..${MAX_CURVE_STOPS} stops`);
43
+ }
44
+ else if (!c.every(isColor))
45
+ out.push(`${at}: colorCurve stops must be colours`);
46
+ }
47
+ if (p.tile !== undefined && typeof p.tile !== 'number' && !isPair(p.tile)) {
48
+ out.push(`${at}: tile must be a number or [from, to]`);
49
+ }
50
+ if (p.shape !== undefined) {
51
+ const s = p.shape;
52
+ if (!isRecord(s) || typeof s.kind !== 'string')
53
+ out.push(`${at}: shape needs a kind`);
54
+ else if (s.kind === 'mesh' && !Array.isArray(s.positions)) {
55
+ out.push(`${at}: a mesh shape needs positions`);
56
+ }
57
+ }
58
+ for (const k of ['onDeath', 'onLife']) {
59
+ const sub = p[k];
60
+ if (sub === undefined)
61
+ continue;
62
+ if (!isRecord(sub)) {
63
+ out.push(`${at}.${k}: must be { params, ${k === 'onDeath' ? 'count' : 'rate'} }`);
64
+ continue;
65
+ }
66
+ const amount = k === 'onDeath' ? sub.count : sub.rate;
67
+ if (typeof amount !== 'number' || amount < 0) {
68
+ out.push(`${at}.${k}: ${k === 'onDeath' ? 'count' : 'rate'} must be a number ≥ 0`);
69
+ }
70
+ if (depth > 0)
71
+ out.push(`${at}.${k}: sub-emitters go one level deep`);
72
+ else
73
+ validateParams(sub.params, `${at}.${k}`, textures, out, depth + 1);
74
+ }
75
+ }
76
+ /**
77
+ * Check a parsed effect JSON. Returns the problems found, each with its path (empty = valid).
78
+ * With `textures` (names, or the map `createEffect` will get) unknown texture names are errors.
79
+ */
80
+ export function validateEffectDesc(json, opts = {}) {
81
+ const out = [];
82
+ const textures = opts.textures
83
+ ? Array.isArray(opts.textures)
84
+ ? opts.textures
85
+ : Object.keys(opts.textures)
86
+ : null;
87
+ if (!isRecord(json))
88
+ return ['effect: must be an object'];
89
+ if (json.duration !== undefined && !(typeof json.duration === 'number' && json.duration > 0)) {
90
+ out.push('effect: duration must be a number > 0');
91
+ }
92
+ if (json.loop !== undefined && typeof json.loop !== 'boolean')
93
+ out.push('effect: loop must be a boolean');
94
+ if (!Array.isArray(json.systems) || json.systems.length === 0) {
95
+ out.push('effect: systems must be a non-empty array');
96
+ return out;
97
+ }
98
+ const names = new Set();
99
+ json.systems.forEach((sys, i) => {
100
+ const at = `systems[${i}]`;
101
+ if (!isRecord(sys)) {
102
+ out.push(`${at}: must be an object`);
103
+ return;
104
+ }
105
+ if (typeof sys.name !== 'string' || sys.name === '')
106
+ out.push(`${at}: name must be a string`);
107
+ else if (names.has(sys.name))
108
+ out.push(`${at}: duplicate name "${sys.name}"`);
109
+ else
110
+ names.add(sys.name);
111
+ if (sys.options !== undefined) {
112
+ const o = sys.options;
113
+ if (!isRecord(o))
114
+ out.push(`${at}.options: must be an object`);
115
+ else {
116
+ if (o.space !== undefined && o.space !== '2d' && o.space !== 'world') {
117
+ out.push(`${at}.options: space must be '2d' or 'world'`);
118
+ }
119
+ if (o.blend !== undefined && o.blend !== 'additive' && o.blend !== 'alpha') {
120
+ out.push(`${at}.options: blend must be 'additive' or 'alpha'`);
121
+ }
122
+ if (o.texture !== undefined) {
123
+ if (typeof o.texture !== 'string')
124
+ out.push(`${at}.options: texture must be a name`);
125
+ else if (textures && !textures.includes(o.texture)) {
126
+ out.push(`${at}.options: unknown texture "${o.texture}"`);
127
+ }
128
+ }
129
+ if (o.atlas !== undefined) {
130
+ const a = o.atlas;
131
+ if (!isRecord(a) || typeof a.columns !== 'number' || typeof a.rows !== 'number') {
132
+ out.push(`${at}.options: atlas must be { columns, rows }`);
133
+ }
134
+ }
135
+ if (o.depthTarget !== undefined)
136
+ out.push(`${at}.options: depthTarget is not serialisable`);
137
+ }
138
+ }
139
+ if (!Array.isArray(sys.emitters) || sys.emitters.length === 0) {
140
+ out.push(`${at}: emitters must be a non-empty array`);
141
+ return;
142
+ }
143
+ sys.emitters.forEach((em, j) => {
144
+ const ea = `${at}.emitters[${j}]`;
145
+ if (!isRecord(em)) {
146
+ out.push(`${ea}: must be an object`);
147
+ return;
148
+ }
149
+ for (const k of NUMBER_FIELDS) {
150
+ const v = em[k];
151
+ if (v !== undefined && !(typeof v === 'number' && Number.isFinite(v) && v >= 0)) {
152
+ out.push(`${ea}: ${k} must be a number ≥ 0`);
153
+ }
154
+ }
155
+ if (!em.rate && !em.burst)
156
+ out.push(`${ea}: needs a rate or a burst`);
157
+ validateParams(em.params, ea, textures, out, 0);
158
+ });
159
+ });
160
+ return out;
161
+ }
162
+ /** One playing of an effect: at a point, or following `attach`. */
163
+ export class EffectInstance {
164
+ /** World (or logical) position, xyz. */
165
+ position = new Float32Array(3);
166
+ /** Seconds since it started (wraps when the effect loops). */
167
+ time = 0;
168
+ /** Set once it has finished emitting (or `stop()` was called); the effect drops it then. */
169
+ done = false;
170
+ /** @internal */
171
+ follow = null;
172
+ /** @internal per system, per emitter. */
173
+ states = [];
174
+ /** Keep the instance at wherever `getPosition` says each update. */
175
+ attach(getPosition) {
176
+ this.follow = getPosition;
177
+ return this;
178
+ }
179
+ /** Stop emitting; the particles already born die on their own. */
180
+ stop() {
181
+ this.done = true;
182
+ }
183
+ }
184
+ /**
185
+ * A playable effect built from an `EffectDesc`: its systems are created once; each `play` or
186
+ * `attach` adds an instance that drives the emitters. Call `update(dt)` once a frame, then
187
+ * `draw(frame)` to queue every system.
188
+ */
189
+ export class Effect {
190
+ systems = [];
191
+ /** The instances now playing. */
192
+ instances = [];
193
+ /** Seconds an instance lives (Infinity: until stopped). */
194
+ duration;
195
+ loop;
196
+ /**
197
+ * The effect's stream (ws/fx-4): system `name` draws from `random.fork(name)`, so the same
198
+ * seed plays the same particles whatever else the game draws.
199
+ */
200
+ random;
201
+ desc;
202
+ pool = [];
203
+ constructor(renderer, desc, textures = {}, random) {
204
+ const problems = validateEffectDesc(desc, { textures });
205
+ if (problems.length)
206
+ throw new Error(`createEffect: ${problems.join('; ')}`);
207
+ this.desc = desc;
208
+ this.loop = desc.loop ?? false;
209
+ this.random = random ?? defaultFxRandom('effect');
210
+ let end = 0;
211
+ for (const sys of desc.systems) {
212
+ const { texture, ...rest } = sys.options ?? {};
213
+ const options = {
214
+ ...rest,
215
+ extended: true,
216
+ random: this.random.fork(sys.name),
217
+ };
218
+ if (texture)
219
+ options.texture = textures[texture];
220
+ this.systems.push(new ParticleSystem(renderer, options));
221
+ for (const em of sys.emitters) {
222
+ const emEnd = em.duration === undefined ? Infinity : (em.delay ?? 0) + em.duration;
223
+ if (emEnd > end)
224
+ end = emEnd;
225
+ }
226
+ }
227
+ this.duration = desc.duration ?? (end > 0 ? end : Infinity);
228
+ }
229
+ /** Start an instance at `at` (default the origin). */
230
+ play(at) {
231
+ const inst = this.pool.pop() ?? this.makeInstance();
232
+ inst.time = 0;
233
+ inst.done = false;
234
+ inst.follow = null;
235
+ inst.position[0] = at?.x ?? 0;
236
+ inst.position[1] = at?.y ?? 0;
237
+ inst.position[2] = at?.z ?? 0;
238
+ for (const states of inst.states) {
239
+ for (const s of states) {
240
+ s.carry = 0;
241
+ s.fired = false;
242
+ }
243
+ }
244
+ this.instances.push(inst);
245
+ return inst;
246
+ }
247
+ /** Start an instance that follows `getPosition`. */
248
+ attach(getPosition) {
249
+ const inst = this.play();
250
+ inst.follow = getPosition;
251
+ getPosition(inst.position);
252
+ return inst;
253
+ }
254
+ /** Stop every instance (particles already born die on their own). */
255
+ stop() {
256
+ for (const inst of this.instances)
257
+ inst.done = true;
258
+ }
259
+ /** Drive the instances' emitters and the systems. Call once per frame. */
260
+ update(dt) {
261
+ const instances = this.instances;
262
+ for (let i = instances.length - 1; i >= 0; i--) {
263
+ const inst = instances[i];
264
+ if (inst.done) {
265
+ instances[i] = instances[instances.length - 1];
266
+ instances.pop();
267
+ this.pool.push(inst);
268
+ continue;
269
+ }
270
+ if (inst.follow)
271
+ inst.follow(inst.position);
272
+ const t0 = inst.time;
273
+ inst.time += dt;
274
+ this.emitFor(inst, t0, inst.time);
275
+ if (inst.time >= this.duration) {
276
+ if (this.loop) {
277
+ inst.time -= this.duration;
278
+ for (const states of inst.states)
279
+ for (const s of states)
280
+ s.fired = false;
281
+ }
282
+ else {
283
+ inst.done = true;
284
+ }
285
+ }
286
+ }
287
+ for (const sys of this.systems)
288
+ sys.update(dt);
289
+ }
290
+ emitFor(inst, t0, t1) {
291
+ const x = inst.position[0];
292
+ const y = inst.position[1];
293
+ const z = inst.position[2];
294
+ const descs = this.desc.systems;
295
+ for (let si = 0; si < descs.length; si++) {
296
+ const sys = descs[si];
297
+ const system = this.systems[si];
298
+ const states = inst.states[si];
299
+ for (let ei = 0; ei < sys.emitters.length; ei++) {
300
+ const em = sys.emitters[ei];
301
+ const st = states[ei];
302
+ const delay = em.delay ?? 0;
303
+ const end = em.duration === undefined ? Infinity : delay + em.duration;
304
+ const p = st.params;
305
+ p.x = x + (em.params.x ?? 0);
306
+ p.y = y + (em.params.y ?? 0);
307
+ p.z = z + (em.params.z ?? 0);
308
+ if (!st.fired && t1 >= delay) {
309
+ st.fired = true;
310
+ if (em.burst)
311
+ system.emit(p, em.burst);
312
+ }
313
+ if (em.rate && t1 > delay && t0 < end) {
314
+ const active = Math.min(t1, end) - Math.max(t0, delay);
315
+ st.carry += em.rate * active;
316
+ const n = Math.floor(st.carry);
317
+ if (n > 0) {
318
+ st.carry -= n;
319
+ system.emit(p, n);
320
+ }
321
+ }
322
+ }
323
+ }
324
+ }
325
+ /** Queue every system for drawing (`frame.drawable`). */
326
+ draw(frame, order = 0) {
327
+ for (const sys of this.systems)
328
+ frame.drawable(sys, order);
329
+ }
330
+ destroy() {
331
+ for (const sys of this.systems)
332
+ sys.destroy();
333
+ this.instances.length = 0;
334
+ }
335
+ makeInstance() {
336
+ const inst = new EffectInstance();
337
+ for (const sys of this.desc.systems) {
338
+ inst.states.push(sys.emitters.map((em) => ({ params: { ...em.params }, carry: 0, fired: false })));
339
+ }
340
+ return inst;
341
+ }
342
+ }
343
+ /**
344
+ * Build an `Effect` from a descriptor, resolving texture names through `textures`. Throws a
345
+ * readable `Error` listing every problem `validateEffectDesc` finds.
346
+ */
347
+ export function createEffect(renderer, desc, opts = {}) {
348
+ return new Effect(renderer, desc, opts.textures ?? {}, opts.random);
349
+ }
@@ -0,0 +1,48 @@
1
+ {
2
+ "duration": 0.4,
3
+ "systems": [
4
+ {
5
+ "name": "sparks",
6
+ "options": { "space": "2d", "blend": "additive", "stretch": 0.03 },
7
+ "emitters": [
8
+ {
9
+ "burst": 40,
10
+ "params": {
11
+ "x": 0,
12
+ "y": 0,
13
+ "speed": [200, 600],
14
+ "life": [0.2, 0.45],
15
+ "sizeCurve": [5, 3, 0],
16
+ "colorCurve": [[4, 3.2, 1.6, 1], [3, 1, 0.2, 1], [1, 0.2, 0.05, 0]],
17
+ "gravity": [0, 900],
18
+ "drag": 2,
19
+ "emissive": 2,
20
+ "colorStart": [4, 3.2, 1.6, 1]
21
+ }
22
+ }
23
+ ]
24
+ },
25
+ {
26
+ "name": "flash",
27
+ "options": { "space": "2d", "blend": "additive", "stretch": 0 },
28
+ "emitters": [
29
+ {
30
+ "burst": 1,
31
+ "params": {
32
+ "x": 0,
33
+ "y": 0,
34
+ "speed": [0, 0],
35
+ "life": [0.12, 0.12],
36
+ "sizeCurve": [10, 48, 20],
37
+ "colorStart": [3, 2.4, 1.2, 1],
38
+ "colorEnd": [3, 2.4, 1.2, 0],
39
+ "gravity": [0, 0],
40
+ "drag": 0,
41
+ "emissive": 3,
42
+ "alignToVelocity": false
43
+ }
44
+ }
45
+ ]
46
+ }
47
+ ]
48
+ }
@@ -0,0 +1,8 @@
1
+ /** The built-in effect descriptors (`src/fx/effects/*.json`), typed as `EffectDesc`. */
2
+ import type { EffectDesc } from '../effect.js';
3
+ /** A 2D impact: a burst of bright sparks and a short flash. */
4
+ export declare const HIT_SPARK_EFFECT: EffectDesc;
5
+ /** A 2D alpha-blended smoke puff that grows, spins and fades. */
6
+ export declare const SMOKE_PUFF_EFFECT: EffectDesc;
7
+ /** A looping world-space aura: rising motes that trail sparkles (sub-emission). */
8
+ export declare const MAGIC_AURA_EFFECT: EffectDesc;
@@ -0,0 +1,9 @@
1
+ import hitSpark from './hit-spark.json' with { type: 'json' };
2
+ import magicAura from './magic-aura.json' with { type: 'json' };
3
+ import smokePuff from './smoke-puff.json' with { type: 'json' };
4
+ /** A 2D impact: a burst of bright sparks and a short flash. */
5
+ export const HIT_SPARK_EFFECT = hitSpark;
6
+ /** A 2D alpha-blended smoke puff that grows, spins and fades. */
7
+ export const SMOKE_PUFF_EFFECT = smokePuff;
8
+ /** A looping world-space aura: rising motes that trail sparkles (sub-emission). */
9
+ export const MAGIC_AURA_EFFECT = magicAura;
@@ -0,0 +1,47 @@
1
+ {
2
+ "loop": true,
3
+ "duration": 1,
4
+ "systems": [
5
+ {
6
+ "name": "motes",
7
+ "options": { "space": "world", "blend": "additive", "stretch": 0.01, "softness": 0.15 },
8
+ "emitters": [
9
+ {
10
+ "rate": 24,
11
+ "params": {
12
+ "x": 0,
13
+ "y": 0,
14
+ "z": 0,
15
+ "shape": { "kind": "sphere", "radius": 0.35 },
16
+ "angle": 1.5707963,
17
+ "spread": 1.0,
18
+ "speed": [0.4, 0.9],
19
+ "life": [1.0, 1.6],
20
+ "sizeCurve": [0.02, 0.08, 0.06, 0.0],
21
+ "colorCurve": [[0.4, 0.6, 2.4, 1], [1.2, 0.5, 2.8, 1], [0.2, 0.9, 2.0, 0]],
22
+ "gravity": [0, 0.6, 0],
23
+ "drag": 0.8,
24
+ "emissive": 2.5,
25
+ "inherit": 0.5,
26
+ "onLife": {
27
+ "rate": 18,
28
+ "params": {
29
+ "x": 0,
30
+ "y": 0,
31
+ "z": 0,
32
+ "speed": [0.02, 0.08],
33
+ "life": [0.3, 0.5],
34
+ "size": [0.03, 0.0],
35
+ "colorStart": [0.6, 0.4, 2.0, 0.8],
36
+ "gravity": [0, 0, 0],
37
+ "drag": 2,
38
+ "emissive": 1.5
39
+ }
40
+ },
41
+ "colorStart": [0.4, 0.6, 2.4, 1]
42
+ }
43
+ }
44
+ ]
45
+ }
46
+ ]
47
+ }
@@ -0,0 +1,34 @@
1
+ {
2
+ "duration": 2.5,
3
+ "systems": [
4
+ {
5
+ "name": "smoke",
6
+ "options": { "space": "2d", "blend": "alpha", "stretch": 0 },
7
+ "emitters": [
8
+ {
9
+ "burst": 12,
10
+ "rate": 30,
11
+ "duration": 0.3,
12
+ "params": {
13
+ "x": 0,
14
+ "y": 0,
15
+ "shape": { "kind": "circle", "radius": 8 },
16
+ "angle": -1.5707963,
17
+ "spread": 1.2,
18
+ "speed": [30, 90],
19
+ "life": [1.2, 2.2],
20
+ "sizeCurve": [12, 40, 56, 64],
21
+ "colorCurve": [[0.6, 0.6, 0.6, 0.7], [0.45, 0.45, 0.47, 0.5], [0.35, 0.35, 0.38, 0]],
22
+ "gravity": [0, -40],
23
+ "drag": 1.5,
24
+ "emissive": 0,
25
+ "rotation": [-3.14, 3.14],
26
+ "spin": [-1.2, 1.2],
27
+ "alignToVelocity": false,
28
+ "colorStart": [0.6, 0.6, 0.6, 0.7]
29
+ }
30
+ }
31
+ ]
32
+ }
33
+ ]
34
+ }
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Mesh emission surfaces (ws/fx-3): a triangle list with a cumulative-area table, so particles
3
+ * can be born uniformly over a mesh's surface (`EmitShape` `{ kind: 'mesh' }`). Pure arithmetic;
4
+ * the GPU kernel samples the same table (`SURFACE_TRI_FLOATS` per triangle).
5
+ */
6
+ import type { Geometry } from '../geom/geometry.js';
7
+ /** A triangle mesh by its arrays: `positions` xyz per vertex, optional `normals`, `indices`. */
8
+ export interface MeshShapeSource {
9
+ positions: ArrayLike<number>;
10
+ normals?: ArrayLike<number>;
11
+ indices?: ArrayLike<number>;
12
+ }
13
+ /**
14
+ * A mesh emit shape with its sampling table built: usable as `EmitParams.shape` directly.
15
+ * `table` holds `SURFACE_TRI_FLOATS` per triangle: p0 (xyz + cumulative area 0..1), p1, p2,
16
+ * n0, n1, n2 (unit normals, each xyz + 0).
17
+ */
18
+ export interface EmitSurface extends MeshShapeSource {
19
+ readonly kind: 'mesh';
20
+ /** Launch along the surface normal (instead of `angle`/`spread`). Default false. */
21
+ alongNormal?: boolean;
22
+ readonly table: Float32Array;
23
+ readonly triangles: number;
24
+ /** Total surface area (square units). */
25
+ readonly area: number;
26
+ }
27
+ /**
28
+ * Build the sampling table of a `Geometry` (xyz at 0, normal at 3 of each `layout.floats`
29
+ * vertex) or of raw `positions`/`normals`/`indices`. Without indices every three positions
30
+ * are a triangle; without normals the face normal is used. Allocates; build once per mesh.
31
+ */
32
+ export declare function buildEmitSurface(src: Geometry | MeshShapeSource, opts?: {
33
+ alongNormal?: boolean;
34
+ }): EmitSurface;
35
+ /**
36
+ * The CPU mirror of the kernel's sampling: triangle by `u` (binary search of the cumulative
37
+ * areas), point by `v`, `w` (square-root barycentrics, uniform over the triangle). Writes
38
+ * position xyz then normal xyz into `out` (6 floats). Returns the triangle index.
39
+ */
40
+ export declare function sampleEmitSurface(surface: EmitSurface, u: number, v: number, w: number, out: Float32Array): number;