@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,569 @@
1
+ const HOVER_TINT = 'rgba(255, 255, 255, 0.07)';
2
+ const PRESS_TINT = 'rgba(0, 0, 0, 0.18)';
3
+ const DISABLED_ALPHA = 0.45;
4
+ function toneColor(t, tone) {
5
+ const k = t.tokens;
6
+ switch (tone) {
7
+ case 'muted':
8
+ return k.colorTextMuted;
9
+ case 'accent':
10
+ return k.colorAccent;
11
+ case 'info':
12
+ return k.colorInfo;
13
+ case 'success':
14
+ return k.colorSuccess;
15
+ case 'warn':
16
+ return k.colorWarn;
17
+ case 'danger':
18
+ return k.colorDanger;
19
+ default:
20
+ return k.colorText;
21
+ }
22
+ }
23
+ function fontSize(t, size) {
24
+ return size === 's' ? t.fontSizeS : size === 'l' ? t.fontSizeL : t.fontSizeM;
25
+ }
26
+ /**
27
+ * Base of every panel widget. `O` is its options object; subclasses say which keys change the
28
+ * height (`layoutKeys`) so `set` can ask for a layout pass only then.
29
+ */
30
+ export class WorldWidget {
31
+ /** An explicit place in panel px; `null` lets the flow place it. */
32
+ rect = null;
33
+ /** Where the panel put it (the flow or `rect`). */
34
+ layoutRect = { x: 0, y: 0, w: 0, h: 0 };
35
+ hover = false;
36
+ pressed = false;
37
+ focused = false;
38
+ /** @internal set by the panel on `add`. */
39
+ host = null;
40
+ theme = null;
41
+ opts;
42
+ layoutKeys;
43
+ constructor(opts, layoutKeys = []) {
44
+ this.opts = opts;
45
+ this.layoutKeys = new Set(layoutKeys);
46
+ const r = opts.rect;
47
+ if (r)
48
+ this.rect = { x: r.x, y: r.y, w: r.w, h: r.h };
49
+ }
50
+ /** The current options (read-only view). */
51
+ get options() {
52
+ return this.opts;
53
+ }
54
+ /** Whether the widget takes focus and pointer presses. */
55
+ get focusable() {
56
+ return false;
57
+ }
58
+ /** Disabled widgets paint faded and ignore input. */
59
+ get disabled() {
60
+ return this.opts.disabled === true;
61
+ }
62
+ /** @internal */
63
+ attach(host) {
64
+ this.host = host;
65
+ this.theme = host.painter.theme;
66
+ }
67
+ /** @internal */
68
+ detach() {
69
+ this.host = null;
70
+ this.hover = false;
71
+ this.pressed = false;
72
+ this.focused = false;
73
+ }
74
+ /** Mark the widget's rect dirty. */
75
+ invalidate() {
76
+ this.host?.invalidate(this);
77
+ }
78
+ /**
79
+ * Write the fields of `patch` that differ (`!==`) from the current options. Only a change marks
80
+ * the rect dirty; a change to a layout key also re-runs the flow. Returns whether anything changed.
81
+ */
82
+ set(patch) {
83
+ let changed = false;
84
+ let relayout = false;
85
+ const o = this.opts;
86
+ for (const key of Object.keys(patch)) {
87
+ const v = patch[key];
88
+ if (o[key] === v)
89
+ continue;
90
+ o[key] = v;
91
+ changed = true;
92
+ if (this.layoutKeys.has(key))
93
+ relayout = true;
94
+ if (key === 'rect') {
95
+ const r = v;
96
+ this.rect = r ? { x: r.x, y: r.y, w: r.w, h: r.h } : null;
97
+ relayout = true;
98
+ }
99
+ }
100
+ if (changed) {
101
+ this.changed();
102
+ if (relayout)
103
+ this.host?.relayout();
104
+ else
105
+ this.invalidate();
106
+ }
107
+ return changed;
108
+ }
109
+ /** Hook after `set` wrote something (clamp derived state). */
110
+ changed() { }
111
+ /** Pointer went down at panel px (inside the rect). */
112
+ pointerDown(_x, _y) { }
113
+ /** Pointer moved; `down` while this widget holds the press. */
114
+ pointerMove(_x, _y, _down) { }
115
+ /** The press ended; `inside` when the release was over this widget. */
116
+ pointerUp(_x, _y, _inside) { }
117
+ /** Wheel over the widget, `dy` in px (positive scrolls down). Returns whether it was used. */
118
+ wheel(_dy) {
119
+ return false;
120
+ }
121
+ /** The pad's A / Enter / Space on the focused widget. */
122
+ activate() { }
123
+ /** A key on the focused widget; true when consumed. */
124
+ key(_event) {
125
+ return false;
126
+ }
127
+ get t() {
128
+ const t = this.theme;
129
+ if (!t)
130
+ throw new Error('world panel widget: not added to a panel');
131
+ return t;
132
+ }
133
+ /** The row height a control uses: the M font plus `space3` above and below. */
134
+ controlHeight() {
135
+ const t = this.t;
136
+ return Math.round(t.fontSizeM + t.space3 * 2);
137
+ }
138
+ /** The background, hover and pressed layers of a control, then the border. */
139
+ paintControl(p, r, fill, radius) {
140
+ const t = this.t;
141
+ p.fillRoundRect(r, radius, fill);
142
+ if (this.pressed)
143
+ p.fillRoundRect(r, radius, PRESS_TINT);
144
+ else if (this.hover)
145
+ p.fillRoundRect(r, radius, HOVER_TINT);
146
+ p.strokeRoundRect(r, radius, t.tokens.colorBorder, t.borderWidth);
147
+ }
148
+ /** Run `paint` at the disabled alpha when disabled; the focus ring after. */
149
+ frame(p, r, radius, paint) {
150
+ const ctx = p.ctx;
151
+ const dis = this.disabled;
152
+ if (dis) {
153
+ ctx.save();
154
+ ctx.globalAlpha = DISABLED_ALPHA;
155
+ }
156
+ paint();
157
+ if (dis)
158
+ ctx.restore();
159
+ if (this.focused && !dis)
160
+ p.focusRing(r, radius);
161
+ }
162
+ }
163
+ export class WorldLabel extends WorldWidget {
164
+ constructor(opts) {
165
+ super({ ...opts }, ['size']);
166
+ }
167
+ measure() {
168
+ return Math.round(fontSize(this.t, this.opts.size) * 1.4);
169
+ }
170
+ paint(p, r) {
171
+ const o = this.opts;
172
+ p.text(o.text, r, fontSize(this.t, o.size), toneColor(this.t, o.tone), o.align ?? 'left');
173
+ }
174
+ }
175
+ export class WorldButton extends WorldWidget {
176
+ constructor(opts) {
177
+ super({ ...opts });
178
+ }
179
+ get focusable() {
180
+ return !this.disabled;
181
+ }
182
+ measure() {
183
+ return this.controlHeight();
184
+ }
185
+ paint(p, r) {
186
+ const t = this.t;
187
+ this.frame(p, r, t.radiusM, () => {
188
+ const k = t.tokens;
189
+ this.paintControl(p, r, this.pressed ? k.colorAccent : k.colorSurfaceAlt, t.radiusM);
190
+ p.text(this.opts.text, r, t.fontSizeM, this.pressed ? k.colorAccentText : k.colorText, 'center', 0, 600);
191
+ });
192
+ }
193
+ pointerUp(_x, _y, inside) {
194
+ if (inside)
195
+ this.activate();
196
+ }
197
+ activate() {
198
+ if (!this.disabled)
199
+ this.opts.onPress?.();
200
+ }
201
+ }
202
+ export class WorldToggle extends WorldWidget {
203
+ constructor(opts) {
204
+ super({ ...opts });
205
+ }
206
+ get focusable() {
207
+ return !this.disabled;
208
+ }
209
+ measure() {
210
+ return this.controlHeight();
211
+ }
212
+ paint(p, r) {
213
+ const t = this.t;
214
+ this.frame(p, r, t.radiusM, () => {
215
+ const k = t.tokens;
216
+ this.paintControl(p, r, k.colorSurfaceAlt, t.radiusM);
217
+ p.text(this.opts.text, r, t.fontSizeM, k.colorText, 'left', t.space3);
218
+ // The pill: twice as wide as tall, the knob at the on side when `value`.
219
+ const h = Math.round(t.fontSizeM * 0.9);
220
+ const w = h * 2;
221
+ const pill = { x: r.x + r.w - t.space3 - w, y: r.y + (r.h - h) / 2, w, h };
222
+ const on = this.opts.value;
223
+ p.fillRoundRect(pill, h / 2, on ? k.colorAccent : k.colorSurface);
224
+ p.strokeRoundRect(pill, h / 2, k.colorBorder, t.borderWidth);
225
+ const pad = t.borderWidth + 1;
226
+ const d = h - pad * 2;
227
+ const knob = {
228
+ x: on ? pill.x + w - pad - d : pill.x + pad,
229
+ y: pill.y + pad,
230
+ w: d,
231
+ h: d,
232
+ };
233
+ p.fillRoundRect(knob, d / 2, on ? k.colorAccentText : k.colorTextMuted);
234
+ });
235
+ }
236
+ pointerUp(_x, _y, inside) {
237
+ if (inside)
238
+ this.activate();
239
+ }
240
+ activate() {
241
+ if (this.disabled)
242
+ return;
243
+ const v = !this.opts.value;
244
+ this.set({ value: v });
245
+ this.opts.onChange?.(v);
246
+ }
247
+ }
248
+ export class WorldSlider extends WorldWidget {
249
+ dragging = false;
250
+ constructor(opts) {
251
+ super({ ...opts });
252
+ this.opts.value = this.snap(this.opts.value);
253
+ }
254
+ get focusable() {
255
+ return !this.disabled;
256
+ }
257
+ measure() {
258
+ return this.controlHeight();
259
+ }
260
+ /** The value for a panel px `x` inside `r`. */
261
+ valueAt(x) {
262
+ const r = this.layoutRect;
263
+ const t = this.t;
264
+ const inset = t.space3;
265
+ const span = Math.max(1, r.w - inset * 2);
266
+ const f = Math.min(1, Math.max(0, (x - r.x - inset) / span));
267
+ const o = this.opts;
268
+ return this.snap(o.min + f * (o.max - o.min));
269
+ }
270
+ snap(v) {
271
+ const o = this.opts;
272
+ const lo = Math.min(o.min, o.max);
273
+ const hi = Math.max(o.min, o.max);
274
+ let out = Math.min(hi, Math.max(lo, v));
275
+ const step = o.step ?? 0;
276
+ if (step > 0) {
277
+ out = o.min + Math.round((out - o.min) / step) * step;
278
+ out = Math.min(hi, Math.max(lo, out));
279
+ // Round away float dust (0.30000000000000004).
280
+ const digits = Math.min(10, Math.max(0, Math.ceil(-Math.log10(step)) + 2));
281
+ out = Number(out.toFixed(digits));
282
+ }
283
+ return out;
284
+ }
285
+ changed() {
286
+ const v = this.snap(this.opts.value);
287
+ if (v !== this.opts.value)
288
+ this.opts.value = v;
289
+ }
290
+ commit(v) {
291
+ if (v === this.opts.value)
292
+ return;
293
+ this.opts.value = v;
294
+ this.invalidate();
295
+ this.opts.onChange?.(v);
296
+ }
297
+ paint(p, r) {
298
+ const t = this.t;
299
+ this.frame(p, r, t.radiusM, () => {
300
+ const k = t.tokens;
301
+ const o = this.opts;
302
+ const inset = t.space3;
303
+ const trackH = Math.max(2, Math.round(t.space2));
304
+ const track = {
305
+ x: r.x + inset,
306
+ y: r.y + (r.h - trackH) / 2,
307
+ w: r.w - inset * 2,
308
+ h: trackH,
309
+ };
310
+ p.fillRoundRect(track, trackH / 2, k.colorSurfaceAlt);
311
+ p.strokeRoundRect(track, trackH / 2, k.colorBorder, 1);
312
+ const span = o.max - o.min;
313
+ const f = span === 0 ? 0 : Math.min(1, Math.max(0, (o.value - o.min) / span));
314
+ const fill = { x: track.x, y: track.y, w: track.w * f, h: track.h };
315
+ if (fill.w > 0)
316
+ p.fillRoundRect(fill, trackH / 2, k.colorAccent);
317
+ const d = Math.round(t.fontSizeM * 0.9);
318
+ const knob = {
319
+ x: track.x + track.w * f - d / 2,
320
+ y: r.y + (r.h - d) / 2,
321
+ w: d,
322
+ h: d,
323
+ };
324
+ p.fillRoundRect(knob, d / 2, this.pressed ? k.colorFocus : k.colorAccent);
325
+ if (this.hover && !this.pressed)
326
+ p.fillRoundRect(knob, d / 2, HOVER_TINT);
327
+ p.strokeRoundRect(knob, d / 2, k.colorAccentText, 1);
328
+ });
329
+ }
330
+ pointerDown(x) {
331
+ if (this.disabled)
332
+ return;
333
+ this.dragging = true;
334
+ this.commit(this.valueAt(x));
335
+ }
336
+ pointerMove(x, _y, down) {
337
+ if (this.dragging && down)
338
+ this.commit(this.valueAt(x));
339
+ }
340
+ pointerUp(x) {
341
+ if (this.dragging) {
342
+ this.dragging = false;
343
+ if (Number.isFinite(x))
344
+ this.commit(this.valueAt(x));
345
+ }
346
+ }
347
+ key(e) {
348
+ if (this.disabled)
349
+ return false;
350
+ const o = this.opts;
351
+ const step = o.step && o.step > 0 ? o.step : (o.max - o.min) / 20;
352
+ if (e.key === 'ArrowLeft' || e.key === 'ArrowDown') {
353
+ this.commit(this.snap(o.value - step));
354
+ return true;
355
+ }
356
+ if (e.key === 'ArrowRight' || e.key === 'ArrowUp') {
357
+ this.commit(this.snap(o.value + step));
358
+ return true;
359
+ }
360
+ return false;
361
+ }
362
+ }
363
+ /** Px a press may travel before it is a scroll drag rather than a tap. */
364
+ const LIST_DRAG_PX = 4;
365
+ export class WorldList extends WorldWidget {
366
+ /** Scroll offset in px from the top of the items. */
367
+ scroll = 0;
368
+ pressY = 0;
369
+ pressScroll = 0;
370
+ dragging = false;
371
+ down = false;
372
+ constructor(opts) {
373
+ super({ selected: -1, visibleRows: 4, ...opts }, ['visibleRows']);
374
+ }
375
+ get focusable() {
376
+ return !this.disabled;
377
+ }
378
+ /** Row height in px. */
379
+ get rowHeight() {
380
+ const t = this.t;
381
+ return Math.round(t.fontSizeM + t.space2 * 2);
382
+ }
383
+ /** The largest `scroll` that still shows a full last row. */
384
+ get maxScroll() {
385
+ const rows = this.opts.visibleRows ?? 4;
386
+ return Math.max(0, (this.opts.items.length - rows) * this.rowHeight);
387
+ }
388
+ measure() {
389
+ return this.rowHeight * (this.opts.visibleRows ?? 4) + this.t.borderWidth * 2;
390
+ }
391
+ changed() {
392
+ this.setScroll(this.scroll);
393
+ }
394
+ /** Set the scroll offset, clamped to `[0, maxScroll]`; dirty only when it moved. */
395
+ setScroll(px) {
396
+ const v = Math.min(this.maxScroll, Math.max(0, px));
397
+ if (v === this.scroll)
398
+ return;
399
+ this.scroll = v;
400
+ this.invalidate();
401
+ }
402
+ /** Select `index` (clamped; -1 clears), scroll it into view and fire `onSelect` when it changed. */
403
+ select(index) {
404
+ const n = this.opts.items.length;
405
+ const i = index < 0 || n === 0 ? -1 : Math.min(n - 1, Math.max(0, Math.floor(index)));
406
+ if (i >= 0) {
407
+ const rh = this.rowHeight;
408
+ const rows = this.opts.visibleRows ?? 4;
409
+ if (i * rh < this.scroll)
410
+ this.setScroll(i * rh);
411
+ else if ((i + 1) * rh > this.scroll + rows * rh)
412
+ this.setScroll((i + 1) * rh - rows * rh);
413
+ }
414
+ if (i === this.opts.selected)
415
+ return;
416
+ this.opts.selected = i;
417
+ this.invalidate();
418
+ this.opts.onSelect?.(i);
419
+ }
420
+ /** The item index under panel px `y`, or -1 between/after the items. */
421
+ rowAt(y) {
422
+ const r = this.layoutRect;
423
+ const i = Math.floor((y - r.y - this.t.borderWidth + this.scroll) / this.rowHeight);
424
+ return i >= 0 && i < this.opts.items.length ? i : -1;
425
+ }
426
+ paint(p, r) {
427
+ const t = this.t;
428
+ this.frame(p, r, t.radiusS, () => {
429
+ const k = t.tokens;
430
+ const o = this.opts;
431
+ p.fillRoundRect(r, t.radiusS, k.colorSurfaceAlt);
432
+ const ctx = p.ctx;
433
+ ctx.save();
434
+ const bw = t.borderWidth;
435
+ const inner = { x: r.x + bw, y: r.y + bw, w: r.w - bw * 2, h: r.h - bw * 2 };
436
+ ctx.beginPath();
437
+ ctx.rect(inner.x, inner.y, inner.w, inner.h);
438
+ ctx.clip();
439
+ const rh = this.rowHeight;
440
+ const first = Math.floor(this.scroll / rh);
441
+ const last = Math.min(o.items.length - 1, Math.ceil((this.scroll + inner.h) / rh));
442
+ const row = { x: inner.x, y: 0, w: inner.w, h: rh };
443
+ for (let i = first; i <= last; i++) {
444
+ row.y = inner.y + i * rh - this.scroll;
445
+ if (i === o.selected)
446
+ p.fillRoundRect(row, 0, k.colorAccent);
447
+ else if (i % 2 === 1)
448
+ p.fillRoundRect(row, 0, 'rgba(255, 255, 255, 0.03)');
449
+ p.text(o.items[i], row, t.fontSizeM, i === o.selected ? k.colorAccentText : k.colorText, 'left', t.space3);
450
+ }
451
+ ctx.restore();
452
+ if (this.hover)
453
+ p.fillRoundRect(r, t.radiusS, HOVER_TINT);
454
+ p.strokeRoundRect(r, t.radiusS, k.colorBorder, bw);
455
+ // Scrollbar when the items overflow.
456
+ const max = this.maxScroll;
457
+ if (max > 0) {
458
+ const total = o.items.length * rh;
459
+ const barH = Math.max(rh, (inner.h * inner.h) / total);
460
+ const barY = inner.y + (this.scroll / max) * (inner.h - barH);
461
+ const bar = {
462
+ x: inner.x + inner.w - t.space2 - 2,
463
+ y: barY,
464
+ w: t.space2,
465
+ h: barH,
466
+ };
467
+ p.fillRoundRect(bar, t.space2 / 2, k.colorTextMuted);
468
+ }
469
+ });
470
+ }
471
+ pointerDown(_x, y) {
472
+ if (this.disabled)
473
+ return;
474
+ this.down = true;
475
+ this.dragging = false;
476
+ this.pressY = y;
477
+ this.pressScroll = this.scroll;
478
+ }
479
+ pointerMove(_x, y, down) {
480
+ if (!this.down || !down)
481
+ return;
482
+ const dy = y - this.pressY;
483
+ if (!this.dragging && Math.abs(dy) > LIST_DRAG_PX)
484
+ this.dragging = true;
485
+ if (this.dragging)
486
+ this.setScroll(this.pressScroll - dy);
487
+ }
488
+ pointerUp(_x, y, inside) {
489
+ if (!this.down)
490
+ return;
491
+ this.down = false;
492
+ if (this.dragging) {
493
+ this.dragging = false;
494
+ return;
495
+ }
496
+ if (inside) {
497
+ const i = this.rowAt(y);
498
+ if (i >= 0)
499
+ this.select(i);
500
+ }
501
+ }
502
+ wheel(dy) {
503
+ if (this.disabled || this.maxScroll === 0)
504
+ return false;
505
+ this.setScroll(this.scroll + dy);
506
+ return true;
507
+ }
508
+ activate() {
509
+ if (this.disabled)
510
+ return;
511
+ const i = this.opts.selected ?? -1;
512
+ if (i >= 0)
513
+ this.opts.onSelect?.(i);
514
+ }
515
+ key(e) {
516
+ if (this.disabled || this.opts.items.length === 0)
517
+ return false;
518
+ const sel = this.opts.selected ?? -1;
519
+ if (e.key === 'ArrowDown') {
520
+ this.select(Math.min(this.opts.items.length - 1, sel + 1));
521
+ return true;
522
+ }
523
+ if (e.key === 'ArrowUp') {
524
+ this.select(Math.max(0, sel - 1));
525
+ return true;
526
+ }
527
+ return false;
528
+ }
529
+ }
530
+ export class WorldProgress extends WorldWidget {
531
+ constructor(opts) {
532
+ super({ ...opts });
533
+ }
534
+ measure() {
535
+ return Math.round(this.t.space4);
536
+ }
537
+ paint(p, r) {
538
+ const t = this.t;
539
+ const k = t.tokens;
540
+ const radius = r.h / 2;
541
+ p.fillRoundRect(r, radius, k.colorSurfaceAlt);
542
+ const f = Math.min(1, Math.max(0, this.opts.value));
543
+ if (f > 0) {
544
+ const fill = { x: r.x, y: r.y, w: Math.max(r.h, r.w * f), h: r.h };
545
+ p.fillRoundRect(fill, radius, toneColor(t, this.opts.tone ?? 'accent'));
546
+ }
547
+ p.strokeRoundRect(r, radius, k.colorBorder, t.borderWidth);
548
+ }
549
+ }
550
+ // ---------------------------------------------------------------------------------------------
551
+ // Factories (the names a game reaches for)
552
+ export function label(opts) {
553
+ return new WorldLabel(opts);
554
+ }
555
+ export function button(opts) {
556
+ return new WorldButton(opts);
557
+ }
558
+ export function toggle(opts) {
559
+ return new WorldToggle(opts);
560
+ }
561
+ export function slider(opts) {
562
+ return new WorldSlider(opts);
563
+ }
564
+ export function list(opts) {
565
+ return new WorldList(opts);
566
+ }
567
+ export function progress(opts) {
568
+ return new WorldProgress(opts);
569
+ }
@@ -0,0 +1,77 @@
1
+ /**
2
+ * The chunk renderer: one `Mesh` per non-empty chunk of a `VoxelGrid`, remeshed through a
3
+ * `VoxelMesher` as chunks go dirty and drawn through `frame.mesh` after a frustum test on each
4
+ * chunk's bounding sphere. `update()` once per tick (requests for dirty chunks out, finished
5
+ * remeshes in and uploaded), `draw(frame, camera)` once per view.
6
+ *
7
+ * Each mesh is created on the chunk's first non-empty reply with `slack` times that reply's
8
+ * counts of room (at least `minQuads` quads), so the edits that follow rewrite it in place and
9
+ * `Mesh.growths` stays 0 until a chunk grows past its slack. A chunk that empties keeps its
10
+ * mesh with nothing to draw. Meshes carry no bounds of their own (`autoBounds` off); the
11
+ * reply's chunk-local sphere, offset by the chunk origin, is the one `draw` tests.
12
+ */
13
+ import type { Camera } from '../render/camera.js';
14
+ import type { Frame, InstanceParams } from '../render/frame.js';
15
+ import type { Material } from '../render/material.js';
16
+ import { type Mesh } from '../render/mesh.js';
17
+ import type { Renderer } from '../render/renderer.js';
18
+ import { Transform } from '../render/transform.js';
19
+ import type { VoxelGrid } from './grid.js';
20
+ import type { MeshChunkOptions } from './mesher.js';
21
+ import { type VoxelMesher } from './worker-client.js';
22
+ export interface VoxelChunksOptions extends MeshChunkOptions {
23
+ /** The block material every chunk is drawn with. */
24
+ material: Material;
25
+ /** Room factor on each mesh's first upload (1 = exact). Default 1.5. */
26
+ slack?: number;
27
+ /** Floor on a mesh's room, in quads. Default 64. */
28
+ minQuads?: number;
29
+ /** The mesher to request from. Default: an in-thread one over `grid` with these options. */
30
+ mesher?: VoxelMesher;
31
+ /** World position of the grid's corner. Default the origin. */
32
+ origin?: ArrayLike<number>;
33
+ /** Instance params (tint, params) every chunk draw carries. */
34
+ params?: InstanceParams;
35
+ /** Clock in ms for `stats.remeshMs`. Default `performance.now()`. */
36
+ now?: () => number;
37
+ }
38
+ export interface VoxelDrawStats {
39
+ /** Chunks drawn this call. */
40
+ drawn: number;
41
+ /** Non-empty chunks the camera did not see. */
42
+ culled: number;
43
+ /** Triangles drawn this call. */
44
+ triangles: number;
45
+ }
46
+ export interface VoxelChunksStats extends VoxelDrawStats {
47
+ /** Non-empty chunks (with a mesh that draws). */
48
+ chunks: number;
49
+ /** Sum of `Mesh.growths` over the chunk meshes. */
50
+ growths: number;
51
+ /** Remeshes requested and not yet applied. */
52
+ pending: number;
53
+ /** Remeshes applied so far. */
54
+ remeshes: number;
55
+ /** Request-to-upload time of the last applied remesh, ms. */
56
+ remeshMs: number;
57
+ }
58
+ export interface VoxelChunks {
59
+ readonly grid: VoxelGrid;
60
+ readonly material: Material;
61
+ readonly mesher: VoxelMesher;
62
+ /** Per chunk index: its mesh once it has drawn anything, else null. */
63
+ readonly meshes: readonly (Mesh | null)[];
64
+ /** Per chunk index: the transform placing it (the chunk origin plus `origin`). */
65
+ readonly transforms: readonly Transform[];
66
+ readonly stats: VoxelChunksStats;
67
+ /**
68
+ * Upload every finished remesh, then request one for every dirty chunk. Returns how many
69
+ * were uploaded. Call once per tick.
70
+ */
71
+ update(): number;
72
+ /** Push every visible non-empty chunk into `frame` and return the draw counts (`stats`). */
73
+ draw(frame: Frame, camera: Camera): VoxelDrawStats;
74
+ /** Destroy the meshes; dispose the mesher when this made it. */
75
+ dispose(): void;
76
+ }
77
+ export declare function createVoxelChunks(renderer: Renderer, grid: VoxelGrid, opts: VoxelChunksOptions): VoxelChunks;