@downdraft/engine 0.0.0 → 0.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 (907) hide show
  1. package/app/src/index.ts +10 -0
  2. package/app/src/renderer/bootstrap.ts +271 -0
  3. package/app/src/renderer/downdraft-base.css +93 -0
  4. package/app/src/renderer/feature-log.ts +200 -0
  5. package/app/src/renderer/game-module.ts +923 -0
  6. package/app/src/renderer/hooks.ts +88 -0
  7. package/app/src/renderer/hot-reload.ts +178 -0
  8. package/app/src/renderer/import-cache.ts +88 -0
  9. package/app/src/renderer/index.ts +206 -0
  10. package/app/src/renderer/mcp-harness.ts +144 -0
  11. package/app/src/renderer/save-store-factory.ts +239 -0
  12. package/app/src/renderer/sim-bridge.ts +183 -0
  13. package/app/src/renderer/standard-automation-tools.ts +771 -0
  14. package/app/src/shared/feature-log.ts +71 -0
  15. package/app/src/shared/gpu-info.ts +82 -0
  16. package/app/src/shared/import-cache-store.ts +142 -0
  17. package/app/src/shared/index.ts +6 -0
  18. package/app/src/shared/mcp-discovery.ts +47 -0
  19. package/app/src/shared/mcp-proxy.ts +82 -0
  20. package/app/src/shared/types.ts +324 -0
  21. package/asset-bake/src/bake-audio.ts +119 -0
  22. package/asset-bake/src/bake-gltf.ts +172 -0
  23. package/asset-bake/src/bake.ts +78 -0
  24. package/asset-bake/src/cache.ts +188 -0
  25. package/asset-bake/src/config.ts +186 -0
  26. package/asset-bake/src/index.ts +36 -0
  27. package/core/src/animation/animation-event.ts +41 -0
  28. package/core/src/animation/bone-mask.ts +122 -0
  29. package/core/src/animation/clip.ts +252 -0
  30. package/core/src/animation/index.ts +22 -0
  31. package/core/src/animation/mixamo.ts +113 -0
  32. package/core/src/animation/morph-target.ts +69 -0
  33. package/core/src/animation/player.ts +697 -0
  34. package/core/src/animation/retarget.ts +158 -0
  35. package/core/src/animation/skeleton-animator.ts +1399 -0
  36. package/core/src/animation/skeleton.ts +214 -0
  37. package/core/src/animation/state-machine.ts +280 -0
  38. package/core/src/assets/blob-store.ts +66 -0
  39. package/core/src/assets/cache.ts +186 -0
  40. package/core/src/assets/cubemap-converter.ts +155 -0
  41. package/core/src/assets/environment-manager.ts +121 -0
  42. package/core/src/assets/import-cache.ts +65 -0
  43. package/core/src/assets/import-settings.ts +72 -0
  44. package/core/src/assets/importer.ts +108 -0
  45. package/core/src/assets/index.ts +74 -0
  46. package/core/src/assets/irradiance-generator.ts +198 -0
  47. package/core/src/assets/loader-audio.ts +86 -0
  48. package/core/src/assets/loader-cubemap.ts +211 -0
  49. package/core/src/assets/loader-dds.ts +236 -0
  50. package/core/src/assets/loader-hdr.ts +474 -0
  51. package/core/src/assets/loader-mesh.ts +143 -0
  52. package/core/src/assets/loader-shader.ts +73 -0
  53. package/core/src/assets/loader-texture.ts +349 -0
  54. package/core/src/assets/lod.ts +198 -0
  55. package/core/src/assets/manager.ts +480 -0
  56. package/core/src/assets/manifest.ts +81 -0
  57. package/core/src/assets/material-bridge.ts +186 -0
  58. package/core/src/assets/model-importer.ts +72 -0
  59. package/core/src/assets/model-normalizer.ts +248 -0
  60. package/core/src/assets/model-to-gpu.ts +70 -0
  61. package/core/src/assets/model-to-mesh.ts +237 -0
  62. package/core/src/assets/prefilter-generator.ts +250 -0
  63. package/core/src/audio/engine.ts +177 -0
  64. package/core/src/audio/interface.ts +130 -0
  65. package/core/src/audio/listener.ts +32 -0
  66. package/core/src/audio/mixer.ts +141 -0
  67. package/core/src/audio/registry.ts +52 -0
  68. package/core/src/audio/sab.ts +87 -0
  69. package/core/src/audio/source.ts +89 -0
  70. package/core/src/change-detection/atomics.ts +1 -0
  71. package/core/src/change-detection/tracker.ts +47 -0
  72. package/core/src/debug-draw/lines.ts +64 -0
  73. package/core/src/debug-draw/points.ts +17 -0
  74. package/core/src/debug-draw/queue.ts +124 -0
  75. package/core/src/debug-draw/text.ts +25 -0
  76. package/core/src/ecs/archetype.ts +323 -0
  77. package/core/src/ecs/component.ts +188 -0
  78. package/core/src/ecs/entity.ts +25 -0
  79. package/core/src/ecs/events.ts +93 -0
  80. package/core/src/ecs/hierarchy.ts +124 -0
  81. package/core/src/ecs/hmr-swap-registry.ts +22 -0
  82. package/core/src/ecs/index.ts +25 -0
  83. package/core/src/ecs/query.ts +141 -0
  84. package/core/src/ecs/resource.ts +8 -0
  85. package/core/src/ecs/schedule.ts +181 -0
  86. package/core/src/ecs/system-params.ts +99 -0
  87. package/core/src/ecs/system.ts +42 -0
  88. package/core/src/ecs/world.ts +348 -0
  89. package/core/src/index.ts +352 -0
  90. package/core/src/input/context.ts +73 -0
  91. package/core/src/input/dom-handler.ts +380 -0
  92. package/core/src/input/local-player-manager.ts +218 -0
  93. package/core/src/input/mapping.ts +40 -0
  94. package/core/src/input/multi-sab-bridge.ts +276 -0
  95. package/core/src/input/multi-state.ts +54 -0
  96. package/core/src/input/sab-bridge.ts +71 -0
  97. package/core/src/input/state.ts +132 -0
  98. package/core/src/input/ui-router.ts +87 -0
  99. package/core/src/library/host.ts +317 -0
  100. package/core/src/library/index.ts +16 -0
  101. package/core/src/library/library.ts +292 -0
  102. package/core/src/material/compiler.ts +80 -0
  103. package/core/src/material/graph-bridge.ts +172 -0
  104. package/core/src/material/index.ts +9 -0
  105. package/core/src/material/library.ts +442 -0
  106. package/core/src/material/material.ts +156 -0
  107. package/core/src/material/variants.ts +61 -0
  108. package/core/src/math/mat4.ts +202 -0
  109. package/core/src/math/perlin-noise-2d.ts +77 -0
  110. package/core/src/math/perlin-noise-3d.ts +110 -0
  111. package/core/src/math/quat.ts +33 -0
  112. package/core/src/math/rng.ts +29 -0
  113. package/core/src/math/trig.ts +47 -0
  114. package/core/src/math/value-noise.ts +67 -0
  115. package/core/src/mesh/builder.ts +177 -0
  116. package/core/src/mesh/csg.ts +312 -0
  117. package/core/src/mesh/greased-line.ts +145 -0
  118. package/core/src/mesh/mesh.ts +17 -0
  119. package/core/src/mesh/parametric.ts +501 -0
  120. package/core/src/mesh/skinning.ts +67 -0
  121. package/core/src/mesh/vertex-layout.ts +91 -0
  122. package/core/src/module/cross-thread.ts +163 -0
  123. package/core/src/module/diagnostics.ts +123 -0
  124. package/core/src/module/host.ts +451 -0
  125. package/core/src/module/index.ts +22 -0
  126. package/core/src/module/module.ts +109 -0
  127. package/core/src/module/registry.ts +94 -0
  128. package/core/src/module/renderer-module.ts +247 -0
  129. package/core/src/module/ts-loader.ts +26 -0
  130. package/core/src/particles/compute-pass.ts +378 -0
  131. package/core/src/particles/emitter.ts +156 -0
  132. package/core/src/particles/index.ts +11 -0
  133. package/core/src/particles/particle-data.ts +47 -0
  134. package/core/src/particles/render-pass.ts +365 -0
  135. package/core/src/particles/simulator.ts +264 -0
  136. package/core/src/particles/system.ts +193 -0
  137. package/core/src/physics/body.ts +59 -0
  138. package/core/src/physics/ccd-heuristic.ts +55 -0
  139. package/core/src/physics/character.ts +282 -0
  140. package/core/src/physics/collider.ts +55 -0
  141. package/core/src/physics/collision-system.ts +91 -0
  142. package/core/src/physics/events.ts +133 -0
  143. package/core/src/physics/index.ts +34 -0
  144. package/core/src/physics/interface.ts +473 -0
  145. package/core/src/physics/interpolation-buffer.ts +192 -0
  146. package/core/src/physics/lifecycle.ts +87 -0
  147. package/core/src/physics/load-shedder.ts +164 -0
  148. package/core/src/physics/physics-accumulator.ts +101 -0
  149. package/core/src/physics/physics-system.ts +240 -0
  150. package/core/src/physics/ragdoll-presets.ts +272 -0
  151. package/core/src/physics/ragdoll-system.ts +220 -0
  152. package/core/src/physics/ragdoll.ts +182 -0
  153. package/core/src/physics/raycast.ts +143 -0
  154. package/core/src/physics/realm-manager.ts +499 -0
  155. package/core/src/physics/realm-worker-pool.ts +191 -0
  156. package/core/src/physics/realm-worker.ts +102 -0
  157. package/core/src/physics/realm.ts +189 -0
  158. package/core/src/physics/registry.ts +52 -0
  159. package/core/src/physics/safety.ts +247 -0
  160. package/core/src/physics/snapshot-manager.ts +141 -0
  161. package/core/src/physics/worker-protocol.ts +30 -0
  162. package/core/src/platform/bun-preload.ts +169 -0
  163. package/core/src/platform/css-stub.ts +4 -0
  164. package/core/src/platform/glob-polyfill.ts +124 -0
  165. package/core/src/platform/hidpi.ts +57 -0
  166. package/core/src/platform/render-surface.ts +77 -0
  167. package/core/src/platform/rpc.ts +98 -0
  168. package/core/src/platform/runtime.ts +123 -0
  169. package/core/src/plugin/context.ts +364 -0
  170. package/core/src/plugin/diagnostics.ts +61 -0
  171. package/core/src/plugin/discovery.ts +186 -0
  172. package/core/src/plugin/extension-loaders.ts +172 -0
  173. package/core/src/plugin/host.ts +659 -0
  174. package/core/src/plugin/index.ts +106 -0
  175. package/core/src/plugin/loader-asset.ts +124 -0
  176. package/core/src/plugin/loader-quickjs.ts +84 -0
  177. package/core/src/plugin/loader-wasm.ts +411 -0
  178. package/core/src/plugin/loader-worker.ts +261 -0
  179. package/core/src/plugin/manifest.ts +653 -0
  180. package/core/src/plugin/material-registry.ts +65 -0
  181. package/core/src/plugin/mcp-tools.ts +165 -0
  182. package/core/src/plugin/permissions.ts +175 -0
  183. package/core/src/plugin/quickjs-bridge.ts +294 -0
  184. package/core/src/plugin/registry.ts +107 -0
  185. package/core/src/plugin/sandbox-shim.ts +86 -0
  186. package/core/src/plugin/sandbox-worker.ts +215 -0
  187. package/core/src/plugin/wasm-abi.ts +152 -0
  188. package/core/src/plugin/wasm-worker.ts +229 -0
  189. package/core/src/plugin/workshop.ts +169 -0
  190. package/core/src/profiling/event-loop.ts +180 -0
  191. package/core/src/profiling/index.ts +69 -0
  192. package/core/src/profiling/iops/idb-patch.ts +242 -0
  193. package/core/src/profiling/iops/opfs-patch.ts +276 -0
  194. package/core/src/profiling/profiling-sab.ts +839 -0
  195. package/core/src/profiling/task-latency.ts +134 -0
  196. package/core/src/profiling/thread-metrics.ts +126 -0
  197. package/core/src/profiling/trace-event-writer.ts +205 -0
  198. package/core/src/profiling/warnings.ts +423 -0
  199. package/core/src/profiling/worker-prelude.ts +376 -0
  200. package/core/src/render/bind-group.ts +38 -0
  201. package/core/src/render/bindless/bindless-struct.ts +42 -0
  202. package/core/src/render/bindless/bindless.wgsl.ts +167 -0
  203. package/core/src/render/bindless/frame-bindings.ts +176 -0
  204. package/core/src/render/bindless/index.ts +10 -0
  205. package/core/src/render/bindless/material-manager.ts +257 -0
  206. package/core/src/render/bindless/texture-registry.ts +609 -0
  207. package/core/src/render/buffer.ts +82 -0
  208. package/core/src/render/camera-2d.ts +217 -0
  209. package/core/src/render/camera-controller.ts +440 -0
  210. package/core/src/render/camera.ts +409 -0
  211. package/core/src/render/canvas-resize-watcher.ts +46 -0
  212. package/core/src/render/compute-kernel.ts +172 -0
  213. package/core/src/render/constants.ts +2 -0
  214. package/core/src/render/device.ts +111 -0
  215. package/core/src/render/frame-graph.ts +768 -0
  216. package/core/src/render/frustum.ts +185 -0
  217. package/core/src/render/fullscreen-vs.ts +25 -0
  218. package/core/src/render/g-buffer.ts +186 -0
  219. package/core/src/render/game-renderer.ts +1452 -0
  220. package/core/src/render/gpu-driven/cull-pass.ts +394 -0
  221. package/core/src/render/gpu-driven/hzb.ts +215 -0
  222. package/core/src/render/gpu-driven/index.ts +7 -0
  223. package/core/src/render/gpu-driven/indirect-draw-pass.ts +324 -0
  224. package/core/src/render/gpu-driven/instance-buffer.ts +178 -0
  225. package/core/src/render/gpu-driven/mesh-table.ts +175 -0
  226. package/core/src/render/gpu-driven/passes/hzb-build-pass.ts +47 -0
  227. package/core/src/render/gpu-utils.ts +96 -0
  228. package/core/src/render/hdr.ts +88 -0
  229. package/core/src/render/hot-reload.ts +295 -0
  230. package/core/src/render/ibl-bind-group.ts +266 -0
  231. package/core/src/render/ibl.ts +180 -0
  232. package/core/src/render/index.ts +163 -0
  233. package/core/src/render/input-manager.ts +259 -0
  234. package/core/src/render/lighting/area-light.ts +196 -0
  235. package/core/src/render/lighting/cluster-grid.ts +288 -0
  236. package/core/src/render/lighting/cluster-types.ts +193 -0
  237. package/core/src/render/lighting/ies-parser.ts +162 -0
  238. package/core/src/render/lighting.ts +454 -0
  239. package/core/src/render/material-types/depth.wgsl +44 -0
  240. package/core/src/render/material-types/line.wgsl +50 -0
  241. package/core/src/render/material-types/matcap.wgsl +51 -0
  242. package/core/src/render/material-types/normal.wgsl +41 -0
  243. package/core/src/render/material-types/physical.wgsl +152 -0
  244. package/core/src/render/material-types/sprite.wgsl +46 -0
  245. package/core/src/render/material-types/sss.wgsl +79 -0
  246. package/core/src/render/material-types/toon.wgsl +79 -0
  247. package/core/src/render/passes/README.md +121 -0
  248. package/core/src/render/passes/atmosphere.ts +152 -0
  249. package/core/src/render/passes/cluster-lighting-pass.ts +476 -0
  250. package/core/src/render/passes/csm.ts +408 -0
  251. package/core/src/render/passes/cubemap-capture.ts +114 -0
  252. package/core/src/render/passes/debug-viz.ts +278 -0
  253. package/core/src/render/passes/debug.ts +538 -0
  254. package/core/src/render/passes/decal-mesh.ts +111 -0
  255. package/core/src/render/passes/decal-pass.ts +377 -0
  256. package/core/src/render/passes/deferred-lighting.ts +434 -0
  257. package/core/src/render/passes/depth-prepass.ts +163 -0
  258. package/core/src/render/passes/dome-360.ts +83 -0
  259. package/core/src/render/passes/fluid-render.ts +137 -0
  260. package/core/src/render/passes/gi-types.ts +118 -0
  261. package/core/src/render/passes/graph-compute.ts +300 -0
  262. package/core/src/render/passes/greased-line-pass.ts +232 -0
  263. package/core/src/render/passes/morph-target.ts +40 -0
  264. package/core/src/render/passes/opaque.ts +1028 -0
  265. package/core/src/render/passes/point-light-shadow.ts +266 -0
  266. package/core/src/render/passes/procedural-texture.ts +185 -0
  267. package/core/src/render/passes/reflection-probe.ts +140 -0
  268. package/core/src/render/passes/rsm-pass.ts +248 -0
  269. package/core/src/render/passes/sdf-text.ts +155 -0
  270. package/core/src/render/passes/shadow-map.ts +163 -0
  271. package/core/src/render/passes/shadow.ts +220 -0
  272. package/core/src/render/passes/skinning-vs.ts +121 -0
  273. package/core/src/render/passes/skinning.ts +326 -0
  274. package/core/src/render/passes/sky-dome.ts +404 -0
  275. package/core/src/render/passes/skybox.ts +162 -0
  276. package/core/src/render/passes/spot-light-shadow.ts +273 -0
  277. package/core/src/render/passes/terrain.ts +326 -0
  278. package/core/src/render/passes/transparent.ts +353 -0
  279. package/core/src/render/passes/underwater-fog.ts +185 -0
  280. package/core/src/render/passes/video-texture.ts +79 -0
  281. package/core/src/render/passes/volumetric-pass.ts +312 -0
  282. package/core/src/render/passes/volumetric-types.ts +171 -0
  283. package/core/src/render/passes/water.ts +753 -0
  284. package/core/src/render/pbr.ts +296 -0
  285. package/core/src/render/pipeline.ts +52 -0
  286. package/core/src/render/render-pass.ts +30 -0
  287. package/core/src/render/renderer-input-bus.ts +220 -0
  288. package/core/src/render/renderer-module-host.ts +623 -0
  289. package/core/src/render/resource-tracker.ts +67 -0
  290. package/core/src/render/sab-canvas-overlay.ts +122 -0
  291. package/core/src/render/shader-validator.ts +200 -0
  292. package/core/src/render/shaders/debug/debug-line.wgsl +27 -0
  293. package/core/src/render/shaders/debug/debug-point.wgsl +30 -0
  294. package/core/src/render/shaders/debug/debug-text.wgsl +42 -0
  295. package/core/src/render/shaders/debug-viz/aabb.wgsl +20 -0
  296. package/core/src/render/shaders/debug-viz/depth.wgsl +29 -0
  297. package/core/src/render/shaders/debug-viz/lod.wgsl +38 -0
  298. package/core/src/render/shaders/debug-viz/normals.wgsl +30 -0
  299. package/core/src/render/shaders/debug-viz/overdraw.wgsl +21 -0
  300. package/core/src/render/shaders/debug-viz/tangents.wgsl +29 -0
  301. package/core/src/render/shaders/debug-viz/wireframe.wgsl +33 -0
  302. package/core/src/render/shaders/shadow-chunks.ts +135 -0
  303. package/core/src/render/skybox.ts +146 -0
  304. package/core/src/render/splitscreen.ts +85 -0
  305. package/core/src/render/surface.ts +78 -0
  306. package/core/src/render/tonemap.ts +180 -0
  307. package/core/src/render/tracked-render-pass.ts +158 -0
  308. package/core/src/render/viewport.ts +109 -0
  309. package/core/src/render/wgsl-hmr.ts +70 -0
  310. package/core/src/sab/core-input-channel.ts +23 -0
  311. package/core/src/sab/define.ts +239 -0
  312. package/core/src/sab/errors.ts +76 -0
  313. package/core/src/sab/game-input.ts +343 -0
  314. package/core/src/sab/gamepad-devices.ts +259 -0
  315. package/core/src/sab/grid-buffer.ts +117 -0
  316. package/core/src/sab/input.ts +55 -0
  317. package/core/src/sab/layout.ts +219 -0
  318. package/core/src/sab/multi-input-channel.ts +50 -0
  319. package/core/src/sab/record-buffer.ts +155 -0
  320. package/core/src/sab/sab-polyfill.ts +56 -0
  321. package/core/src/sab/sim-channel.ts +453 -0
  322. package/core/src/sab/slot-buffer.ts +190 -0
  323. package/core/src/sab/types.ts +158 -0
  324. package/core/src/safety/bounds.ts +76 -0
  325. package/core/src/safety/json.ts +80 -0
  326. package/core/src/safety/path.ts +167 -0
  327. package/core/src/save/binary-format.ts +117 -0
  328. package/core/src/save/game-save-system.ts +161 -0
  329. package/core/src/save/grid-save-system.ts +158 -0
  330. package/core/src/save/migrate.ts +44 -0
  331. package/core/src/save/migration-registry.ts +94 -0
  332. package/core/src/save/persist-types.ts +208 -0
  333. package/core/src/save/schema.ts +46 -0
  334. package/core/src/save/serializer.ts +180 -0
  335. package/core/src/scene/builder.ts +65 -0
  336. package/core/src/scene/camera.ts +142 -0
  337. package/core/src/scene/checkpoint.ts +109 -0
  338. package/core/src/scene/game-loop.ts +198 -0
  339. package/core/src/scene/index.ts +24 -0
  340. package/core/src/scene/layer.ts +6 -0
  341. package/core/src/scene/prefab.ts +145 -0
  342. package/core/src/scene/scene-manager.ts +157 -0
  343. package/core/src/scene/scene.ts +192 -0
  344. package/core/src/scene/sky.ts +256 -0
  345. package/core/src/scene/spatial-grid.ts +176 -0
  346. package/core/src/scene/streaming.ts +304 -0
  347. package/core/src/scene/vegetation.ts +163 -0
  348. package/core/src/scene/world.ts +89 -0
  349. package/core/src/scripting/binding.ts +129 -0
  350. package/core/src/scripting/hot-reload.ts +144 -0
  351. package/core/src/scripting/script.ts +99 -0
  352. package/core/src/sim/hot-reload-pipeline.ts +49 -0
  353. package/core/src/sim/sim-state-helper.ts +47 -0
  354. package/core/src/sim/transient-state-registry.ts +77 -0
  355. package/core/src/sim/types.ts +113 -0
  356. package/core/src/sim/worker-loop.ts +222 -0
  357. package/core/src/stores/game-store.ts +158 -0
  358. package/core/src/stores/hot-reload-store.ts +44 -0
  359. package/core/src/telemetry/collector.ts +410 -0
  360. package/core/src/telemetry/gc-controller.ts +453 -0
  361. package/core/src/telemetry/gc-profiler.ts +126 -0
  362. package/core/src/telemetry/gc-tracker.ts +69 -0
  363. package/core/src/telemetry/gpu-profiler.ts +703 -0
  364. package/core/src/telemetry/gpu-resource-tracker.ts +285 -0
  365. package/core/src/telemetry/gpu-timer-pool.ts +234 -0
  366. package/core/src/telemetry/gpu-timer.ts +123 -0
  367. package/core/src/telemetry/gpu-timestamp-gate.ts +21 -0
  368. package/core/src/telemetry/reporter.ts +62 -0
  369. package/core/src/types/engine-types.ts +129 -0
  370. package/core/src/ui-font-scale.ts +112 -0
  371. package/core/src/util/broad-phase-grid.ts +82 -0
  372. package/core/src/util/feature-log.ts +220 -0
  373. package/core/src/util/index.ts +17 -0
  374. package/core/src/util/logger.ts +604 -0
  375. package/core/src/webgpu-destroy-augmentation.d.ts +25 -0
  376. package/core/src/worker/base-worker-host.ts +183 -0
  377. package/core/src/worker/buffer-sync.ts +550 -0
  378. package/core/src/worker/crash-recovery.ts +201 -0
  379. package/core/src/worker/entity-sim-worker-host.ts +190 -0
  380. package/core/src/worker/instrumented-worker-host.ts +171 -0
  381. package/core/src/worker/rpc.ts +253 -0
  382. package/core/src/worker/sim-worker-base.ts +913 -0
  383. package/core/src/worker/sim-worker-host.ts +358 -0
  384. package/core/src/worker/task-pool.ts +256 -0
  385. package/core/src/worker/task-worker.ts +83 -0
  386. package/libraries/asset-browser/src/index.ts +11 -0
  387. package/libraries/asset-browser/src/software-thumbnails.ts +949 -0
  388. package/libraries/audio-kira/README.md +17 -0
  389. package/libraries/audio-kira/native/Cargo.toml +14 -0
  390. package/libraries/audio-kira/native/src/engine.rs +27 -0
  391. package/libraries/audio-kira/native/src/lib.rs +185 -0
  392. package/libraries/audio-kira/native/src/mixer.rs +11 -0
  393. package/libraries/audio-kira/native/src/source.rs +80 -0
  394. package/libraries/audio-kira/src/backend.ts +469 -0
  395. package/libraries/audio-kira/src/index.ts +8 -0
  396. package/libraries/audio-kira/src/library.ts +82 -0
  397. package/libraries/blitz-ui/native/Cargo.toml +33 -0
  398. package/libraries/blitz-ui/native/assets/DejaVuSans.woff2 +0 -0
  399. package/libraries/blitz-ui/native/src/bridge.rs +100 -0
  400. package/libraries/blitz-ui/native/src/fonts.rs +20 -0
  401. package/libraries/blitz-ui/native/src/input.rs +80 -0
  402. package/libraries/blitz-ui/native/src/lib.rs +96 -0
  403. package/libraries/blitz-ui/native/src/shell.rs +301 -0
  404. package/libraries/blitz-ui/native-osr/Cargo.toml +24 -0
  405. package/libraries/blitz-ui/native-osr/src/events.rs +237 -0
  406. package/libraries/blitz-ui/native-osr/src/lib.rs +846 -0
  407. package/libraries/blitz-ui/native-osr/src/mutate.rs +385 -0
  408. package/libraries/blitz-ui/native-osr/src/resources.rs +45 -0
  409. package/libraries/blitz-ui/native-osr-spike.ts +70 -0
  410. package/libraries/blitz-ui/src/index.ts +15 -0
  411. package/libraries/blitz-ui/src/native-module.ts +221 -0
  412. package/libraries/blitz-ui/src/native-osr-ffi.ts +423 -0
  413. package/libraries/blitz-ui/src/router.ts +101 -0
  414. package/libraries/blitz-ui/src/shaders/ui-blit.wgsl.ts +35 -0
  415. package/libraries/blitz-ui/src/ui-blit-pass.ts +116 -0
  416. package/libraries/character/README.md +25 -0
  417. package/libraries/character/src/character-animator.ts +374 -0
  418. package/libraries/character/src/index.ts +24 -0
  419. package/libraries/character/src/loader.ts +375 -0
  420. package/libraries/character/src/locomotion.ts +124 -0
  421. package/libraries/character/src/preview.ts +287 -0
  422. package/libraries/devtools/README.md +51 -0
  423. package/libraries/devtools/native/Cargo.toml +12 -0
  424. package/libraries/devtools/native/src/lib.rs +1646 -0
  425. package/libraries/devtools/native/src/panels/console.rs +338 -0
  426. package/libraries/devtools/native/src/panels/dom_tree.rs +47 -0
  427. package/libraries/devtools/native/src/panels/generic.rs +317 -0
  428. package/libraries/devtools/native/src/panels/gpu.rs +107 -0
  429. package/libraries/devtools/native/src/panels/input.rs +88 -0
  430. package/libraries/devtools/native/src/panels/mod.rs +154 -0
  431. package/libraries/devtools/native/src/panels/perf_metrics.rs +91 -0
  432. package/libraries/devtools/native/src/panels/perf_recorder.rs +158 -0
  433. package/libraries/devtools/native/src/panels/scene.rs +72 -0
  434. package/libraries/devtools/native/src/state.rs +394 -0
  435. package/libraries/devtools/src/cdp-bridge.ts +349 -0
  436. package/libraries/devtools/src/collectors.ts +346 -0
  437. package/libraries/devtools/src/egui-ffi.ts +804 -0
  438. package/libraries/devtools/src/egui-renderer.ts +407 -0
  439. package/libraries/devtools/src/host.ts +363 -0
  440. package/libraries/devtools/src/index.ts +40 -0
  441. package/libraries/devtools/src/mirror.ts +794 -0
  442. package/libraries/devtools/src/native-providers.ts +744 -0
  443. package/libraries/devtools/src/verify.ts +167 -0
  444. package/libraries/devtools/src/web/browser.ts +102 -0
  445. package/libraries/devtools/src/web/host.ts +212 -0
  446. package/libraries/devtools/src/web/mirror.ts +430 -0
  447. package/libraries/devtools/src/web/server.ts +198 -0
  448. package/libraries/entities/README.md +17 -0
  449. package/libraries/entities/src/index.ts +4 -0
  450. package/libraries/entities/src/library.ts +64 -0
  451. package/libraries/entities/src/model-renderer.ts +1345 -0
  452. package/libraries/entities/src/shaders/model.wgsl +375 -0
  453. package/libraries/gamepad/src/feed-input.ts +83 -0
  454. package/libraries/gamepad/src/filters.ts +49 -0
  455. package/libraries/gamepad/src/glyphs.ts +93 -0
  456. package/libraries/gamepad/src/hub.ts +206 -0
  457. package/libraries/gamepad/src/index.ts +22 -0
  458. package/libraries/gamepad/src/library.ts +68 -0
  459. package/libraries/gamepad/src/source-sab.ts +70 -0
  460. package/libraries/gamepad/src/sysfs-enrich.ts +138 -0
  461. package/libraries/gaussian-splats/README.md +25 -0
  462. package/libraries/gaussian-splats/src/gpu-sort.ts +595 -0
  463. package/libraries/gaussian-splats/src/index.ts +31 -0
  464. package/libraries/gaussian-splats/src/library.ts +60 -0
  465. package/libraries/gaussian-splats/src/parser.ts +382 -0
  466. package/libraries/gaussian-splats/src/renderer.ts +427 -0
  467. package/libraries/gaussian-splats/src/sh-eval.ts +211 -0
  468. package/libraries/gaussian-splats/src/sorter.ts +110 -0
  469. package/libraries/gaussian-splats/src/tile-raster.ts +473 -0
  470. package/libraries/gpu-kernels/README.md +154 -0
  471. package/libraries/gpu-kernels/src/index.ts +11 -0
  472. package/libraries/gpu-kernels/src/kernel.ts +696 -0
  473. package/libraries/gpu-kernels/src/transpile.ts +958 -0
  474. package/libraries/html-ui-kit/src/behaviors.ts +250 -0
  475. package/libraries/html-ui-kit/src/components.ts +309 -0
  476. package/libraries/html-ui-kit/src/index.ts +30 -0
  477. package/libraries/html-ui-kit/src/nav/nav-controller.ts +238 -0
  478. package/libraries/html-ui-kit/src/nav/nav-input.ts +145 -0
  479. package/libraries/html-ui-kit/src/nav/osk.ts +153 -0
  480. package/libraries/html-ui-kit/src/nav/router.ts +167 -0
  481. package/libraries/html-ui-kit/src/nav/vcursor.ts +203 -0
  482. package/libraries/html-ui-kit/src/ten-foot.ts +182 -0
  483. package/libraries/html-ui-kit/src/theme.ts +238 -0
  484. package/libraries/lighting/README.md +20 -0
  485. package/libraries/lighting/src/index.ts +5 -0
  486. package/libraries/lighting/src/library.ts +66 -0
  487. package/libraries/lighting/src/light-system.ts +452 -0
  488. package/libraries/lighting/src/lighting-system.ts +68 -0
  489. package/libraries/lighting/src/shaders/light-debug.wgsl +30 -0
  490. package/libraries/marching-cubes/README.md +25 -0
  491. package/libraries/marching-cubes/src/chunked-field.ts +177 -0
  492. package/libraries/marching-cubes/src/deformation.ts +63 -0
  493. package/libraries/marching-cubes/src/generator.ts +407 -0
  494. package/libraries/marching-cubes/src/index.ts +32 -0
  495. package/libraries/marching-cubes/src/library.ts +80 -0
  496. package/libraries/marching-cubes/src/lod.ts +122 -0
  497. package/libraries/marching-cubes/src/marching-tetrahedra.ts +252 -0
  498. package/libraries/marching-cubes/src/sab.ts +45 -0
  499. package/libraries/marching-cubes/src/streaming-config.ts +48 -0
  500. package/libraries/marching-cubes/src/streaming-manager.ts +686 -0
  501. package/libraries/marching-cubes/src/tables.ts +323 -0
  502. package/libraries/marching-cubes/src/types.ts +18 -0
  503. package/libraries/models/README.md +25 -0
  504. package/libraries/models/src/bake-node-transforms.ts +171 -0
  505. package/libraries/models/src/codecs/basisu-codec.ts +180 -0
  506. package/libraries/models/src/codecs/draco-codec.ts +372 -0
  507. package/libraries/models/src/codecs/draco3dgltf.d.ts +40 -0
  508. package/libraries/models/src/codecs/index.ts +22 -0
  509. package/libraries/models/src/codecs/meshopt-codec.ts +91 -0
  510. package/libraries/models/src/codecs/registry.ts +221 -0
  511. package/libraries/models/src/dae.ts +753 -0
  512. package/libraries/models/src/default-part-selection.ts +56 -0
  513. package/libraries/models/src/dxf.ts +200 -0
  514. package/libraries/models/src/fbx/index.ts +457 -0
  515. package/libraries/models/src/fbx/interpreter/animation.ts +431 -0
  516. package/libraries/models/src/fbx/interpreter/blend-shapes.ts +323 -0
  517. package/libraries/models/src/fbx/interpreter/connections.ts +166 -0
  518. package/libraries/models/src/fbx/interpreter/diagnostics.ts +65 -0
  519. package/libraries/models/src/fbx/interpreter/geometry.ts +535 -0
  520. package/libraries/models/src/fbx/interpreter/global-settings.ts +92 -0
  521. package/libraries/models/src/fbx/interpreter/materials.ts +265 -0
  522. package/libraries/models/src/fbx/interpreter/nodes.ts +197 -0
  523. package/libraries/models/src/fbx/interpreter/skeleton.ts +476 -0
  524. package/libraries/models/src/fbx/parsers/binary-parser.ts +244 -0
  525. package/libraries/models/src/fbx/types.ts +119 -0
  526. package/libraries/models/src/gltf-extensions.ts +196 -0
  527. package/libraries/models/src/gltf.ts +935 -0
  528. package/libraries/models/src/index.ts +87 -0
  529. package/libraries/models/src/library.ts +75 -0
  530. package/libraries/models/src/loader.ts +265 -0
  531. package/libraries/models/src/material-adapter.ts +108 -0
  532. package/libraries/models/src/mini-xml.ts +174 -0
  533. package/libraries/models/src/normalize.ts +216 -0
  534. package/libraries/models/src/obj.ts +264 -0
  535. package/libraries/models/src/off.ts +95 -0
  536. package/libraries/models/src/ply.ts +348 -0
  537. package/libraries/models/src/pose-sampler.ts +219 -0
  538. package/libraries/models/src/sidecar/blender-extras.ts +37 -0
  539. package/libraries/models/src/sidecar/ddmeta.ts +114 -0
  540. package/libraries/models/src/sidecar/godot-import.ts +86 -0
  541. package/libraries/models/src/sidecar/resolver.ts +145 -0
  542. package/libraries/models/src/sidecar/types.ts +11 -0
  543. package/libraries/models/src/sidecar/unity-meta.ts +61 -0
  544. package/libraries/models/src/skeleton-synthesis.ts +132 -0
  545. package/libraries/models/src/stl.ts +149 -0
  546. package/libraries/models/src/threeds.ts +363 -0
  547. package/libraries/models/src/threemf.ts +201 -0
  548. package/libraries/models/src/types.ts +188 -0
  549. package/libraries/models/src/vtk.ts +218 -0
  550. package/libraries/models/test-fixtures/fbx/LICENSE-notice.txt +24 -0
  551. package/libraries/models/test-fixtures/fbx/README.md +46 -0
  552. package/libraries/models/test-fixtures/fbx/m01_cube_phong.fbx +0 -0
  553. package/libraries/models/test-fixtures/fbx/m02_geo_ngons.fbx +0 -0
  554. package/libraries/models/test-fixtures/fbx/m03_normals.fbx +0 -0
  555. package/libraries/models/test-fixtures/fbx/m04_material_properties.fbx +0 -0
  556. package/libraries/models/test-fixtures/fbx/m05_external_diffuse.png +0 -0
  557. package/libraries/models/test-fixtures/fbx/m05_textures.fbx +0 -0
  558. package/libraries/models/test-fixtures/fbx/m06_uv_transform.fbx +0 -0
  559. package/libraries/models/test-fixtures/fbx/m07_multimaterial.fbx +0 -0
  560. package/libraries/models/test-fixtures/fbx/m08_transforms.fbx +0 -0
  561. package/libraries/models/test-fixtures/fbx/m09_skinning.fbx +0 -0
  562. package/libraries/models/test-fixtures/fbx/m10_morph.fbx +0 -0
  563. package/libraries/models/test-fixtures/fbx/m11_node_anim.fbx +0 -0
  564. package/libraries/models/test-fixtures/fbx/m12_skeletal_anim.fbx +0 -0
  565. package/libraries/models/test-fixtures/fbx/m13_morph_anim.fbx +0 -0
  566. package/libraries/models/test-fixtures/fbx/m14_multiclip.fbx +0 -0
  567. package/libraries/models/test-fixtures/fbx/m15_camera_lights.fbx +0 -0
  568. package/libraries/models/test-fixtures/fbx/m16_axis_yup.fbx +0 -0
  569. package/libraries/models/test-fixtures/fbx/m16_axis_zup.fbx +0 -0
  570. package/libraries/models/test-fixtures/fbx/m16_units_254.fbx +0 -0
  571. package/libraries/navmesh/README.md +23 -0
  572. package/libraries/navmesh/src/crowd-system.ts +240 -0
  573. package/libraries/navmesh/src/debug-viz.ts +74 -0
  574. package/libraries/navmesh/src/index.ts +15 -0
  575. package/libraries/navmesh/src/library.ts +64 -0
  576. package/libraries/navmesh/src/navmesh-generator.ts +407 -0
  577. package/libraries/navmesh/src/navmesh.ts +159 -0
  578. package/libraries/navmesh/src/pathfinder.ts +252 -0
  579. package/libraries/navmesh/src/types.ts +63 -0
  580. package/libraries/networking/README.md +25 -0
  581. package/libraries/networking/src/authority.ts +121 -0
  582. package/libraries/networking/src/connection.ts +139 -0
  583. package/libraries/networking/src/discovery.ts +373 -0
  584. package/libraries/networking/src/enhanced-replication.ts +355 -0
  585. package/libraries/networking/src/epic-adapter.ts +129 -0
  586. package/libraries/networking/src/index.ts +45 -0
  587. package/libraries/networking/src/library.ts +69 -0
  588. package/libraries/networking/src/lobby.ts +108 -0
  589. package/libraries/networking/src/platform-adapter.ts +163 -0
  590. package/libraries/networking/src/rcs-adapter.ts +127 -0
  591. package/libraries/networking/src/remote-input.ts +188 -0
  592. package/libraries/networking/src/replication.ts +327 -0
  593. package/libraries/networking/src/rpc.ts +188 -0
  594. package/libraries/networking/src/session.ts +173 -0
  595. package/libraries/networking/src/transport.ts +201 -0
  596. package/libraries/networking/src/webrtc.ts +323 -0
  597. package/libraries/pathfinding-2d/README.md +15 -0
  598. package/libraries/pathfinding-2d/src/astar-grid.ts +312 -0
  599. package/libraries/pathfinding-2d/src/index.ts +11 -0
  600. package/libraries/persistence/README.md +25 -0
  601. package/libraries/persistence/src/autosave-manager.ts +112 -0
  602. package/libraries/persistence/src/binary-record-store.ts +244 -0
  603. package/libraries/persistence/src/browser.ts +51 -0
  604. package/libraries/persistence/src/file-save-store.ts +553 -0
  605. package/libraries/persistence/src/hash-utils.ts +59 -0
  606. package/libraries/persistence/src/index.ts +57 -0
  607. package/libraries/persistence/src/library.ts +74 -0
  608. package/libraries/persistence/src/mock-opfs.ts +141 -0
  609. package/libraries/persistence/src/node-fs-directory-handle.ts +161 -0
  610. package/libraries/persistence/src/opfs-save-store.ts +745 -0
  611. package/libraries/persistence/src/save-worker-proxy.ts +127 -0
  612. package/libraries/persistence/src/save-worker.ts +99 -0
  613. package/libraries/persistence/src/xxh3-ts.d.ts +10 -0
  614. package/libraries/physics-native/README.md +21 -0
  615. package/libraries/physics-native/native/Cargo.toml +11 -0
  616. package/libraries/physics-native/native/src/body.rs +403 -0
  617. package/libraries/physics-native/native/src/character.rs +226 -0
  618. package/libraries/physics-native/native/src/collider.rs +299 -0
  619. package/libraries/physics-native/native/src/joint.rs +81 -0
  620. package/libraries/physics-native/native/src/lib.rs +830 -0
  621. package/libraries/physics-native/native/src/query.rs +261 -0
  622. package/libraries/physics-native/native/src/realm.rs +33 -0
  623. package/libraries/physics-native/native/src/step.rs +54 -0
  624. package/libraries/physics-native/native/src/world.rs +148 -0
  625. package/libraries/physics-native/src/backend.ts +1046 -0
  626. package/libraries/physics-native/src/broadphase.ts +101 -0
  627. package/libraries/physics-native/src/ffi-spike-worker.ts +71 -0
  628. package/libraries/physics-native/src/index.ts +11 -0
  629. package/libraries/physics-native/src/library.ts +79 -0
  630. package/libraries/physics-native/src/narrowphase-shapes.ts +420 -0
  631. package/libraries/physics-native/src/narrowphase.ts +123 -0
  632. package/libraries/physics-native/src/solver.ts +141 -0
  633. package/libraries/physics-native/src/types.ts +76 -0
  634. package/libraries/physics-rapier/README.md +21 -0
  635. package/libraries/physics-rapier/bench/ffi-bench.ts +79 -0
  636. package/libraries/physics-rapier/bench/wasm-baseline.ts +90 -0
  637. package/libraries/physics-rapier/src/api.ts +452 -0
  638. package/libraries/physics-rapier/src/auto-backend.ts +59 -0
  639. package/libraries/physics-rapier/src/backend.ts +1207 -0
  640. package/libraries/physics-rapier/src/bulk-ops.ts +68 -0
  641. package/libraries/physics-rapier/src/ffi-backend.ts +21 -0
  642. package/libraries/physics-rapier/src/ffi-lib.ts +597 -0
  643. package/libraries/physics-rapier/src/index.ts +12 -0
  644. package/libraries/physics-rapier/src/library.ts +107 -0
  645. package/libraries/physics-rapier/src/rapier-backend.ts +1052 -0
  646. package/libraries/physics-rapier/src/realm-worker-script.ts +237 -0
  647. package/libraries/postfx/README.md +17 -0
  648. package/libraries/postfx/src/index.ts +19 -0
  649. package/libraries/postfx/src/library.ts +337 -0
  650. package/libraries/postfx/src/post-process-stack.ts +1752 -0
  651. package/libraries/postfx/src/shaders/post-process/afterimage.wgsl +14 -0
  652. package/libraries/postfx/src/shaders/post-process/ascii.wgsl +24 -0
  653. package/libraries/postfx/src/shaders/post-process/blit.wgsl +12 -0
  654. package/libraries/postfx/src/shaders/post-process/bloom-blur.wgsl +21 -0
  655. package/libraries/postfx/src/shaders/post-process/bloom-bright.wgsl +15 -0
  656. package/libraries/postfx/src/shaders/post-process/bloom-composite.wgsl +14 -0
  657. package/libraries/postfx/src/shaders/post-process/bloom-downsample.wgsl +60 -0
  658. package/libraries/postfx/src/shaders/post-process/bloom-soft.wgsl +46 -0
  659. package/libraries/postfx/src/shaders/post-process/bloom-upsample.wgsl +51 -0
  660. package/libraries/postfx/src/shaders/post-process/channel-mixer.wgsl +36 -0
  661. package/libraries/postfx/src/shaders/post-process/chromatic-aberration.wgsl +37 -0
  662. package/libraries/postfx/src/shaders/post-process/dithering.wgsl +64 -0
  663. package/libraries/postfx/src/shaders/post-process/dof.wgsl +131 -0
  664. package/libraries/postfx/src/shaders/post-process/edges.wgsl +45 -0
  665. package/libraries/postfx/src/shaders/post-process/fullscreen-vs.wgsl +15 -0
  666. package/libraries/postfx/src/shaders/post-process/fxaa.wgsl +102 -0
  667. package/libraries/postfx/src/shaders/post-process/gaussian-blur.wgsl +37 -0
  668. package/libraries/postfx/src/shaders/post-process/glow-blur.wgsl +33 -0
  669. package/libraries/postfx/src/shaders/post-process/glow-composite.wgsl +25 -0
  670. package/libraries/postfx/src/shaders/post-process/grain.wgsl +37 -0
  671. package/libraries/postfx/src/shaders/post-process/halftone.wgsl +80 -0
  672. package/libraries/postfx/src/shaders/post-process/highlight-blur.wgsl +33 -0
  673. package/libraries/postfx/src/shaders/post-process/highlight-composite.wgsl +32 -0
  674. package/libraries/postfx/src/shaders/post-process/lens-distortion.wgsl +43 -0
  675. package/libraries/postfx/src/shaders/post-process/lens-flare.wgsl +68 -0
  676. package/libraries/postfx/src/shaders/post-process/lut.wgsl +30 -0
  677. package/libraries/postfx/src/shaders/post-process/motion-blur.wgsl +55 -0
  678. package/libraries/postfx/src/shaders/post-process/occluder-chunk.wgsl +28 -0
  679. package/libraries/postfx/src/shaders/post-process/outline.wgsl +51 -0
  680. package/libraries/postfx/src/shaders/post-process/pixelation.wgsl +47 -0
  681. package/libraries/postfx/src/shaders/post-process/sharpen.wgsl +32 -0
  682. package/libraries/postfx/src/shaders/post-process/sobel.wgsl +26 -0
  683. package/libraries/postfx/src/shaders/post-process/split-tone.wgsl +36 -0
  684. package/libraries/postfx/src/shaders/post-process/ssao-blur.wgsl +38 -0
  685. package/libraries/postfx/src/shaders/post-process/ssao-composite.wgsl +25 -0
  686. package/libraries/postfx/src/shaders/post-process/ssao.wgsl +147 -0
  687. package/libraries/postfx/src/shaders/post-process/ssr.wgsl +155 -0
  688. package/libraries/postfx/src/shaders/post-process/taa.wgsl +98 -0
  689. package/libraries/postfx/src/shaders/post-process/tonemap.wgsl +40 -0
  690. package/libraries/postfx/src/shaders/post-process/watercolor.wgsl +82 -0
  691. package/libraries/postfx/src/shaders/post-process/white-balance.wgsl +41 -0
  692. package/libraries/recast/README.md +21 -0
  693. package/libraries/recast/src/backend.ts +150 -0
  694. package/libraries/recast/src/crowd-system.ts +352 -0
  695. package/libraries/recast/src/index.ts +12 -0
  696. package/libraries/recast/src/library.ts +91 -0
  697. package/libraries/recast/src/types.ts +86 -0
  698. package/libraries/sand/README.md +25 -0
  699. package/libraries/sand/src/cell.ts +43 -0
  700. package/libraries/sand/src/fields.ts +29 -0
  701. package/libraries/sand/src/fluid-grid.ts +261 -0
  702. package/libraries/sand/src/grid-dims.ts +74 -0
  703. package/libraries/sand/src/grid-sim-buffer.ts +271 -0
  704. package/libraries/sand/src/index.ts +81 -0
  705. package/libraries/sand/src/library.ts +92 -0
  706. package/libraries/sand/src/materials.ts +492 -0
  707. package/libraries/sand/src/palette.ts +93 -0
  708. package/libraries/sand/src/particles.ts +185 -0
  709. package/libraries/sand/src/render/sand-grid-pass.ts +430 -0
  710. package/libraries/sand/src/rng.ts +51 -0
  711. package/libraries/sand/src/rules/builtin-rules.ts +132 -0
  712. package/libraries/sand/src/rules/rule-compiler.ts +162 -0
  713. package/libraries/sand/src/rules/rule-engine.ts +231 -0
  714. package/libraries/sand/src/rules/rule-types.ts +87 -0
  715. package/libraries/sand/src/sand-step-pool.ts +484 -0
  716. package/libraries/sand/src/sand-step-worker.ts +97 -0
  717. package/libraries/sand/src/sand-world.ts +3227 -0
  718. package/libraries/stickman/README.md +25 -0
  719. package/libraries/stickman/src/index.ts +25 -0
  720. package/libraries/stickman/src/library.ts +61 -0
  721. package/libraries/stickman/src/proportions.ts +45 -0
  722. package/libraries/stickman/src/shader.ts +117 -0
  723. package/libraries/stickman/src/skeleton.ts +197 -0
  724. package/libraries/stickman/src/stickman-pass.ts +255 -0
  725. package/libraries/stickman/src/thick-line.ts +123 -0
  726. package/libraries/surface-nets/README.md +25 -0
  727. package/libraries/surface-nets/src/chunked-field.ts +14 -0
  728. package/libraries/surface-nets/src/deformation.ts +45 -0
  729. package/libraries/surface-nets/src/index.ts +36 -0
  730. package/libraries/surface-nets/src/library.ts +59 -0
  731. package/libraries/surface-nets/src/lod.ts +7 -0
  732. package/libraries/surface-nets/src/sab.ts +4 -0
  733. package/libraries/surface-nets/src/streaming-config.ts +5 -0
  734. package/libraries/surface-nets/src/streaming-manager.ts +15 -0
  735. package/libraries/surface-nets/src/surface-nets.ts +334 -0
  736. package/libraries/surface-nets/src/types.ts +23 -0
  737. package/libraries/water/README.md +25 -0
  738. package/libraries/water/src/buoyancy.ts +103 -0
  739. package/libraries/water/src/index.ts +43 -0
  740. package/libraries/water/src/library.ts +85 -0
  741. package/libraries/water/src/shore-damping.ts +93 -0
  742. package/libraries/water/src/water-buffer.ts +89 -0
  743. package/libraries/water/src/water-chunks.ts +13 -0
  744. package/libraries/water/src/water-physics.ts +376 -0
  745. package/libraries/water/src/water-renderer.ts +809 -0
  746. package/libraries/water/src/water-sab.ts +161 -0
  747. package/libraries/water/src/wave-sources.ts +84 -0
  748. package/libraries/weather/README.md +20 -0
  749. package/libraries/weather/src/index.ts +9 -0
  750. package/libraries/weather/src/library.ts +72 -0
  751. package/libraries/weather/src/types.ts +64 -0
  752. package/libraries/weather/src/weather-blend.ts +112 -0
  753. package/libraries/weather/src/weather-system.ts +271 -0
  754. package/libraries/weatherfx/README.md +24 -0
  755. package/libraries/weatherfx/src/cloud-provider.ts +31 -0
  756. package/libraries/weatherfx/src/cloud-system.ts +372 -0
  757. package/libraries/weatherfx/src/index.ts +9 -0
  758. package/libraries/weatherfx/src/library.ts +58 -0
  759. package/libraries/weatherfx/src/particle-system.ts +434 -0
  760. package/libraries/weatherfx/src/shaders/cloud.wgsl +111 -0
  761. package/libraries/weatherfx/src/shaders/particle-compute.wgsl +187 -0
  762. package/libraries/weatherfx/src/shaders/particle-render.wgsl +95 -0
  763. package/lint-plugin.mjs +41 -0
  764. package/mcp/src/client.ts +703 -0
  765. package/mcp/src/engine-context.ts +186 -0
  766. package/mcp/src/http-transport.ts +471 -0
  767. package/mcp/src/index.ts +13 -0
  768. package/mcp/src/prompts/add-entity.ts +42 -0
  769. package/mcp/src/prompts/create-scene.ts +44 -0
  770. package/mcp/src/prompts/debug-frame.ts +39 -0
  771. package/mcp/src/prompts/index.ts +12 -0
  772. package/mcp/src/resources/asset-list.ts +32 -0
  773. package/mcp/src/resources/checkpoint-list.ts +33 -0
  774. package/mcp/src/resources/entity-state.ts +55 -0
  775. package/mcp/src/resources/gpu-info.ts +103 -0
  776. package/mcp/src/resources/index.ts +57 -0
  777. package/mcp/src/resources/performance.ts +37 -0
  778. package/mcp/src/resources/scene-tree.ts +43 -0
  779. package/mcp/src/server.ts +375 -0
  780. package/mcp/src/tools/animation.ts +118 -0
  781. package/mcp/src/tools/asset.ts +161 -0
  782. package/mcp/src/tools/audio.ts +96 -0
  783. package/mcp/src/tools/build.ts +143 -0
  784. package/mcp/src/tools/camera.ts +167 -0
  785. package/mcp/src/tools/checkpoint.ts +100 -0
  786. package/mcp/src/tools/component.ts +199 -0
  787. package/mcp/src/tools/debug.ts +300 -0
  788. package/mcp/src/tools/entity.ts +361 -0
  789. package/mcp/src/tools/inspect.ts +210 -0
  790. package/mcp/src/tools/lighting.ts +263 -0
  791. package/mcp/src/tools/material.ts +243 -0
  792. package/mcp/src/tools/mesh.ts +239 -0
  793. package/mcp/src/tools/physics.ts +266 -0
  794. package/mcp/src/tools/scene.ts +153 -0
  795. package/mcp/src/tools/script.ts +122 -0
  796. package/mcp/src/types.ts +92 -0
  797. package/mcp/src/undo-redo.ts +77 -0
  798. package/modules/camera-controls/README.md +20 -0
  799. package/modules/camera-controls/src/index.ts +161 -0
  800. package/modules/controller-ui/src/index.ts +164 -0
  801. package/modules/devtools/README.md +25 -0
  802. package/modules/devtools/src/api.ts +461 -0
  803. package/modules/devtools/src/asset-utils.ts +105 -0
  804. package/modules/devtools/src/bind-debug-store.ts +48 -0
  805. package/modules/devtools/src/data-bridge.ts +286 -0
  806. package/modules/devtools/src/debug-overlay.ts +238 -0
  807. package/modules/devtools/src/debug-raycast.ts +328 -0
  808. package/modules/devtools/src/debug-store.ts +92 -0
  809. package/modules/devtools/src/debug-view-descriptors.ts +59 -0
  810. package/modules/devtools/src/doctor-panel.ts +182 -0
  811. package/modules/devtools/src/gizmo-module.ts +136 -0
  812. package/modules/devtools/src/graph-model.ts +509 -0
  813. package/modules/devtools/src/grid-renderer.ts +157 -0
  814. package/modules/devtools/src/height-ruler-renderer.ts +216 -0
  815. package/modules/devtools/src/index.ts +81 -0
  816. package/modules/devtools/src/init.ts +261 -0
  817. package/modules/devtools/src/label-overlay.ts +154 -0
  818. package/modules/devtools/src/material-stats-panel.ts +188 -0
  819. package/modules/devtools/src/profiling-bridge.ts +377 -0
  820. package/modules/devtools/src/profiling-hooks.ts +98 -0
  821. package/modules/devtools/src/renderer-adapter.ts +76 -0
  822. package/modules/devtools/src/scene-inspector.ts +637 -0
  823. package/modules/devtools/src/scene-store.ts +320 -0
  824. package/modules/devtools/src/scene-sync.ts +116 -0
  825. package/modules/devtools/src/shaders/transform-gizmo.wgsl +38 -0
  826. package/modules/devtools/src/sim-stats-panel.ts +272 -0
  827. package/modules/devtools/src/sim-stats-provider.ts +105 -0
  828. package/modules/devtools/src/skeleton-renderer.ts +351 -0
  829. package/modules/devtools/src/transform-gizmo.ts +928 -0
  830. package/modules/devtools/src/types.ts +290 -0
  831. package/modules/devtools/src/worker-expose.ts +67 -0
  832. package/modules/devtools/src/worker-sync.ts +137 -0
  833. package/modules/editor/src/commands/component.ts +156 -0
  834. package/modules/editor/src/commands/entity.ts +287 -0
  835. package/modules/editor/src/commands/hierarchy.ts +83 -0
  836. package/modules/editor/src/commands/index.ts +61 -0
  837. package/modules/editor/src/commands/prefab.ts +163 -0
  838. package/modules/editor/src/commands/registry.ts +331 -0
  839. package/modules/editor/src/commands/scene-io.ts +211 -0
  840. package/modules/editor/src/commands/selection.ts +73 -0
  841. package/modules/editor/src/commands/transform.ts +91 -0
  842. package/modules/editor/src/ddscene.ts +267 -0
  843. package/modules/editor/src/document.ts +123 -0
  844. package/modules/editor/src/editor-context.ts +172 -0
  845. package/modules/editor/src/index.ts +41 -0
  846. package/modules/editor/src/mcp.ts +103 -0
  847. package/modules/editor/src/module.ts +148 -0
  848. package/modules/editor/src/selection.ts +70 -0
  849. package/modules/editor/src/shell.ts +456 -0
  850. package/modules/editor/src/viewport.ts +199 -0
  851. package/modules/html-ui/src/composite.ts +135 -0
  852. package/modules/html-ui/src/create-html-ui.ts +188 -0
  853. package/modules/html-ui/src/doc-backend.ts +343 -0
  854. package/modules/html-ui/src/host.ts +646 -0
  855. package/modules/html-ui/src/index.ts +13 -0
  856. package/modules/html-ui/src/jsx-dev-runtime.ts +12 -0
  857. package/modules/html-ui/src/jsx-runtime.ts +126 -0
  858. package/modules/html-ui/src/protocol.ts +88 -0
  859. package/modules/html-ui/src/ui-worker.ts +16 -0
  860. package/modules/mcp/README.md +18 -0
  861. package/modules/mcp/src/index.ts +27 -0
  862. package/modules/movement-2d/README.md +19 -0
  863. package/modules/movement-2d/src/grid-character.ts +455 -0
  864. package/modules/movement-2d/src/index.ts +45 -0
  865. package/modules/movement-3d/README.md +21 -0
  866. package/modules/movement-3d/src/character-motor.ts +230 -0
  867. package/modules/movement-3d/src/index.ts +46 -0
  868. package/modules/native-osr/src/index.ts +22 -0
  869. package/modules/native-osr/src/input-router.ts +401 -0
  870. package/modules/native-osr/src/native-osr-manager.ts +247 -0
  871. package/modules/native-osr/src/native-texture-source.ts +86 -0
  872. package/modules/native-osr/src/types.ts +112 -0
  873. package/modules/native-osr/src/world-space-ui-pass.ts +351 -0
  874. package/modules/sailing/README.md +18 -0
  875. package/modules/sailing/src/index.ts +51 -0
  876. package/modules/terrain/README.md +18 -0
  877. package/modules/terrain/src/index.ts +78 -0
  878. package/modules/vitals/README.md +17 -0
  879. package/modules/vitals/src/index.ts +43 -0
  880. package/modules/vitals/src/vitals.ts +265 -0
  881. package/modules/xr/README.md +25 -0
  882. package/modules/xr/src/camera-rig.ts +146 -0
  883. package/modules/xr/src/debug.ts +59 -0
  884. package/modules/xr/src/frame-loop.ts +197 -0
  885. package/modules/xr/src/index.ts +16 -0
  886. package/modules/xr/src/input.ts +208 -0
  887. package/modules/xr/src/layer.ts +140 -0
  888. package/modules/xr/src/session.ts +156 -0
  889. package/modules/xr/src/sim-module.ts +23 -0
  890. package/modules/xr/src/types.ts +32 -0
  891. package/modules/xr/src/webxr.d.ts +182 -0
  892. package/modules/xr/src/xr-module.ts +179 -0
  893. package/package.json +232 -3
  894. package/shader-graph/src/chunks.ts +349 -0
  895. package/shader-graph/src/compiler.ts +732 -0
  896. package/shader-graph/src/compute-compiler.ts +453 -0
  897. package/shader-graph/src/compute-graph.ts +112 -0
  898. package/shader-graph/src/compute-profiles.ts +54 -0
  899. package/shader-graph/src/graph.ts +52 -0
  900. package/shader-graph/src/index.ts +53 -0
  901. package/shader-graph/src/profiles.ts +407 -0
  902. package/shader-graph/src/validator.ts +48 -0
  903. package/shader-graph/src/wgsl-binding-validator.ts +143 -0
  904. package/shader-graph/src/wgsl-struct-validator.ts +245 -0
  905. package/shader-graph/src/wgsl-struct.ts +397 -0
  906. package/test/src/index.ts +7 -0
  907. package/test/src/vision-test.ts +369 -0
@@ -0,0 +1,958 @@
1
+ // ============================================================================
2
+ // transpile.ts — restricted-JavaScript → WGSL kernel transpiler (gpu.js-inspired)
3
+ //
4
+ // Deliberately small dialect — "old/simple ECMAScript":
5
+ // function (a, b, scale) {
6
+ // let sum = 0;
7
+ // for (let i = 0; i < a.length; i++) { sum += a[i] * b[i]; }
8
+ // return sum * scale;
9
+ // }
10
+ //
11
+ // Type model: f32 dominates; i32/u32 only for integer literals, `this.thread.*`
12
+ // and `arg.length` (which keeps loops/indexing exact). Everything else is
13
+ // coerced to f32. Array args are `array<f32>` storage buffers; scalar args are
14
+ // packed into a `scalars: array<f32>` buffer read by slot. `this.thread`,
15
+ // `this.output`, `this.constants` are the only `this` members.
16
+ // ============================================================================
17
+
18
+ import * as acorn from "acorn";
19
+
20
+ export type KernelArgKind = "array" | "scalar" | "buffer";
21
+
22
+ export interface KernelBinding {
23
+ /** User parameter name. */
24
+ param: string;
25
+ /** Parameter position in the JS signature. */
26
+ index: number;
27
+ /** WGSL @binding index in group(0). */
28
+ binding: number;
29
+ kind: "array" | "buffer";
30
+ access: "read" | "read_write";
31
+ }
32
+
33
+ export interface TranspileOptions {
34
+ /** Dispatch grid in elements: [x, y?, z?] — missing components become 1. */
35
+ output: number[];
36
+ /** Components written per element (1|2|3|4). */
37
+ outputStride: number;
38
+ constants?: Record<string, number>;
39
+ /** Kind per parameter position, in fn signature order. */
40
+ argKinds: KernelArgKind[];
41
+ /** Access per parameter position (storage args only; default "read"). */
42
+ argAccess?: ("read" | "read_write")[];
43
+ workgroupSize: [number, number, number];
44
+ }
45
+
46
+ export interface TranspileResult {
47
+ wgsl: string;
48
+ /** Parameter names in signature order. */
49
+ paramOrder: string[];
50
+ bindings: KernelBinding[];
51
+ /** Scalar params and their slot in the `scalars` buffer, in param order. */
52
+ scalarSlots: Map<string, number>;
53
+ scalarsBinding: number | null;
54
+ resultBinding: number;
55
+ /** Return arity actually emitted (1 or outputStride). */
56
+ resultComponents: number;
57
+ }
58
+
59
+ export class KernelSyntaxError extends Error {
60
+ constructor(message: string, node?: { start?: number; end?: number }) {
61
+ const where = node && typeof node.start === "number" ? ` (at offset ${node.start})` : "";
62
+ super(`kernel transpile: ${message}${where}`);
63
+ this.name = "KernelSyntaxError";
64
+ }
65
+ }
66
+
67
+ type Ty = "f32" | "i32" | "u32" | "bool" | "vec" | "void";
68
+
69
+ interface E {
70
+ code: string;
71
+ ty: Ty;
72
+ /** For ty "vec": component count. */
73
+ vecN?: number;
74
+ }
75
+
76
+ const WGSL_RESERVED = new Set([
77
+ "var", "let", "const", "fn", "return", "if", "else", "for", "while", "loop",
78
+ "break", "continue", "switch", "case", "default", "true", "false", "struct",
79
+ "storage", "uniform", "workgroup", "read", "write", "read_write", "function",
80
+ "private", "array", "vec2", "vec3", "vec4", "mat2x2", "mat3x3", "mat4x4",
81
+ "f32", "f16", "i32", "u32", "bool", "main", "scalars", "result", "gid",
82
+ "enable", "requires", "alias", "discard", "texture", "sampler", "ptr",
83
+ "wgsl", "premerge", "trait", "null", "align", "binding", "builtin",
84
+ "compute", "fragment", "vertex", "group", "location", "override", "diagnostic",
85
+ ]);
86
+
87
+ /** Names the generated module owns — user identifiers can't collide. */
88
+ const GENERATED_IDENT = new Set([
89
+ "Math", "NaN", "Infinity", "undefined", "scalars", "result", "gid",
90
+ "user_kernel", "OUT_X", "OUT_Y", "OUT_Z", "STRIDE", "RAND_SEED", "_rs",
91
+ ]);
92
+ const GENERATED_PREFIX = ["CONST_", "_m_", "_dd_", "_ai"];
93
+
94
+ function assertUsableIdent(name: string, node?: { start?: number }): void {
95
+ if (
96
+ !IDENT_RE.test(name) || name.startsWith("_") ||
97
+ WGSL_RESERVED.has(name) || GENERATED_IDENT.has(name) ||
98
+ GENERATED_PREFIX.some((p) => name.startsWith(p))
99
+ ) {
100
+ throw new KernelSyntaxError(`"${name}" is not a usable kernel identifier`, node);
101
+ }
102
+ }
103
+
104
+ // Math.* → direct WGSL builtin renames
105
+ const MATH_DIRECT: Record<string, string> = {
106
+ abs: "abs", acos: "acos", asin: "asin", atan: "atan", atan2: "atan2",
107
+ ceil: "ceil", cos: "cos", cosh: "cosh", exp: "exp", exp2: "exp2",
108
+ floor: "floor", log: "log", log2: "log2", max: "max", min: "min",
109
+ pow: "pow", sign: "sign", sin: "sin", sinh: "sinh", sqrt: "sqrt",
110
+ tan: "tan", tanh: "tanh", trunc: "trunc",
111
+ };
112
+
113
+ // Math.* → module-scope helper functions (emitted only when used)
114
+ const MATH_HELPERS: Record<string, string> = {
115
+ round: "fn _m_round(x: f32) -> f32 { return floor(x + 0.5); }",
116
+ cbrt: "fn _m_cbrt(x: f32) -> f32 { return sign(x) * pow(abs(x), 1.0 / 3.0); }",
117
+ expm1: "fn _m_expm1(x: f32) -> f32 { return exp(x) - 1.0; }",
118
+ log10: "fn _m_log10(x: f32) -> f32 { return log2(x) * 0.3010299956639812; }",
119
+ log1p: "fn _m_log1p(x: f32) -> f32 { return log(1.0 + x); }",
120
+ clz32: "fn _m_clz32(x: f32) -> f32 { return f32(countLeadingZeros(u32(x))); }",
121
+ imul: "fn _m_imul(a: f32, b: f32) -> f32 { return f32(i32(a) * i32(b)); }",
122
+ hypot: "fn _m_hypot(a: f32, b: f32) -> f32 { return sqrt(a * a + b * b); }",
123
+ fround: "fn _m_fround(x: f32) -> f32 { return x; }",
124
+ };
125
+
126
+ // Expected arity per supported Math.* name ("+" = 2 or more).
127
+ const MATH_ARITY: Record<string, number | "+"> = {
128
+ abs: 1, acos: 1, asin: 1, atan: 1, ceil: 1, cos: 1, cosh: 1, exp: 1,
129
+ exp2: 1, floor: 1, log: 1, log2: 1, sign: 1, sin: 1, sinh: 1, sqrt: 1,
130
+ tan: 1, tanh: 1, trunc: 1, atan2: 2, pow: 2, min: "+", max: "+",
131
+ round: 1, cbrt: 1, expm1: 1, log10: 1, log1p: 1, clz32: 1, fround: 1,
132
+ imul: 2, hypot: 2, random: 0,
133
+ };
134
+
135
+ const RAND_HELPER = `fn _dd_rand(state: ptr<function, u32>) -> f32 {
136
+ let s = *state;
137
+ *state = s * 747796405u + 2891336453u;
138
+ let w = ((s >> ((s >> 28u) + 4u)) ^ s) * 277803737u;
139
+ return f32((w >> 22u) ^ w) * (1.0 / 4294967296.0);
140
+ }`;
141
+
142
+ /** Format a JS number as a valid WGSL f32 literal. */
143
+ export function wgslF32(value: number): string {
144
+ if (Number.isNaN(value)) return "bitcast<f32>(0x7fc00000u)";
145
+ if (value === Infinity || value > 3.4028234663852886e38) return "0x1.fffffep+127";
146
+ if (value === -Infinity || value < -3.4028234663852886e38) return "(-0x1.fffffep+127)";
147
+ let str = `${value}`;
148
+ if (str.indexOf(".") === -1 && str.indexOf("e") === -1 && str.indexOf("E") === -1) str += ".0";
149
+ return value < 0 ? `(${str})` : str;
150
+ }
151
+
152
+ const IDENT_RE = /^[a-zA-Z_][a-zA-Z0-9_]*$/;
153
+
154
+ class Emitter {
155
+ private scopes: Map<string, Ty>[] = [new Map()];
156
+ private helpersUsed = new Set<string>();
157
+ private usesRandom = false;
158
+ /** Vars auto-widened to f32 after an int-typed decl saw a float assignment
159
+ * (JS vars are untyped; `var sum = 0; sum += a[i]` must just work — and
160
+ * Bun's toString() rewrites `0.0` → `0`, so we can't rely on the literal
161
+ * form surviving). Widening is monotonic: emit retries converge. */
162
+ private widened = new Set<string>();
163
+ private dirty = false;
164
+ private tempCounter = 0;
165
+ private consts = new Set<string>();
166
+ private paramKind: Map<string, KernelArgKind>;
167
+ private paramWritable = new Set<string>();
168
+ private scalarSlot = new Map<string, number>();
169
+ private constants: Record<string, number>;
170
+
171
+ constructor(private opts: TranspileOptions, private params: string[]) {
172
+ this.constants = opts.constants ?? {};
173
+ this.paramKind = new Map();
174
+ let slot = 0;
175
+ params.forEach((name, i) => {
176
+ const kind = opts.argKinds[i] ?? "scalar";
177
+ this.paramKind.set(name, kind);
178
+ if (kind === "scalar") {
179
+ this.scalarSlot.set(name, slot++);
180
+ this.declare(name, "f32");
181
+ }
182
+ if (kind !== "scalar" && opts.argAccess?.[i] === "read_write") {
183
+ this.paramWritable.add(name);
184
+ }
185
+ });
186
+ }
187
+
188
+ private declare(name: string, ty: Ty): void {
189
+ this.scopes[this.scopes.length - 1].set(name, ty);
190
+ }
191
+
192
+ private lookup(name: string): Ty | null {
193
+ for (let i = this.scopes.length - 1; i >= 0; i--) {
194
+ const ty = this.scopes[i].get(name);
195
+ if (ty !== undefined) return ty;
196
+ }
197
+ return null;
198
+ }
199
+
200
+ private push(): void { this.scopes.push(new Map()); }
201
+ private pop(): void { this.scopes.pop(); }
202
+
203
+ private f32(e: E): string {
204
+ if (e.ty === "f32") return e.code;
205
+ if (e.ty === "i32" || e.ty === "u32") return `f32(${e.code})`;
206
+ if (e.ty === "bool") return `select(0.0, 1.0, ${e.code})`;
207
+ throw new KernelSyntaxError(`can't use a ${e.ty === "void" ? "statement" : e.ty} as a number`);
208
+ }
209
+
210
+ private i32(e: E): string {
211
+ if (e.ty === "i32") return e.code;
212
+ if (e.ty === "f32" || e.ty === "u32") return `i32(${e.code})`;
213
+ if (e.ty === "bool") return `select(0, 1, ${e.code})`;
214
+ throw new KernelSyntaxError(`can't use a ${e.ty === "void" ? "statement" : e.ty} as a number`);
215
+ }
216
+
217
+ private u32(e: E): string {
218
+ if (e.ty === "u32") return e.code;
219
+ if (e.ty === "f32" || e.ty === "i32") return `u32(${e.code})`;
220
+ if (e.ty === "bool") return `select(0u, 1u, ${e.code})`;
221
+ throw new KernelSyntaxError(`can't use a ${e.ty === "void" ? "statement" : e.ty} as a number`);
222
+ }
223
+
224
+ private boolify(e: E): string {
225
+ if (e.ty === "bool") return e.code;
226
+ if (e.ty === "f32") return `(${e.code} != 0.0)`;
227
+ if (e.ty === "i32" || e.ty === "u32") return `(${e.code} != 0)`;
228
+ throw new KernelSyntaxError(`can't use a ${e.ty === "void" ? "statement" : e.ty} as a condition`);
229
+ }
230
+
231
+ /** Coerce a pair to a common arithmetic type. Returns [l, r, ty]. */
232
+ private unify(l: E, r: E): [string, string, Ty] {
233
+ if (l.ty === r.ty) return [l.code, r.code, l.ty];
234
+ if (l.ty === "f32" || r.ty === "f32") return [this.f32(l), this.f32(r), "f32"];
235
+ if (l.ty === "bool" || r.ty === "bool") {
236
+ // JS numeric context: bool → 0/1, then unify as ints
237
+ return [
238
+ l.ty === "bool" ? `select(0, 1, ${l.code})` : l.ty === "i32" ? l.code : `i32(${l.code})`,
239
+ r.ty === "bool" ? `select(0, 1, ${r.code})` : r.ty === "i32" ? r.code : `i32(${r.code})`,
240
+ "i32",
241
+ ];
242
+ }
243
+ if (l.ty === "vec" || r.ty === "vec" || l.ty === "void" || r.ty === "void") {
244
+ throw new KernelSyntaxError(`incompatible operand types ${l.ty} and ${r.ty}`);
245
+ }
246
+ // i32⊕u32 → i32, never u32: `i >= 0` must terminate and `x - 1` must be
247
+ // able to go negative (JS semantics). u32() is applied only at indexes.
248
+ return [
249
+ l.ty === "i32" ? l.code : `i32(${l.code})`,
250
+ r.ty === "i32" ? r.code : `i32(${r.code})`,
251
+ "i32",
252
+ ];
253
+ }
254
+
255
+ // ── Expressions ──────────────────────────────────────────────────────────
256
+
257
+ private expr(node: any): E {
258
+ // Synthetic node carrying an already-emitted expression (used to expand
259
+ // compound assignments without re-evaluating the index expression).
260
+ if (node.type === "__e") return node.e as E;
261
+ switch (node.type) {
262
+ case "Literal": return this.literal(node);
263
+ case "Identifier": return this.ident(node);
264
+ case "MemberExpression": return this.member(node);
265
+ case "CallExpression": return this.call(node);
266
+ case "BinaryExpression": return this.binary(node);
267
+ case "LogicalExpression": return this.logical(node);
268
+ case "UnaryExpression": return this.unary(node);
269
+ case "UpdateExpression": return this.update(node);
270
+ case "AssignmentExpression": return this.assign(node);
271
+ case "ConditionalExpression": return this.conditional(node);
272
+ case "ArrayExpression": return this.arrayLiteral(node);
273
+ case "ParenthesizedExpression": return this.expr(node.expression);
274
+ default:
275
+ throw new KernelSyntaxError(`unsupported expression "${node.type}"`, node);
276
+ }
277
+ }
278
+
279
+ private literal(node: any): E {
280
+ const v = node.value;
281
+ if (typeof v === "number") {
282
+ // Respect the source form: `2.0`/`1e3` are floats; `2`/`0x10` are ints.
283
+ const raw: string | undefined = node.raw;
284
+ const floatForm = raw ? /[.eExX]/.test(raw) && !/^0[xX]/.test(raw) : !Number.isInteger(v);
285
+ if (!floatForm && Number.isInteger(v) && Math.abs(v) <= 2147483647) {
286
+ return { code: `${v}`, ty: "i32" };
287
+ }
288
+ return { code: wgslF32(v), ty: "f32" };
289
+ }
290
+ if (typeof v === "boolean") return { code: `${v}`, ty: "bool" };
291
+ if (typeof v === "bigint") throw new KernelSyntaxError(`bigint literals aren't supported`, node);
292
+ throw new KernelSyntaxError(`unsupported literal ${String(v)}`, node);
293
+ }
294
+
295
+ private ident(node: any): E {
296
+ const name: string = node.name;
297
+ if (name === "NaN") return { code: "bitcast<f32>(0x7fc00000u)", ty: "f32" };
298
+ if (name === "Infinity") return { code: "0x1.fffffep+127", ty: "f32" };
299
+ if (name === "undefined") throw new KernelSyntaxError(`"undefined" is not available in kernels`, node);
300
+ const kind = this.paramKind.get(name);
301
+ if (kind === "array" || kind === "buffer") {
302
+ throw new KernelSyntaxError(`array arg "${name}" used as a value — index it (${name}[i]) or take ${name}.length`, node);
303
+ }
304
+ const ty = this.lookup(name);
305
+ if (ty === null) {
306
+ throw new KernelSyntaxError(`unknown identifier "${name}" — kernels can't close over outer scope (pass it as an argument or constants entry)`, node);
307
+ }
308
+ return { code: name, ty };
309
+ }
310
+
311
+ private member(node: any): E {
312
+ const obj = node.object;
313
+ // this.<group>.<prop> — also this["group"].<prop>
314
+ if (obj.type === "MemberExpression" && obj.object.type === "ThisExpression") {
315
+ return this.thisAccess(node);
316
+ }
317
+ if (obj.type === "ThisExpression") {
318
+ throw new KernelSyntaxError(`use this.thread.x / this.output.x / this.constants.NAME`, node);
319
+ }
320
+ if (obj.type === "Identifier" && this.paramKind.has(obj.name)) {
321
+ const kind = this.paramKind.get(obj.name);
322
+ if (kind === "scalar") {
323
+ throw new KernelSyntaxError(`scalar arg "${obj.name}" can't be indexed`, node);
324
+ }
325
+ if (!node.computed) {
326
+ if (node.property.type === "Identifier" && node.property.name === "length") {
327
+ return { code: `arrayLength(&${obj.name})`, ty: "u32" };
328
+ }
329
+ throw new KernelSyntaxError(`unsupported member ".${node.property.name}" on arg "${obj.name}" — only .length and indexing`, node);
330
+ }
331
+ if (node.property.type === "Literal" && node.property.value === "length") {
332
+ return { code: `arrayLength(&${obj.name})`, ty: "u32" };
333
+ }
334
+ const idx = this.expr(node.property);
335
+ return { code: `${obj.name}[${this.u32(idx)}]`, ty: "f32" };
336
+ }
337
+ throw new KernelSyntaxError(`unsupported member expression — only arg[i], arg.length, this.thread/output/constants`, node);
338
+ }
339
+
340
+ private thisAccess(node: any): E {
341
+ // node: MemberExpression{ object: MemberExpression{ object: This, property: group }, property: prop }
342
+ const group = node.object.computed ? this.constKey(node.object.property) : node.object.property.name;
343
+ if (group === null) {
344
+ throw new KernelSyntaxError(`this[...] needs a literal key (this.thread / this.output / this.constants)`, node.object);
345
+ }
346
+ const prop = node.computed ? this.constKey(node.property) : node.property.name;
347
+ if (group === "thread" || group === "output") {
348
+ if (prop !== "x" && prop !== "y" && prop !== "z") {
349
+ throw new KernelSyntaxError(`this.${group} supports .x/.y/.z only`, node);
350
+ }
351
+ return { code: group === "thread" ? `gid.${prop}` : `OUT_${prop.toUpperCase()}`, ty: "u32" };
352
+ }
353
+ if (group === "constants") {
354
+ if (prop === null || !Object.prototype.hasOwnProperty.call(this.constants, prop)) {
355
+ throw new KernelSyntaxError(`this.constants.${prop ?? "?"} is not in the kernel's constants map`, node);
356
+ }
357
+ // RAND_SEED is emitted as the u32 seed constant, not CONST_*
358
+ if (prop === "RAND_SEED") return { code: "f32(RAND_SEED)", ty: "f32" };
359
+ return { code: `CONST_${prop}`, ty: "f32" };
360
+ }
361
+ throw new KernelSyntaxError(`unsupported this.${group}`, node);
362
+ }
363
+
364
+ private constKey(node: any): string | null {
365
+ if (node.type === "Literal" && typeof node.value === "string") return node.value;
366
+ return null;
367
+ }
368
+
369
+ private call(node: any): E {
370
+ const callee = node.callee;
371
+ if (
372
+ callee.type === "MemberExpression" && !callee.computed &&
373
+ callee.object.type === "Identifier" && callee.object.name === "Math" &&
374
+ callee.property.type === "Identifier"
375
+ ) {
376
+ const name: string = callee.property.name;
377
+ const arity = MATH_ARITY[name];
378
+ if (arity === undefined) {
379
+ throw new KernelSyntaxError(`Math.${name} is not supported in kernels`, node);
380
+ }
381
+ const args = node.arguments.map((a: any) => this.expr(a));
382
+ const argcOk = arity === "+" ? args.length >= 2 : args.length === arity;
383
+ if (!argcOk) {
384
+ throw new KernelSyntaxError(`Math.${name} takes ${arity === "+" ? "≥2" : arity} arg(s), got ${args.length}`, node);
385
+ }
386
+ if (name === "random") {
387
+ this.usesRandom = true;
388
+ return { code: `_dd_rand(&_rs)`, ty: "f32" };
389
+ }
390
+ if (name === "min" || name === "max") {
391
+ let code = this.f32(args[0]);
392
+ for (let i = 1; i < args.length; i++) code = `${name}(${code}, ${this.f32(args[i])})`;
393
+ return { code, ty: "f32" };
394
+ }
395
+ if (MATH_DIRECT[name]) {
396
+ return { code: `${MATH_DIRECT[name]}(${args.map((a: any) => this.f32(a)).join(", ")})`, ty: "f32" };
397
+ }
398
+ this.helpersUsed.add(name);
399
+ return { code: `_m_${name}(${args.map((a: any) => this.f32(a)).join(", ")})`, ty: "f32" };
400
+ }
401
+ throw new KernelSyntaxError(`unsupported call — kernels only support Math.* builtins (no helper functions yet)`, node);
402
+ }
403
+
404
+ private binary(node: any): E {
405
+ const op: string = node.operator;
406
+ if (op === "**") {
407
+ const l = this.expr(node.left);
408
+ const r = this.expr(node.right);
409
+ return { code: `pow(${this.f32(l)}, ${this.f32(r)})`, ty: "f32" };
410
+ }
411
+ if (op === "instanceof" || op === "in") {
412
+ throw new KernelSyntaxError(`operator "${op}" is not supported`, node);
413
+ }
414
+ const l = this.expr(node.left);
415
+ const r = this.expr(node.right);
416
+ // JS "/" is always float division — never emit int `/` (it truncates).
417
+ if (op === "/") {
418
+ return { code: `(${this.f32(l)} / ${this.f32(r)})`, ty: "f32" };
419
+ }
420
+ if (op === "&" || op === "|" || op === "^" || op === "<<" || op === ">>") {
421
+ // WGSL shift amounts must be u32.
422
+ const rhs = op === "<<" || op === ">>" ? this.u32(r) : this.i32(r);
423
+ return { code: `(${this.i32(l)} ${op} ${rhs})`, ty: "i32" };
424
+ }
425
+ if (op === ">>>") {
426
+ return { code: `(${this.u32(l)} >> ${this.u32(r)})`, ty: "u32" };
427
+ }
428
+ if (op === "==" || op === "!=" || op === "<" || op === "<=" || op === ">" || op === ">=" ||
429
+ op === "===" || op === "!==") {
430
+ const realOp = op === "===" ? "==" : op === "!==" ? "!=" : op;
431
+ const [lc, rc] = this.unify(l, r);
432
+ return { code: `(${lc} ${realOp} ${rc})`, ty: "bool" };
433
+ }
434
+ const [lc, rc, ty] = this.unify(l, r);
435
+ return { code: `(${lc} ${op} ${rc})`, ty };
436
+ }
437
+
438
+ private logical(node: any): E {
439
+ const op: string = node.operator;
440
+ if (op === "??") {
441
+ throw new KernelSyntaxError(`"??" isn't supported — write an explicit check`, node);
442
+ }
443
+ const l = this.expr(node.left);
444
+ const r = this.expr(node.right);
445
+ const [lc, rc, ty] = this.unify(l, r);
446
+ if (ty === "bool") {
447
+ return { code: `(${this.boolify(l)} ${op} ${this.boolify(r)})`, ty: "bool" };
448
+ }
449
+ // JS returns an operand, not a boolean — select() preserves that.
450
+ return op === "||"
451
+ ? { code: `select(${rc}, ${lc}, ${this.boolify(l)})`, ty }
452
+ : { code: `select(${lc}, ${rc}, ${this.boolify(l)})`, ty };
453
+ }
454
+
455
+ private unary(node: any): E {
456
+ const a = this.expr(node.argument);
457
+ switch (node.operator) {
458
+ case "-": {
459
+ if (a.ty === "bool" || a.ty === "void" || a.ty === "vec") {
460
+ throw new KernelSyntaxError(`unary - on ${a.ty}`, node);
461
+ }
462
+ // u32 has no unary minus in WGSL — negate through i32.
463
+ const code = a.ty === "u32" ? this.i32(a) : a.code;
464
+ return { code: `-(${code})`, ty: a.ty === "u32" ? "i32" : a.ty };
465
+ }
466
+ case "+": {
467
+ if (a.ty === "bool") return { code: `select(0.0, 1.0, ${a.code})`, ty: "f32" };
468
+ if (a.ty === "void" || a.ty === "vec") {
469
+ throw new KernelSyntaxError(`unary + on ${a.ty}`, node);
470
+ }
471
+ return a;
472
+ }
473
+ case "!": return { code: `!(${this.boolify(a)})`, ty: "bool" };
474
+ case "~": return { code: `~(${this.i32(a)})`, ty: "i32" };
475
+ default: throw new KernelSyntaxError(`unsupported unary "${node.operator}"`, node);
476
+ }
477
+ }
478
+
479
+ private update(node: any): E {
480
+ const t = node.argument;
481
+ const op = node.operator === "++" ? "+=" : "-=";
482
+ if (t.type === "Identifier") {
483
+ const ty = this.lookup(t.name);
484
+ if (ty === null) throw new KernelSyntaxError(`unknown identifier "${t.name}"`, t);
485
+ if (this.consts.has(t.name)) {
486
+ throw new KernelSyntaxError(`can't ${node.operator} a const "${t.name}"`, node);
487
+ }
488
+ if (ty === "bool" || ty === "void" || ty === "vec") {
489
+ throw new KernelSyntaxError(`can't ${node.operator} a ${ty} variable`, node);
490
+ }
491
+ const lit = ty === "u32" ? "1u" : ty === "i32" ? "1" : "1.0";
492
+ return { code: `${t.name} ${op} ${lit}`, ty: "void" };
493
+ }
494
+ if (t.type === "MemberExpression") {
495
+ const obj = t.object;
496
+ if (t.computed && obj.type === "Identifier" && this.paramWritable.has(obj.name)) {
497
+ const idx = this.expr(t.property);
498
+ return { code: `${obj.name}[${this.u32(idx)}] ${op} 1.0`, ty: "void" };
499
+ }
500
+ throw new KernelSyntaxError(`${node.operator} on that target needs a "read_write" arg`, node);
501
+ }
502
+ throw new KernelSyntaxError(`unsupported ${node.operator} target`, node);
503
+ }
504
+
505
+ /** Expand `x op= v` → `x = x op v` via binary() for correct op semantics. */
506
+ private compoundOp(op: string, lhsNode: any, rhsNode: any): E {
507
+ if (op === "&&=" || op === "||=" || op === "??=") {
508
+ throw new KernelSyntaxError(`"${op}" isn't supported`, rhsNode);
509
+ }
510
+ return this.binary({
511
+ type: "BinaryExpression",
512
+ operator: op.slice(0, -1),
513
+ left: lhsNode,
514
+ right: rhsNode,
515
+ });
516
+ }
517
+
518
+ private assign(node: any): E {
519
+ const op: string = node.operator;
520
+ const t = node.left;
521
+ if (t.type === "Identifier") {
522
+ const name: string = t.name;
523
+ const kind = this.paramKind.get(name);
524
+ if (kind === "array" || kind === "buffer") {
525
+ throw new KernelSyntaxError(`can't assign to array arg "${name}" — assign to ${name}[i]`, node);
526
+ }
527
+ const ty = this.lookup(name);
528
+ if (ty === null) {
529
+ throw new KernelSyntaxError(`can't assign to undeclared "${name}" — declare it first`, t);
530
+ }
531
+ if (this.consts.has(name)) {
532
+ throw new KernelSyntaxError(`can't assign to const "${name}"`, node);
533
+ }
534
+ const rhs = op === "=" ? this.expr(node.right) : this.compoundOp(op, t, node.right);
535
+ this.checkAssignTypes(name, ty, rhs);
536
+ const code = ty === "f32" ? this.f32(rhs) : ty === "i32" ? this.i32(rhs) : ty === "u32" ? this.u32(rhs) : rhs.code;
537
+ return { code: `${name} = ${code}`, ty: "void" };
538
+ }
539
+ if (t.type === "MemberExpression" && t.computed) {
540
+ const obj = t.object;
541
+ if (obj.type === "Identifier" && this.paramKind.has(obj.name) && this.paramKind.get(obj.name) !== "scalar") {
542
+ if (!this.paramWritable.has(obj.name)) {
543
+ throw new KernelSyntaxError(`writes to "${obj.name}" require access: "read_write" for that arg`, node);
544
+ }
545
+ const idx = this.expr(t.property);
546
+ if (op === "=") {
547
+ const rhs = this.expr(node.right);
548
+ if (rhs.ty === "vec") {
549
+ throw new KernelSyntaxError(`can't store a vector in ${obj.name}[i]`, node);
550
+ }
551
+ return { code: `${obj.name}[${this.u32(idx)}] = ${this.f32(rhs)}`, ty: "void" };
552
+ }
553
+ // a[i] op= v → `var _aiN = i; a[_aiN] = f32(a[_aiN] op v)` — the
554
+ // index evaluates exactly once (Math.random/side effects safe).
555
+ const tmp = `_ai${this.tempCounter++}`;
556
+ const lhsE: E = { code: `${obj.name}[${tmp}]`, ty: "f32" };
557
+ const bin = this.compoundOp(op, { type: "__e", e: lhsE }, node.right);
558
+ return {
559
+ code: `var ${tmp} = ${this.u32(idx)}; ${lhsE.code} = ${this.f32(bin)}`,
560
+ ty: "void",
561
+ };
562
+ }
563
+ throw new KernelSyntaxError(`unsupported assignment target`, node);
564
+ }
565
+ throw new KernelSyntaxError(`unsupported assignment target "${t.type}"`, node);
566
+ }
567
+
568
+ /**
569
+ * Type-check an assignment. Int-typed vars that receive a float get widened
570
+ * to f32 and the emit re-runs (JS number semantics). Bool mismatches are
571
+ * real errors.
572
+ */
573
+ private checkAssignTypes(name: string, ty: Ty, rhs: E): void {
574
+ if (rhs.ty === "vec") {
575
+ throw new KernelSyntaxError(`can't assign a vector to "${name}"`, undefined);
576
+ }
577
+ if ((ty === "i32" || ty === "u32") && rhs.ty === "f32" && !this.paramKind.has(name)) {
578
+ this.widened.add(name);
579
+ this.dirty = true;
580
+ }
581
+ if (ty === "bool" && rhs.ty !== "bool") {
582
+ throw new KernelSyntaxError(`"${name}" is bool but the assignment isn't`);
583
+ }
584
+ if (ty === "f32" && rhs.ty === "bool") {
585
+ throw new KernelSyntaxError(`"${name}" is f32 but the assignment is bool`);
586
+ }
587
+ }
588
+
589
+ private conditional(node: any): E {
590
+ const c = this.expr(node.test);
591
+ const cons = this.expr(node.consequent);
592
+ const alt = this.expr(node.alternate);
593
+ if (cons.ty === "vec" || alt.ty === "vec") {
594
+ if (cons.ty === "vec" && alt.ty === "vec" && cons.vecN === alt.vecN) {
595
+ return { code: `select(${alt.code}, ${cons.code}, ${this.boolify(c)})`, ty: "vec", vecN: cons.vecN };
596
+ }
597
+ throw new KernelSyntaxError(`ternary branches have incompatible types ${cons.ty} and ${alt.ty}`, node);
598
+ }
599
+ const [tc, fc, ty] = this.unify(cons, alt);
600
+ return { code: `select(${fc}, ${tc}, ${this.boolify(c)})`, ty };
601
+ }
602
+
603
+ private arrayLiteral(node: any): E {
604
+ const els = node.elements.map((e: any) => this.expr(e));
605
+ if (els.length < 1 || els.length > 4) {
606
+ throw new KernelSyntaxError(`return arrays must have 1–4 elements`, node);
607
+ }
608
+ return { code: `vec${els.length}<f32>(${els.map((e: any) => this.f32(e)).join(", ")})`, ty: "vec", vecN: els.length };
609
+ }
610
+
611
+ // ── Statements ───────────────────────────────────────────────────────────
612
+
613
+ private stmt(node: any, ind: string): string {
614
+ switch (node.type) {
615
+ case "BlockStatement": {
616
+ this.push();
617
+ const body = node.body.map((s: any) => this.stmt(s, ind + " ")).join("");
618
+ this.pop();
619
+ return `${ind}{\n${body}${ind}}\n`;
620
+ }
621
+ case "VariableDeclaration": return this.varDecl(node, ind);
622
+ case "ExpressionStatement": {
623
+ const e = this.expr(node.expression);
624
+ if (e.ty !== "void") {
625
+ throw new KernelSyntaxError(`expression statement has no effect`, node.expression);
626
+ }
627
+ return `${ind}${e.code};\n`;
628
+ }
629
+ case "IfStatement": return this.ifStmt(node, ind);
630
+ case "ForStatement": return this.forStmt(node, ind);
631
+ case "WhileStatement": {
632
+ const c = this.expr(node.test);
633
+ return `${ind}while (${this.boolify(c)}) {\n${this.stmtBody(node.body, ind)}${ind}}\n`;
634
+ }
635
+ case "DoWhileStatement": {
636
+ const c = this.expr(node.test);
637
+ // JS do..while tests after every pass — including passes ended by
638
+ // `continue`, which a bare tail check would skip. naga rejects
639
+ // `break` inside `continuing`, so the test sets a flag that the
640
+ // loop head breaks on.
641
+ const tmp = `_dw${this.tempCounter++}`;
642
+ return `${ind}var ${tmp} = false;\n${ind}loop {\n${ind} if (${tmp}) { break; }\n${this.stmtBody(node.body, ind)}${ind} continuing {\n${ind} ${tmp} = !(${this.boolify(c)});\n${ind} }\n${ind}}\n`;
643
+ }
644
+ case "ReturnStatement": return `${ind}return ${this.returnValue(node.argument)};\n`;
645
+ case "BreakStatement": return `${ind}break;\n`;
646
+ case "ContinueStatement": return `${ind}continue;\n`;
647
+ case "EmptyStatement": return "";
648
+ default:
649
+ throw new KernelSyntaxError(`unsupported statement "${node.type}"`, node);
650
+ }
651
+ }
652
+
653
+ private stmtBody(node: any, ind: string): string {
654
+ if (node.type === "BlockStatement") {
655
+ this.push();
656
+ const body = node.body.map((s: any) => this.stmt(s, ind + " ")).join("");
657
+ this.pop();
658
+ return body;
659
+ }
660
+ return this.stmt(node, ind + " ");
661
+ }
662
+
663
+ private returnValue(arg: any): string {
664
+ if (!arg) {
665
+ return this.opts.outputStride > 1 ? `vec${this.opts.outputStride}<f32>()` : "0.0";
666
+ }
667
+ if (arg.type === "ArrayExpression") {
668
+ if (this.opts.outputStride <= 1) {
669
+ throw new KernelSyntaxError(`kernel returns an array — set outputStride to its length`, arg);
670
+ }
671
+ const v = this.expr(arg);
672
+ if (v.vecN !== this.opts.outputStride) {
673
+ throw new KernelSyntaxError(`return array has ${v.vecN} components but outputStride is ${this.opts.outputStride}`, arg);
674
+ }
675
+ return v.code;
676
+ }
677
+ const e = this.expr(arg);
678
+ if (e.ty === "vec") {
679
+ if (this.opts.outputStride > 1 && e.vecN === this.opts.outputStride) return e.code;
680
+ throw new KernelSyntaxError(
681
+ `kernel returns a vec${e.vecN} but outputStride is ${this.opts.outputStride}`, arg);
682
+ }
683
+ if (this.opts.outputStride > 1) {
684
+ throw new KernelSyntaxError(`outputStride is ${this.opts.outputStride} — kernel must return an array of that length`, arg);
685
+ }
686
+ return this.f32(e);
687
+ }
688
+
689
+ private varDecl(node: any, ind: string): string {
690
+ let out = "";
691
+ node.declarations.forEach((d: any) => {
692
+ if (d.id.type !== "Identifier") {
693
+ throw new KernelSyntaxError(`destructuring is not supported in kernels`, d.id);
694
+ }
695
+ const name: string = d.id.name;
696
+ assertUsableIdent(name, d.id);
697
+ if (this.paramKind.has(name) && !this.scopes[0].has(name)) {
698
+ // Array/buffer params keep paramKind semantics on member access —
699
+ // a shadowing local would read the buffer, not the local. Reject.
700
+ throw new KernelSyntaxError(`local "${name}" shadows a kernel param`, d.id);
701
+ }
702
+ // JS `var` (and sloppy redeclaration) may redeclare in the same scope —
703
+ // WGSL can't. A same-scope redeclare degrades to a plain assignment.
704
+ const current = this.scopes[this.scopes.length - 1];
705
+ if (current.has(name)) {
706
+ if (d.init) {
707
+ const e = this.expr(d.init);
708
+ const ty = current.get(name)!;
709
+ this.checkAssignTypes(name, ty, e);
710
+ const code = ty === "f32" ? this.f32(e) : ty === "i32" ? this.i32(e) : ty === "u32" ? this.u32(e) : e.code;
711
+ out += `${ind}${name} = ${code};\n`;
712
+ }
713
+ return;
714
+ }
715
+ if (d.init) {
716
+ const e = this.expr(d.init);
717
+ if (e.ty === "void") {
718
+ throw new KernelSyntaxError(`can't initialize "${name}" from a statement`, d.init);
719
+ }
720
+ if (e.ty === "vec") {
721
+ throw new KernelSyntaxError(`arrays can't live in locals — return them directly`, d.init);
722
+ }
723
+ const widen = this.widened.has(name) && e.ty !== "f32" && e.ty !== "bool" && e.ty !== "vec";
724
+ this.declare(name, widen ? "f32" : e.ty);
725
+ if (node.kind === "const") this.consts.add(name);
726
+ const kw = node.kind === "const" ? "let" : "var";
727
+ out += `${ind}${kw} ${name} = ${widen ? `f32(${e.code})` : e.code};\n`;
728
+ } else {
729
+ this.declare(name, "f32");
730
+ out += `${ind}var ${name}: f32;\n`;
731
+ }
732
+ });
733
+ return out;
734
+ }
735
+
736
+ private ifStmt(node: any, ind: string): string {
737
+ const c = this.expr(node.test);
738
+ let out = `${ind}if (${this.boolify(c)}) {\n${this.stmtBody(node.consequent, ind)}${ind}}`;
739
+ if (node.alternate) {
740
+ if (node.alternate.type === "IfStatement") {
741
+ out += ` else ${this.ifStmt(node.alternate, ind).slice(ind.length)}`;
742
+ } else {
743
+ out += ` else {\n${this.stmtBody(node.alternate, ind)}${ind}}\n`;
744
+ }
745
+ } else {
746
+ out += `\n`;
747
+ }
748
+ return out;
749
+ }
750
+
751
+ private forStmt(node: any, ind: string): string {
752
+ this.push();
753
+ let init = "";
754
+ if (node.init) {
755
+ if (node.init.type === "VariableDeclaration") {
756
+ if (node.init.declarations.length > 1) {
757
+ throw new KernelSyntaxError(`for-init with multiple declarators isn't supported — split it`, node.init);
758
+ }
759
+ init = this.varDecl(node.init, "").trimEnd().replace(/;$/, "");
760
+ } else {
761
+ const e = this.expr(node.init);
762
+ if (e.ty !== "void") {
763
+ throw new KernelSyntaxError(`for-init must be an assignment or declaration`, node.init);
764
+ }
765
+ init = e.code;
766
+ }
767
+ }
768
+ const test = node.test ? this.boolify(this.expr(node.test)) : "";
769
+ let update = "";
770
+ if (node.update) {
771
+ const e = this.expr(node.update);
772
+ if (e.ty !== "void") {
773
+ throw new KernelSyntaxError(`for-update must be an assignment or ++/--`, node.update);
774
+ }
775
+ update = e.code;
776
+ }
777
+ const body = this.stmtBody(node.body, ind);
778
+ this.pop();
779
+ return `${ind}for (${init}; ${test}; ${update}) {\n${body}${ind}}\n`;
780
+ }
781
+
782
+ // ── Assembly ─────────────────────────────────────────────────────────────
783
+
784
+ emit(body: any[]): TranspileResult {
785
+ // bindings: storage args in param order, scalars, then result
786
+ const bindings: KernelBinding[] = [];
787
+ let b = 0;
788
+ const decls: string[] = [];
789
+ this.params.forEach((name, i) => {
790
+ const kind = this.opts.argKinds[i] ?? "scalar";
791
+ if (kind === "scalar") return;
792
+ const access = this.paramWritable.has(name) ? "read_write" : "read";
793
+ decls.push(`@group(0) @binding(${b}) var<storage, ${access}> ${name}: array<f32>;`);
794
+ bindings.push({ param: name, index: i, binding: b, kind, access });
795
+ b++;
796
+ });
797
+ let scalarsBinding: number | null = null;
798
+ if (this.scalarSlot.size > 0) {
799
+ scalarsBinding = b++;
800
+ decls.push(`@group(0) @binding(${scalarsBinding}) var<storage, read> scalars: array<f32>;`);
801
+ }
802
+ const resultBinding = b;
803
+ decls.push(`@group(0) @binding(${resultBinding}) var<storage, read_write> result: array<f32>;`);
804
+
805
+ const [ox, oy, oz] = [this.opts.output[0], this.opts.output[1] ?? 1, this.opts.output[2] ?? 1];
806
+ const lines: string[] = [];
807
+ lines.push("// generated by @downdraft/engine/libraries/gpu-kernels — do not edit");
808
+ for (const [name, value] of Object.entries(this.constants)) {
809
+ if (typeof value !== "number") {
810
+ throw new KernelSyntaxError(`constant "${name}" isn't a number (got ${typeof value})`);
811
+ }
812
+ if (name === "RAND_SEED") continue;
813
+ assertUsableIdent(name);
814
+ lines.push(`const CONST_${name}: f32 = ${wgslF32(value)};`);
815
+ }
816
+ lines.push(`const OUT_X: u32 = ${ox}u;`);
817
+ lines.push(`const OUT_Y: u32 = ${oy}u;`);
818
+ lines.push(`const OUT_Z: u32 = ${oz}u;`);
819
+ lines.push(`const STRIDE: u32 = ${this.opts.outputStride}u;`);
820
+ if (this.constants.RAND_SEED !== undefined) {
821
+ lines.push(`const RAND_SEED: u32 = ${this.constants.RAND_SEED >>> 0}u;`);
822
+ }
823
+ lines.push("");
824
+ lines.push(decls.join("\n"));
825
+ lines.push("");
826
+
827
+ // prologue: scalar param locals (+ rand state), then body
828
+ let prologue = "";
829
+ this.scalarSlot.forEach((slot, name) => {
830
+ prologue += ` var ${name} = scalars[${slot}u];\n`;
831
+ });
832
+ // Emit the body, retrying while int-typed vars get widened to f32.
833
+ let bodyStr = "";
834
+ do {
835
+ this.dirty = false;
836
+ this.push();
837
+ bodyStr = "";
838
+ body.forEach((s: any) => { bodyStr += this.stmt(s, " "); });
839
+ this.pop();
840
+ } while (this.dirty);
841
+ // Kernels that fall through without a return produce 0.
842
+ bodyStr += ` return ${this.opts.outputStride > 1 ? `vec${this.opts.outputStride}<f32>()` : "0.0"};\n`;
843
+
844
+ this.helpersUsed.forEach((h) => lines.push(MATH_HELPERS[h]));
845
+ if (this.usesRandom) {
846
+ if (this.constants.RAND_SEED === undefined) {
847
+ lines.push(`const RAND_SEED: u32 = 3067833785u;`);
848
+ }
849
+ lines.push(RAND_HELPER);
850
+ }
851
+ if (this.helpersUsed.size || this.usesRandom) lines.push("");
852
+
853
+ const retTy = this.opts.outputStride > 1 ? `vec${this.opts.outputStride}<f32>` : "f32";
854
+ const randDecl = this.usesRandom
855
+ ? ` var _rs: u32 = ((gid.x * 747796405u + gid.y * 2891336453u + gid.z * 277803737u) ^ RAND_SEED) + 1u;\n`
856
+ : "";
857
+ lines.push(`fn user_kernel(gid: vec3<u32>) -> ${retTy} {`);
858
+ lines.push(prologue + randDecl + bodyStr.trimEnd());
859
+ lines.push(`}`);
860
+ lines.push("");
861
+ const [wx, wy, wz] = this.opts.workgroupSize;
862
+ lines.push(`@compute @workgroup_size(${wx}, ${wy}, ${wz})`);
863
+ lines.push(`fn main(@builtin(global_invocation_id) gid: vec3<u32>) {`);
864
+ lines.push(` if (gid.x >= OUT_X || gid.y >= OUT_Y || gid.z >= OUT_Z) { return; }`);
865
+ lines.push(` let idx = (gid.z * OUT_Y + gid.y) * OUT_X + gid.x;`);
866
+ lines.push(` let v = user_kernel(gid);`);
867
+ if (this.opts.outputStride === 1) {
868
+ lines.push(` result[idx] = v;`);
869
+ } else {
870
+ lines.push(` let base = idx * STRIDE;`);
871
+ for (let i = 0; i < this.opts.outputStride; i++) {
872
+ lines.push(` result[base + ${i}u] = v[${i}u];`);
873
+ }
874
+ }
875
+ lines.push(`}`);
876
+
877
+ return {
878
+ wgsl: lines.join("\n"),
879
+ paramOrder: [...this.params],
880
+ bindings,
881
+ scalarSlots: this.scalarSlot,
882
+ scalarsBinding,
883
+ resultBinding,
884
+ resultComponents: this.opts.outputStride,
885
+ };
886
+ }
887
+ }
888
+
889
+ /** Extract the function node from kernel source (`function (...) {}`, arrows). */
890
+ function parseKernelFn(source: string): any {
891
+ let ast: any;
892
+ try {
893
+ ast = acorn.parse(`(${source})`, { ecmaVersion: "latest" });
894
+ } catch (e) {
895
+ throw new KernelSyntaxError(`can't parse kernel source: ${(e as Error).message}`);
896
+ }
897
+ const stmt = ast.body[0];
898
+ if (stmt?.type !== "ExpressionStatement") {
899
+ throw new KernelSyntaxError(`kernel must be a single function expression`);
900
+ }
901
+ const fn = stmt.expression;
902
+ if (fn.async || fn.generator) {
903
+ throw new KernelSyntaxError(`kernel can't be async or a generator`);
904
+ }
905
+ if (fn.type === "FunctionExpression" || fn.type === "FunctionDeclaration") return fn;
906
+ if (fn.type === "ArrowFunctionExpression") {
907
+ if (fn.body.type !== "BlockStatement") {
908
+ fn.body = { type: "BlockStatement", body: [{ type: "ReturnStatement", argument: fn.body }] };
909
+ }
910
+ return fn;
911
+ }
912
+ throw new KernelSyntaxError(`kernel must be a function expression — got "${fn.type}"`);
913
+ }
914
+
915
+ /**
916
+ * Transpile a restricted-JS kernel function to a complete WGSL module.
917
+ *
918
+ * `source` is `fn.toString()`. `argKinds[i]` classifies each parameter:
919
+ * "array" (TypedArray → storage buffer), "buffer" (GPUBuffer → direct bind),
920
+ * "scalar" (number → packed into the scalars buffer).
921
+ */
922
+ export function transpileKernel(source: string, opts: TranspileOptions): TranspileResult {
923
+ const fn = parseKernelFn(source);
924
+ const params: string[] = fn.params.map((p: any) => {
925
+ if (p.type !== "Identifier") {
926
+ throw new KernelSyntaxError(`kernel params must be plain identifiers`, p);
927
+ }
928
+ assertUsableIdent(p.name, p);
929
+ return p.name;
930
+ });
931
+ if (params.length > opts.argKinds.length) {
932
+ throw new KernelSyntaxError(
933
+ `kernel takes ${params.length} params but argKinds declares ${opts.argKinds.length}`);
934
+ }
935
+ if (new Set(params).size !== params.length) {
936
+ throw new KernelSyntaxError(`kernel params must be unique`);
937
+ }
938
+ if (opts.output.length < 1 || opts.output.length > 3) {
939
+ throw new KernelSyntaxError(`output must have 1–3 dims, got ${opts.output.length}`);
940
+ }
941
+ const stride = opts.outputStride;
942
+ if (!Number.isInteger(stride) || stride < 1 || stride > 4) {
943
+ throw new KernelSyntaxError(`outputStride must be an integer 1–4, got ${stride}`);
944
+ }
945
+ for (let i = 0; i < Math.min(opts.output.length, 3); i++) {
946
+ const d = opts.output[i];
947
+ if (!Number.isInteger(d) || d <= 0) {
948
+ throw new KernelSyntaxError(`output dims must be positive integers, got ${d}`);
949
+ }
950
+ }
951
+ opts.workgroupSize.forEach((w) => {
952
+ if (!Number.isInteger(w) || w <= 0) {
953
+ throw new KernelSyntaxError(`workgroupSize must be positive integers, got ${w}`);
954
+ }
955
+ });
956
+ const emitter = new Emitter(opts, params);
957
+ return emitter.emit(fn.body.body);
958
+ }