@downdraft/engine 0.0.0 → 0.1.1

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 (908) hide show
  1. package/README.md +33 -0
  2. package/app/src/index.ts +10 -0
  3. package/app/src/renderer/bootstrap.ts +271 -0
  4. package/app/src/renderer/downdraft-base.css +93 -0
  5. package/app/src/renderer/feature-log.ts +200 -0
  6. package/app/src/renderer/game-module.ts +923 -0
  7. package/app/src/renderer/hooks.ts +88 -0
  8. package/app/src/renderer/hot-reload.ts +178 -0
  9. package/app/src/renderer/import-cache.ts +88 -0
  10. package/app/src/renderer/index.ts +206 -0
  11. package/app/src/renderer/mcp-harness.ts +144 -0
  12. package/app/src/renderer/save-store-factory.ts +239 -0
  13. package/app/src/renderer/sim-bridge.ts +183 -0
  14. package/app/src/renderer/standard-automation-tools.ts +771 -0
  15. package/app/src/shared/feature-log.ts +71 -0
  16. package/app/src/shared/gpu-info.ts +82 -0
  17. package/app/src/shared/import-cache-store.ts +142 -0
  18. package/app/src/shared/index.ts +6 -0
  19. package/app/src/shared/mcp-discovery.ts +47 -0
  20. package/app/src/shared/mcp-proxy.ts +82 -0
  21. package/app/src/shared/types.ts +324 -0
  22. package/asset-bake/src/bake-audio.ts +119 -0
  23. package/asset-bake/src/bake-gltf.ts +172 -0
  24. package/asset-bake/src/bake.ts +78 -0
  25. package/asset-bake/src/cache.ts +188 -0
  26. package/asset-bake/src/config.ts +186 -0
  27. package/asset-bake/src/index.ts +36 -0
  28. package/core/src/animation/animation-event.ts +41 -0
  29. package/core/src/animation/bone-mask.ts +122 -0
  30. package/core/src/animation/clip.ts +252 -0
  31. package/core/src/animation/index.ts +22 -0
  32. package/core/src/animation/mixamo.ts +113 -0
  33. package/core/src/animation/morph-target.ts +69 -0
  34. package/core/src/animation/player.ts +697 -0
  35. package/core/src/animation/retarget.ts +158 -0
  36. package/core/src/animation/skeleton-animator.ts +1399 -0
  37. package/core/src/animation/skeleton.ts +214 -0
  38. package/core/src/animation/state-machine.ts +280 -0
  39. package/core/src/assets/blob-store.ts +66 -0
  40. package/core/src/assets/cache.ts +186 -0
  41. package/core/src/assets/cubemap-converter.ts +155 -0
  42. package/core/src/assets/environment-manager.ts +121 -0
  43. package/core/src/assets/import-cache.ts +65 -0
  44. package/core/src/assets/import-settings.ts +72 -0
  45. package/core/src/assets/importer.ts +108 -0
  46. package/core/src/assets/index.ts +74 -0
  47. package/core/src/assets/irradiance-generator.ts +198 -0
  48. package/core/src/assets/loader-audio.ts +86 -0
  49. package/core/src/assets/loader-cubemap.ts +211 -0
  50. package/core/src/assets/loader-dds.ts +236 -0
  51. package/core/src/assets/loader-hdr.ts +474 -0
  52. package/core/src/assets/loader-mesh.ts +143 -0
  53. package/core/src/assets/loader-shader.ts +73 -0
  54. package/core/src/assets/loader-texture.ts +349 -0
  55. package/core/src/assets/lod.ts +198 -0
  56. package/core/src/assets/manager.ts +480 -0
  57. package/core/src/assets/manifest.ts +81 -0
  58. package/core/src/assets/material-bridge.ts +186 -0
  59. package/core/src/assets/model-importer.ts +72 -0
  60. package/core/src/assets/model-normalizer.ts +248 -0
  61. package/core/src/assets/model-to-gpu.ts +70 -0
  62. package/core/src/assets/model-to-mesh.ts +237 -0
  63. package/core/src/assets/prefilter-generator.ts +250 -0
  64. package/core/src/audio/engine.ts +177 -0
  65. package/core/src/audio/interface.ts +130 -0
  66. package/core/src/audio/listener.ts +32 -0
  67. package/core/src/audio/mixer.ts +141 -0
  68. package/core/src/audio/registry.ts +52 -0
  69. package/core/src/audio/sab.ts +87 -0
  70. package/core/src/audio/source.ts +89 -0
  71. package/core/src/change-detection/atomics.ts +1 -0
  72. package/core/src/change-detection/tracker.ts +47 -0
  73. package/core/src/debug-draw/lines.ts +64 -0
  74. package/core/src/debug-draw/points.ts +17 -0
  75. package/core/src/debug-draw/queue.ts +124 -0
  76. package/core/src/debug-draw/text.ts +25 -0
  77. package/core/src/ecs/archetype.ts +323 -0
  78. package/core/src/ecs/component.ts +188 -0
  79. package/core/src/ecs/entity.ts +25 -0
  80. package/core/src/ecs/events.ts +93 -0
  81. package/core/src/ecs/hierarchy.ts +124 -0
  82. package/core/src/ecs/hmr-swap-registry.ts +22 -0
  83. package/core/src/ecs/index.ts +25 -0
  84. package/core/src/ecs/query.ts +141 -0
  85. package/core/src/ecs/resource.ts +8 -0
  86. package/core/src/ecs/schedule.ts +181 -0
  87. package/core/src/ecs/system-params.ts +99 -0
  88. package/core/src/ecs/system.ts +42 -0
  89. package/core/src/ecs/world.ts +348 -0
  90. package/core/src/index.ts +352 -0
  91. package/core/src/input/context.ts +73 -0
  92. package/core/src/input/dom-handler.ts +380 -0
  93. package/core/src/input/local-player-manager.ts +218 -0
  94. package/core/src/input/mapping.ts +40 -0
  95. package/core/src/input/multi-sab-bridge.ts +276 -0
  96. package/core/src/input/multi-state.ts +54 -0
  97. package/core/src/input/sab-bridge.ts +71 -0
  98. package/core/src/input/state.ts +132 -0
  99. package/core/src/input/ui-router.ts +87 -0
  100. package/core/src/library/host.ts +317 -0
  101. package/core/src/library/index.ts +16 -0
  102. package/core/src/library/library.ts +292 -0
  103. package/core/src/material/compiler.ts +80 -0
  104. package/core/src/material/graph-bridge.ts +172 -0
  105. package/core/src/material/index.ts +9 -0
  106. package/core/src/material/library.ts +442 -0
  107. package/core/src/material/material.ts +156 -0
  108. package/core/src/material/variants.ts +61 -0
  109. package/core/src/math/mat4.ts +202 -0
  110. package/core/src/math/perlin-noise-2d.ts +77 -0
  111. package/core/src/math/perlin-noise-3d.ts +110 -0
  112. package/core/src/math/quat.ts +33 -0
  113. package/core/src/math/rng.ts +29 -0
  114. package/core/src/math/trig.ts +47 -0
  115. package/core/src/math/value-noise.ts +67 -0
  116. package/core/src/mesh/builder.ts +177 -0
  117. package/core/src/mesh/csg.ts +312 -0
  118. package/core/src/mesh/greased-line.ts +145 -0
  119. package/core/src/mesh/mesh.ts +17 -0
  120. package/core/src/mesh/parametric.ts +501 -0
  121. package/core/src/mesh/skinning.ts +67 -0
  122. package/core/src/mesh/vertex-layout.ts +91 -0
  123. package/core/src/module/cross-thread.ts +163 -0
  124. package/core/src/module/diagnostics.ts +123 -0
  125. package/core/src/module/host.ts +451 -0
  126. package/core/src/module/index.ts +22 -0
  127. package/core/src/module/module.ts +109 -0
  128. package/core/src/module/registry.ts +94 -0
  129. package/core/src/module/renderer-module.ts +247 -0
  130. package/core/src/module/ts-loader.ts +26 -0
  131. package/core/src/particles/compute-pass.ts +378 -0
  132. package/core/src/particles/emitter.ts +156 -0
  133. package/core/src/particles/index.ts +11 -0
  134. package/core/src/particles/particle-data.ts +47 -0
  135. package/core/src/particles/render-pass.ts +365 -0
  136. package/core/src/particles/simulator.ts +264 -0
  137. package/core/src/particles/system.ts +193 -0
  138. package/core/src/physics/body.ts +59 -0
  139. package/core/src/physics/ccd-heuristic.ts +55 -0
  140. package/core/src/physics/character.ts +282 -0
  141. package/core/src/physics/collider.ts +55 -0
  142. package/core/src/physics/collision-system.ts +91 -0
  143. package/core/src/physics/events.ts +133 -0
  144. package/core/src/physics/index.ts +34 -0
  145. package/core/src/physics/interface.ts +473 -0
  146. package/core/src/physics/interpolation-buffer.ts +192 -0
  147. package/core/src/physics/lifecycle.ts +87 -0
  148. package/core/src/physics/load-shedder.ts +164 -0
  149. package/core/src/physics/physics-accumulator.ts +101 -0
  150. package/core/src/physics/physics-system.ts +240 -0
  151. package/core/src/physics/ragdoll-presets.ts +272 -0
  152. package/core/src/physics/ragdoll-system.ts +220 -0
  153. package/core/src/physics/ragdoll.ts +182 -0
  154. package/core/src/physics/raycast.ts +143 -0
  155. package/core/src/physics/realm-manager.ts +499 -0
  156. package/core/src/physics/realm-worker-pool.ts +191 -0
  157. package/core/src/physics/realm-worker.ts +102 -0
  158. package/core/src/physics/realm.ts +189 -0
  159. package/core/src/physics/registry.ts +52 -0
  160. package/core/src/physics/safety.ts +247 -0
  161. package/core/src/physics/snapshot-manager.ts +141 -0
  162. package/core/src/physics/worker-protocol.ts +30 -0
  163. package/core/src/platform/bun-preload.ts +169 -0
  164. package/core/src/platform/css-stub.ts +4 -0
  165. package/core/src/platform/glob-polyfill.ts +124 -0
  166. package/core/src/platform/hidpi.ts +57 -0
  167. package/core/src/platform/render-surface.ts +77 -0
  168. package/core/src/platform/rpc.ts +98 -0
  169. package/core/src/platform/runtime.ts +132 -0
  170. package/core/src/plugin/context.ts +364 -0
  171. package/core/src/plugin/diagnostics.ts +61 -0
  172. package/core/src/plugin/discovery.ts +186 -0
  173. package/core/src/plugin/extension-loaders.ts +172 -0
  174. package/core/src/plugin/host.ts +659 -0
  175. package/core/src/plugin/index.ts +106 -0
  176. package/core/src/plugin/loader-asset.ts +124 -0
  177. package/core/src/plugin/loader-quickjs.ts +84 -0
  178. package/core/src/plugin/loader-wasm.ts +411 -0
  179. package/core/src/plugin/loader-worker.ts +261 -0
  180. package/core/src/plugin/manifest.ts +653 -0
  181. package/core/src/plugin/material-registry.ts +65 -0
  182. package/core/src/plugin/mcp-tools.ts +165 -0
  183. package/core/src/plugin/permissions.ts +175 -0
  184. package/core/src/plugin/quickjs-bridge.ts +294 -0
  185. package/core/src/plugin/registry.ts +107 -0
  186. package/core/src/plugin/sandbox-shim.ts +86 -0
  187. package/core/src/plugin/sandbox-worker.ts +215 -0
  188. package/core/src/plugin/wasm-abi.ts +152 -0
  189. package/core/src/plugin/wasm-worker.ts +229 -0
  190. package/core/src/plugin/workshop.ts +169 -0
  191. package/core/src/profiling/event-loop.ts +180 -0
  192. package/core/src/profiling/index.ts +69 -0
  193. package/core/src/profiling/iops/idb-patch.ts +242 -0
  194. package/core/src/profiling/iops/opfs-patch.ts +276 -0
  195. package/core/src/profiling/profiling-sab.ts +839 -0
  196. package/core/src/profiling/task-latency.ts +134 -0
  197. package/core/src/profiling/thread-metrics.ts +126 -0
  198. package/core/src/profiling/trace-event-writer.ts +205 -0
  199. package/core/src/profiling/warnings.ts +423 -0
  200. package/core/src/profiling/worker-prelude.ts +376 -0
  201. package/core/src/render/bind-group.ts +38 -0
  202. package/core/src/render/bindless/bindless-struct.ts +42 -0
  203. package/core/src/render/bindless/bindless.wgsl.ts +167 -0
  204. package/core/src/render/bindless/frame-bindings.ts +176 -0
  205. package/core/src/render/bindless/index.ts +10 -0
  206. package/core/src/render/bindless/material-manager.ts +257 -0
  207. package/core/src/render/bindless/texture-registry.ts +609 -0
  208. package/core/src/render/buffer.ts +82 -0
  209. package/core/src/render/camera-2d.ts +217 -0
  210. package/core/src/render/camera-controller.ts +440 -0
  211. package/core/src/render/camera.ts +409 -0
  212. package/core/src/render/canvas-resize-watcher.ts +46 -0
  213. package/core/src/render/compute-kernel.ts +172 -0
  214. package/core/src/render/constants.ts +2 -0
  215. package/core/src/render/device.ts +111 -0
  216. package/core/src/render/frame-graph.ts +768 -0
  217. package/core/src/render/frustum.ts +185 -0
  218. package/core/src/render/fullscreen-vs.ts +25 -0
  219. package/core/src/render/g-buffer.ts +186 -0
  220. package/core/src/render/game-renderer.ts +1452 -0
  221. package/core/src/render/gpu-driven/cull-pass.ts +394 -0
  222. package/core/src/render/gpu-driven/hzb.ts +215 -0
  223. package/core/src/render/gpu-driven/index.ts +7 -0
  224. package/core/src/render/gpu-driven/indirect-draw-pass.ts +324 -0
  225. package/core/src/render/gpu-driven/instance-buffer.ts +178 -0
  226. package/core/src/render/gpu-driven/mesh-table.ts +175 -0
  227. package/core/src/render/gpu-driven/passes/hzb-build-pass.ts +47 -0
  228. package/core/src/render/gpu-utils.ts +96 -0
  229. package/core/src/render/hdr.ts +88 -0
  230. package/core/src/render/hot-reload.ts +295 -0
  231. package/core/src/render/ibl-bind-group.ts +266 -0
  232. package/core/src/render/ibl.ts +180 -0
  233. package/core/src/render/index.ts +163 -0
  234. package/core/src/render/input-manager.ts +259 -0
  235. package/core/src/render/lighting/area-light.ts +196 -0
  236. package/core/src/render/lighting/cluster-grid.ts +288 -0
  237. package/core/src/render/lighting/cluster-types.ts +193 -0
  238. package/core/src/render/lighting/ies-parser.ts +162 -0
  239. package/core/src/render/lighting.ts +454 -0
  240. package/core/src/render/material-types/depth.wgsl +44 -0
  241. package/core/src/render/material-types/line.wgsl +50 -0
  242. package/core/src/render/material-types/matcap.wgsl +51 -0
  243. package/core/src/render/material-types/normal.wgsl +41 -0
  244. package/core/src/render/material-types/physical.wgsl +152 -0
  245. package/core/src/render/material-types/sprite.wgsl +46 -0
  246. package/core/src/render/material-types/sss.wgsl +79 -0
  247. package/core/src/render/material-types/toon.wgsl +79 -0
  248. package/core/src/render/passes/README.md +121 -0
  249. package/core/src/render/passes/atmosphere.ts +152 -0
  250. package/core/src/render/passes/cluster-lighting-pass.ts +476 -0
  251. package/core/src/render/passes/csm.ts +408 -0
  252. package/core/src/render/passes/cubemap-capture.ts +114 -0
  253. package/core/src/render/passes/debug-viz.ts +278 -0
  254. package/core/src/render/passes/debug.ts +538 -0
  255. package/core/src/render/passes/decal-mesh.ts +111 -0
  256. package/core/src/render/passes/decal-pass.ts +377 -0
  257. package/core/src/render/passes/deferred-lighting.ts +434 -0
  258. package/core/src/render/passes/depth-prepass.ts +163 -0
  259. package/core/src/render/passes/dome-360.ts +83 -0
  260. package/core/src/render/passes/fluid-render.ts +137 -0
  261. package/core/src/render/passes/gi-types.ts +118 -0
  262. package/core/src/render/passes/graph-compute.ts +300 -0
  263. package/core/src/render/passes/greased-line-pass.ts +232 -0
  264. package/core/src/render/passes/morph-target.ts +40 -0
  265. package/core/src/render/passes/opaque.ts +1028 -0
  266. package/core/src/render/passes/point-light-shadow.ts +266 -0
  267. package/core/src/render/passes/procedural-texture.ts +185 -0
  268. package/core/src/render/passes/reflection-probe.ts +140 -0
  269. package/core/src/render/passes/rsm-pass.ts +248 -0
  270. package/core/src/render/passes/sdf-text.ts +155 -0
  271. package/core/src/render/passes/shadow-map.ts +163 -0
  272. package/core/src/render/passes/shadow.ts +220 -0
  273. package/core/src/render/passes/skinning-vs.ts +121 -0
  274. package/core/src/render/passes/skinning.ts +326 -0
  275. package/core/src/render/passes/sky-dome.ts +404 -0
  276. package/core/src/render/passes/skybox.ts +162 -0
  277. package/core/src/render/passes/spot-light-shadow.ts +273 -0
  278. package/core/src/render/passes/terrain.ts +326 -0
  279. package/core/src/render/passes/transparent.ts +353 -0
  280. package/core/src/render/passes/underwater-fog.ts +185 -0
  281. package/core/src/render/passes/video-texture.ts +79 -0
  282. package/core/src/render/passes/volumetric-pass.ts +312 -0
  283. package/core/src/render/passes/volumetric-types.ts +171 -0
  284. package/core/src/render/passes/water.ts +753 -0
  285. package/core/src/render/pbr.ts +296 -0
  286. package/core/src/render/pipeline.ts +52 -0
  287. package/core/src/render/render-pass.ts +30 -0
  288. package/core/src/render/renderer-input-bus.ts +220 -0
  289. package/core/src/render/renderer-module-host.ts +623 -0
  290. package/core/src/render/resource-tracker.ts +67 -0
  291. package/core/src/render/sab-canvas-overlay.ts +122 -0
  292. package/core/src/render/shader-validator.ts +200 -0
  293. package/core/src/render/shaders/debug/debug-line.wgsl +27 -0
  294. package/core/src/render/shaders/debug/debug-point.wgsl +30 -0
  295. package/core/src/render/shaders/debug/debug-text.wgsl +42 -0
  296. package/core/src/render/shaders/debug-viz/aabb.wgsl +20 -0
  297. package/core/src/render/shaders/debug-viz/depth.wgsl +29 -0
  298. package/core/src/render/shaders/debug-viz/lod.wgsl +38 -0
  299. package/core/src/render/shaders/debug-viz/normals.wgsl +30 -0
  300. package/core/src/render/shaders/debug-viz/overdraw.wgsl +21 -0
  301. package/core/src/render/shaders/debug-viz/tangents.wgsl +29 -0
  302. package/core/src/render/shaders/debug-viz/wireframe.wgsl +33 -0
  303. package/core/src/render/shaders/shadow-chunks.ts +135 -0
  304. package/core/src/render/skybox.ts +146 -0
  305. package/core/src/render/splitscreen.ts +85 -0
  306. package/core/src/render/surface.ts +78 -0
  307. package/core/src/render/tonemap.ts +180 -0
  308. package/core/src/render/tracked-render-pass.ts +158 -0
  309. package/core/src/render/viewport.ts +109 -0
  310. package/core/src/render/wgsl-hmr.ts +70 -0
  311. package/core/src/sab/core-input-channel.ts +23 -0
  312. package/core/src/sab/define.ts +239 -0
  313. package/core/src/sab/errors.ts +76 -0
  314. package/core/src/sab/game-input.ts +343 -0
  315. package/core/src/sab/gamepad-devices.ts +259 -0
  316. package/core/src/sab/grid-buffer.ts +117 -0
  317. package/core/src/sab/input.ts +55 -0
  318. package/core/src/sab/layout.ts +219 -0
  319. package/core/src/sab/multi-input-channel.ts +50 -0
  320. package/core/src/sab/record-buffer.ts +155 -0
  321. package/core/src/sab/sab-polyfill.ts +56 -0
  322. package/core/src/sab/sim-channel.ts +453 -0
  323. package/core/src/sab/slot-buffer.ts +190 -0
  324. package/core/src/sab/types.ts +158 -0
  325. package/core/src/safety/bounds.ts +76 -0
  326. package/core/src/safety/json.ts +80 -0
  327. package/core/src/safety/path.ts +167 -0
  328. package/core/src/save/binary-format.ts +117 -0
  329. package/core/src/save/game-save-system.ts +161 -0
  330. package/core/src/save/grid-save-system.ts +158 -0
  331. package/core/src/save/migrate.ts +44 -0
  332. package/core/src/save/migration-registry.ts +94 -0
  333. package/core/src/save/persist-types.ts +208 -0
  334. package/core/src/save/schema.ts +46 -0
  335. package/core/src/save/serializer.ts +180 -0
  336. package/core/src/scene/builder.ts +65 -0
  337. package/core/src/scene/camera.ts +142 -0
  338. package/core/src/scene/checkpoint.ts +109 -0
  339. package/core/src/scene/game-loop.ts +198 -0
  340. package/core/src/scene/index.ts +24 -0
  341. package/core/src/scene/layer.ts +6 -0
  342. package/core/src/scene/prefab.ts +145 -0
  343. package/core/src/scene/scene-manager.ts +157 -0
  344. package/core/src/scene/scene.ts +192 -0
  345. package/core/src/scene/sky.ts +256 -0
  346. package/core/src/scene/spatial-grid.ts +176 -0
  347. package/core/src/scene/streaming.ts +304 -0
  348. package/core/src/scene/vegetation.ts +163 -0
  349. package/core/src/scene/world.ts +89 -0
  350. package/core/src/scripting/binding.ts +129 -0
  351. package/core/src/scripting/hot-reload.ts +144 -0
  352. package/core/src/scripting/script.ts +99 -0
  353. package/core/src/sim/hot-reload-pipeline.ts +49 -0
  354. package/core/src/sim/sim-state-helper.ts +47 -0
  355. package/core/src/sim/transient-state-registry.ts +77 -0
  356. package/core/src/sim/types.ts +113 -0
  357. package/core/src/sim/worker-loop.ts +222 -0
  358. package/core/src/stores/game-store.ts +158 -0
  359. package/core/src/stores/hot-reload-store.ts +44 -0
  360. package/core/src/telemetry/collector.ts +410 -0
  361. package/core/src/telemetry/gc-controller.ts +453 -0
  362. package/core/src/telemetry/gc-profiler.ts +126 -0
  363. package/core/src/telemetry/gc-tracker.ts +69 -0
  364. package/core/src/telemetry/gpu-profiler.ts +703 -0
  365. package/core/src/telemetry/gpu-resource-tracker.ts +285 -0
  366. package/core/src/telemetry/gpu-timer-pool.ts +234 -0
  367. package/core/src/telemetry/gpu-timer.ts +123 -0
  368. package/core/src/telemetry/gpu-timestamp-gate.ts +21 -0
  369. package/core/src/telemetry/reporter.ts +62 -0
  370. package/core/src/types/engine-types.ts +129 -0
  371. package/core/src/ui-font-scale.ts +112 -0
  372. package/core/src/util/broad-phase-grid.ts +82 -0
  373. package/core/src/util/feature-log.ts +220 -0
  374. package/core/src/util/index.ts +17 -0
  375. package/core/src/util/logger.ts +604 -0
  376. package/core/src/webgpu-destroy-augmentation.d.ts +25 -0
  377. package/core/src/worker/base-worker-host.ts +183 -0
  378. package/core/src/worker/buffer-sync.ts +550 -0
  379. package/core/src/worker/crash-recovery.ts +201 -0
  380. package/core/src/worker/entity-sim-worker-host.ts +190 -0
  381. package/core/src/worker/instrumented-worker-host.ts +171 -0
  382. package/core/src/worker/rpc.ts +253 -0
  383. package/core/src/worker/sim-worker-base.ts +913 -0
  384. package/core/src/worker/sim-worker-host.ts +358 -0
  385. package/core/src/worker/task-pool.ts +256 -0
  386. package/core/src/worker/task-worker.ts +83 -0
  387. package/libraries/asset-browser/src/index.ts +11 -0
  388. package/libraries/asset-browser/src/software-thumbnails.ts +949 -0
  389. package/libraries/audio-kira/README.md +17 -0
  390. package/libraries/audio-kira/native/Cargo.toml +14 -0
  391. package/libraries/audio-kira/native/src/engine.rs +27 -0
  392. package/libraries/audio-kira/native/src/lib.rs +185 -0
  393. package/libraries/audio-kira/native/src/mixer.rs +11 -0
  394. package/libraries/audio-kira/native/src/source.rs +80 -0
  395. package/libraries/audio-kira/src/backend.ts +469 -0
  396. package/libraries/audio-kira/src/index.ts +8 -0
  397. package/libraries/audio-kira/src/library.ts +82 -0
  398. package/libraries/blitz-ui/native/Cargo.toml +33 -0
  399. package/libraries/blitz-ui/native/assets/DejaVuSans.woff2 +0 -0
  400. package/libraries/blitz-ui/native/src/bridge.rs +100 -0
  401. package/libraries/blitz-ui/native/src/fonts.rs +20 -0
  402. package/libraries/blitz-ui/native/src/input.rs +80 -0
  403. package/libraries/blitz-ui/native/src/lib.rs +96 -0
  404. package/libraries/blitz-ui/native/src/shell.rs +301 -0
  405. package/libraries/blitz-ui/native-osr/Cargo.toml +24 -0
  406. package/libraries/blitz-ui/native-osr/src/events.rs +237 -0
  407. package/libraries/blitz-ui/native-osr/src/lib.rs +846 -0
  408. package/libraries/blitz-ui/native-osr/src/mutate.rs +385 -0
  409. package/libraries/blitz-ui/native-osr/src/resources.rs +45 -0
  410. package/libraries/blitz-ui/native-osr-spike.ts +70 -0
  411. package/libraries/blitz-ui/src/index.ts +15 -0
  412. package/libraries/blitz-ui/src/native-module.ts +221 -0
  413. package/libraries/blitz-ui/src/native-osr-ffi.ts +423 -0
  414. package/libraries/blitz-ui/src/router.ts +101 -0
  415. package/libraries/blitz-ui/src/shaders/ui-blit.wgsl.ts +35 -0
  416. package/libraries/blitz-ui/src/ui-blit-pass.ts +116 -0
  417. package/libraries/character/README.md +25 -0
  418. package/libraries/character/src/character-animator.ts +374 -0
  419. package/libraries/character/src/index.ts +24 -0
  420. package/libraries/character/src/loader.ts +375 -0
  421. package/libraries/character/src/locomotion.ts +124 -0
  422. package/libraries/character/src/preview.ts +287 -0
  423. package/libraries/devtools/README.md +51 -0
  424. package/libraries/devtools/native/Cargo.toml +12 -0
  425. package/libraries/devtools/native/src/lib.rs +1646 -0
  426. package/libraries/devtools/native/src/panels/console.rs +338 -0
  427. package/libraries/devtools/native/src/panels/dom_tree.rs +47 -0
  428. package/libraries/devtools/native/src/panels/generic.rs +317 -0
  429. package/libraries/devtools/native/src/panels/gpu.rs +107 -0
  430. package/libraries/devtools/native/src/panels/input.rs +88 -0
  431. package/libraries/devtools/native/src/panels/mod.rs +154 -0
  432. package/libraries/devtools/native/src/panels/perf_metrics.rs +91 -0
  433. package/libraries/devtools/native/src/panels/perf_recorder.rs +158 -0
  434. package/libraries/devtools/native/src/panels/scene.rs +72 -0
  435. package/libraries/devtools/native/src/state.rs +394 -0
  436. package/libraries/devtools/src/cdp-bridge.ts +349 -0
  437. package/libraries/devtools/src/collectors.ts +346 -0
  438. package/libraries/devtools/src/egui-ffi.ts +804 -0
  439. package/libraries/devtools/src/egui-renderer.ts +407 -0
  440. package/libraries/devtools/src/host.ts +363 -0
  441. package/libraries/devtools/src/index.ts +40 -0
  442. package/libraries/devtools/src/mirror.ts +794 -0
  443. package/libraries/devtools/src/native-providers.ts +744 -0
  444. package/libraries/devtools/src/verify.ts +167 -0
  445. package/libraries/devtools/src/web/browser.ts +102 -0
  446. package/libraries/devtools/src/web/host.ts +212 -0
  447. package/libraries/devtools/src/web/mirror.ts +430 -0
  448. package/libraries/devtools/src/web/server.ts +198 -0
  449. package/libraries/entities/README.md +17 -0
  450. package/libraries/entities/src/index.ts +4 -0
  451. package/libraries/entities/src/library.ts +64 -0
  452. package/libraries/entities/src/model-renderer.ts +1345 -0
  453. package/libraries/entities/src/shaders/model.wgsl +375 -0
  454. package/libraries/gamepad/src/feed-input.ts +83 -0
  455. package/libraries/gamepad/src/filters.ts +49 -0
  456. package/libraries/gamepad/src/glyphs.ts +93 -0
  457. package/libraries/gamepad/src/hub.ts +206 -0
  458. package/libraries/gamepad/src/index.ts +22 -0
  459. package/libraries/gamepad/src/library.ts +68 -0
  460. package/libraries/gamepad/src/source-sab.ts +70 -0
  461. package/libraries/gamepad/src/sysfs-enrich.ts +138 -0
  462. package/libraries/gaussian-splats/README.md +25 -0
  463. package/libraries/gaussian-splats/src/gpu-sort.ts +595 -0
  464. package/libraries/gaussian-splats/src/index.ts +31 -0
  465. package/libraries/gaussian-splats/src/library.ts +60 -0
  466. package/libraries/gaussian-splats/src/parser.ts +382 -0
  467. package/libraries/gaussian-splats/src/renderer.ts +427 -0
  468. package/libraries/gaussian-splats/src/sh-eval.ts +211 -0
  469. package/libraries/gaussian-splats/src/sorter.ts +110 -0
  470. package/libraries/gaussian-splats/src/tile-raster.ts +473 -0
  471. package/libraries/gpu-kernels/README.md +154 -0
  472. package/libraries/gpu-kernels/src/index.ts +11 -0
  473. package/libraries/gpu-kernels/src/kernel.ts +696 -0
  474. package/libraries/gpu-kernels/src/transpile.ts +958 -0
  475. package/libraries/html-ui-kit/src/behaviors.ts +250 -0
  476. package/libraries/html-ui-kit/src/components.ts +309 -0
  477. package/libraries/html-ui-kit/src/index.ts +30 -0
  478. package/libraries/html-ui-kit/src/nav/nav-controller.ts +238 -0
  479. package/libraries/html-ui-kit/src/nav/nav-input.ts +145 -0
  480. package/libraries/html-ui-kit/src/nav/osk.ts +153 -0
  481. package/libraries/html-ui-kit/src/nav/router.ts +167 -0
  482. package/libraries/html-ui-kit/src/nav/vcursor.ts +203 -0
  483. package/libraries/html-ui-kit/src/ten-foot.ts +182 -0
  484. package/libraries/html-ui-kit/src/theme.ts +238 -0
  485. package/libraries/lighting/README.md +20 -0
  486. package/libraries/lighting/src/index.ts +5 -0
  487. package/libraries/lighting/src/library.ts +66 -0
  488. package/libraries/lighting/src/light-system.ts +452 -0
  489. package/libraries/lighting/src/lighting-system.ts +68 -0
  490. package/libraries/lighting/src/shaders/light-debug.wgsl +30 -0
  491. package/libraries/marching-cubes/README.md +25 -0
  492. package/libraries/marching-cubes/src/chunked-field.ts +177 -0
  493. package/libraries/marching-cubes/src/deformation.ts +63 -0
  494. package/libraries/marching-cubes/src/generator.ts +407 -0
  495. package/libraries/marching-cubes/src/index.ts +32 -0
  496. package/libraries/marching-cubes/src/library.ts +80 -0
  497. package/libraries/marching-cubes/src/lod.ts +122 -0
  498. package/libraries/marching-cubes/src/marching-tetrahedra.ts +252 -0
  499. package/libraries/marching-cubes/src/sab.ts +45 -0
  500. package/libraries/marching-cubes/src/streaming-config.ts +48 -0
  501. package/libraries/marching-cubes/src/streaming-manager.ts +686 -0
  502. package/libraries/marching-cubes/src/tables.ts +323 -0
  503. package/libraries/marching-cubes/src/types.ts +18 -0
  504. package/libraries/models/README.md +25 -0
  505. package/libraries/models/src/bake-node-transforms.ts +171 -0
  506. package/libraries/models/src/codecs/basisu-codec.ts +180 -0
  507. package/libraries/models/src/codecs/draco-codec.ts +372 -0
  508. package/libraries/models/src/codecs/draco3dgltf.d.ts +40 -0
  509. package/libraries/models/src/codecs/index.ts +22 -0
  510. package/libraries/models/src/codecs/meshopt-codec.ts +91 -0
  511. package/libraries/models/src/codecs/registry.ts +221 -0
  512. package/libraries/models/src/dae.ts +753 -0
  513. package/libraries/models/src/default-part-selection.ts +56 -0
  514. package/libraries/models/src/dxf.ts +200 -0
  515. package/libraries/models/src/fbx/index.ts +457 -0
  516. package/libraries/models/src/fbx/interpreter/animation.ts +431 -0
  517. package/libraries/models/src/fbx/interpreter/blend-shapes.ts +323 -0
  518. package/libraries/models/src/fbx/interpreter/connections.ts +166 -0
  519. package/libraries/models/src/fbx/interpreter/diagnostics.ts +65 -0
  520. package/libraries/models/src/fbx/interpreter/geometry.ts +535 -0
  521. package/libraries/models/src/fbx/interpreter/global-settings.ts +92 -0
  522. package/libraries/models/src/fbx/interpreter/materials.ts +265 -0
  523. package/libraries/models/src/fbx/interpreter/nodes.ts +197 -0
  524. package/libraries/models/src/fbx/interpreter/skeleton.ts +476 -0
  525. package/libraries/models/src/fbx/parsers/binary-parser.ts +244 -0
  526. package/libraries/models/src/fbx/types.ts +119 -0
  527. package/libraries/models/src/gltf-extensions.ts +196 -0
  528. package/libraries/models/src/gltf.ts +935 -0
  529. package/libraries/models/src/index.ts +87 -0
  530. package/libraries/models/src/library.ts +75 -0
  531. package/libraries/models/src/loader.ts +265 -0
  532. package/libraries/models/src/material-adapter.ts +108 -0
  533. package/libraries/models/src/mini-xml.ts +174 -0
  534. package/libraries/models/src/normalize.ts +216 -0
  535. package/libraries/models/src/obj.ts +264 -0
  536. package/libraries/models/src/off.ts +95 -0
  537. package/libraries/models/src/ply.ts +348 -0
  538. package/libraries/models/src/pose-sampler.ts +219 -0
  539. package/libraries/models/src/sidecar/blender-extras.ts +37 -0
  540. package/libraries/models/src/sidecar/ddmeta.ts +114 -0
  541. package/libraries/models/src/sidecar/godot-import.ts +86 -0
  542. package/libraries/models/src/sidecar/resolver.ts +145 -0
  543. package/libraries/models/src/sidecar/types.ts +11 -0
  544. package/libraries/models/src/sidecar/unity-meta.ts +61 -0
  545. package/libraries/models/src/skeleton-synthesis.ts +132 -0
  546. package/libraries/models/src/stl.ts +149 -0
  547. package/libraries/models/src/threeds.ts +363 -0
  548. package/libraries/models/src/threemf.ts +201 -0
  549. package/libraries/models/src/types.ts +188 -0
  550. package/libraries/models/src/vtk.ts +218 -0
  551. package/libraries/models/test-fixtures/fbx/LICENSE-notice.txt +24 -0
  552. package/libraries/models/test-fixtures/fbx/README.md +46 -0
  553. package/libraries/models/test-fixtures/fbx/m01_cube_phong.fbx +0 -0
  554. package/libraries/models/test-fixtures/fbx/m02_geo_ngons.fbx +0 -0
  555. package/libraries/models/test-fixtures/fbx/m03_normals.fbx +0 -0
  556. package/libraries/models/test-fixtures/fbx/m04_material_properties.fbx +0 -0
  557. package/libraries/models/test-fixtures/fbx/m05_external_diffuse.png +0 -0
  558. package/libraries/models/test-fixtures/fbx/m05_textures.fbx +0 -0
  559. package/libraries/models/test-fixtures/fbx/m06_uv_transform.fbx +0 -0
  560. package/libraries/models/test-fixtures/fbx/m07_multimaterial.fbx +0 -0
  561. package/libraries/models/test-fixtures/fbx/m08_transforms.fbx +0 -0
  562. package/libraries/models/test-fixtures/fbx/m09_skinning.fbx +0 -0
  563. package/libraries/models/test-fixtures/fbx/m10_morph.fbx +0 -0
  564. package/libraries/models/test-fixtures/fbx/m11_node_anim.fbx +0 -0
  565. package/libraries/models/test-fixtures/fbx/m12_skeletal_anim.fbx +0 -0
  566. package/libraries/models/test-fixtures/fbx/m13_morph_anim.fbx +0 -0
  567. package/libraries/models/test-fixtures/fbx/m14_multiclip.fbx +0 -0
  568. package/libraries/models/test-fixtures/fbx/m15_camera_lights.fbx +0 -0
  569. package/libraries/models/test-fixtures/fbx/m16_axis_yup.fbx +0 -0
  570. package/libraries/models/test-fixtures/fbx/m16_axis_zup.fbx +0 -0
  571. package/libraries/models/test-fixtures/fbx/m16_units_254.fbx +0 -0
  572. package/libraries/navmesh/README.md +23 -0
  573. package/libraries/navmesh/src/crowd-system.ts +240 -0
  574. package/libraries/navmesh/src/debug-viz.ts +74 -0
  575. package/libraries/navmesh/src/index.ts +15 -0
  576. package/libraries/navmesh/src/library.ts +64 -0
  577. package/libraries/navmesh/src/navmesh-generator.ts +407 -0
  578. package/libraries/navmesh/src/navmesh.ts +159 -0
  579. package/libraries/navmesh/src/pathfinder.ts +252 -0
  580. package/libraries/navmesh/src/types.ts +63 -0
  581. package/libraries/networking/README.md +25 -0
  582. package/libraries/networking/src/authority.ts +121 -0
  583. package/libraries/networking/src/connection.ts +139 -0
  584. package/libraries/networking/src/discovery.ts +373 -0
  585. package/libraries/networking/src/enhanced-replication.ts +355 -0
  586. package/libraries/networking/src/epic-adapter.ts +129 -0
  587. package/libraries/networking/src/index.ts +45 -0
  588. package/libraries/networking/src/library.ts +69 -0
  589. package/libraries/networking/src/lobby.ts +108 -0
  590. package/libraries/networking/src/platform-adapter.ts +163 -0
  591. package/libraries/networking/src/rcs-adapter.ts +127 -0
  592. package/libraries/networking/src/remote-input.ts +188 -0
  593. package/libraries/networking/src/replication.ts +327 -0
  594. package/libraries/networking/src/rpc.ts +188 -0
  595. package/libraries/networking/src/session.ts +173 -0
  596. package/libraries/networking/src/transport.ts +201 -0
  597. package/libraries/networking/src/webrtc.ts +323 -0
  598. package/libraries/pathfinding-2d/README.md +15 -0
  599. package/libraries/pathfinding-2d/src/astar-grid.ts +312 -0
  600. package/libraries/pathfinding-2d/src/index.ts +11 -0
  601. package/libraries/persistence/README.md +25 -0
  602. package/libraries/persistence/src/autosave-manager.ts +112 -0
  603. package/libraries/persistence/src/binary-record-store.ts +244 -0
  604. package/libraries/persistence/src/browser.ts +51 -0
  605. package/libraries/persistence/src/file-save-store.ts +553 -0
  606. package/libraries/persistence/src/hash-utils.ts +59 -0
  607. package/libraries/persistence/src/index.ts +57 -0
  608. package/libraries/persistence/src/library.ts +74 -0
  609. package/libraries/persistence/src/mock-opfs.ts +141 -0
  610. package/libraries/persistence/src/node-fs-directory-handle.ts +161 -0
  611. package/libraries/persistence/src/opfs-save-store.ts +745 -0
  612. package/libraries/persistence/src/save-worker-proxy.ts +127 -0
  613. package/libraries/persistence/src/save-worker.ts +99 -0
  614. package/libraries/persistence/src/xxh3-ts.d.ts +10 -0
  615. package/libraries/physics-native/README.md +21 -0
  616. package/libraries/physics-native/native/Cargo.toml +11 -0
  617. package/libraries/physics-native/native/src/body.rs +403 -0
  618. package/libraries/physics-native/native/src/character.rs +226 -0
  619. package/libraries/physics-native/native/src/collider.rs +299 -0
  620. package/libraries/physics-native/native/src/joint.rs +81 -0
  621. package/libraries/physics-native/native/src/lib.rs +830 -0
  622. package/libraries/physics-native/native/src/query.rs +261 -0
  623. package/libraries/physics-native/native/src/realm.rs +33 -0
  624. package/libraries/physics-native/native/src/step.rs +54 -0
  625. package/libraries/physics-native/native/src/world.rs +148 -0
  626. package/libraries/physics-native/src/backend.ts +1046 -0
  627. package/libraries/physics-native/src/broadphase.ts +101 -0
  628. package/libraries/physics-native/src/ffi-spike-worker.ts +71 -0
  629. package/libraries/physics-native/src/index.ts +11 -0
  630. package/libraries/physics-native/src/library.ts +79 -0
  631. package/libraries/physics-native/src/narrowphase-shapes.ts +420 -0
  632. package/libraries/physics-native/src/narrowphase.ts +123 -0
  633. package/libraries/physics-native/src/solver.ts +141 -0
  634. package/libraries/physics-native/src/types.ts +76 -0
  635. package/libraries/physics-rapier/README.md +21 -0
  636. package/libraries/physics-rapier/bench/ffi-bench.ts +79 -0
  637. package/libraries/physics-rapier/bench/wasm-baseline.ts +90 -0
  638. package/libraries/physics-rapier/src/api.ts +452 -0
  639. package/libraries/physics-rapier/src/auto-backend.ts +59 -0
  640. package/libraries/physics-rapier/src/backend.ts +1207 -0
  641. package/libraries/physics-rapier/src/bulk-ops.ts +68 -0
  642. package/libraries/physics-rapier/src/ffi-backend.ts +21 -0
  643. package/libraries/physics-rapier/src/ffi-lib.ts +597 -0
  644. package/libraries/physics-rapier/src/index.ts +12 -0
  645. package/libraries/physics-rapier/src/library.ts +107 -0
  646. package/libraries/physics-rapier/src/rapier-backend.ts +1052 -0
  647. package/libraries/physics-rapier/src/realm-worker-script.ts +237 -0
  648. package/libraries/postfx/README.md +17 -0
  649. package/libraries/postfx/src/index.ts +19 -0
  650. package/libraries/postfx/src/library.ts +337 -0
  651. package/libraries/postfx/src/post-process-stack.ts +1752 -0
  652. package/libraries/postfx/src/shaders/post-process/afterimage.wgsl +14 -0
  653. package/libraries/postfx/src/shaders/post-process/ascii.wgsl +24 -0
  654. package/libraries/postfx/src/shaders/post-process/blit.wgsl +12 -0
  655. package/libraries/postfx/src/shaders/post-process/bloom-blur.wgsl +21 -0
  656. package/libraries/postfx/src/shaders/post-process/bloom-bright.wgsl +15 -0
  657. package/libraries/postfx/src/shaders/post-process/bloom-composite.wgsl +14 -0
  658. package/libraries/postfx/src/shaders/post-process/bloom-downsample.wgsl +60 -0
  659. package/libraries/postfx/src/shaders/post-process/bloom-soft.wgsl +46 -0
  660. package/libraries/postfx/src/shaders/post-process/bloom-upsample.wgsl +51 -0
  661. package/libraries/postfx/src/shaders/post-process/channel-mixer.wgsl +36 -0
  662. package/libraries/postfx/src/shaders/post-process/chromatic-aberration.wgsl +37 -0
  663. package/libraries/postfx/src/shaders/post-process/dithering.wgsl +64 -0
  664. package/libraries/postfx/src/shaders/post-process/dof.wgsl +131 -0
  665. package/libraries/postfx/src/shaders/post-process/edges.wgsl +45 -0
  666. package/libraries/postfx/src/shaders/post-process/fullscreen-vs.wgsl +15 -0
  667. package/libraries/postfx/src/shaders/post-process/fxaa.wgsl +102 -0
  668. package/libraries/postfx/src/shaders/post-process/gaussian-blur.wgsl +37 -0
  669. package/libraries/postfx/src/shaders/post-process/glow-blur.wgsl +33 -0
  670. package/libraries/postfx/src/shaders/post-process/glow-composite.wgsl +25 -0
  671. package/libraries/postfx/src/shaders/post-process/grain.wgsl +37 -0
  672. package/libraries/postfx/src/shaders/post-process/halftone.wgsl +80 -0
  673. package/libraries/postfx/src/shaders/post-process/highlight-blur.wgsl +33 -0
  674. package/libraries/postfx/src/shaders/post-process/highlight-composite.wgsl +32 -0
  675. package/libraries/postfx/src/shaders/post-process/lens-distortion.wgsl +43 -0
  676. package/libraries/postfx/src/shaders/post-process/lens-flare.wgsl +68 -0
  677. package/libraries/postfx/src/shaders/post-process/lut.wgsl +30 -0
  678. package/libraries/postfx/src/shaders/post-process/motion-blur.wgsl +55 -0
  679. package/libraries/postfx/src/shaders/post-process/occluder-chunk.wgsl +28 -0
  680. package/libraries/postfx/src/shaders/post-process/outline.wgsl +51 -0
  681. package/libraries/postfx/src/shaders/post-process/pixelation.wgsl +47 -0
  682. package/libraries/postfx/src/shaders/post-process/sharpen.wgsl +32 -0
  683. package/libraries/postfx/src/shaders/post-process/sobel.wgsl +26 -0
  684. package/libraries/postfx/src/shaders/post-process/split-tone.wgsl +36 -0
  685. package/libraries/postfx/src/shaders/post-process/ssao-blur.wgsl +38 -0
  686. package/libraries/postfx/src/shaders/post-process/ssao-composite.wgsl +25 -0
  687. package/libraries/postfx/src/shaders/post-process/ssao.wgsl +147 -0
  688. package/libraries/postfx/src/shaders/post-process/ssr.wgsl +155 -0
  689. package/libraries/postfx/src/shaders/post-process/taa.wgsl +98 -0
  690. package/libraries/postfx/src/shaders/post-process/tonemap.wgsl +40 -0
  691. package/libraries/postfx/src/shaders/post-process/watercolor.wgsl +82 -0
  692. package/libraries/postfx/src/shaders/post-process/white-balance.wgsl +41 -0
  693. package/libraries/recast/README.md +21 -0
  694. package/libraries/recast/src/backend.ts +150 -0
  695. package/libraries/recast/src/crowd-system.ts +352 -0
  696. package/libraries/recast/src/index.ts +12 -0
  697. package/libraries/recast/src/library.ts +91 -0
  698. package/libraries/recast/src/types.ts +86 -0
  699. package/libraries/sand/README.md +25 -0
  700. package/libraries/sand/src/cell.ts +43 -0
  701. package/libraries/sand/src/fields.ts +29 -0
  702. package/libraries/sand/src/fluid-grid.ts +261 -0
  703. package/libraries/sand/src/grid-dims.ts +74 -0
  704. package/libraries/sand/src/grid-sim-buffer.ts +271 -0
  705. package/libraries/sand/src/index.ts +81 -0
  706. package/libraries/sand/src/library.ts +92 -0
  707. package/libraries/sand/src/materials.ts +492 -0
  708. package/libraries/sand/src/palette.ts +93 -0
  709. package/libraries/sand/src/particles.ts +185 -0
  710. package/libraries/sand/src/render/sand-grid-pass.ts +430 -0
  711. package/libraries/sand/src/rng.ts +51 -0
  712. package/libraries/sand/src/rules/builtin-rules.ts +132 -0
  713. package/libraries/sand/src/rules/rule-compiler.ts +162 -0
  714. package/libraries/sand/src/rules/rule-engine.ts +231 -0
  715. package/libraries/sand/src/rules/rule-types.ts +87 -0
  716. package/libraries/sand/src/sand-step-pool.ts +484 -0
  717. package/libraries/sand/src/sand-step-worker.ts +97 -0
  718. package/libraries/sand/src/sand-world.ts +3227 -0
  719. package/libraries/stickman/README.md +25 -0
  720. package/libraries/stickman/src/index.ts +25 -0
  721. package/libraries/stickman/src/library.ts +61 -0
  722. package/libraries/stickman/src/proportions.ts +45 -0
  723. package/libraries/stickman/src/shader.ts +117 -0
  724. package/libraries/stickman/src/skeleton.ts +197 -0
  725. package/libraries/stickman/src/stickman-pass.ts +255 -0
  726. package/libraries/stickman/src/thick-line.ts +123 -0
  727. package/libraries/surface-nets/README.md +25 -0
  728. package/libraries/surface-nets/src/chunked-field.ts +14 -0
  729. package/libraries/surface-nets/src/deformation.ts +45 -0
  730. package/libraries/surface-nets/src/index.ts +36 -0
  731. package/libraries/surface-nets/src/library.ts +59 -0
  732. package/libraries/surface-nets/src/lod.ts +7 -0
  733. package/libraries/surface-nets/src/sab.ts +4 -0
  734. package/libraries/surface-nets/src/streaming-config.ts +5 -0
  735. package/libraries/surface-nets/src/streaming-manager.ts +15 -0
  736. package/libraries/surface-nets/src/surface-nets.ts +334 -0
  737. package/libraries/surface-nets/src/types.ts +23 -0
  738. package/libraries/water/README.md +25 -0
  739. package/libraries/water/src/buoyancy.ts +103 -0
  740. package/libraries/water/src/index.ts +43 -0
  741. package/libraries/water/src/library.ts +85 -0
  742. package/libraries/water/src/shore-damping.ts +93 -0
  743. package/libraries/water/src/water-buffer.ts +89 -0
  744. package/libraries/water/src/water-chunks.ts +13 -0
  745. package/libraries/water/src/water-physics.ts +376 -0
  746. package/libraries/water/src/water-renderer.ts +809 -0
  747. package/libraries/water/src/water-sab.ts +161 -0
  748. package/libraries/water/src/wave-sources.ts +84 -0
  749. package/libraries/weather/README.md +20 -0
  750. package/libraries/weather/src/index.ts +9 -0
  751. package/libraries/weather/src/library.ts +72 -0
  752. package/libraries/weather/src/types.ts +64 -0
  753. package/libraries/weather/src/weather-blend.ts +112 -0
  754. package/libraries/weather/src/weather-system.ts +271 -0
  755. package/libraries/weatherfx/README.md +24 -0
  756. package/libraries/weatherfx/src/cloud-provider.ts +31 -0
  757. package/libraries/weatherfx/src/cloud-system.ts +372 -0
  758. package/libraries/weatherfx/src/index.ts +9 -0
  759. package/libraries/weatherfx/src/library.ts +58 -0
  760. package/libraries/weatherfx/src/particle-system.ts +434 -0
  761. package/libraries/weatherfx/src/shaders/cloud.wgsl +111 -0
  762. package/libraries/weatherfx/src/shaders/particle-compute.wgsl +187 -0
  763. package/libraries/weatherfx/src/shaders/particle-render.wgsl +95 -0
  764. package/lint-plugin.mjs +41 -0
  765. package/mcp/src/client.ts +703 -0
  766. package/mcp/src/engine-context.ts +186 -0
  767. package/mcp/src/http-transport.ts +471 -0
  768. package/mcp/src/index.ts +13 -0
  769. package/mcp/src/prompts/add-entity.ts +42 -0
  770. package/mcp/src/prompts/create-scene.ts +44 -0
  771. package/mcp/src/prompts/debug-frame.ts +39 -0
  772. package/mcp/src/prompts/index.ts +12 -0
  773. package/mcp/src/resources/asset-list.ts +32 -0
  774. package/mcp/src/resources/checkpoint-list.ts +33 -0
  775. package/mcp/src/resources/entity-state.ts +55 -0
  776. package/mcp/src/resources/gpu-info.ts +103 -0
  777. package/mcp/src/resources/index.ts +57 -0
  778. package/mcp/src/resources/performance.ts +37 -0
  779. package/mcp/src/resources/scene-tree.ts +43 -0
  780. package/mcp/src/server.ts +375 -0
  781. package/mcp/src/tools/animation.ts +118 -0
  782. package/mcp/src/tools/asset.ts +161 -0
  783. package/mcp/src/tools/audio.ts +96 -0
  784. package/mcp/src/tools/build.ts +143 -0
  785. package/mcp/src/tools/camera.ts +167 -0
  786. package/mcp/src/tools/checkpoint.ts +100 -0
  787. package/mcp/src/tools/component.ts +199 -0
  788. package/mcp/src/tools/debug.ts +300 -0
  789. package/mcp/src/tools/entity.ts +361 -0
  790. package/mcp/src/tools/inspect.ts +210 -0
  791. package/mcp/src/tools/lighting.ts +263 -0
  792. package/mcp/src/tools/material.ts +243 -0
  793. package/mcp/src/tools/mesh.ts +239 -0
  794. package/mcp/src/tools/physics.ts +266 -0
  795. package/mcp/src/tools/scene.ts +153 -0
  796. package/mcp/src/tools/script.ts +122 -0
  797. package/mcp/src/types.ts +92 -0
  798. package/mcp/src/undo-redo.ts +77 -0
  799. package/modules/camera-controls/README.md +20 -0
  800. package/modules/camera-controls/src/index.ts +161 -0
  801. package/modules/controller-ui/src/index.ts +164 -0
  802. package/modules/devtools/README.md +25 -0
  803. package/modules/devtools/src/api.ts +461 -0
  804. package/modules/devtools/src/asset-utils.ts +105 -0
  805. package/modules/devtools/src/bind-debug-store.ts +48 -0
  806. package/modules/devtools/src/data-bridge.ts +286 -0
  807. package/modules/devtools/src/debug-overlay.ts +238 -0
  808. package/modules/devtools/src/debug-raycast.ts +328 -0
  809. package/modules/devtools/src/debug-store.ts +92 -0
  810. package/modules/devtools/src/debug-view-descriptors.ts +59 -0
  811. package/modules/devtools/src/doctor-panel.ts +182 -0
  812. package/modules/devtools/src/gizmo-module.ts +136 -0
  813. package/modules/devtools/src/graph-model.ts +509 -0
  814. package/modules/devtools/src/grid-renderer.ts +157 -0
  815. package/modules/devtools/src/height-ruler-renderer.ts +216 -0
  816. package/modules/devtools/src/index.ts +81 -0
  817. package/modules/devtools/src/init.ts +261 -0
  818. package/modules/devtools/src/label-overlay.ts +154 -0
  819. package/modules/devtools/src/material-stats-panel.ts +188 -0
  820. package/modules/devtools/src/profiling-bridge.ts +377 -0
  821. package/modules/devtools/src/profiling-hooks.ts +98 -0
  822. package/modules/devtools/src/renderer-adapter.ts +76 -0
  823. package/modules/devtools/src/scene-inspector.ts +637 -0
  824. package/modules/devtools/src/scene-store.ts +320 -0
  825. package/modules/devtools/src/scene-sync.ts +116 -0
  826. package/modules/devtools/src/shaders/transform-gizmo.wgsl +38 -0
  827. package/modules/devtools/src/sim-stats-panel.ts +272 -0
  828. package/modules/devtools/src/sim-stats-provider.ts +105 -0
  829. package/modules/devtools/src/skeleton-renderer.ts +351 -0
  830. package/modules/devtools/src/transform-gizmo.ts +928 -0
  831. package/modules/devtools/src/types.ts +290 -0
  832. package/modules/devtools/src/worker-expose.ts +67 -0
  833. package/modules/devtools/src/worker-sync.ts +137 -0
  834. package/modules/editor/src/commands/component.ts +156 -0
  835. package/modules/editor/src/commands/entity.ts +287 -0
  836. package/modules/editor/src/commands/hierarchy.ts +83 -0
  837. package/modules/editor/src/commands/index.ts +61 -0
  838. package/modules/editor/src/commands/prefab.ts +163 -0
  839. package/modules/editor/src/commands/registry.ts +331 -0
  840. package/modules/editor/src/commands/scene-io.ts +211 -0
  841. package/modules/editor/src/commands/selection.ts +73 -0
  842. package/modules/editor/src/commands/transform.ts +91 -0
  843. package/modules/editor/src/ddscene.ts +267 -0
  844. package/modules/editor/src/document.ts +123 -0
  845. package/modules/editor/src/editor-context.ts +172 -0
  846. package/modules/editor/src/index.ts +41 -0
  847. package/modules/editor/src/mcp.ts +103 -0
  848. package/modules/editor/src/module.ts +148 -0
  849. package/modules/editor/src/selection.ts +70 -0
  850. package/modules/editor/src/shell.ts +456 -0
  851. package/modules/editor/src/viewport.ts +199 -0
  852. package/modules/html-ui/src/composite.ts +135 -0
  853. package/modules/html-ui/src/create-html-ui.ts +188 -0
  854. package/modules/html-ui/src/doc-backend.ts +343 -0
  855. package/modules/html-ui/src/host.ts +646 -0
  856. package/modules/html-ui/src/index.ts +13 -0
  857. package/modules/html-ui/src/jsx-dev-runtime.ts +12 -0
  858. package/modules/html-ui/src/jsx-runtime.ts +126 -0
  859. package/modules/html-ui/src/protocol.ts +88 -0
  860. package/modules/html-ui/src/ui-worker.ts +16 -0
  861. package/modules/mcp/README.md +18 -0
  862. package/modules/mcp/src/index.ts +27 -0
  863. package/modules/movement-2d/README.md +19 -0
  864. package/modules/movement-2d/src/grid-character.ts +455 -0
  865. package/modules/movement-2d/src/index.ts +45 -0
  866. package/modules/movement-3d/README.md +21 -0
  867. package/modules/movement-3d/src/character-motor.ts +230 -0
  868. package/modules/movement-3d/src/index.ts +46 -0
  869. package/modules/native-osr/src/index.ts +22 -0
  870. package/modules/native-osr/src/input-router.ts +401 -0
  871. package/modules/native-osr/src/native-osr-manager.ts +247 -0
  872. package/modules/native-osr/src/native-texture-source.ts +86 -0
  873. package/modules/native-osr/src/types.ts +112 -0
  874. package/modules/native-osr/src/world-space-ui-pass.ts +351 -0
  875. package/modules/sailing/README.md +18 -0
  876. package/modules/sailing/src/index.ts +51 -0
  877. package/modules/terrain/README.md +18 -0
  878. package/modules/terrain/src/index.ts +78 -0
  879. package/modules/vitals/README.md +17 -0
  880. package/modules/vitals/src/index.ts +43 -0
  881. package/modules/vitals/src/vitals.ts +265 -0
  882. package/modules/xr/README.md +25 -0
  883. package/modules/xr/src/camera-rig.ts +146 -0
  884. package/modules/xr/src/debug.ts +59 -0
  885. package/modules/xr/src/frame-loop.ts +197 -0
  886. package/modules/xr/src/index.ts +16 -0
  887. package/modules/xr/src/input.ts +208 -0
  888. package/modules/xr/src/layer.ts +140 -0
  889. package/modules/xr/src/session.ts +156 -0
  890. package/modules/xr/src/sim-module.ts +23 -0
  891. package/modules/xr/src/types.ts +32 -0
  892. package/modules/xr/src/webxr.d.ts +182 -0
  893. package/modules/xr/src/xr-module.ts +179 -0
  894. package/package.json +232 -3
  895. package/shader-graph/src/chunks.ts +349 -0
  896. package/shader-graph/src/compiler.ts +732 -0
  897. package/shader-graph/src/compute-compiler.ts +453 -0
  898. package/shader-graph/src/compute-graph.ts +112 -0
  899. package/shader-graph/src/compute-profiles.ts +54 -0
  900. package/shader-graph/src/graph.ts +52 -0
  901. package/shader-graph/src/index.ts +53 -0
  902. package/shader-graph/src/profiles.ts +407 -0
  903. package/shader-graph/src/validator.ts +48 -0
  904. package/shader-graph/src/wgsl-binding-validator.ts +143 -0
  905. package/shader-graph/src/wgsl-struct-validator.ts +245 -0
  906. package/shader-graph/src/wgsl-struct.ts +397 -0
  907. package/test/src/index.ts +7 -0
  908. package/test/src/vision-test.ts +369 -0
@@ -0,0 +1,553 @@
1
+ // ============================================================================
2
+ // FileSaveStore — filesystem-based ISaveStore implementation
3
+ // ============================================================================
4
+ //
5
+ // Saves are written as binary files with an uncompressed header (magic,
6
+ // format version, engine version, timestamp, entity/player counts, XXH128
7
+ // hash, uncompressed body length) followed by a zstd-compressed JSON body.
8
+ //
9
+ // On save, the previous file is rotated to `.bak`. On load failure (hash
10
+ // mismatch, parse error, migration error), the `.bak` is tried as fallback.
11
+ //
12
+ // Forward incompatibility: saves from a newer engine version are refused.
13
+ // Consumers should implement version backups for unstable releases.
14
+
15
+ import { safeJsonParse } from "@downdraft/engine";
16
+ import {
17
+ encodeHeader,
18
+ engineVersionString,
19
+ HEADER_SIZE,
20
+ packEngineVersion,
21
+ readHeaderFromFile,
22
+ SAVE_FORMAT_VERSION,
23
+ SAVE_MAGIC,
24
+ type SaveHeader
25
+ } from "@downdraft/engine/save/binary-format";
26
+ import { MigrationRegistryImpl } from "@downdraft/engine/save/migration-registry";
27
+ import type {
28
+ IMigrationRegistry,
29
+ ISaveStore,
30
+ LoadOptions,
31
+ LoadResult,
32
+ SaveGenerationInfo,
33
+ SaveOptions,
34
+ SaveResult,
35
+ SaveSlotInfo,
36
+ SaveState,
37
+ SaveWarning
38
+ } from "@downdraft/engine/save/persist-types";
39
+ import { createLogger } from "@downdraft/engine/util/logger";
40
+ import { promises as fs } from "node:fs";
41
+ import { join } from "node:path";
42
+
43
+ const log = createLogger("info");
44
+
45
+ const SAVE_EXT = ".ddsave";
46
+ const BACKUP_EXT = ".ddsave.bak";
47
+ const THUMB_EXT = ".thumb";
48
+ const PROPS_EXT = ".props.json";
49
+ const BLOBS_DIR_SUFFIX = ".blobs";
50
+
51
+ // zstd-wasm init() is NOT idempotent — a second call re-instantiates the
52
+ // wasm module while Module.HEAP8 still points at the old memory, silently
53
+ // corrupting every subsequent decompress. Guard it at module level so all
54
+ // FileSaveStore instances (and the services worker's) share one init.
55
+ let zstdInitPromise: Promise<void> | null = null;
56
+ function ensureZstdGlobal(): Promise<void> {
57
+ if (!zstdInitPromise) {
58
+ zstdInitPromise = (async () => {
59
+ const { init } = await import("@bokuweb/zstd-wasm");
60
+ await init();
61
+ })();
62
+ // Don't cache a rejection forever — a transient failure (missing wasm
63
+ // asset, fs hiccup) would otherwise permanently break all saves.
64
+ zstdInitPromise.catch(() => { zstdInitPromise = null; });
65
+ }
66
+ return zstdInitPromise;
67
+ }
68
+
69
+ export interface FileSaveStoreOptions {
70
+ /** Directory to store save files (typically app.getPath("userData") + "/saves") */
71
+ saveDir: string;
72
+ /** Current engine/game version string (e.g. "0.1.0") */
73
+ engineVersion: string;
74
+ /** Migration registry (optional — a new one is created if not provided) */
75
+ migrationRegistry?: IMigrationRegistry;
76
+ /** Optional compression provider (for testing or custom compression) */
77
+ compress?: (data: Uint8Array) => Uint8Array;
78
+ /** Optional decompression provider (for testing or custom compression) */
79
+ decompress?: (data: Uint8Array, originalSize: number) => Uint8Array;
80
+ /** Optional hash provider (for testing or custom hashing) */
81
+ hash128?: (data: Uint8Array) => Uint8Array;
82
+ /** Skip migration step on load — pass through components unchanged (for pure storage layers) */
83
+ skipMigrations?: boolean;
84
+ }
85
+
86
+ export class FileSaveStore implements ISaveStore {
87
+ private saveDir: string;
88
+ private engineVersionPacked: number;
89
+ private migrations: IMigrationRegistry;
90
+ private warningCallbacks: Array<(w: SaveWarning) => void> = [];
91
+ private zstdReady: Promise<void> | null = null;
92
+ private _compress: ((data: Uint8Array) => Uint8Array) | null = null;
93
+ private _decompress: ((data: Uint8Array, originalSize: number) => Uint8Array) | null = null;
94
+ private _hash128: ((data: Uint8Array) => Uint8Array) | null = null;
95
+ private _skipMigrations: boolean = false;
96
+
97
+ constructor(opts: FileSaveStoreOptions) {
98
+ this.saveDir = opts.saveDir;
99
+ const parts = opts.engineVersion.split(".").map(Number);
100
+ this.engineVersionPacked = packEngineVersion(parts[0] ?? 0, parts[1] ?? 0, parts[2] ?? 0);
101
+ this.migrations = opts.migrationRegistry ?? new MigrationRegistryImpl();
102
+ this._compress = opts.compress ?? null;
103
+ this._decompress = opts.decompress ?? null;
104
+ this._hash128 = opts.hash128 ?? null;
105
+ this._skipMigrations = opts.skipMigrations ?? false;
106
+ }
107
+
108
+ getMigrationRegistry(): IMigrationRegistry {
109
+ return this.migrations;
110
+ }
111
+
112
+ onWarning(cb: (warning: SaveWarning) => void): () => void {
113
+ this.warningCallbacks.push(cb);
114
+ return () => {
115
+ const idx = this.warningCallbacks.indexOf(cb);
116
+ if (idx >= 0) this.warningCallbacks.splice(idx, 1);
117
+ };
118
+ }
119
+
120
+ private warn(warning: SaveWarning): void {
121
+ this.warningCallbacks.forEach((cb) => {
122
+ try {
123
+ cb(warning);
124
+ } catch {
125
+ // ignore callback errors
126
+ }
127
+ });
128
+ }
129
+
130
+ private async ensureZstd(): Promise<void> {
131
+ if (!this.zstdReady) this.zstdReady = ensureZstdGlobal();
132
+ return this.zstdReady;
133
+ }
134
+
135
+ private async computeHash(data: Uint8Array): Promise<Uint8Array> {
136
+ // True XXH3-128 hash (16 bytes) — no longer padded h64.
137
+ const { xxh3_128 } = await import("./hash-utils");
138
+ return xxh3_128(data);
139
+ }
140
+
141
+ private async compressBytes(data: Uint8Array): Promise<Uint8Array> {
142
+ await this.ensureZstd();
143
+ const { compress } = await import("@bokuweb/zstd-wasm");
144
+ return compress(data);
145
+ }
146
+
147
+ private async decompressBytes(data: Uint8Array, originalSize: number): Promise<Uint8Array> {
148
+ await this.ensureZstd();
149
+ const { decompress } = await import("@bokuweb/zstd-wasm");
150
+ return decompress(data);
151
+ }
152
+
153
+ // Saves are serialized — concurrent save() calls (e.g. an autosave tick
154
+ // racing a sim-emitted 'saved' event forwarded through the bridge) share
155
+ // the same .tmp path and would otherwise rename-fail with ENOENT.
156
+ private saveQueue: Promise<unknown> = Promise.resolve();
157
+
158
+ async save(slot: string, state: SaveState, opts?: SaveOptions): Promise<SaveResult> {
159
+ const run = this.saveQueue.then(() => this.doSave(slot, state, opts));
160
+ this.saveQueue = run.catch(() => { /* error reported via SaveResult */ });
161
+ return run;
162
+ }
163
+
164
+ private async doSave(slot: string, state: SaveState, opts?: SaveOptions): Promise<SaveResult> {
165
+ try {
166
+ await fs.mkdir(this.saveDir, { recursive: true });
167
+ const bodyJson = JSON.stringify(state.components);
168
+ const bodyBytes = new TextEncoder().encode(bodyJson);
169
+
170
+ const hashBytes = this._hash128 ? this._hash128(bodyBytes) : await this.computeHash(bodyBytes);
171
+ const compressed = this._compress ? this._compress(bodyBytes) : await this.compressBytes(bodyBytes);
172
+
173
+ const header: SaveHeader = {
174
+ magic: SAVE_MAGIC,
175
+ formatVersion: SAVE_FORMAT_VERSION,
176
+ engineVersionPacked: this.engineVersionPacked,
177
+ timestamp: state.meta.timestamp,
178
+ entityCount: state.meta.entityCount,
179
+ playerCount: state.meta.playerCount,
180
+ bodyHash: hashBytes,
181
+ uncompressedBodyLength: bodyBytes.length,
182
+ };
183
+
184
+ const headerBuf = encodeHeader(header);
185
+ const filePath = this.slotPath(slot);
186
+ const bakPath = filePath + ".bak";
187
+ const tmpPath = filePath + ".tmp";
188
+
189
+ const blobsDir = this.blobsDirPath(slot);
190
+ const bakBlobsDir = blobsDir + ".bak";
191
+ const tmpBlobsDir = blobsDir + ".tmp";
192
+
193
+ // Phase 1: Write everything to temp locations first.
194
+ // If the process crashes here, the old save is still intact.
195
+ // Clean up any stale temp blobs dir from a crashed previous save so its
196
+ // leftover files don't get renamed into the final blobs dir.
197
+ try { await fs.rm(tmpBlobsDir, { recursive: true, force: true }); } catch { /* ignore */ }
198
+ const fileBuf = new Uint8Array(headerBuf.byteLength + compressed.length);
199
+ fileBuf.set(new Uint8Array(headerBuf), 0);
200
+ fileBuf.set(compressed, headerBuf.byteLength);
201
+ await fs.writeFile(tmpPath, fileBuf);
202
+
203
+ // Write blobs to temp dir
204
+ let blobBytes = 0;
205
+ if (opts?.blobs && Object.keys(opts.blobs).length > 0) {
206
+ await fs.mkdir(tmpBlobsDir, { recursive: true });
207
+ for (let _i = 0, _it = Object.entries(opts.blobs) as Array<[string, ArrayBuffer]>, _n = _it.length; _i < _n; _i++) { const [key, buf] = _it[_i];
208
+ const safeKey = key.replace(/[^a-zA-Z0-9_\-]/g, "_");
209
+ await fs.writeFile(join(tmpBlobsDir, safeKey), new Uint8Array(buf));
210
+ blobBytes += buf.byteLength;
211
+ }
212
+ }
213
+
214
+ // Phase 2: All writes succeeded — now rotate old → .bak, then rename .tmp → final.
215
+ // This minimizes the crash-corruption window: the old save is only rotated
216
+ // after the new save is fully written to .tmp.
217
+ try {
218
+ await fs.access(filePath);
219
+ await fs.rename(filePath, bakPath);
220
+ } catch {
221
+ // No existing file — fine
222
+ }
223
+ try {
224
+ await fs.access(blobsDir);
225
+ // Remove a stale .bak blobs dir first: renaming a directory onto an
226
+ // existing non-empty directory fails with ENOTEMPTY on Linux, which
227
+ // would leave blobsDir in place and cause the .tmp → final rename
228
+ // below to fail with ENOTEMPTY as well.
229
+ try { await fs.rm(bakBlobsDir, { recursive: true, force: true }); } catch { /* ignore */ }
230
+ await fs.rename(blobsDir, bakBlobsDir);
231
+ } catch {
232
+ // No existing blobs dir — fine
233
+ }
234
+
235
+ // Atomic rename: .tmp → final
236
+ await fs.rename(tmpPath, filePath);
237
+ // Rename temp blobs dir → final
238
+ if (opts?.blobs && Object.keys(opts.blobs).length > 0) {
239
+ await fs.rename(tmpBlobsDir, blobsDir);
240
+ }
241
+
242
+ // Write thumbnail if provided (not part of the atomic commit — thumbnail is non-critical)
243
+ if (opts?.thumbnail) {
244
+ const thumbData = opts.thumbnail instanceof Uint8Array ? opts.thumbnail : new Uint8Array(opts.thumbnail);
245
+ await fs.writeFile(this.thumbPath(slot), thumbData);
246
+ }
247
+
248
+ // Write properties if provided (not part of the atomic commit — properties are non-critical)
249
+ if (opts?.properties) {
250
+ await fs.writeFile(this.propsPath(slot), JSON.stringify(opts.properties, null, 2));
251
+ }
252
+
253
+ log.debug("FileSaveStore", `Saved slot '${slot}' (${fileBuf.length + blobBytes} bytes)`);
254
+ return { success: true, bytes: fileBuf.length + blobBytes, gen: 1 };
255
+ } catch (err) {
256
+ log.error("FileSaveStore", `Save failed for slot '${slot}': ${err}`);
257
+ return { success: false, bytes: 0 };
258
+ }
259
+ }
260
+
261
+ async load(slot: string, opts?: LoadOptions): Promise<LoadResult> {
262
+ const filePath = this.slotPath(slot);
263
+ const bakPath = filePath + ".bak";
264
+ const includeBlobs = opts?.includeBlobs ?? true;
265
+
266
+ const result = await this.loadFromFile(filePath, slot, includeBlobs);
267
+ if (result.state) return result;
268
+
269
+ // Try backup
270
+ const bakResult = await this.loadFromFile(bakPath, slot, includeBlobs);
271
+ if (bakResult.state) {
272
+ this.warn({
273
+ kind: "backup_loaded",
274
+ slot,
275
+ message: `Primary save failed, loaded backup for slot '${slot}'`,
276
+ });
277
+ return bakResult;
278
+ }
279
+
280
+ this.warn({
281
+ kind: "no_saves_found",
282
+ slot,
283
+ message: `No valid save found for slot '${slot}'`,
284
+ });
285
+ return { state: null };
286
+ }
287
+
288
+ private async loadFromFile(filePath: string, slot: string, includeBlobs: boolean): Promise<LoadResult> {
289
+ try {
290
+ const fileBuf = await fs.readFile(filePath);
291
+ // fs.readFile returns a Buffer that may be a view into a shared pool —
292
+ // .buffer alone ignores byteOffset and reads garbage. Slice first.
293
+ const fileBytes = fileBuf.buffer.slice(fileBuf.byteOffset, fileBuf.byteOffset + fileBuf.byteLength);
294
+ const header = readHeaderFromFile(fileBytes);
295
+ if (!header) {
296
+ this.warn({ kind: "corruption", slot, message: `Invalid header in ${filePath}` });
297
+ return { state: null };
298
+ }
299
+
300
+ // Forward incompatibility check
301
+ if (header.engineVersionPacked > this.engineVersionPacked) {
302
+ const saveVer = engineVersionString(header.engineVersionPacked);
303
+ this.warn({
304
+ kind: "forward_incompatible",
305
+ slot,
306
+ message: `Save version ${saveVer} > engine version — refusing to load`,
307
+ });
308
+ return { state: null };
309
+ }
310
+
311
+ const compressedBody = new Uint8Array(fileBytes, HEADER_SIZE);
312
+ const decompressed = this._decompress
313
+ ? this._decompress(compressedBody, header.uncompressedBodyLength)
314
+ : await this.decompressBytes(compressedBody, header.uncompressedBodyLength);
315
+
316
+ // Verify hash
317
+ const computedHash = this._hash128 ? this._hash128(decompressed) : await this.computeHash(decompressed);
318
+ if (!this.hashEqual(computedHash, header.bodyHash)) {
319
+ this.warn({ kind: "corruption", slot, message: `Hash mismatch in ${filePath}` });
320
+ return { state: null };
321
+ }
322
+
323
+ const bodyJson = new TextDecoder().decode(decompressed);
324
+ const components = safeJsonParse<Record<string, { v: number; data: unknown }>>(bodyJson);
325
+
326
+ // Run migrations per component (or pass through if skipped)
327
+ const migrated: Record<string, { v: number; data: unknown }> = {};
328
+ const abandoned: Record<string, unknown> = {};
329
+
330
+ for (const [name, section] of Object.entries(components)) {
331
+ if (this._skipMigrations) {
332
+ migrated[name] = { v: section.v, data: section.data };
333
+ continue;
334
+ }
335
+ const result = this.migrations.migrate(name, section.data, section.v);
336
+ if (result) {
337
+ migrated[name] = { v: result.version, data: result.data };
338
+ } else {
339
+ // Mark as abandoned — keep data but don't load it
340
+ abandoned[name] = section.data;
341
+ this.warn({
342
+ kind: "abandoned_data",
343
+ slot,
344
+ component: name,
345
+ message: `Component '${name}' could not be migrated from v${section.v}`,
346
+ abandonedData: section.data,
347
+ });
348
+ }
349
+ }
350
+
351
+ const state: SaveState = {
352
+ components: migrated,
353
+ meta: {
354
+ engineVersion: engineVersionString(header.engineVersionPacked),
355
+ timestamp: header.timestamp,
356
+ entityCount: header.entityCount,
357
+ playerCount: header.playerCount,
358
+ },
359
+ };
360
+
361
+ log.info("FileSaveStore", `Loaded slot '${slot}'`);
362
+ // Load blobs if requested
363
+ let blobs: Record<string, ArrayBuffer> | undefined;
364
+ if (includeBlobs) {
365
+ blobs = await this.loadBlobs(slot);
366
+ if (blobs && Object.keys(blobs).length === 0) blobs = undefined;
367
+ }
368
+ return { state, blobs, gen: 1 };
369
+ } catch (err) {
370
+ // File doesn't exist or other error — return null silently
371
+ return { state: null };
372
+ }
373
+ }
374
+
375
+ private async loadBlobs(slot: string): Promise<Record<string, ArrayBuffer> | undefined> {
376
+ try {
377
+ const blobsDir = this.blobsDirPath(slot);
378
+ const files = await fs.readdir(blobsDir);
379
+ const blobs: Record<string, ArrayBuffer> = {};
380
+ for (let _i = 0, _it = files, _n = _it.length; _i < _n; _i++) { const file = _it[_i];
381
+ const buf = await fs.readFile(join(blobsDir, file));
382
+ blobs[file] = buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength);
383
+ }
384
+ return blobs;
385
+ } catch {
386
+ return undefined;
387
+ }
388
+ }
389
+
390
+ async listSaves(): Promise<SaveSlotInfo[]> {
391
+ try {
392
+ const files = await fs.readdir(this.saveDir);
393
+ const saves: SaveSlotInfo[] = [];
394
+
395
+ for (let _i = 0, _it = files, _n = _it.length; _i < _n; _i++) { const file = _it[_i];
396
+ if (!file.endsWith(SAVE_EXT)) continue;
397
+ const filePath = join(this.saveDir, file);
398
+ const stat = await fs.stat(filePath);
399
+ const fileBuf = await fs.readFile(filePath);
400
+ const header = readHeaderFromFile(
401
+ fileBuf.buffer.slice(fileBuf.byteOffset, fileBuf.byteOffset + fileBuf.byteLength));
402
+ if (!header) continue;
403
+
404
+ const slotName = file.replace(SAVE_EXT, "");
405
+ const hasThumbnail = await this.fileExists(this.thumbPath(slotName));
406
+ const properties = await this.readProps(slotName);
407
+
408
+ saves.push({
409
+ slot: slotName,
410
+ timestamp: header.timestamp,
411
+ entityCount: header.entityCount,
412
+ playerCount: header.playerCount,
413
+ engineVersion: engineVersionString(header.engineVersionPacked),
414
+ fileSize: stat.size,
415
+ currentGen: 1,
416
+ generationCount: 1,
417
+ hasThumbnail,
418
+ properties: Object.keys(properties).length > 0 ? properties : undefined,
419
+ });
420
+ }
421
+
422
+ saves.sort((a, b) => b.timestamp - a.timestamp);
423
+ return saves;
424
+ } catch {
425
+ return [];
426
+ }
427
+ }
428
+
429
+ async listGenerations(slot: string): Promise<SaveGenerationInfo[]> {
430
+ try {
431
+ const filePath = this.slotPath(slot);
432
+ const fileBuf = await fs.readFile(filePath);
433
+ const header = readHeaderFromFile(
434
+ fileBuf.buffer.slice(fileBuf.byteOffset, fileBuf.byteOffset + fileBuf.byteLength));
435
+ if (!header) return [];
436
+ const stat = await fs.stat(filePath);
437
+ return [{
438
+ gen: 1,
439
+ timestamp: header.timestamp,
440
+ engineVersion: engineVersionString(header.engineVersionPacked),
441
+ entityCount: header.entityCount,
442
+ playerCount: header.playerCount,
443
+ bodySize: stat.size,
444
+ blobCount: 0,
445
+ }];
446
+ } catch {
447
+ return [];
448
+ }
449
+ }
450
+
451
+ async deleteGeneration(slot: string, _gen: number): Promise<boolean> {
452
+ // FileSaveStore only has one "generation" — deleting it deletes the slot
453
+ if (_gen !== 1) return false;
454
+ return this.deleteSave(slot);
455
+ }
456
+
457
+ async setThumbnail(slot: string, data: ArrayBuffer | Uint8Array): Promise<void> {
458
+ const thumbData = data instanceof Uint8Array ? data : new Uint8Array(data);
459
+ await fs.writeFile(this.thumbPath(slot), thumbData);
460
+ }
461
+
462
+ async getThumbnail(slot: string): Promise<ArrayBuffer | null> {
463
+ try {
464
+ const buf = await fs.readFile(this.thumbPath(slot));
465
+ return buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength);
466
+ } catch {
467
+ return null;
468
+ }
469
+ }
470
+
471
+ async setProperties(slot: string, props: Record<string, unknown>): Promise<void> {
472
+ const existing = await this.readProps(slot);
473
+ const merged = { ...existing, ...props };
474
+ await fs.writeFile(this.propsPath(slot), JSON.stringify(merged, null, 2));
475
+ }
476
+
477
+ async getProperties(slot: string): Promise<Record<string, unknown>> {
478
+ return this.readProps(slot);
479
+ }
480
+
481
+ private async readProps(slot: string): Promise<Record<string, unknown>> {
482
+ try {
483
+ const text = await fs.readFile(this.propsPath(slot), "utf-8");
484
+ return safeJsonParse<Record<string, unknown>>(text);
485
+ } catch {
486
+ return {};
487
+ }
488
+ }
489
+
490
+ private async fileExists(path: string): Promise<boolean> {
491
+ try { await fs.access(path); return true; } catch { return false; }
492
+ }
493
+
494
+ async deleteSave(slot: string): Promise<boolean> {
495
+ const filePath = this.slotPath(slot);
496
+ const bakPath = filePath + ".bak";
497
+ const tmpPath = filePath + ".tmp";
498
+ let deleted = false;
499
+ try {
500
+ await fs.unlink(filePath);
501
+ deleted = true;
502
+ } catch {
503
+ // ignore
504
+ }
505
+ try {
506
+ await fs.unlink(bakPath);
507
+ deleted = true;
508
+ } catch {
509
+ // ignore
510
+ }
511
+ try {
512
+ await fs.unlink(tmpPath);
513
+ } catch {
514
+ // ignore — orphaned temp from a crashed save
515
+ }
516
+ // Clean up blobs, thumbnail, properties, and orphaned temp files
517
+ try { await fs.rm(this.blobsDirPath(slot), { recursive: true, force: true }); } catch {}
518
+ try { await fs.rm(this.blobsDirPath(slot) + ".bak", { recursive: true, force: true }); } catch {}
519
+ try { await fs.rm(this.blobsDirPath(slot) + ".tmp", { recursive: true, force: true }); } catch {}
520
+ try { await fs.unlink(this.thumbPath(slot)); } catch {}
521
+ try { await fs.unlink(this.propsPath(slot)); } catch {}
522
+ return deleted;
523
+ }
524
+
525
+ private slotPath(slot: string): string {
526
+ // Sanitize slot name to prevent path traversal
527
+ const safe = slot.replace(/[^a-zA-Z0-9_\-]/g, "_");
528
+ return join(this.saveDir, safe + SAVE_EXT);
529
+ }
530
+
531
+ private blobsDirPath(slot: string): string {
532
+ const safe = slot.replace(/[^a-zA-Z0-9_\-]/g, "_");
533
+ return join(this.saveDir, safe + BLOBS_DIR_SUFFIX);
534
+ }
535
+
536
+ private thumbPath(slot: string): string {
537
+ const safe = slot.replace(/[^a-zA-Z0-9_\-]/g, "_");
538
+ return join(this.saveDir, safe + THUMB_EXT);
539
+ }
540
+
541
+ private propsPath(slot: string): string {
542
+ const safe = slot.replace(/[^a-zA-Z0-9_\-]/g, "_");
543
+ return join(this.saveDir, safe + PROPS_EXT);
544
+ }
545
+
546
+ private hashEqual(a: Uint8Array, b: Uint8Array): boolean {
547
+ if (a.length !== b.length) return false;
548
+ for (let i = 0; i < a.length; i++) {
549
+ if (a[i] !== b[i]) return false;
550
+ }
551
+ return true;
552
+ }
553
+ }
@@ -0,0 +1,59 @@
1
+ // ============================================================================
2
+ // Hash utilities — true XXH3-128 hashing for save integrity
3
+ // ============================================================================
4
+ //
5
+ // Uses xxh3-ts (pure TypeScript, no native deps) to compute a true 128-bit
6
+ // XXH3 hash. The result is returned as a 16-byte Uint8Array (little-endian),
7
+ // matching the binary format header's XXH128 field.
8
+ //
9
+ // All three save stores (File, OPFS, IndexedDB) share this utility as the
10
+ // default hash implementation. The `hash128` injection option remains for
11
+ // testing or custom hash providers.
12
+ //
13
+ // NOTE: xxh3-ts ships CJS .js files (with require()). A static import lets
14
+ // Vite pre-bundle the CJS→ESM conversion. A dynamic import with a variable
15
+ // name (the previous approach) broke Vite's pre-bundling — the browser got
16
+ // raw CJS with require() calls that fail at runtime, which blocked
17
+ // `loadWorld()` during renderer init and left the canvas black.
18
+ // See ./xxh3-ts.d.ts for the type override that avoids a TS 5.9+
19
+ // BigUint64Array incompatibility in the package's .ts source.
20
+ //
21
+
22
+ import { Buffer } from "buffer";
23
+ import * as xxh3ns from "xxh3-ts";
24
+
25
+ // The bare "xxh3-ts" specifier resolves to the real CJS package under Vite,
26
+ // Bun and Node, but tsconfig `paths` (and the generated deno.json import
27
+ // map) alias it to the type-only ./xxh3-ts.d.ts — tsx and Deno honor the
28
+ // alias at runtime and load the .d.ts, yielding an empty module. Fall back
29
+ // to a require() of the deep /index.js subpath, which the alias doesn't
30
+ // cover (only ever reached on tsx/Deno; the static import always provides
31
+ // the export in Vite/Bun/Node contexts).
32
+ let XXH3_128: ((data: Buffer) => bigint) | undefined =
33
+ (xxh3ns as any).XXH3_128 ?? (xxh3ns as any).default?.XXH3_128;
34
+
35
+ async function getXXH3(): Promise<(data: Buffer) => bigint> {
36
+ if (!XXH3_128) {
37
+ const { createRequire } = await import("node:module");
38
+ const f = createRequire(import.meta.url)("xxh3-ts/index.js").XXH3_128;
39
+ XXH3_128 = f;
40
+ return f;
41
+ }
42
+ return XXH3_128;
43
+ }
44
+
45
+ /**
46
+ * Compute a true XXH3-128 hash of the input data.
47
+ * Returns a 16-byte Uint8Array (little-endian: low 64 bits at offset 0, high 64 bits at offset 8).
48
+ */
49
+ export async function xxh3_128(data: Uint8Array): Promise<Uint8Array> {
50
+ // Buffer.from(uint8array) works in both Node.js (native Buffer) and browser (polyfill).
51
+ const buf = Buffer.from(data.buffer, data.byteOffset, data.byteLength);
52
+ const hash = (await getXXH3())(buf);
53
+ const result = new Uint8Array(16);
54
+ const view = new DataView(result.buffer);
55
+ // Low 64 bits at offset 0, high 64 bits at offset 8 (little-endian).
56
+ view.setBigUint64(0, hash & 0xFFFFFFFFFFFFFFFFn, true);
57
+ view.setBigUint64(8, (hash >> 64n) & 0xFFFFFFFFFFFFFFFFn, true);
58
+ return result;
59
+ }
@@ -0,0 +1,57 @@
1
+ // ============================================================================
2
+ // @downdraft/engine/libraries/persistence — versioned, compressed save system
3
+ // ============================================================================
4
+ //
5
+ // This barrel re-exports everything including FileSaveStore (Node-only).
6
+ // For browser/renderer code that cannot import node:fs/node:path, import from
7
+ // @downdraft/engine/libraries/persistence/browser instead.
8
+
9
+ export { FileSaveStore } from "./file-save-store";
10
+ export type { FileSaveStoreOptions } from "./file-save-store";
11
+
12
+ export { createNodeFsDirectoryHandle } from "./node-fs-directory-handle";
13
+
14
+ export { AutosaveManager } from "./autosave-manager";
15
+ export type { AutosaveManagerOptions } from "./autosave-manager";
16
+
17
+ export { OpfsSaveStore } from "./opfs-save-store";
18
+ export type { OpfsSaveStoreOptions } from "./opfs-save-store";
19
+
20
+ export { BinaryRecordStore, createBinaryRecordStore } from "./binary-record-store";
21
+ export type { BinaryRecordStoreOptions, IBinaryRecordStore } from "./binary-record-store";
22
+
23
+ export { SaveWorkerProxy } from "./save-worker-proxy";
24
+ export type { SaveWorkerProxyOptions } from "./save-worker-proxy";
25
+
26
+ export type { SaveWorkerApi } from "./save-worker";
27
+
28
+ // Re-export core types for convenience
29
+ export {
30
+ decodeHeader, encodeHeader, engineVersionString, HEADER_SIZE, MigrationRegistryImpl,
31
+ packEngineVersion, readHeaderFromFile, SAVE_FORMAT_VERSION, SAVE_MAGIC, unpackEngineVersion, XXH128_SIZE
32
+ } from "@downdraft/engine/index";
33
+
34
+ export type {
35
+ ComponentMigration,
36
+ ComponentSection,
37
+ IMigrationRegistry,
38
+ IRendererStateProvider,
39
+ ISaveStore,
40
+ LoadOptions,
41
+ LoadResult,
42
+ SaveGenerationInfo,
43
+ SaveHeader,
44
+ SaveMeta,
45
+ SaveOptions,
46
+ SaveResult,
47
+ SaveSlotInfo,
48
+ SaveState,
49
+ SaveStateBuilder,
50
+ SaveWarning,
51
+ SaveWarningKind
52
+ } from "@downdraft/engine/index";
53
+
54
+ // Declarative library descriptor
55
+ export { PersistenceLib, PersistenceTok } from "./library";
56
+ export type { PersistenceLibConfig } from "./library";
57
+