@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,771 @@
1
+ // ============================================================================
2
+ // createStandardAutomationTools — the standard MCP automation tool set.
3
+ //
4
+ // Games previously hand-rolled ~10 identical tools in their mcp/setup.ts
5
+ // (to-the-ocean, overburden, sandjongg): capture_screenshot, inject_input,
6
+ // clear_injected_input, dispatch_key, dispatch_click, wait_for_condition,
7
+ // set_test_state, get_player_state, get_world_state, get_ui_state, plus the
8
+ // DOM-inspection trio (get_element_bounds, inspect_dom, get_element_style).
9
+ //
10
+ // This factory centralizes them. Everything game-specific is injected via
11
+ // the context object — state providers, input injector, render hooks.
12
+ //
13
+ // Usage:
14
+ //
15
+ // createMcpHarness({
16
+ // serverName: "downdraft-mygame-automation",
17
+ // tools: createStandardAutomationTools({
18
+ // canvas: () => renderer.getCanvas(),
19
+ // renderOnce: () => renderer.renderOnce(),
20
+ // input: () => renderer.getInputHandler(), // { injectInput, clearInjectedInput }
21
+ // getPlayerState: (i) => readPlayer(i),
22
+ // getWorldState: () => readWorld(),
23
+ // getUiState: () => useGameStore.getState(),
24
+ // extraTools: [...gameSpecificTools],
25
+ // }),
26
+ // });
27
+ // ============================================================================
28
+
29
+ import { getHostCapabilities, KEY, type RenderSurface } from "@downdraft/engine";
30
+ import { createLogger } from "@downdraft/engine/util/logger";
31
+ import { downdraft } from "./index";
32
+ import {
33
+ blobToBase64,
34
+ createMcpHarness,
35
+ errorResult,
36
+ jsonResult,
37
+ type McpToolRegistration
38
+ } from "./mcp-harness";
39
+
40
+ const log = createLogger("info");
41
+
42
+ // ── Types ──
43
+
44
+ /** Standard injected-input frame shape (matches the per-game handlers'). */
45
+ export interface InjectedInputFrame {
46
+ keys: Set<number>;
47
+ leftMouse: boolean;
48
+ rightMouse: boolean;
49
+ mouseDx: number;
50
+ mouseDy: number;
51
+ wheel: number;
52
+ framesRemaining: number;
53
+ }
54
+
55
+ /** Minimal input-injection surface for inject_input/clear_injected_input. */
56
+ export interface StandardInputInjector {
57
+ injectInput(frame: InjectedInputFrame): void;
58
+ clearInjectedInput(): void;
59
+ }
60
+
61
+ export type StandardToolName =
62
+ | "capture_screenshot"
63
+ | "inject_input"
64
+ | "clear_injected_input"
65
+ | "dispatch_key"
66
+ | "dispatch_click"
67
+ | "wait_for_condition"
68
+ | "set_test_state"
69
+ | "get_player_state"
70
+ | "get_world_state"
71
+ | "get_ui_state"
72
+ | "get_element_bounds"
73
+ | "inspect_dom"
74
+ | "get_element_style";
75
+
76
+ // dispatch_click: real pointer input produces a pointer* event before its
77
+ // compat mouse* event (pointerdown→mousedown, pointermove→mousemove,
78
+ // pointerup→mouseup).
79
+ const POINTER_COMPANION: Record<string, string> = {
80
+ mousedown: "pointerdown",
81
+ mouseup: "pointerup",
82
+ mousemove: "pointermove",
83
+ };
84
+ // DOM `buttons` bitmask per `button` index (0=left→1, 1=middle→4, 2=right→2).
85
+ const MOUSE_BUTTON_MASK = [1, 4, 2];
86
+
87
+ // dispatch_key: KeyboardEventInit carries no keyCode, but engine UI code
88
+ // (e.g. UITextInput) reads it — derive the legacy DOM value from `key`.
89
+ const DOM_KEY_CODES: Record<string, number> = {
90
+ Backspace: 8, Tab: 9, Enter: 13, Shift: 16, Control: 17, Alt: 18,
91
+ Pause: 19, CapsLock: 20, Escape: 27, " ": 32, PageUp: 33, PageDown: 34,
92
+ End: 35, Home: 36, ArrowLeft: 37, ArrowUp: 38, ArrowRight: 39,
93
+ ArrowDown: 40, Insert: 45, Delete: 46, Meta: 91,
94
+ };
95
+ function domKeyCodeFor(key: string): number {
96
+ if (key.length === 1) {
97
+ const c = key.toUpperCase().charCodeAt(0);
98
+ if (c >= 32 && c <= 126) return c;
99
+ }
100
+ return DOM_KEY_CODES[key] ?? 0;
101
+ }
102
+
103
+ export interface StandardAutomationContext {
104
+ /** The game render surface (layer 0). Used by capture_screenshot + dispatch_click. */
105
+ surface: RenderSurface | (() => RenderSurface | null);
106
+
107
+ /**
108
+ * Extra canvases to composite between the game canvas and the DOM overlay
109
+ * in full-page screenshots (e.g. a 2D tile canvas). DOM hosts only —
110
+ * native capture returns the composited swapchain via captureFrame().
111
+ * Default: none.
112
+ */
113
+ extraLayers?: () => HTMLCanvasElement[];
114
+
115
+ /**
116
+ * Render one frame when the render loop is paused (deterministic mode), so
117
+ * screenshots reflect current state. Called by capture_screenshot when the
118
+ * game reports not-running. Omit if the canvas is always live.
119
+ */
120
+ renderOnce?: () => void;
121
+ /** Whether the render loop is running. Default: true (always live). */
122
+ isRunning?: () => boolean;
123
+ /**
124
+ * Default value of the `fullPage` param in capture_screenshot when the
125
+ * caller omits it. Default: true (composite game canvas + DOM overlay).
126
+ */
127
+ fullPageDefault?: boolean;
128
+
129
+ /**
130
+ * Input injector for inject_input / clear_injected_input. Typically
131
+ * `() => renderer.getInputHandler()`. Omit to exclude those tools.
132
+ */
133
+ input?: () => StandardInputInjector | null;
134
+ /** Key-name → DOM keyCode overrides merged over core's KEY map. */
135
+ keyMap?: Record<string, number>;
136
+
137
+ /**
138
+ * State providers for the get_*_state tools and wait_for_condition's
139
+ * `player`/`world`/`tick` variables. Omit any to exclude that tool; a
140
+ * missing provider also removes the corresponding variable from
141
+ * wait_for_condition (it will be undefined).
142
+ */
143
+ /**
144
+ * The playerIndex param is `undefined` when the caller omits it, so
145
+ * providers can apply a game-specific default (e.g. the active player).
146
+ */
147
+ getPlayerState?: (playerIndex: number | undefined) => unknown;
148
+ getWorldState?: () => unknown | Promise<unknown>;
149
+ getUiState?: () => unknown;
150
+
151
+ /**
152
+ * Extra variables exposed to wait_for_condition expressions, keyed by name.
153
+ * E.g. `{ ui: () => store.getState() }` exposes `ui` in the predicate.
154
+ */
155
+ conditionVars?: Record<string, () => unknown>;
156
+
157
+ /**
158
+ * Game-specific test-state handler for set_test_state — receives the raw
159
+ * params (minus the built-in keys handled here: pauseRendering,
160
+ * resumeRendering, targetFPS). Omit to exclude the built-in tool.
161
+ */
162
+ setTestState?: (params: Record<string, unknown>) => void | Promise<void>;
163
+ /** Pause the render loop (set_test_state pauseRendering). */
164
+ pauseRendering?: () => void;
165
+ /** Resume the render loop (set_test_state resumeRendering). */
166
+ resumeRendering?: () => void;
167
+ /** Set a target FPS cap (set_test_state targetFPS). */
168
+ setTargetFPS?: (fps: number) => void;
169
+
170
+ /** Game-specific tools appended to the standard set. */
171
+ extraTools?: McpToolRegistration[];
172
+ /** Restrict to a subset of standard tools. Default: all applicable. */
173
+ include?: StandardToolName[];
174
+ /** Exclude standard tools by name. Default: none. */
175
+ exclude?: StandardToolName[];
176
+ }
177
+
178
+ // ── Helpers ──
179
+
180
+ const DEFAULT_KEY_MAP: Record<string, number> = { ...KEY };
181
+
182
+ function resolveKeys(keys: (string | number)[], keyMap: Record<string, number>): Set<number> {
183
+ const out = new Set<number>();
184
+ keys.forEach((k) => {
185
+ if (typeof k === "number") out.add(k);
186
+ else {
187
+ const code = keyMap[k.toUpperCase()];
188
+ if (code !== undefined) out.add(code);
189
+ }
190
+ });
191
+ return out;
192
+ }
193
+
194
+ function resolveSurface(surface: StandardAutomationContext["surface"]): RenderSurface | null {
195
+ return typeof surface === "function" ? surface() : surface;
196
+ }
197
+
198
+ // ── Factory ──
199
+
200
+ /**
201
+ * Build the standard MCP automation tool set. Returns McpToolRegistration[]
202
+ * suitable for `createMcpHarness({ tools })`.
203
+ */
204
+ export function createStandardAutomationTools(ctx: StandardAutomationContext): McpToolRegistration[] {
205
+ const keyMap = { ...DEFAULT_KEY_MAP, ...ctx.keyMap };
206
+ const tools: McpToolRegistration[] = [];
207
+
208
+ const want = (name: StandardToolName): boolean => {
209
+ if (ctx.include && !ctx.include.includes(name)) return false;
210
+ if (ctx.exclude?.includes(name)) return false;
211
+ return true;
212
+ };
213
+
214
+ // ── capture_screenshot ──
215
+ if (want("capture_screenshot")) {
216
+ tools.push({
217
+ def: {
218
+ name: "capture_screenshot",
219
+ description:
220
+ "Capture the current frame as a PNG image. By default composites the game canvas with the UI overlay (HUD, menus, etc.). Set fullPage=false to capture only the game canvas. Returns the image inline as base64.",
221
+ inputSchema: {
222
+ type: "object",
223
+ properties: {
224
+ fullPage: {
225
+ type: "boolean",
226
+ default: true,
227
+ description: "If true, composite the game canvas + extra layers + DOM overlay. If false, capture only the game canvas.",
228
+ },
229
+ },
230
+ },
231
+ },
232
+ handler: async (params: Record<string, unknown>) => {
233
+ const surface = resolveSurface(ctx.surface);
234
+ if (!surface) return errorResult("Surface not available");
235
+ const fullPage = (params.fullPage as boolean | undefined) ?? ctx.fullPageDefault ?? true;
236
+ const width = surface.width;
237
+ const height = surface.height;
238
+
239
+ // If the render loop is paused (test/headless mode), render one frame
240
+ // first so the screenshot reflects current simulation state.
241
+ if (ctx.isRunning && !ctx.isRunning()) ctx.renderOnce?.();
242
+
243
+ if (fullPage) {
244
+ // Host capture: captureFrame() returns the fully composited
245
+ // swapchain (game + all overlay layers) — no DOM composite
246
+ // needed.
247
+ if (typeof downdraft?.captureFrame === "function") {
248
+ try {
249
+ const framePng = await downdraft.captureFrame();
250
+ if (framePng && framePng.byteLength > 0) {
251
+ const u8 = new Uint8Array(framePng);
252
+ let bin = "";
253
+ for (let i = 0; i < u8.length; i += 0x8000) {
254
+ bin += String.fromCharCode(...u8.subarray(i, i + 0x8000));
255
+ }
256
+ const base64 = btoa(bin);
257
+ return {
258
+ content: [
259
+ { type: "text", text: JSON.stringify({ width, height, fullPage: true }, null, 2) },
260
+ { type: "image", data: base64, mimeType: "image/png" },
261
+ ],
262
+ };
263
+ }
264
+ } catch (e) {
265
+ log.warn("MCP", `Host frame capture failed, falling back to canvas-only: ${(e as Error).message}`);
266
+ }
267
+ }
268
+ }
269
+
270
+ // Surface-only capture. toBlob is a canvas-compat API — it exists on
271
+ // HTMLCanvasElement and the native surface's canvas-compat layer,
272
+ // but is not part of the RenderSurface contract.
273
+ const toBlob = (surface as { toBlob?: (cb: (b: Blob | null) => void, type?: string) => void }).toBlob;
274
+ if (typeof toBlob !== "function") {
275
+ return errorResult("Screenshot capture requires canvas.toBlob or a host captureFrame()");
276
+ }
277
+ const blob = await new Promise<Blob | null>((resolve) => {
278
+ toBlob.call(surface, (b) => resolve(b), "image/png");
279
+ });
280
+ if (!blob) return errorResult("Screenshot capture failed");
281
+ const base64 = await blobToBase64(blob);
282
+ return {
283
+ content: [
284
+ { type: "text", text: JSON.stringify({ width, height, fullPage: false }, null, 2) },
285
+ { type: "image", data: base64, mimeType: "image/png" },
286
+ ],
287
+ };
288
+ },
289
+ });
290
+ }
291
+
292
+ // ── inject_input ──
293
+ if (want("inject_input") && ctx.input) {
294
+ tools.push({
295
+ def: {
296
+ name: "inject_input",
297
+ description: "Inject keyboard/mouse input for a number of frames. Useful for automation tests when no real user is interacting with the game.",
298
+ inputSchema: {
299
+ type: "object",
300
+ properties: {
301
+ playerIndex: { type: "number", description: "Player slot index", default: 0 },
302
+ keys: {
303
+ type: "array",
304
+ items: { type: "string" },
305
+ description: "Key names to hold (e.g. ['W','A','SPACE']) or keyCodes if numbers",
306
+ default: [],
307
+ },
308
+ leftMouse: { type: "boolean", default: false },
309
+ rightMouse: { type: "boolean", default: false },
310
+ mouseDx: { type: "number", default: 0 },
311
+ mouseDy: { type: "number", default: 0 },
312
+ wheel: { type: "number", default: 0 },
313
+ frames: { type: "number", description: "Number of frames to hold the input", default: 1 },
314
+ },
315
+ },
316
+ },
317
+ handler: (params: Record<string, unknown>) => {
318
+ const input = ctx.input!();
319
+ if (!input) return errorResult("Input handler not initialized");
320
+ const frames = Math.max(1, Math.floor((params.frames as number) ?? 1));
321
+ input.injectInput({
322
+ keys: resolveKeys((params.keys as (string | number)[]) ?? [], keyMap),
323
+ leftMouse: !!params.leftMouse,
324
+ rightMouse: !!params.rightMouse,
325
+ mouseDx: (params.mouseDx as number) ?? 0,
326
+ mouseDy: (params.mouseDy as number) ?? 0,
327
+ wheel: (params.wheel as number) ?? 0,
328
+ framesRemaining: frames,
329
+ });
330
+ return jsonResult({ injected: true, frames, playerIndex: (params.playerIndex as number) ?? 0 });
331
+ },
332
+ });
333
+ }
334
+
335
+ // ── clear_injected_input ──
336
+ if (want("clear_injected_input") && ctx.input) {
337
+ tools.push({
338
+ def: {
339
+ name: "clear_injected_input",
340
+ description: "Clear any pending injected input frames.",
341
+ inputSchema: { type: "object", properties: {} },
342
+ },
343
+ handler: () => {
344
+ const input = ctx.input!();
345
+ if (!input) return errorResult("Input handler not initialized");
346
+ input.clearInjectedInput();
347
+ return jsonResult({ cleared: true });
348
+ },
349
+ });
350
+ }
351
+
352
+ // ── dispatch_key ──
353
+ if (want("dispatch_key")) {
354
+ tools.push({
355
+ def: {
356
+ name: "dispatch_key",
357
+ description: "Dispatch a real DOM keyboard event on the main thread (keydown or keyup). This tests the full input pipeline: DOM event → game handler.",
358
+ inputSchema: {
359
+ type: "object",
360
+ properties: {
361
+ key: { type: "string", description: "Key value (e.g. 'i', 'Tab', 'Escape')" },
362
+ code: { type: "string", description: "Key code (e.g. 'KeyI', 'Tab', 'Escape')" },
363
+ type: { type: "string", enum: ["keydown", "keyup"], default: "keydown" },
364
+ repeat: { type: "boolean", default: false },
365
+ },
366
+ required: ["key"],
367
+ },
368
+ },
369
+ handler: (params: Record<string, unknown>) => {
370
+ const key = params.key as string;
371
+ const code = (params.code as string) ?? key;
372
+ const type = (params.type as string) ?? "keydown";
373
+ const ev = new KeyboardEvent(type, {
374
+ key, code, keyCode: domKeyCodeFor(key),
375
+ bubbles: true, cancelable: true, repeat: !!params.repeat,
376
+ } as KeyboardEventInit);
377
+ // Real KeyboardEvent ignores keyCode in the init dict — force it.
378
+ try { Object.defineProperty(ev, "keyCode", { value: domKeyCodeFor(key) }); } catch { /* polyfill already set it */ }
379
+ window.dispatchEvent(ev);
380
+ return jsonResult({ dispatched: true, key, code, type });
381
+ },
382
+ });
383
+ }
384
+
385
+ // ── dispatch_click ──
386
+ if (want("dispatch_click")) {
387
+ tools.push({
388
+ def: {
389
+ name: "dispatch_click",
390
+ description: "Dispatch a real DOM click event at canvas-relative coordinates. The event hits the topmost element at that point (mimics a real user click through UI overlays).",
391
+ inputSchema: {
392
+ type: "object",
393
+ properties: {
394
+ x: { type: "number", description: "X coordinate (default: center of canvas)" },
395
+ y: { type: "number", description: "Y coordinate (default: center of canvas)" },
396
+ type: { type: "string", enum: ["click", "mousedown", "mouseup", "mousemove", "wheel"], default: "click", description: "Event type — 'click' fires the full press/release sequence (pointerdown→mousedown→pointerup→mouseup→click); mousedown/mouseup/mousemove fire just that event plus its pointer* companion. 'wheel' fires a WheelEvent with deltaX/deltaY." },
397
+ button: { type: "number", description: "Mouse button (0=left, 1=middle, 2=right). Default 0." },
398
+ deltaX: { type: "number", description: "Wheel deltaX in pixels (type=wheel only). Default 0." },
399
+ deltaY: { type: "number", description: "Wheel deltaY in pixels (type=wheel only). Default 120 (one detent down)." },
400
+ },
401
+ },
402
+ },
403
+ handler: (params: Record<string, unknown>) => {
404
+ const surface = resolveSurface(ctx.surface);
405
+ if (!surface) return errorResult("Surface not available");
406
+ const x = (params.x as number) ?? surface.clientWidth / 2;
407
+ const y = (params.y as number) ?? surface.clientHeight / 2;
408
+ const type = (params.type as string) ?? "click";
409
+ const button = (params.button as number) ?? 0;
410
+ const rect = surface.getBoundingClientRect();
411
+ const clientX = rect.left + x;
412
+ const clientY = rect.top + y;
413
+ const hasDom = getHostCapabilities().hasDom;
414
+ // DOM hosts hit-test the topmost element (mimics a real user click
415
+ // through UI overlays). On native there is no DOM tree — the surface
416
+ // itself is the input target.
417
+ const target = hasDom
418
+ ? (document.elementFromPoint(clientX, clientY) ?? (surface as unknown as HTMLElement))
419
+ : (surface as unknown as EventTarget);
420
+ // MiniEventTarget (native event polyfill) has no capture/bubble —
421
+ // mirror real propagation by also dispatching on window. In a real
422
+ // DOM this would double-fire, so only do it under the polyfill.
423
+ const isNativeDom = !hasDom;
424
+ const fire = (ev: Event) => {
425
+ target.dispatchEvent(ev);
426
+ if (isNativeDom) (window as any).dispatchEvent?.(ev);
427
+ };
428
+ if (type === "wheel") {
429
+ const deltaX = (params.deltaX as number) ?? 0;
430
+ const deltaY = (params.deltaY as number) ?? 120;
431
+ fire(new WheelEvent("wheel", {
432
+ bubbles: true, cancelable: true, clientX, clientY, deltaX, deltaY, deltaMode: 0,
433
+ }));
434
+ return jsonResult({ dispatched: true, x, y, type, deltaX, deltaY });
435
+ }
436
+ // Real pointer input produces the pointer* event before its compat
437
+ // mouse* event. RendererInputBus listens on pointer*; older UI code
438
+ // listens on mouse* — emit both so either sees a real click.
439
+ const PtrEvent = (globalThis as any).PointerEvent;
440
+ const downMask = MOUSE_BUTTON_MASK[button] ?? 1;
441
+ const fireOne = (name: string, isPointer: boolean, buttons: number) => {
442
+ if (isPointer && PtrEvent) {
443
+ fire(new PtrEvent(name, {
444
+ bubbles: true, cancelable: true, clientX, clientY, button, buttons,
445
+ pointerId: 1, pointerType: "mouse", isPrimary: true,
446
+ }));
447
+ } else if (!isPointer) {
448
+ fire(new MouseEvent(name, { bubbles: true, cancelable: true, clientX, clientY, button, buttons }));
449
+ }
450
+ };
451
+ if (type === "click") {
452
+ // A real click is a full press/release cycle — UI hit-testing needs
453
+ // the pointerdown→pointerup pair to register press and click.
454
+ fireOne("pointerdown", true, downMask);
455
+ fireOne("mousedown", false, downMask);
456
+ fireOne("pointerup", true, 0);
457
+ fireOne("mouseup", false, 0);
458
+ fireOne("click", false, 0);
459
+ } else {
460
+ const buttons = type === "mouseup" || type === "mousemove" ? 0 : downMask;
461
+ const pointerType = POINTER_COMPANION[type];
462
+ if (pointerType) fireOne(pointerType, true, buttons);
463
+ fireOne(type, false, buttons);
464
+ }
465
+ const targetEl = target as Partial<HTMLElement>;
466
+ return jsonResult({
467
+ dispatched: true, x, y, type,
468
+ targetTag: targetEl.tagName ?? (targetEl as { id?: string }).id ?? "surface",
469
+ targetClass: targetEl.className?.toString().slice(0, 80),
470
+ });
471
+ },
472
+ });
473
+ }
474
+
475
+ // ── wait_for_condition ──
476
+ if (want("wait_for_condition")) {
477
+ tools.push({
478
+ def: {
479
+ name: "wait_for_condition",
480
+ description: "Poll until a condition on game state is met or a timeout occurs. Conditions are JS predicate expressions evaluated against named state variables (e.g. 'player.position[1] < -2').",
481
+ inputSchema: {
482
+ type: "object",
483
+ properties: {
484
+ condition: {
485
+ type: "string",
486
+ description: "JavaScript predicate expression. Variables: player, world, tick (when providers configured) plus any conditionVars.",
487
+ },
488
+ timeoutMs: { type: "number", default: 5000, description: "Maximum time to wait in milliseconds" },
489
+ intervalMs: { type: "number", default: 50, description: "Polling interval" },
490
+ },
491
+ required: ["condition"],
492
+ },
493
+ },
494
+ handler: async (params: Record<string, unknown>) => {
495
+ const condition = params.condition as string;
496
+ const timeoutMs = (params.timeoutMs as number) ?? 5000;
497
+ const intervalMs = (params.intervalMs as number) ?? 50;
498
+ const start = performance.now();
499
+
500
+ const extraNames = Object.keys(ctx.conditionVars ?? {});
501
+ const names = ["player", "world", "tick", ...extraNames];
502
+
503
+ return new Promise((resolve) => {
504
+ const check = async () => {
505
+ const player = ctx.getPlayerState?.(0) ?? null;
506
+ const world = (await ctx.getWorldState?.()) ?? null;
507
+ const tick = (world as { tick?: number } | null)?.tick ?? 0;
508
+ const extraValues = extraNames.map((n) => ctx.conditionVars![n]());
509
+ try {
510
+ // eslint-disable-next-line no-new-func
511
+ const fn = new Function(...names, `"use strict"; return (${condition});`);
512
+ if (fn(player, world, tick, ...extraValues)) {
513
+ resolve(jsonResult({ satisfied: true, elapsedMs: performance.now() - start, player, world }));
514
+ return;
515
+ }
516
+ } catch (e) {
517
+ resolve(errorResult(`Condition evaluation error: ${(e as Error).message}`));
518
+ return;
519
+ }
520
+ if (performance.now() - start > timeoutMs) {
521
+ resolve(errorResult(`Timeout waiting for condition: ${condition}`));
522
+ return;
523
+ }
524
+ setTimeout(check, intervalMs);
525
+ };
526
+ check();
527
+ });
528
+ },
529
+ });
530
+ }
531
+
532
+ // ── set_test_state ──
533
+ if (want("set_test_state") && (ctx.setTestState || ctx.pauseRendering || ctx.resumeRendering || ctx.setTargetFPS)) {
534
+ tools.push({
535
+ def: {
536
+ name: "set_test_state",
537
+ description: "Set deterministic game state for tests. Built-in keys: pauseRendering, resumeRendering, targetFPS. Additional keys are forwarded to the game's setTestState handler.",
538
+ inputSchema: {
539
+ type: "object",
540
+ properties: {
541
+ pauseRendering: { type: "boolean", description: "Pause the continuous render loop to save CPU. Screenshot capture still works (renders on demand)." },
542
+ resumeRendering: { type: "boolean", description: "Resume the continuous render loop." },
543
+ targetFPS: { type: "number", description: "Set a target FPS limit for the render loop (0 = unlimited)." },
544
+ },
545
+ },
546
+ },
547
+ handler: async (params: Record<string, unknown>) => {
548
+ if (params.pauseRendering) ctx.pauseRendering?.();
549
+ if (params.resumeRendering) ctx.resumeRendering?.();
550
+ if (params.targetFPS !== undefined) ctx.setTargetFPS?.(params.targetFPS as number);
551
+ if (ctx.setTestState) {
552
+ const { pauseRendering: _p, resumeRendering: _r, targetFPS: _t, ...rest } = params;
553
+ await ctx.setTestState(rest);
554
+ }
555
+ return jsonResult({ applied: true, params });
556
+ },
557
+ });
558
+ }
559
+
560
+ // ── get_player_state ──
561
+ if (want("get_player_state") && ctx.getPlayerState) {
562
+ tools.push({
563
+ def: {
564
+ name: "get_player_state",
565
+ description: "Read the current state of a player from the simulation SharedArrayBuffer.",
566
+ inputSchema: {
567
+ type: "object",
568
+ properties: { playerIndex: { type: "number", default: 0 } },
569
+ },
570
+ },
571
+ handler: (params: Record<string, unknown>) => {
572
+ const playerIndex = params.playerIndex as number | undefined;
573
+ const state = ctx.getPlayerState!(playerIndex);
574
+ if (state === null || state === undefined) return errorResult(`Player ${playerIndex} not available`);
575
+ return jsonResult(state);
576
+ },
577
+ });
578
+ }
579
+
580
+ // ── get_world_state ──
581
+ if (want("get_world_state") && ctx.getWorldState) {
582
+ tools.push({
583
+ def: {
584
+ name: "get_world_state",
585
+ description: "Read global simulation state (tick, entity count, weather, etc.).",
586
+ inputSchema: { type: "object", properties: {} },
587
+ },
588
+ handler: async () => {
589
+ const state = await ctx.getWorldState!();
590
+ if (state === null || state === undefined) return errorResult("World state not available");
591
+ return jsonResult(state);
592
+ },
593
+ });
594
+ }
595
+
596
+ // ── get_ui_state ──
597
+ if (want("get_ui_state") && ctx.getUiState) {
598
+ tools.push({
599
+ def: {
600
+ name: "get_ui_state",
601
+ description: "Read the current UI store state (menu visibility, pointer lock, readiness flags, etc.).",
602
+ inputSchema: { type: "object", properties: {} },
603
+ },
604
+ handler: () => jsonResult(ctx.getUiState!()),
605
+ });
606
+ }
607
+
608
+ // ── get_element_bounds ──
609
+ if (want("get_element_bounds")) {
610
+ tools.push({
611
+ def: {
612
+ name: "get_element_bounds",
613
+ description: "Get the bounding box of a DOM element matching a CSS selector. Returns {x, y, width, height, top, left, bottom, right} or found:false.",
614
+ inputSchema: {
615
+ type: "object",
616
+ properties: { selector: { type: "string", description: "CSS selector" } },
617
+ required: ["selector"],
618
+ },
619
+ },
620
+ handler: (params: Record<string, unknown>) => {
621
+ const selector = params.selector as string;
622
+ try {
623
+ const el = document.querySelector(selector);
624
+ if (!el) return jsonResult({ found: false, selector });
625
+ const rect = el.getBoundingClientRect();
626
+ return jsonResult({
627
+ found: true, selector,
628
+ x: rect.x, y: rect.y, width: rect.width, height: rect.height,
629
+ top: rect.top, left: rect.left, bottom: rect.bottom, right: rect.right,
630
+ });
631
+ } catch (e) {
632
+ return errorResult(`Failed to query selector "${selector}": ${(e as Error).message}`);
633
+ }
634
+ },
635
+ });
636
+ }
637
+
638
+ // ── inspect_dom ──
639
+ if (want("inspect_dom")) {
640
+ tools.push({
641
+ def: {
642
+ name: "inspect_dom",
643
+ description: "Inspect the main thread's DOM for debugging CSS/layout issues. 'stylesheets' lists all <style>/<link> tags; 'element' gets details for a selector.",
644
+ inputSchema: {
645
+ type: "object",
646
+ properties: {
647
+ action: { type: "string", enum: ["stylesheets", "element"] },
648
+ selector: { type: "string", description: "CSS selector (for action='element')" },
649
+ },
650
+ required: ["action"],
651
+ },
652
+ },
653
+ handler: (params: Record<string, unknown>) => {
654
+ if (!getHostCapabilities().hasDom) {
655
+ return errorResult("inspect_dom requires a real DOM — the native host's document is a canvas-compat facade, not a DOM tree");
656
+ }
657
+ const action = params.action as string;
658
+ if (action === "stylesheets") {
659
+ const styles = Array.from(document.querySelectorAll("style, link[rel='stylesheet']")).map((el) => {
660
+ const tag = el.tagName.toLowerCase();
661
+ if (tag === "style") {
662
+ const text = el.textContent ?? "";
663
+ return { tag, length: text.length, preview: text.slice(0, 200) };
664
+ }
665
+ return { tag, href: (el as HTMLLinkElement).href };
666
+ });
667
+ return jsonResult({ stylesheets: styles, count: styles.length });
668
+ }
669
+ if (action === "element" && params.selector) {
670
+ const el = document.querySelector(params.selector as string);
671
+ if (!el) return jsonResult({ found: false, selector: params.selector });
672
+ const cs = getComputedStyle(el);
673
+ return jsonResult({
674
+ found: true,
675
+ selector: params.selector,
676
+ tagName: el.tagName,
677
+ className: el.className,
678
+ id: el.id,
679
+ style: {
680
+ width: cs.width, height: cs.height,
681
+ maxWidth: cs.maxWidth, maxHeight: cs.maxHeight,
682
+ display: cs.display, position: cs.position,
683
+ top: cs.top, left: cs.left, overflow: cs.overflow,
684
+ },
685
+ bounds: el.getBoundingClientRect().toJSON(),
686
+ childCount: el.children.length,
687
+ });
688
+ }
689
+ return errorResult("Invalid action or missing selector");
690
+ },
691
+ });
692
+ }
693
+
694
+ // ── get_element_style ──
695
+ if (want("get_element_style")) {
696
+ tools.push({
697
+ def: {
698
+ name: "get_element_style",
699
+ description: "Get computed style of a DOM element matching a CSS selector. Pass properties[] to read specific CSS properties.",
700
+ inputSchema: {
701
+ type: "object",
702
+ properties: {
703
+ selector: { type: "string", description: "CSS selector" },
704
+ properties: { type: "array", items: { type: "string" }, description: "CSS properties to read" },
705
+ },
706
+ required: ["selector"],
707
+ },
708
+ },
709
+ handler: (params: Record<string, unknown>) => {
710
+ if (!getHostCapabilities().hasDom) {
711
+ return errorResult("get_element_style requires a real DOM — no computed styles on the native host");
712
+ }
713
+ const selector = params.selector as string;
714
+ const props = (params.properties as string[]) ?? [];
715
+ try {
716
+ const el = document.querySelector(selector);
717
+ if (!el) return jsonResult({ found: false, selector });
718
+ const cs = getComputedStyle(el);
719
+ const result: Record<string, unknown> = { found: true, selector };
720
+ props.forEach((p) => { result[p] = cs.getPropertyValue(p);; });
721
+ result._className = el.className;
722
+ return jsonResult(result);
723
+ } catch (e) {
724
+ return errorResult(`Failed to query style for "${selector}": ${(e as Error).message}`);
725
+ }
726
+ },
727
+ });
728
+ }
729
+
730
+ return [...tools, ...(ctx.extraTools ?? [])];
731
+ }
732
+
733
+ // ── createGameMcp — one-liner harness setup ──
734
+ //
735
+ // Every game ended the same way: wrap createStandardAutomationTools() in
736
+ // createMcpHarness() inside a try/catch, deriving serverName from the host
737
+ // appId. This folds that ceremony into one call:
738
+ //
739
+ // createGameMcp({
740
+ // appId: "downdraft-mygame", // → serverName "<appId>-automation"
741
+ // surface: () => renderer.getSurface(),
742
+ // getUiState: () => store.getState(),
743
+ // tools: [...gameSpecificTools],
744
+ // });
745
+ //
746
+ // Non-fatal by design — logs a warning and returns when the host bridge or
747
+ // tool construction fails (matches the per-game try/catch it replaces).
748
+ export interface GameMcpOptions extends StandardAutomationContext {
749
+ /** Host appId (e.g. "downdraft-falling-sand") — serverName becomes `<appId>-automation`. */
750
+ appId: string;
751
+ /** Game-specific tools appended after the standard set (alias of extraTools). */
752
+ tools?: McpToolRegistration[];
753
+ /** MCP server version. Default "0.1.0". */
754
+ serverVersion?: string;
755
+ }
756
+
757
+ export function createGameMcp(opts: GameMcpOptions): void {
758
+ const { appId, tools, serverVersion, ...ctx } = opts;
759
+ try {
760
+ createMcpHarness({
761
+ serverName: `${appId}-automation`,
762
+ serverVersion,
763
+ tools: createStandardAutomationTools({
764
+ ...ctx,
765
+ extraTools: [...(ctx.extraTools ?? []), ...(tools ?? [])],
766
+ }),
767
+ });
768
+ } catch (e) {
769
+ log.warn("MCP", `${appId} automation harness setup failed (non-fatal): ${e}`);
770
+ }
771
+ }