@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.
- package/README.md +33 -0
- package/app/src/index.ts +10 -0
- package/app/src/renderer/bootstrap.ts +271 -0
- package/app/src/renderer/downdraft-base.css +93 -0
- package/app/src/renderer/feature-log.ts +200 -0
- package/app/src/renderer/game-module.ts +923 -0
- package/app/src/renderer/hooks.ts +88 -0
- package/app/src/renderer/hot-reload.ts +178 -0
- package/app/src/renderer/import-cache.ts +88 -0
- package/app/src/renderer/index.ts +206 -0
- package/app/src/renderer/mcp-harness.ts +144 -0
- package/app/src/renderer/save-store-factory.ts +239 -0
- package/app/src/renderer/sim-bridge.ts +183 -0
- package/app/src/renderer/standard-automation-tools.ts +771 -0
- package/app/src/shared/feature-log.ts +71 -0
- package/app/src/shared/gpu-info.ts +82 -0
- package/app/src/shared/import-cache-store.ts +142 -0
- package/app/src/shared/index.ts +6 -0
- package/app/src/shared/mcp-discovery.ts +47 -0
- package/app/src/shared/mcp-proxy.ts +82 -0
- package/app/src/shared/types.ts +324 -0
- package/asset-bake/src/bake-audio.ts +119 -0
- package/asset-bake/src/bake-gltf.ts +172 -0
- package/asset-bake/src/bake.ts +78 -0
- package/asset-bake/src/cache.ts +188 -0
- package/asset-bake/src/config.ts +186 -0
- package/asset-bake/src/index.ts +36 -0
- package/core/src/animation/animation-event.ts +41 -0
- package/core/src/animation/bone-mask.ts +122 -0
- package/core/src/animation/clip.ts +252 -0
- package/core/src/animation/index.ts +22 -0
- package/core/src/animation/mixamo.ts +113 -0
- package/core/src/animation/morph-target.ts +69 -0
- package/core/src/animation/player.ts +697 -0
- package/core/src/animation/retarget.ts +158 -0
- package/core/src/animation/skeleton-animator.ts +1399 -0
- package/core/src/animation/skeleton.ts +214 -0
- package/core/src/animation/state-machine.ts +280 -0
- package/core/src/assets/blob-store.ts +66 -0
- package/core/src/assets/cache.ts +186 -0
- package/core/src/assets/cubemap-converter.ts +155 -0
- package/core/src/assets/environment-manager.ts +121 -0
- package/core/src/assets/import-cache.ts +65 -0
- package/core/src/assets/import-settings.ts +72 -0
- package/core/src/assets/importer.ts +108 -0
- package/core/src/assets/index.ts +74 -0
- package/core/src/assets/irradiance-generator.ts +198 -0
- package/core/src/assets/loader-audio.ts +86 -0
- package/core/src/assets/loader-cubemap.ts +211 -0
- package/core/src/assets/loader-dds.ts +236 -0
- package/core/src/assets/loader-hdr.ts +474 -0
- package/core/src/assets/loader-mesh.ts +143 -0
- package/core/src/assets/loader-shader.ts +73 -0
- package/core/src/assets/loader-texture.ts +349 -0
- package/core/src/assets/lod.ts +198 -0
- package/core/src/assets/manager.ts +480 -0
- package/core/src/assets/manifest.ts +81 -0
- package/core/src/assets/material-bridge.ts +186 -0
- package/core/src/assets/model-importer.ts +72 -0
- package/core/src/assets/model-normalizer.ts +248 -0
- package/core/src/assets/model-to-gpu.ts +70 -0
- package/core/src/assets/model-to-mesh.ts +237 -0
- package/core/src/assets/prefilter-generator.ts +250 -0
- package/core/src/audio/engine.ts +177 -0
- package/core/src/audio/interface.ts +130 -0
- package/core/src/audio/listener.ts +32 -0
- package/core/src/audio/mixer.ts +141 -0
- package/core/src/audio/registry.ts +52 -0
- package/core/src/audio/sab.ts +87 -0
- package/core/src/audio/source.ts +89 -0
- package/core/src/change-detection/atomics.ts +1 -0
- package/core/src/change-detection/tracker.ts +47 -0
- package/core/src/debug-draw/lines.ts +64 -0
- package/core/src/debug-draw/points.ts +17 -0
- package/core/src/debug-draw/queue.ts +124 -0
- package/core/src/debug-draw/text.ts +25 -0
- package/core/src/ecs/archetype.ts +323 -0
- package/core/src/ecs/component.ts +188 -0
- package/core/src/ecs/entity.ts +25 -0
- package/core/src/ecs/events.ts +93 -0
- package/core/src/ecs/hierarchy.ts +124 -0
- package/core/src/ecs/hmr-swap-registry.ts +22 -0
- package/core/src/ecs/index.ts +25 -0
- package/core/src/ecs/query.ts +141 -0
- package/core/src/ecs/resource.ts +8 -0
- package/core/src/ecs/schedule.ts +181 -0
- package/core/src/ecs/system-params.ts +99 -0
- package/core/src/ecs/system.ts +42 -0
- package/core/src/ecs/world.ts +348 -0
- package/core/src/index.ts +352 -0
- package/core/src/input/context.ts +73 -0
- package/core/src/input/dom-handler.ts +380 -0
- package/core/src/input/local-player-manager.ts +218 -0
- package/core/src/input/mapping.ts +40 -0
- package/core/src/input/multi-sab-bridge.ts +276 -0
- package/core/src/input/multi-state.ts +54 -0
- package/core/src/input/sab-bridge.ts +71 -0
- package/core/src/input/state.ts +132 -0
- package/core/src/input/ui-router.ts +87 -0
- package/core/src/library/host.ts +317 -0
- package/core/src/library/index.ts +16 -0
- package/core/src/library/library.ts +292 -0
- package/core/src/material/compiler.ts +80 -0
- package/core/src/material/graph-bridge.ts +172 -0
- package/core/src/material/index.ts +9 -0
- package/core/src/material/library.ts +442 -0
- package/core/src/material/material.ts +156 -0
- package/core/src/material/variants.ts +61 -0
- package/core/src/math/mat4.ts +202 -0
- package/core/src/math/perlin-noise-2d.ts +77 -0
- package/core/src/math/perlin-noise-3d.ts +110 -0
- package/core/src/math/quat.ts +33 -0
- package/core/src/math/rng.ts +29 -0
- package/core/src/math/trig.ts +47 -0
- package/core/src/math/value-noise.ts +67 -0
- package/core/src/mesh/builder.ts +177 -0
- package/core/src/mesh/csg.ts +312 -0
- package/core/src/mesh/greased-line.ts +145 -0
- package/core/src/mesh/mesh.ts +17 -0
- package/core/src/mesh/parametric.ts +501 -0
- package/core/src/mesh/skinning.ts +67 -0
- package/core/src/mesh/vertex-layout.ts +91 -0
- package/core/src/module/cross-thread.ts +163 -0
- package/core/src/module/diagnostics.ts +123 -0
- package/core/src/module/host.ts +451 -0
- package/core/src/module/index.ts +22 -0
- package/core/src/module/module.ts +109 -0
- package/core/src/module/registry.ts +94 -0
- package/core/src/module/renderer-module.ts +247 -0
- package/core/src/module/ts-loader.ts +26 -0
- package/core/src/particles/compute-pass.ts +378 -0
- package/core/src/particles/emitter.ts +156 -0
- package/core/src/particles/index.ts +11 -0
- package/core/src/particles/particle-data.ts +47 -0
- package/core/src/particles/render-pass.ts +365 -0
- package/core/src/particles/simulator.ts +264 -0
- package/core/src/particles/system.ts +193 -0
- package/core/src/physics/body.ts +59 -0
- package/core/src/physics/ccd-heuristic.ts +55 -0
- package/core/src/physics/character.ts +282 -0
- package/core/src/physics/collider.ts +55 -0
- package/core/src/physics/collision-system.ts +91 -0
- package/core/src/physics/events.ts +133 -0
- package/core/src/physics/index.ts +34 -0
- package/core/src/physics/interface.ts +473 -0
- package/core/src/physics/interpolation-buffer.ts +192 -0
- package/core/src/physics/lifecycle.ts +87 -0
- package/core/src/physics/load-shedder.ts +164 -0
- package/core/src/physics/physics-accumulator.ts +101 -0
- package/core/src/physics/physics-system.ts +240 -0
- package/core/src/physics/ragdoll-presets.ts +272 -0
- package/core/src/physics/ragdoll-system.ts +220 -0
- package/core/src/physics/ragdoll.ts +182 -0
- package/core/src/physics/raycast.ts +143 -0
- package/core/src/physics/realm-manager.ts +499 -0
- package/core/src/physics/realm-worker-pool.ts +191 -0
- package/core/src/physics/realm-worker.ts +102 -0
- package/core/src/physics/realm.ts +189 -0
- package/core/src/physics/registry.ts +52 -0
- package/core/src/physics/safety.ts +247 -0
- package/core/src/physics/snapshot-manager.ts +141 -0
- package/core/src/physics/worker-protocol.ts +30 -0
- package/core/src/platform/bun-preload.ts +169 -0
- package/core/src/platform/css-stub.ts +4 -0
- package/core/src/platform/glob-polyfill.ts +124 -0
- package/core/src/platform/hidpi.ts +57 -0
- package/core/src/platform/render-surface.ts +77 -0
- package/core/src/platform/rpc.ts +98 -0
- package/core/src/platform/runtime.ts +132 -0
- package/core/src/plugin/context.ts +364 -0
- package/core/src/plugin/diagnostics.ts +61 -0
- package/core/src/plugin/discovery.ts +186 -0
- package/core/src/plugin/extension-loaders.ts +172 -0
- package/core/src/plugin/host.ts +659 -0
- package/core/src/plugin/index.ts +106 -0
- package/core/src/plugin/loader-asset.ts +124 -0
- package/core/src/plugin/loader-quickjs.ts +84 -0
- package/core/src/plugin/loader-wasm.ts +411 -0
- package/core/src/plugin/loader-worker.ts +261 -0
- package/core/src/plugin/manifest.ts +653 -0
- package/core/src/plugin/material-registry.ts +65 -0
- package/core/src/plugin/mcp-tools.ts +165 -0
- package/core/src/plugin/permissions.ts +175 -0
- package/core/src/plugin/quickjs-bridge.ts +294 -0
- package/core/src/plugin/registry.ts +107 -0
- package/core/src/plugin/sandbox-shim.ts +86 -0
- package/core/src/plugin/sandbox-worker.ts +215 -0
- package/core/src/plugin/wasm-abi.ts +152 -0
- package/core/src/plugin/wasm-worker.ts +229 -0
- package/core/src/plugin/workshop.ts +169 -0
- package/core/src/profiling/event-loop.ts +180 -0
- package/core/src/profiling/index.ts +69 -0
- package/core/src/profiling/iops/idb-patch.ts +242 -0
- package/core/src/profiling/iops/opfs-patch.ts +276 -0
- package/core/src/profiling/profiling-sab.ts +839 -0
- package/core/src/profiling/task-latency.ts +134 -0
- package/core/src/profiling/thread-metrics.ts +126 -0
- package/core/src/profiling/trace-event-writer.ts +205 -0
- package/core/src/profiling/warnings.ts +423 -0
- package/core/src/profiling/worker-prelude.ts +376 -0
- package/core/src/render/bind-group.ts +38 -0
- package/core/src/render/bindless/bindless-struct.ts +42 -0
- package/core/src/render/bindless/bindless.wgsl.ts +167 -0
- package/core/src/render/bindless/frame-bindings.ts +176 -0
- package/core/src/render/bindless/index.ts +10 -0
- package/core/src/render/bindless/material-manager.ts +257 -0
- package/core/src/render/bindless/texture-registry.ts +609 -0
- package/core/src/render/buffer.ts +82 -0
- package/core/src/render/camera-2d.ts +217 -0
- package/core/src/render/camera-controller.ts +440 -0
- package/core/src/render/camera.ts +409 -0
- package/core/src/render/canvas-resize-watcher.ts +46 -0
- package/core/src/render/compute-kernel.ts +172 -0
- package/core/src/render/constants.ts +2 -0
- package/core/src/render/device.ts +111 -0
- package/core/src/render/frame-graph.ts +768 -0
- package/core/src/render/frustum.ts +185 -0
- package/core/src/render/fullscreen-vs.ts +25 -0
- package/core/src/render/g-buffer.ts +186 -0
- package/core/src/render/game-renderer.ts +1452 -0
- package/core/src/render/gpu-driven/cull-pass.ts +394 -0
- package/core/src/render/gpu-driven/hzb.ts +215 -0
- package/core/src/render/gpu-driven/index.ts +7 -0
- package/core/src/render/gpu-driven/indirect-draw-pass.ts +324 -0
- package/core/src/render/gpu-driven/instance-buffer.ts +178 -0
- package/core/src/render/gpu-driven/mesh-table.ts +175 -0
- package/core/src/render/gpu-driven/passes/hzb-build-pass.ts +47 -0
- package/core/src/render/gpu-utils.ts +96 -0
- package/core/src/render/hdr.ts +88 -0
- package/core/src/render/hot-reload.ts +295 -0
- package/core/src/render/ibl-bind-group.ts +266 -0
- package/core/src/render/ibl.ts +180 -0
- package/core/src/render/index.ts +163 -0
- package/core/src/render/input-manager.ts +259 -0
- package/core/src/render/lighting/area-light.ts +196 -0
- package/core/src/render/lighting/cluster-grid.ts +288 -0
- package/core/src/render/lighting/cluster-types.ts +193 -0
- package/core/src/render/lighting/ies-parser.ts +162 -0
- package/core/src/render/lighting.ts +454 -0
- package/core/src/render/material-types/depth.wgsl +44 -0
- package/core/src/render/material-types/line.wgsl +50 -0
- package/core/src/render/material-types/matcap.wgsl +51 -0
- package/core/src/render/material-types/normal.wgsl +41 -0
- package/core/src/render/material-types/physical.wgsl +152 -0
- package/core/src/render/material-types/sprite.wgsl +46 -0
- package/core/src/render/material-types/sss.wgsl +79 -0
- package/core/src/render/material-types/toon.wgsl +79 -0
- package/core/src/render/passes/README.md +121 -0
- package/core/src/render/passes/atmosphere.ts +152 -0
- package/core/src/render/passes/cluster-lighting-pass.ts +476 -0
- package/core/src/render/passes/csm.ts +408 -0
- package/core/src/render/passes/cubemap-capture.ts +114 -0
- package/core/src/render/passes/debug-viz.ts +278 -0
- package/core/src/render/passes/debug.ts +538 -0
- package/core/src/render/passes/decal-mesh.ts +111 -0
- package/core/src/render/passes/decal-pass.ts +377 -0
- package/core/src/render/passes/deferred-lighting.ts +434 -0
- package/core/src/render/passes/depth-prepass.ts +163 -0
- package/core/src/render/passes/dome-360.ts +83 -0
- package/core/src/render/passes/fluid-render.ts +137 -0
- package/core/src/render/passes/gi-types.ts +118 -0
- package/core/src/render/passes/graph-compute.ts +300 -0
- package/core/src/render/passes/greased-line-pass.ts +232 -0
- package/core/src/render/passes/morph-target.ts +40 -0
- package/core/src/render/passes/opaque.ts +1028 -0
- package/core/src/render/passes/point-light-shadow.ts +266 -0
- package/core/src/render/passes/procedural-texture.ts +185 -0
- package/core/src/render/passes/reflection-probe.ts +140 -0
- package/core/src/render/passes/rsm-pass.ts +248 -0
- package/core/src/render/passes/sdf-text.ts +155 -0
- package/core/src/render/passes/shadow-map.ts +163 -0
- package/core/src/render/passes/shadow.ts +220 -0
- package/core/src/render/passes/skinning-vs.ts +121 -0
- package/core/src/render/passes/skinning.ts +326 -0
- package/core/src/render/passes/sky-dome.ts +404 -0
- package/core/src/render/passes/skybox.ts +162 -0
- package/core/src/render/passes/spot-light-shadow.ts +273 -0
- package/core/src/render/passes/terrain.ts +326 -0
- package/core/src/render/passes/transparent.ts +353 -0
- package/core/src/render/passes/underwater-fog.ts +185 -0
- package/core/src/render/passes/video-texture.ts +79 -0
- package/core/src/render/passes/volumetric-pass.ts +312 -0
- package/core/src/render/passes/volumetric-types.ts +171 -0
- package/core/src/render/passes/water.ts +753 -0
- package/core/src/render/pbr.ts +296 -0
- package/core/src/render/pipeline.ts +52 -0
- package/core/src/render/render-pass.ts +30 -0
- package/core/src/render/renderer-input-bus.ts +220 -0
- package/core/src/render/renderer-module-host.ts +623 -0
- package/core/src/render/resource-tracker.ts +67 -0
- package/core/src/render/sab-canvas-overlay.ts +122 -0
- package/core/src/render/shader-validator.ts +200 -0
- package/core/src/render/shaders/debug/debug-line.wgsl +27 -0
- package/core/src/render/shaders/debug/debug-point.wgsl +30 -0
- package/core/src/render/shaders/debug/debug-text.wgsl +42 -0
- package/core/src/render/shaders/debug-viz/aabb.wgsl +20 -0
- package/core/src/render/shaders/debug-viz/depth.wgsl +29 -0
- package/core/src/render/shaders/debug-viz/lod.wgsl +38 -0
- package/core/src/render/shaders/debug-viz/normals.wgsl +30 -0
- package/core/src/render/shaders/debug-viz/overdraw.wgsl +21 -0
- package/core/src/render/shaders/debug-viz/tangents.wgsl +29 -0
- package/core/src/render/shaders/debug-viz/wireframe.wgsl +33 -0
- package/core/src/render/shaders/shadow-chunks.ts +135 -0
- package/core/src/render/skybox.ts +146 -0
- package/core/src/render/splitscreen.ts +85 -0
- package/core/src/render/surface.ts +78 -0
- package/core/src/render/tonemap.ts +180 -0
- package/core/src/render/tracked-render-pass.ts +158 -0
- package/core/src/render/viewport.ts +109 -0
- package/core/src/render/wgsl-hmr.ts +70 -0
- package/core/src/sab/core-input-channel.ts +23 -0
- package/core/src/sab/define.ts +239 -0
- package/core/src/sab/errors.ts +76 -0
- package/core/src/sab/game-input.ts +343 -0
- package/core/src/sab/gamepad-devices.ts +259 -0
- package/core/src/sab/grid-buffer.ts +117 -0
- package/core/src/sab/input.ts +55 -0
- package/core/src/sab/layout.ts +219 -0
- package/core/src/sab/multi-input-channel.ts +50 -0
- package/core/src/sab/record-buffer.ts +155 -0
- package/core/src/sab/sab-polyfill.ts +56 -0
- package/core/src/sab/sim-channel.ts +453 -0
- package/core/src/sab/slot-buffer.ts +190 -0
- package/core/src/sab/types.ts +158 -0
- package/core/src/safety/bounds.ts +76 -0
- package/core/src/safety/json.ts +80 -0
- package/core/src/safety/path.ts +167 -0
- package/core/src/save/binary-format.ts +117 -0
- package/core/src/save/game-save-system.ts +161 -0
- package/core/src/save/grid-save-system.ts +158 -0
- package/core/src/save/migrate.ts +44 -0
- package/core/src/save/migration-registry.ts +94 -0
- package/core/src/save/persist-types.ts +208 -0
- package/core/src/save/schema.ts +46 -0
- package/core/src/save/serializer.ts +180 -0
- package/core/src/scene/builder.ts +65 -0
- package/core/src/scene/camera.ts +142 -0
- package/core/src/scene/checkpoint.ts +109 -0
- package/core/src/scene/game-loop.ts +198 -0
- package/core/src/scene/index.ts +24 -0
- package/core/src/scene/layer.ts +6 -0
- package/core/src/scene/prefab.ts +145 -0
- package/core/src/scene/scene-manager.ts +157 -0
- package/core/src/scene/scene.ts +192 -0
- package/core/src/scene/sky.ts +256 -0
- package/core/src/scene/spatial-grid.ts +176 -0
- package/core/src/scene/streaming.ts +304 -0
- package/core/src/scene/vegetation.ts +163 -0
- package/core/src/scene/world.ts +89 -0
- package/core/src/scripting/binding.ts +129 -0
- package/core/src/scripting/hot-reload.ts +144 -0
- package/core/src/scripting/script.ts +99 -0
- package/core/src/sim/hot-reload-pipeline.ts +49 -0
- package/core/src/sim/sim-state-helper.ts +47 -0
- package/core/src/sim/transient-state-registry.ts +77 -0
- package/core/src/sim/types.ts +113 -0
- package/core/src/sim/worker-loop.ts +222 -0
- package/core/src/stores/game-store.ts +158 -0
- package/core/src/stores/hot-reload-store.ts +44 -0
- package/core/src/telemetry/collector.ts +410 -0
- package/core/src/telemetry/gc-controller.ts +453 -0
- package/core/src/telemetry/gc-profiler.ts +126 -0
- package/core/src/telemetry/gc-tracker.ts +69 -0
- package/core/src/telemetry/gpu-profiler.ts +703 -0
- package/core/src/telemetry/gpu-resource-tracker.ts +285 -0
- package/core/src/telemetry/gpu-timer-pool.ts +234 -0
- package/core/src/telemetry/gpu-timer.ts +123 -0
- package/core/src/telemetry/gpu-timestamp-gate.ts +21 -0
- package/core/src/telemetry/reporter.ts +62 -0
- package/core/src/types/engine-types.ts +129 -0
- package/core/src/ui-font-scale.ts +112 -0
- package/core/src/util/broad-phase-grid.ts +82 -0
- package/core/src/util/feature-log.ts +220 -0
- package/core/src/util/index.ts +17 -0
- package/core/src/util/logger.ts +604 -0
- package/core/src/webgpu-destroy-augmentation.d.ts +25 -0
- package/core/src/worker/base-worker-host.ts +183 -0
- package/core/src/worker/buffer-sync.ts +550 -0
- package/core/src/worker/crash-recovery.ts +201 -0
- package/core/src/worker/entity-sim-worker-host.ts +190 -0
- package/core/src/worker/instrumented-worker-host.ts +171 -0
- package/core/src/worker/rpc.ts +253 -0
- package/core/src/worker/sim-worker-base.ts +913 -0
- package/core/src/worker/sim-worker-host.ts +358 -0
- package/core/src/worker/task-pool.ts +256 -0
- package/core/src/worker/task-worker.ts +83 -0
- package/libraries/asset-browser/src/index.ts +11 -0
- package/libraries/asset-browser/src/software-thumbnails.ts +949 -0
- package/libraries/audio-kira/README.md +17 -0
- package/libraries/audio-kira/native/Cargo.toml +14 -0
- package/libraries/audio-kira/native/src/engine.rs +27 -0
- package/libraries/audio-kira/native/src/lib.rs +185 -0
- package/libraries/audio-kira/native/src/mixer.rs +11 -0
- package/libraries/audio-kira/native/src/source.rs +80 -0
- package/libraries/audio-kira/src/backend.ts +469 -0
- package/libraries/audio-kira/src/index.ts +8 -0
- package/libraries/audio-kira/src/library.ts +82 -0
- package/libraries/blitz-ui/native/Cargo.toml +33 -0
- package/libraries/blitz-ui/native/assets/DejaVuSans.woff2 +0 -0
- package/libraries/blitz-ui/native/src/bridge.rs +100 -0
- package/libraries/blitz-ui/native/src/fonts.rs +20 -0
- package/libraries/blitz-ui/native/src/input.rs +80 -0
- package/libraries/blitz-ui/native/src/lib.rs +96 -0
- package/libraries/blitz-ui/native/src/shell.rs +301 -0
- package/libraries/blitz-ui/native-osr/Cargo.toml +24 -0
- package/libraries/blitz-ui/native-osr/src/events.rs +237 -0
- package/libraries/blitz-ui/native-osr/src/lib.rs +846 -0
- package/libraries/blitz-ui/native-osr/src/mutate.rs +385 -0
- package/libraries/blitz-ui/native-osr/src/resources.rs +45 -0
- package/libraries/blitz-ui/native-osr-spike.ts +70 -0
- package/libraries/blitz-ui/src/index.ts +15 -0
- package/libraries/blitz-ui/src/native-module.ts +221 -0
- package/libraries/blitz-ui/src/native-osr-ffi.ts +423 -0
- package/libraries/blitz-ui/src/router.ts +101 -0
- package/libraries/blitz-ui/src/shaders/ui-blit.wgsl.ts +35 -0
- package/libraries/blitz-ui/src/ui-blit-pass.ts +116 -0
- package/libraries/character/README.md +25 -0
- package/libraries/character/src/character-animator.ts +374 -0
- package/libraries/character/src/index.ts +24 -0
- package/libraries/character/src/loader.ts +375 -0
- package/libraries/character/src/locomotion.ts +124 -0
- package/libraries/character/src/preview.ts +287 -0
- package/libraries/devtools/README.md +51 -0
- package/libraries/devtools/native/Cargo.toml +12 -0
- package/libraries/devtools/native/src/lib.rs +1646 -0
- package/libraries/devtools/native/src/panels/console.rs +338 -0
- package/libraries/devtools/native/src/panels/dom_tree.rs +47 -0
- package/libraries/devtools/native/src/panels/generic.rs +317 -0
- package/libraries/devtools/native/src/panels/gpu.rs +107 -0
- package/libraries/devtools/native/src/panels/input.rs +88 -0
- package/libraries/devtools/native/src/panels/mod.rs +154 -0
- package/libraries/devtools/native/src/panels/perf_metrics.rs +91 -0
- package/libraries/devtools/native/src/panels/perf_recorder.rs +158 -0
- package/libraries/devtools/native/src/panels/scene.rs +72 -0
- package/libraries/devtools/native/src/state.rs +394 -0
- package/libraries/devtools/src/cdp-bridge.ts +349 -0
- package/libraries/devtools/src/collectors.ts +346 -0
- package/libraries/devtools/src/egui-ffi.ts +804 -0
- package/libraries/devtools/src/egui-renderer.ts +407 -0
- package/libraries/devtools/src/host.ts +363 -0
- package/libraries/devtools/src/index.ts +40 -0
- package/libraries/devtools/src/mirror.ts +794 -0
- package/libraries/devtools/src/native-providers.ts +744 -0
- package/libraries/devtools/src/verify.ts +167 -0
- package/libraries/devtools/src/web/browser.ts +102 -0
- package/libraries/devtools/src/web/host.ts +212 -0
- package/libraries/devtools/src/web/mirror.ts +430 -0
- package/libraries/devtools/src/web/server.ts +198 -0
- package/libraries/entities/README.md +17 -0
- package/libraries/entities/src/index.ts +4 -0
- package/libraries/entities/src/library.ts +64 -0
- package/libraries/entities/src/model-renderer.ts +1345 -0
- package/libraries/entities/src/shaders/model.wgsl +375 -0
- package/libraries/gamepad/src/feed-input.ts +83 -0
- package/libraries/gamepad/src/filters.ts +49 -0
- package/libraries/gamepad/src/glyphs.ts +93 -0
- package/libraries/gamepad/src/hub.ts +206 -0
- package/libraries/gamepad/src/index.ts +22 -0
- package/libraries/gamepad/src/library.ts +68 -0
- package/libraries/gamepad/src/source-sab.ts +70 -0
- package/libraries/gamepad/src/sysfs-enrich.ts +138 -0
- package/libraries/gaussian-splats/README.md +25 -0
- package/libraries/gaussian-splats/src/gpu-sort.ts +595 -0
- package/libraries/gaussian-splats/src/index.ts +31 -0
- package/libraries/gaussian-splats/src/library.ts +60 -0
- package/libraries/gaussian-splats/src/parser.ts +382 -0
- package/libraries/gaussian-splats/src/renderer.ts +427 -0
- package/libraries/gaussian-splats/src/sh-eval.ts +211 -0
- package/libraries/gaussian-splats/src/sorter.ts +110 -0
- package/libraries/gaussian-splats/src/tile-raster.ts +473 -0
- package/libraries/gpu-kernels/README.md +154 -0
- package/libraries/gpu-kernels/src/index.ts +11 -0
- package/libraries/gpu-kernels/src/kernel.ts +696 -0
- package/libraries/gpu-kernels/src/transpile.ts +958 -0
- package/libraries/html-ui-kit/src/behaviors.ts +250 -0
- package/libraries/html-ui-kit/src/components.ts +309 -0
- package/libraries/html-ui-kit/src/index.ts +30 -0
- package/libraries/html-ui-kit/src/nav/nav-controller.ts +238 -0
- package/libraries/html-ui-kit/src/nav/nav-input.ts +145 -0
- package/libraries/html-ui-kit/src/nav/osk.ts +153 -0
- package/libraries/html-ui-kit/src/nav/router.ts +167 -0
- package/libraries/html-ui-kit/src/nav/vcursor.ts +203 -0
- package/libraries/html-ui-kit/src/ten-foot.ts +182 -0
- package/libraries/html-ui-kit/src/theme.ts +238 -0
- package/libraries/lighting/README.md +20 -0
- package/libraries/lighting/src/index.ts +5 -0
- package/libraries/lighting/src/library.ts +66 -0
- package/libraries/lighting/src/light-system.ts +452 -0
- package/libraries/lighting/src/lighting-system.ts +68 -0
- package/libraries/lighting/src/shaders/light-debug.wgsl +30 -0
- package/libraries/marching-cubes/README.md +25 -0
- package/libraries/marching-cubes/src/chunked-field.ts +177 -0
- package/libraries/marching-cubes/src/deformation.ts +63 -0
- package/libraries/marching-cubes/src/generator.ts +407 -0
- package/libraries/marching-cubes/src/index.ts +32 -0
- package/libraries/marching-cubes/src/library.ts +80 -0
- package/libraries/marching-cubes/src/lod.ts +122 -0
- package/libraries/marching-cubes/src/marching-tetrahedra.ts +252 -0
- package/libraries/marching-cubes/src/sab.ts +45 -0
- package/libraries/marching-cubes/src/streaming-config.ts +48 -0
- package/libraries/marching-cubes/src/streaming-manager.ts +686 -0
- package/libraries/marching-cubes/src/tables.ts +323 -0
- package/libraries/marching-cubes/src/types.ts +18 -0
- package/libraries/models/README.md +25 -0
- package/libraries/models/src/bake-node-transforms.ts +171 -0
- package/libraries/models/src/codecs/basisu-codec.ts +180 -0
- package/libraries/models/src/codecs/draco-codec.ts +372 -0
- package/libraries/models/src/codecs/draco3dgltf.d.ts +40 -0
- package/libraries/models/src/codecs/index.ts +22 -0
- package/libraries/models/src/codecs/meshopt-codec.ts +91 -0
- package/libraries/models/src/codecs/registry.ts +221 -0
- package/libraries/models/src/dae.ts +753 -0
- package/libraries/models/src/default-part-selection.ts +56 -0
- package/libraries/models/src/dxf.ts +200 -0
- package/libraries/models/src/fbx/index.ts +457 -0
- package/libraries/models/src/fbx/interpreter/animation.ts +431 -0
- package/libraries/models/src/fbx/interpreter/blend-shapes.ts +323 -0
- package/libraries/models/src/fbx/interpreter/connections.ts +166 -0
- package/libraries/models/src/fbx/interpreter/diagnostics.ts +65 -0
- package/libraries/models/src/fbx/interpreter/geometry.ts +535 -0
- package/libraries/models/src/fbx/interpreter/global-settings.ts +92 -0
- package/libraries/models/src/fbx/interpreter/materials.ts +265 -0
- package/libraries/models/src/fbx/interpreter/nodes.ts +197 -0
- package/libraries/models/src/fbx/interpreter/skeleton.ts +476 -0
- package/libraries/models/src/fbx/parsers/binary-parser.ts +244 -0
- package/libraries/models/src/fbx/types.ts +119 -0
- package/libraries/models/src/gltf-extensions.ts +196 -0
- package/libraries/models/src/gltf.ts +935 -0
- package/libraries/models/src/index.ts +87 -0
- package/libraries/models/src/library.ts +75 -0
- package/libraries/models/src/loader.ts +265 -0
- package/libraries/models/src/material-adapter.ts +108 -0
- package/libraries/models/src/mini-xml.ts +174 -0
- package/libraries/models/src/normalize.ts +216 -0
- package/libraries/models/src/obj.ts +264 -0
- package/libraries/models/src/off.ts +95 -0
- package/libraries/models/src/ply.ts +348 -0
- package/libraries/models/src/pose-sampler.ts +219 -0
- package/libraries/models/src/sidecar/blender-extras.ts +37 -0
- package/libraries/models/src/sidecar/ddmeta.ts +114 -0
- package/libraries/models/src/sidecar/godot-import.ts +86 -0
- package/libraries/models/src/sidecar/resolver.ts +145 -0
- package/libraries/models/src/sidecar/types.ts +11 -0
- package/libraries/models/src/sidecar/unity-meta.ts +61 -0
- package/libraries/models/src/skeleton-synthesis.ts +132 -0
- package/libraries/models/src/stl.ts +149 -0
- package/libraries/models/src/threeds.ts +363 -0
- package/libraries/models/src/threemf.ts +201 -0
- package/libraries/models/src/types.ts +188 -0
- package/libraries/models/src/vtk.ts +218 -0
- package/libraries/models/test-fixtures/fbx/LICENSE-notice.txt +24 -0
- package/libraries/models/test-fixtures/fbx/README.md +46 -0
- package/libraries/models/test-fixtures/fbx/m01_cube_phong.fbx +0 -0
- package/libraries/models/test-fixtures/fbx/m02_geo_ngons.fbx +0 -0
- package/libraries/models/test-fixtures/fbx/m03_normals.fbx +0 -0
- package/libraries/models/test-fixtures/fbx/m04_material_properties.fbx +0 -0
- package/libraries/models/test-fixtures/fbx/m05_external_diffuse.png +0 -0
- package/libraries/models/test-fixtures/fbx/m05_textures.fbx +0 -0
- package/libraries/models/test-fixtures/fbx/m06_uv_transform.fbx +0 -0
- package/libraries/models/test-fixtures/fbx/m07_multimaterial.fbx +0 -0
- package/libraries/models/test-fixtures/fbx/m08_transforms.fbx +0 -0
- package/libraries/models/test-fixtures/fbx/m09_skinning.fbx +0 -0
- package/libraries/models/test-fixtures/fbx/m10_morph.fbx +0 -0
- package/libraries/models/test-fixtures/fbx/m11_node_anim.fbx +0 -0
- package/libraries/models/test-fixtures/fbx/m12_skeletal_anim.fbx +0 -0
- package/libraries/models/test-fixtures/fbx/m13_morph_anim.fbx +0 -0
- package/libraries/models/test-fixtures/fbx/m14_multiclip.fbx +0 -0
- package/libraries/models/test-fixtures/fbx/m15_camera_lights.fbx +0 -0
- package/libraries/models/test-fixtures/fbx/m16_axis_yup.fbx +0 -0
- package/libraries/models/test-fixtures/fbx/m16_axis_zup.fbx +0 -0
- package/libraries/models/test-fixtures/fbx/m16_units_254.fbx +0 -0
- package/libraries/navmesh/README.md +23 -0
- package/libraries/navmesh/src/crowd-system.ts +240 -0
- package/libraries/navmesh/src/debug-viz.ts +74 -0
- package/libraries/navmesh/src/index.ts +15 -0
- package/libraries/navmesh/src/library.ts +64 -0
- package/libraries/navmesh/src/navmesh-generator.ts +407 -0
- package/libraries/navmesh/src/navmesh.ts +159 -0
- package/libraries/navmesh/src/pathfinder.ts +252 -0
- package/libraries/navmesh/src/types.ts +63 -0
- package/libraries/networking/README.md +25 -0
- package/libraries/networking/src/authority.ts +121 -0
- package/libraries/networking/src/connection.ts +139 -0
- package/libraries/networking/src/discovery.ts +373 -0
- package/libraries/networking/src/enhanced-replication.ts +355 -0
- package/libraries/networking/src/epic-adapter.ts +129 -0
- package/libraries/networking/src/index.ts +45 -0
- package/libraries/networking/src/library.ts +69 -0
- package/libraries/networking/src/lobby.ts +108 -0
- package/libraries/networking/src/platform-adapter.ts +163 -0
- package/libraries/networking/src/rcs-adapter.ts +127 -0
- package/libraries/networking/src/remote-input.ts +188 -0
- package/libraries/networking/src/replication.ts +327 -0
- package/libraries/networking/src/rpc.ts +188 -0
- package/libraries/networking/src/session.ts +173 -0
- package/libraries/networking/src/transport.ts +201 -0
- package/libraries/networking/src/webrtc.ts +323 -0
- package/libraries/pathfinding-2d/README.md +15 -0
- package/libraries/pathfinding-2d/src/astar-grid.ts +312 -0
- package/libraries/pathfinding-2d/src/index.ts +11 -0
- package/libraries/persistence/README.md +25 -0
- package/libraries/persistence/src/autosave-manager.ts +112 -0
- package/libraries/persistence/src/binary-record-store.ts +244 -0
- package/libraries/persistence/src/browser.ts +51 -0
- package/libraries/persistence/src/file-save-store.ts +553 -0
- package/libraries/persistence/src/hash-utils.ts +59 -0
- package/libraries/persistence/src/index.ts +57 -0
- package/libraries/persistence/src/library.ts +74 -0
- package/libraries/persistence/src/mock-opfs.ts +141 -0
- package/libraries/persistence/src/node-fs-directory-handle.ts +161 -0
- package/libraries/persistence/src/opfs-save-store.ts +745 -0
- package/libraries/persistence/src/save-worker-proxy.ts +127 -0
- package/libraries/persistence/src/save-worker.ts +99 -0
- package/libraries/persistence/src/xxh3-ts.d.ts +10 -0
- package/libraries/physics-native/README.md +21 -0
- package/libraries/physics-native/native/Cargo.toml +11 -0
- package/libraries/physics-native/native/src/body.rs +403 -0
- package/libraries/physics-native/native/src/character.rs +226 -0
- package/libraries/physics-native/native/src/collider.rs +299 -0
- package/libraries/physics-native/native/src/joint.rs +81 -0
- package/libraries/physics-native/native/src/lib.rs +830 -0
- package/libraries/physics-native/native/src/query.rs +261 -0
- package/libraries/physics-native/native/src/realm.rs +33 -0
- package/libraries/physics-native/native/src/step.rs +54 -0
- package/libraries/physics-native/native/src/world.rs +148 -0
- package/libraries/physics-native/src/backend.ts +1046 -0
- package/libraries/physics-native/src/broadphase.ts +101 -0
- package/libraries/physics-native/src/ffi-spike-worker.ts +71 -0
- package/libraries/physics-native/src/index.ts +11 -0
- package/libraries/physics-native/src/library.ts +79 -0
- package/libraries/physics-native/src/narrowphase-shapes.ts +420 -0
- package/libraries/physics-native/src/narrowphase.ts +123 -0
- package/libraries/physics-native/src/solver.ts +141 -0
- package/libraries/physics-native/src/types.ts +76 -0
- package/libraries/physics-rapier/README.md +21 -0
- package/libraries/physics-rapier/bench/ffi-bench.ts +79 -0
- package/libraries/physics-rapier/bench/wasm-baseline.ts +90 -0
- package/libraries/physics-rapier/src/api.ts +452 -0
- package/libraries/physics-rapier/src/auto-backend.ts +59 -0
- package/libraries/physics-rapier/src/backend.ts +1207 -0
- package/libraries/physics-rapier/src/bulk-ops.ts +68 -0
- package/libraries/physics-rapier/src/ffi-backend.ts +21 -0
- package/libraries/physics-rapier/src/ffi-lib.ts +597 -0
- package/libraries/physics-rapier/src/index.ts +12 -0
- package/libraries/physics-rapier/src/library.ts +107 -0
- package/libraries/physics-rapier/src/rapier-backend.ts +1052 -0
- package/libraries/physics-rapier/src/realm-worker-script.ts +237 -0
- package/libraries/postfx/README.md +17 -0
- package/libraries/postfx/src/index.ts +19 -0
- package/libraries/postfx/src/library.ts +337 -0
- package/libraries/postfx/src/post-process-stack.ts +1752 -0
- package/libraries/postfx/src/shaders/post-process/afterimage.wgsl +14 -0
- package/libraries/postfx/src/shaders/post-process/ascii.wgsl +24 -0
- package/libraries/postfx/src/shaders/post-process/blit.wgsl +12 -0
- package/libraries/postfx/src/shaders/post-process/bloom-blur.wgsl +21 -0
- package/libraries/postfx/src/shaders/post-process/bloom-bright.wgsl +15 -0
- package/libraries/postfx/src/shaders/post-process/bloom-composite.wgsl +14 -0
- package/libraries/postfx/src/shaders/post-process/bloom-downsample.wgsl +60 -0
- package/libraries/postfx/src/shaders/post-process/bloom-soft.wgsl +46 -0
- package/libraries/postfx/src/shaders/post-process/bloom-upsample.wgsl +51 -0
- package/libraries/postfx/src/shaders/post-process/channel-mixer.wgsl +36 -0
- package/libraries/postfx/src/shaders/post-process/chromatic-aberration.wgsl +37 -0
- package/libraries/postfx/src/shaders/post-process/dithering.wgsl +64 -0
- package/libraries/postfx/src/shaders/post-process/dof.wgsl +131 -0
- package/libraries/postfx/src/shaders/post-process/edges.wgsl +45 -0
- package/libraries/postfx/src/shaders/post-process/fullscreen-vs.wgsl +15 -0
- package/libraries/postfx/src/shaders/post-process/fxaa.wgsl +102 -0
- package/libraries/postfx/src/shaders/post-process/gaussian-blur.wgsl +37 -0
- package/libraries/postfx/src/shaders/post-process/glow-blur.wgsl +33 -0
- package/libraries/postfx/src/shaders/post-process/glow-composite.wgsl +25 -0
- package/libraries/postfx/src/shaders/post-process/grain.wgsl +37 -0
- package/libraries/postfx/src/shaders/post-process/halftone.wgsl +80 -0
- package/libraries/postfx/src/shaders/post-process/highlight-blur.wgsl +33 -0
- package/libraries/postfx/src/shaders/post-process/highlight-composite.wgsl +32 -0
- package/libraries/postfx/src/shaders/post-process/lens-distortion.wgsl +43 -0
- package/libraries/postfx/src/shaders/post-process/lens-flare.wgsl +68 -0
- package/libraries/postfx/src/shaders/post-process/lut.wgsl +30 -0
- package/libraries/postfx/src/shaders/post-process/motion-blur.wgsl +55 -0
- package/libraries/postfx/src/shaders/post-process/occluder-chunk.wgsl +28 -0
- package/libraries/postfx/src/shaders/post-process/outline.wgsl +51 -0
- package/libraries/postfx/src/shaders/post-process/pixelation.wgsl +47 -0
- package/libraries/postfx/src/shaders/post-process/sharpen.wgsl +32 -0
- package/libraries/postfx/src/shaders/post-process/sobel.wgsl +26 -0
- package/libraries/postfx/src/shaders/post-process/split-tone.wgsl +36 -0
- package/libraries/postfx/src/shaders/post-process/ssao-blur.wgsl +38 -0
- package/libraries/postfx/src/shaders/post-process/ssao-composite.wgsl +25 -0
- package/libraries/postfx/src/shaders/post-process/ssao.wgsl +147 -0
- package/libraries/postfx/src/shaders/post-process/ssr.wgsl +155 -0
- package/libraries/postfx/src/shaders/post-process/taa.wgsl +98 -0
- package/libraries/postfx/src/shaders/post-process/tonemap.wgsl +40 -0
- package/libraries/postfx/src/shaders/post-process/watercolor.wgsl +82 -0
- package/libraries/postfx/src/shaders/post-process/white-balance.wgsl +41 -0
- package/libraries/recast/README.md +21 -0
- package/libraries/recast/src/backend.ts +150 -0
- package/libraries/recast/src/crowd-system.ts +352 -0
- package/libraries/recast/src/index.ts +12 -0
- package/libraries/recast/src/library.ts +91 -0
- package/libraries/recast/src/types.ts +86 -0
- package/libraries/sand/README.md +25 -0
- package/libraries/sand/src/cell.ts +43 -0
- package/libraries/sand/src/fields.ts +29 -0
- package/libraries/sand/src/fluid-grid.ts +261 -0
- package/libraries/sand/src/grid-dims.ts +74 -0
- package/libraries/sand/src/grid-sim-buffer.ts +271 -0
- package/libraries/sand/src/index.ts +81 -0
- package/libraries/sand/src/library.ts +92 -0
- package/libraries/sand/src/materials.ts +492 -0
- package/libraries/sand/src/palette.ts +93 -0
- package/libraries/sand/src/particles.ts +185 -0
- package/libraries/sand/src/render/sand-grid-pass.ts +430 -0
- package/libraries/sand/src/rng.ts +51 -0
- package/libraries/sand/src/rules/builtin-rules.ts +132 -0
- package/libraries/sand/src/rules/rule-compiler.ts +162 -0
- package/libraries/sand/src/rules/rule-engine.ts +231 -0
- package/libraries/sand/src/rules/rule-types.ts +87 -0
- package/libraries/sand/src/sand-step-pool.ts +484 -0
- package/libraries/sand/src/sand-step-worker.ts +97 -0
- package/libraries/sand/src/sand-world.ts +3227 -0
- package/libraries/stickman/README.md +25 -0
- package/libraries/stickman/src/index.ts +25 -0
- package/libraries/stickman/src/library.ts +61 -0
- package/libraries/stickman/src/proportions.ts +45 -0
- package/libraries/stickman/src/shader.ts +117 -0
- package/libraries/stickman/src/skeleton.ts +197 -0
- package/libraries/stickman/src/stickman-pass.ts +255 -0
- package/libraries/stickman/src/thick-line.ts +123 -0
- package/libraries/surface-nets/README.md +25 -0
- package/libraries/surface-nets/src/chunked-field.ts +14 -0
- package/libraries/surface-nets/src/deformation.ts +45 -0
- package/libraries/surface-nets/src/index.ts +36 -0
- package/libraries/surface-nets/src/library.ts +59 -0
- package/libraries/surface-nets/src/lod.ts +7 -0
- package/libraries/surface-nets/src/sab.ts +4 -0
- package/libraries/surface-nets/src/streaming-config.ts +5 -0
- package/libraries/surface-nets/src/streaming-manager.ts +15 -0
- package/libraries/surface-nets/src/surface-nets.ts +334 -0
- package/libraries/surface-nets/src/types.ts +23 -0
- package/libraries/water/README.md +25 -0
- package/libraries/water/src/buoyancy.ts +103 -0
- package/libraries/water/src/index.ts +43 -0
- package/libraries/water/src/library.ts +85 -0
- package/libraries/water/src/shore-damping.ts +93 -0
- package/libraries/water/src/water-buffer.ts +89 -0
- package/libraries/water/src/water-chunks.ts +13 -0
- package/libraries/water/src/water-physics.ts +376 -0
- package/libraries/water/src/water-renderer.ts +809 -0
- package/libraries/water/src/water-sab.ts +161 -0
- package/libraries/water/src/wave-sources.ts +84 -0
- package/libraries/weather/README.md +20 -0
- package/libraries/weather/src/index.ts +9 -0
- package/libraries/weather/src/library.ts +72 -0
- package/libraries/weather/src/types.ts +64 -0
- package/libraries/weather/src/weather-blend.ts +112 -0
- package/libraries/weather/src/weather-system.ts +271 -0
- package/libraries/weatherfx/README.md +24 -0
- package/libraries/weatherfx/src/cloud-provider.ts +31 -0
- package/libraries/weatherfx/src/cloud-system.ts +372 -0
- package/libraries/weatherfx/src/index.ts +9 -0
- package/libraries/weatherfx/src/library.ts +58 -0
- package/libraries/weatherfx/src/particle-system.ts +434 -0
- package/libraries/weatherfx/src/shaders/cloud.wgsl +111 -0
- package/libraries/weatherfx/src/shaders/particle-compute.wgsl +187 -0
- package/libraries/weatherfx/src/shaders/particle-render.wgsl +95 -0
- package/lint-plugin.mjs +41 -0
- package/mcp/src/client.ts +703 -0
- package/mcp/src/engine-context.ts +186 -0
- package/mcp/src/http-transport.ts +471 -0
- package/mcp/src/index.ts +13 -0
- package/mcp/src/prompts/add-entity.ts +42 -0
- package/mcp/src/prompts/create-scene.ts +44 -0
- package/mcp/src/prompts/debug-frame.ts +39 -0
- package/mcp/src/prompts/index.ts +12 -0
- package/mcp/src/resources/asset-list.ts +32 -0
- package/mcp/src/resources/checkpoint-list.ts +33 -0
- package/mcp/src/resources/entity-state.ts +55 -0
- package/mcp/src/resources/gpu-info.ts +103 -0
- package/mcp/src/resources/index.ts +57 -0
- package/mcp/src/resources/performance.ts +37 -0
- package/mcp/src/resources/scene-tree.ts +43 -0
- package/mcp/src/server.ts +375 -0
- package/mcp/src/tools/animation.ts +118 -0
- package/mcp/src/tools/asset.ts +161 -0
- package/mcp/src/tools/audio.ts +96 -0
- package/mcp/src/tools/build.ts +143 -0
- package/mcp/src/tools/camera.ts +167 -0
- package/mcp/src/tools/checkpoint.ts +100 -0
- package/mcp/src/tools/component.ts +199 -0
- package/mcp/src/tools/debug.ts +300 -0
- package/mcp/src/tools/entity.ts +361 -0
- package/mcp/src/tools/inspect.ts +210 -0
- package/mcp/src/tools/lighting.ts +263 -0
- package/mcp/src/tools/material.ts +243 -0
- package/mcp/src/tools/mesh.ts +239 -0
- package/mcp/src/tools/physics.ts +266 -0
- package/mcp/src/tools/scene.ts +153 -0
- package/mcp/src/tools/script.ts +122 -0
- package/mcp/src/types.ts +92 -0
- package/mcp/src/undo-redo.ts +77 -0
- package/modules/camera-controls/README.md +20 -0
- package/modules/camera-controls/src/index.ts +161 -0
- package/modules/controller-ui/src/index.ts +164 -0
- package/modules/devtools/README.md +25 -0
- package/modules/devtools/src/api.ts +461 -0
- package/modules/devtools/src/asset-utils.ts +105 -0
- package/modules/devtools/src/bind-debug-store.ts +48 -0
- package/modules/devtools/src/data-bridge.ts +286 -0
- package/modules/devtools/src/debug-overlay.ts +238 -0
- package/modules/devtools/src/debug-raycast.ts +328 -0
- package/modules/devtools/src/debug-store.ts +92 -0
- package/modules/devtools/src/debug-view-descriptors.ts +59 -0
- package/modules/devtools/src/doctor-panel.ts +182 -0
- package/modules/devtools/src/gizmo-module.ts +136 -0
- package/modules/devtools/src/graph-model.ts +509 -0
- package/modules/devtools/src/grid-renderer.ts +157 -0
- package/modules/devtools/src/height-ruler-renderer.ts +216 -0
- package/modules/devtools/src/index.ts +81 -0
- package/modules/devtools/src/init.ts +261 -0
- package/modules/devtools/src/label-overlay.ts +154 -0
- package/modules/devtools/src/material-stats-panel.ts +188 -0
- package/modules/devtools/src/profiling-bridge.ts +377 -0
- package/modules/devtools/src/profiling-hooks.ts +98 -0
- package/modules/devtools/src/renderer-adapter.ts +76 -0
- package/modules/devtools/src/scene-inspector.ts +637 -0
- package/modules/devtools/src/scene-store.ts +320 -0
- package/modules/devtools/src/scene-sync.ts +116 -0
- package/modules/devtools/src/shaders/transform-gizmo.wgsl +38 -0
- package/modules/devtools/src/sim-stats-panel.ts +272 -0
- package/modules/devtools/src/sim-stats-provider.ts +105 -0
- package/modules/devtools/src/skeleton-renderer.ts +351 -0
- package/modules/devtools/src/transform-gizmo.ts +928 -0
- package/modules/devtools/src/types.ts +290 -0
- package/modules/devtools/src/worker-expose.ts +67 -0
- package/modules/devtools/src/worker-sync.ts +137 -0
- package/modules/editor/src/commands/component.ts +156 -0
- package/modules/editor/src/commands/entity.ts +287 -0
- package/modules/editor/src/commands/hierarchy.ts +83 -0
- package/modules/editor/src/commands/index.ts +61 -0
- package/modules/editor/src/commands/prefab.ts +163 -0
- package/modules/editor/src/commands/registry.ts +331 -0
- package/modules/editor/src/commands/scene-io.ts +211 -0
- package/modules/editor/src/commands/selection.ts +73 -0
- package/modules/editor/src/commands/transform.ts +91 -0
- package/modules/editor/src/ddscene.ts +267 -0
- package/modules/editor/src/document.ts +123 -0
- package/modules/editor/src/editor-context.ts +172 -0
- package/modules/editor/src/index.ts +41 -0
- package/modules/editor/src/mcp.ts +103 -0
- package/modules/editor/src/module.ts +148 -0
- package/modules/editor/src/selection.ts +70 -0
- package/modules/editor/src/shell.ts +456 -0
- package/modules/editor/src/viewport.ts +199 -0
- package/modules/html-ui/src/composite.ts +135 -0
- package/modules/html-ui/src/create-html-ui.ts +188 -0
- package/modules/html-ui/src/doc-backend.ts +343 -0
- package/modules/html-ui/src/host.ts +646 -0
- package/modules/html-ui/src/index.ts +13 -0
- package/modules/html-ui/src/jsx-dev-runtime.ts +12 -0
- package/modules/html-ui/src/jsx-runtime.ts +126 -0
- package/modules/html-ui/src/protocol.ts +88 -0
- package/modules/html-ui/src/ui-worker.ts +16 -0
- package/modules/mcp/README.md +18 -0
- package/modules/mcp/src/index.ts +27 -0
- package/modules/movement-2d/README.md +19 -0
- package/modules/movement-2d/src/grid-character.ts +455 -0
- package/modules/movement-2d/src/index.ts +45 -0
- package/modules/movement-3d/README.md +21 -0
- package/modules/movement-3d/src/character-motor.ts +230 -0
- package/modules/movement-3d/src/index.ts +46 -0
- package/modules/native-osr/src/index.ts +22 -0
- package/modules/native-osr/src/input-router.ts +401 -0
- package/modules/native-osr/src/native-osr-manager.ts +247 -0
- package/modules/native-osr/src/native-texture-source.ts +86 -0
- package/modules/native-osr/src/types.ts +112 -0
- package/modules/native-osr/src/world-space-ui-pass.ts +351 -0
- package/modules/sailing/README.md +18 -0
- package/modules/sailing/src/index.ts +51 -0
- package/modules/terrain/README.md +18 -0
- package/modules/terrain/src/index.ts +78 -0
- package/modules/vitals/README.md +17 -0
- package/modules/vitals/src/index.ts +43 -0
- package/modules/vitals/src/vitals.ts +265 -0
- package/modules/xr/README.md +25 -0
- package/modules/xr/src/camera-rig.ts +146 -0
- package/modules/xr/src/debug.ts +59 -0
- package/modules/xr/src/frame-loop.ts +197 -0
- package/modules/xr/src/index.ts +16 -0
- package/modules/xr/src/input.ts +208 -0
- package/modules/xr/src/layer.ts +140 -0
- package/modules/xr/src/session.ts +156 -0
- package/modules/xr/src/sim-module.ts +23 -0
- package/modules/xr/src/types.ts +32 -0
- package/modules/xr/src/webxr.d.ts +182 -0
- package/modules/xr/src/xr-module.ts +179 -0
- package/package.json +232 -3
- package/shader-graph/src/chunks.ts +349 -0
- package/shader-graph/src/compiler.ts +732 -0
- package/shader-graph/src/compute-compiler.ts +453 -0
- package/shader-graph/src/compute-graph.ts +112 -0
- package/shader-graph/src/compute-profiles.ts +54 -0
- package/shader-graph/src/graph.ts +52 -0
- package/shader-graph/src/index.ts +53 -0
- package/shader-graph/src/profiles.ts +407 -0
- package/shader-graph/src/validator.ts +48 -0
- package/shader-graph/src/wgsl-binding-validator.ts +143 -0
- package/shader-graph/src/wgsl-struct-validator.ts +245 -0
- package/shader-graph/src/wgsl-struct.ts +397 -0
- package/test/src/index.ts +7 -0
- package/test/src/vision-test.ts +369 -0
|
@@ -0,0 +1,550 @@
|
|
|
1
|
+
// ============================================================================
|
|
2
|
+
// buffer-sync — copy-based buffer synchronization for the SAB polyfill
|
|
3
|
+
// ============================================================================
|
|
4
|
+
//
|
|
5
|
+
// When SharedArrayBuffer is polyfilled, each thread has its
|
|
6
|
+
// own ArrayBuffer instance. This module synchronizes them via postMessage at
|
|
7
|
+
// tick/frame boundaries:
|
|
8
|
+
//
|
|
9
|
+
// Main → Worker (input): driven by requestAnimationFrame, copies only the
|
|
10
|
+
// input region(s) the main thread writes, transfers the ArrayBuffer.
|
|
11
|
+
// Worker → Main (sim): event-driven (after each tick batch), copies only
|
|
12
|
+
// the regions the worker writes, transfers the ArrayBuffer.
|
|
13
|
+
//
|
|
14
|
+
// Optimizations:
|
|
15
|
+
// - Region-aware: only the declared write regions are copied, not the full
|
|
16
|
+
// buffer. For sandjongg's embedded input (64 bytes), main→worker copies
|
|
17
|
+
// 64 bytes, not the full 1.3MB.
|
|
18
|
+
// - Sequence-number gating: if a buffer has a sequence field, the sync is
|
|
19
|
+
// skipped when the sequence hasn't changed since the last sync. Eliminates
|
|
20
|
+
// all copy overhead when the sim is paused.
|
|
21
|
+
// - Transferable ArrayBuffers: postMessage with a transfer list avoids the
|
|
22
|
+
// structured-clone copy (transfer is zero-copy). Net: 1 copy (slice)
|
|
23
|
+
// instead of 2 (slice + structured clone).
|
|
24
|
+
//
|
|
25
|
+
// Single-writer constraint:
|
|
26
|
+
// Each buffer region must have exactly one writer. If both sides write to
|
|
27
|
+
// the same region, the sync will overwrite one side's writes with stale data
|
|
28
|
+
// from the other. The region declarations (writeRegions/readRegions) enforce
|
|
29
|
+
// this — the sync manager only copies declared write regions.
|
|
30
|
+
//
|
|
31
|
+
|
|
32
|
+
import { createLogger } from "../util/logger";
|
|
33
|
+
|
|
34
|
+
const log = createLogger();
|
|
35
|
+
|
|
36
|
+
/** A region within a buffer (offset + length in bytes). */
|
|
37
|
+
export interface BufferRegion {
|
|
38
|
+
offset: number;
|
|
39
|
+
length: number;
|
|
40
|
+
name: string;
|
|
41
|
+
/**
|
|
42
|
+
* If true, the sender zeros this region in the local buffer after copying
|
|
43
|
+
* it outbound. Used for input regions: the main thread writes input (e.g.
|
|
44
|
+
* ACTION=1), rAF copies + sends it, then clears the local copy so it
|
|
45
|
+
* doesn't re-send stale input on the next frame. The worker processes
|
|
46
|
+
* the received input and ignores subsequent zeros (ACTION=0 = no action).
|
|
47
|
+
*
|
|
48
|
+
* This eliminates the race where the worker sends the cleared input back
|
|
49
|
+
* to the main thread, overwriting a new click written between the worker's
|
|
50
|
+
* sync message and the next rAF.
|
|
51
|
+
*/
|
|
52
|
+
clearAfterSend?: boolean;
|
|
53
|
+
/**
|
|
54
|
+
* If true, the region is only sent when it contains non-zero data. Used
|
|
55
|
+
* with clearAfterSend on input regions: after the input is sent and
|
|
56
|
+
* cleared, subsequent rAF frames see all-zeros and skip sending — so
|
|
57
|
+
* they don't overwrite the worker's pending input with zeros before
|
|
58
|
+
* the worker's tick loop processes it.
|
|
59
|
+
*/
|
|
60
|
+
skipIfAllZero?: boolean;
|
|
61
|
+
/**
|
|
62
|
+
* Throttle: only sync this region every N rAF frames (host side only).
|
|
63
|
+
* Default 1 (every frame). Set to e.g. 3 for large grid data regions
|
|
64
|
+
* to reduce copy overhead on mobile. The worker side ignores this field
|
|
65
|
+
* (worker sync is event-driven, not rAF-based).
|
|
66
|
+
*/
|
|
67
|
+
syncInterval?: number;
|
|
68
|
+
/**
|
|
69
|
+
* Dynamic length: if set, the actual region length is read from a Uint32
|
|
70
|
+
* field at this byte offset in the buffer, multiplied by `lengthMultiplier`.
|
|
71
|
+
* This enables syncing only the active portion of a fixed-size buffer
|
|
72
|
+
* (e.g. instance data where only the first N entries are used). The
|
|
73
|
+
* `length` field is treated as the maximum possible length.
|
|
74
|
+
*/
|
|
75
|
+
lengthFieldOffset?: number;
|
|
76
|
+
lengthMultiplier?: number;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/** Declares which regions of a buffer each side writes. */
|
|
80
|
+
export interface BufferSyncRegions {
|
|
81
|
+
/** Regions this side writes — only these are copied outbound. */
|
|
82
|
+
writeRegions: BufferRegion[];
|
|
83
|
+
/** Regions the other side writes — only these are copied inbound. */
|
|
84
|
+
readRegions: BufferRegion[];
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/** Location of a sequence-number field for change gating. */
|
|
88
|
+
export interface SeqField {
|
|
89
|
+
/** Byte offset of the i32 sequence field within the buffer. */
|
|
90
|
+
offset: number;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/** Configuration for the buffer sync protocol. */
|
|
94
|
+
export interface BufferSyncConfig {
|
|
95
|
+
/** Map of buffer name → ArrayBuffer (FakeSAB) instance on this side. */
|
|
96
|
+
buffers: Record<string, ArrayBufferLike>;
|
|
97
|
+
/** Region declarations per buffer (which regions each side writes). */
|
|
98
|
+
regions: Record<string, BufferSyncRegions>;
|
|
99
|
+
/** Sequence-number field locations per buffer (for change gating). Optional. */
|
|
100
|
+
seqFields?: Record<string, SeqField>;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/** A single region copy in a sync message. */
|
|
104
|
+
interface RegionCopy {
|
|
105
|
+
offset: number;
|
|
106
|
+
data: ArrayBuffer;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/** Internal sync message format (posted via postMessage). */
|
|
110
|
+
export interface BufferSyncMessage {
|
|
111
|
+
__bufferSync: true;
|
|
112
|
+
/** Map of buffer name → list of region copies. */
|
|
113
|
+
regions: Record<string, RegionCopy[]>;
|
|
114
|
+
/**
|
|
115
|
+
* Multi-message transfer metadata. Large transfers are split into one
|
|
116
|
+
* region-copy per message with a 16ms gap so the main thread can render
|
|
117
|
+
* between chunks; the receiver buffers the parts and applies them
|
|
118
|
+
* ATOMICALLY once all arrive — otherwise the buffer visibly tears for
|
|
119
|
+
* `total × 16ms` while partially-updated regions are rendered.
|
|
120
|
+
*/
|
|
121
|
+
batch?: { id: number; index: number; total: number };
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/** Check if a message is a buffer-sync message. */
|
|
125
|
+
export function isBufferSyncMessage(msg: unknown): msg is BufferSyncMessage {
|
|
126
|
+
return typeof msg === "object" && msg !== null && "__bufferSync" in msg;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// ---------------------------------------------------------------------------
|
|
130
|
+
// Main-thread side
|
|
131
|
+
// ---------------------------------------------------------------------------
|
|
132
|
+
|
|
133
|
+
// ---------------------------------------------------------------------------
|
|
134
|
+
// Profiling support (lightweight, no deps)
|
|
135
|
+
// ---------------------------------------------------------------------------
|
|
136
|
+
|
|
137
|
+
/** Sync profiling is opt-in: `__DOWNDRAFT_PROFILE_SYNC__` global or
|
|
138
|
+
* `DOWNDRAFT_PROFILE_SYNC=1` env. When off, no samples are recorded and no
|
|
139
|
+
* console output is produced (previously it logged every 5s in production). */
|
|
140
|
+
function syncProfilingEnabled(): boolean {
|
|
141
|
+
const g = globalThis as Record<string, unknown>;
|
|
142
|
+
if (g.__DOWNDRAFT_PROFILE_SYNC__ === true) return true;
|
|
143
|
+
try {
|
|
144
|
+
return (g.process as { env?: Record<string, string> } | undefined)?.env
|
|
145
|
+
?.DOWNDRAFT_PROFILE_SYNC === "1";
|
|
146
|
+
} catch {
|
|
147
|
+
return false;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/** Accumulates timing samples and logs a summary every N calls. */
|
|
152
|
+
class SyncProfiler {
|
|
153
|
+
private samples: Array<{ label: string; ms: number; bytes: number }> = [];
|
|
154
|
+
private logTimer = 0;
|
|
155
|
+
private logInterval: number;
|
|
156
|
+
private enabled = syncProfilingEnabled();
|
|
157
|
+
|
|
158
|
+
constructor(logIntervalMs = 5000) {
|
|
159
|
+
this.logInterval = logIntervalMs;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/** Record a timed operation. Call begin() before, end() after. */
|
|
163
|
+
begin(): number { return this.enabled ? performance.now() : 0; }
|
|
164
|
+
end(label: string, start: number, bytes: number): void {
|
|
165
|
+
if (!this.enabled) return;
|
|
166
|
+
const ms = performance.now() - start;
|
|
167
|
+
this.samples.push({ label, ms, bytes });
|
|
168
|
+
const now = performance.now();
|
|
169
|
+
if (now - this.logTimer >= this.logInterval) {
|
|
170
|
+
this.logTimer = now;
|
|
171
|
+
this.flush();
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
private flush(): void {
|
|
176
|
+
if (this.samples.length === 0) return;
|
|
177
|
+
const byLabel: Record<string, { count: number; totalMs: number; totalBytes: number; maxMs: number }> = {};
|
|
178
|
+
this.samples.forEach((s) => {
|
|
179
|
+
const e = byLabel[s.label] ?? (byLabel[s.label] = { count: 0, totalMs: 0, totalBytes: 0, maxMs: 0 });
|
|
180
|
+
e.count++;
|
|
181
|
+
e.totalMs += s.ms;
|
|
182
|
+
e.totalBytes += s.bytes;
|
|
183
|
+
if (s.ms > e.maxMs) e.maxMs = s.ms;
|
|
184
|
+
});
|
|
185
|
+
const lines: string[] = [];
|
|
186
|
+
for (const [label, e] of Object.entries(byLabel)) {
|
|
187
|
+
const avgMs = (e.totalMs / e.count).toFixed(2);
|
|
188
|
+
const maxMs = e.maxMs.toFixed(2);
|
|
189
|
+
const totalKB = (e.totalBytes / 1024).toFixed(0);
|
|
190
|
+
const avgKB = (e.totalBytes / e.count / 1024).toFixed(1);
|
|
191
|
+
lines.push(` ${label}: ${e.count}x avg=${avgMs}ms max=${maxMs}ms avgSize=${avgKB}KB total=${totalKB}KB`);
|
|
192
|
+
}
|
|
193
|
+
log.warn("BufferSync", `Profiling: ${this.samples.length} samples over last ${this.logInterval}ms:\n${lines.join("\n")}`);
|
|
194
|
+
this.samples = [];
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* Main-thread buffer sync manager.
|
|
200
|
+
*
|
|
201
|
+
* Sends input regions to the worker on requestAnimationFrame, and receives
|
|
202
|
+
* sim data regions from the worker via onMessage. Uses rAF (not setInterval)
|
|
203
|
+
* to adapt to the display refresh rate and pause when the tab is hidden.
|
|
204
|
+
*/
|
|
205
|
+
export class BufferSyncHost {
|
|
206
|
+
private rafId = 0;
|
|
207
|
+
/** Per-region last-synced sequence: buffer name → region name → seq.
|
|
208
|
+
* Tracked per region (not per buffer) so throttled regions aren't starved
|
|
209
|
+
* when another region's sync consumes the buffer-level seq. */
|
|
210
|
+
private lastRegionSeqs: Record<string, Record<string, number>> = {};
|
|
211
|
+
private frameCount = 0;
|
|
212
|
+
private profiler = new SyncProfiler(5000);
|
|
213
|
+
private messageHandler: ((e: MessageEvent) => void) | null = null;
|
|
214
|
+
|
|
215
|
+
constructor(
|
|
216
|
+
private worker: Worker,
|
|
217
|
+
private config: BufferSyncConfig,
|
|
218
|
+
) {}
|
|
219
|
+
|
|
220
|
+
start(): void {
|
|
221
|
+
if (!this.messageHandler) {
|
|
222
|
+
this.messageHandler = (e: MessageEvent) => this.onMessage(e.data);
|
|
223
|
+
this.worker.addEventListener("message", this.messageHandler);
|
|
224
|
+
}
|
|
225
|
+
cancelAnimationFrame(this.rafId); // guard against double-start
|
|
226
|
+
this.syncInput(); // start rAF loop
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
stop(): void {
|
|
230
|
+
cancelAnimationFrame(this.rafId);
|
|
231
|
+
if (this.messageHandler) {
|
|
232
|
+
this.worker.removeEventListener("message", this.messageHandler);
|
|
233
|
+
this.messageHandler = null;
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
/**
|
|
238
|
+
* Sync input regions to the worker. Called on each rAF frame.
|
|
239
|
+
* Copies only the writeRegions of each buffer, transfers the ArrayBuffers.
|
|
240
|
+
* Regions with syncInterval > 1 are only synced every N frames (throttled).
|
|
241
|
+
*/
|
|
242
|
+
private syncInput = (): void => {
|
|
243
|
+
const transfers: ArrayBuffer[] = [];
|
|
244
|
+
const regions: Record<string, RegionCopy[]> = {};
|
|
245
|
+
this.frameCount++;
|
|
246
|
+
let totalBytes = 0;
|
|
247
|
+
const pStart = this.profiler.begin();
|
|
248
|
+
|
|
249
|
+
for (const [name, buf] of Object.entries(this.config.buffers)) {
|
|
250
|
+
const regionDef = this.config.regions[name];
|
|
251
|
+
if (!regionDef || regionDef.writeRegions.length === 0) continue;
|
|
252
|
+
|
|
253
|
+
// Sequence gating is per-region (see below) — read the current seq once.
|
|
254
|
+
const seqField = this.config.seqFields?.[name];
|
|
255
|
+
const seq = seqField ? new Int32Array(buf, seqField.offset, 1)[0] : 0;
|
|
256
|
+
|
|
257
|
+
const copies: RegionCopy[] = [];
|
|
258
|
+
for (let _i = 0, _it = regionDef.writeRegions, _n = _it.length; _i < _n; _i++) { const r = _it[_i];
|
|
259
|
+
// Throttle: skip regions with syncInterval > 1 on most frames.
|
|
260
|
+
// Only sync them every syncInterval frames.
|
|
261
|
+
if (r.syncInterval && r.syncInterval > 1) {
|
|
262
|
+
if (this.frameCount % r.syncInterval !== 0) continue;
|
|
263
|
+
}
|
|
264
|
+
// Per-region sequence gating: skip this region if its last-synced
|
|
265
|
+
// seq matches the buffer's current seq. Per-region tracking (rather
|
|
266
|
+
// than per-buffer) is required because interval-throttled regions
|
|
267
|
+
// would otherwise never sync — a seq change consumed by a non-
|
|
268
|
+
// throttled region would gate the throttled one out forever.
|
|
269
|
+
if (seqField) {
|
|
270
|
+
const lastSeqs = (this.lastRegionSeqs[name] ??= {});
|
|
271
|
+
if (lastSeqs[r.name] === seq) continue;
|
|
272
|
+
}
|
|
273
|
+
const src = new Uint8Array(buf, r.offset, r.length);
|
|
274
|
+
// skipIfAllZero: don't send zero-filled regions (e.g. input with
|
|
275
|
+
// ACTION=0 after clearAfterSend). This prevents overwriting the
|
|
276
|
+
// worker's pending input with zeros before it processes the input.
|
|
277
|
+
if (r.skipIfAllZero) {
|
|
278
|
+
let allZero = true;
|
|
279
|
+
for (let i = 0; i < src.length; i++) {
|
|
280
|
+
if (src[i] !== 0) { allZero = false; break; }
|
|
281
|
+
}
|
|
282
|
+
if (allZero) continue;
|
|
283
|
+
}
|
|
284
|
+
const copy = new ArrayBuffer(r.length);
|
|
285
|
+
new Uint8Array(copy).set(src);
|
|
286
|
+
copies.push({ offset: r.offset, data: copy });
|
|
287
|
+
transfers.push(copy);
|
|
288
|
+
totalBytes += r.length;
|
|
289
|
+
// Clear-after-send: zero the local region so we don't re-send stale
|
|
290
|
+
// data on the next frame. Used for input regions (hand-off pattern).
|
|
291
|
+
if (r.clearAfterSend) {
|
|
292
|
+
new Uint8Array(buf, r.offset, r.length).fill(0);
|
|
293
|
+
}
|
|
294
|
+
if (seqField) {
|
|
295
|
+
this.lastRegionSeqs[name][r.name] = seq;
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
if (copies.length > 0) regions[name] = copies;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
if (Object.keys(regions).length > 0) {
|
|
302
|
+
const postStart = performance.now();
|
|
303
|
+
this.worker.postMessage({ __bufferSync: true, regions } as BufferSyncMessage, transfers);
|
|
304
|
+
this.profiler.end("host→worker postMessage", postStart, totalBytes);
|
|
305
|
+
}
|
|
306
|
+
this.profiler.end("host→worker total", pStart, totalBytes);
|
|
307
|
+
|
|
308
|
+
this.rafId = requestAnimationFrame(this.syncInput);
|
|
309
|
+
};
|
|
310
|
+
|
|
311
|
+
/** In-flight chunked transfers, keyed by batch id. Parts are applied
|
|
312
|
+
* atomically once the batch completes — see BufferSyncMessage.batch. */
|
|
313
|
+
private pendingBatches = new Map<number, {
|
|
314
|
+
parts: (Record<string, RegionCopy[]> | undefined)[];
|
|
315
|
+
received: number;
|
|
316
|
+
}>();
|
|
317
|
+
private lastBatchSeen = -1;
|
|
318
|
+
|
|
319
|
+
private applyRegions(regions: Record<string, RegionCopy[]>): number {
|
|
320
|
+
let totalBytes = 0;
|
|
321
|
+
for (const [name, regionList] of Object.entries(regions)) {
|
|
322
|
+
const local = this.config.buffers[name];
|
|
323
|
+
if (!local) continue;
|
|
324
|
+
regionList.forEach(({ offset, data }) => {
|
|
325
|
+
new Uint8Array(local, offset, data.byteLength).set(new Uint8Array(data));
|
|
326
|
+
totalBytes += data.byteLength;
|
|
327
|
+
});
|
|
328
|
+
}
|
|
329
|
+
return totalBytes;
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
/**
|
|
333
|
+
* Receive sim data regions from the worker. Copies only the readRegions
|
|
334
|
+
* (regions the other side writes) into the local buffer.
|
|
335
|
+
*/
|
|
336
|
+
private onMessage(msg: unknown): void {
|
|
337
|
+
if (!isBufferSyncMessage(msg)) return;
|
|
338
|
+
|
|
339
|
+
const pStart = this.profiler.begin();
|
|
340
|
+
let totalBytes = 0;
|
|
341
|
+
|
|
342
|
+
if (msg.batch) {
|
|
343
|
+
const { id, index, total } = msg.batch;
|
|
344
|
+
// Part of a batch already completed (or evicted) — a duplicate or a
|
|
345
|
+
// straggler from before a worker restart; applying it would tear.
|
|
346
|
+
if (id <= this.lastBatchSeen && !this.pendingBatches.has(id)) return;
|
|
347
|
+
let b = this.pendingBatches.get(id);
|
|
348
|
+
if (!b) {
|
|
349
|
+
b = { parts: new Array(total), received: 0 };
|
|
350
|
+
this.pendingBatches.set(id, b);
|
|
351
|
+
// Bound the map: a batch that never completes (worker died
|
|
352
|
+
// mid-transfer) must not leak entries forever.
|
|
353
|
+
if (this.pendingBatches.size > 8) {
|
|
354
|
+
const oldest = this.pendingBatches.keys().next().value!;
|
|
355
|
+
this.pendingBatches.delete(oldest);
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
b.parts[index] = msg.regions;
|
|
359
|
+
b.received++;
|
|
360
|
+
if (b.received < total) return; // wait for the rest — no tearing
|
|
361
|
+
this.pendingBatches.delete(id);
|
|
362
|
+
this.lastBatchSeen = id;
|
|
363
|
+
b.parts.forEach((part) => {
|
|
364
|
+
if (part) totalBytes += this.applyRegions(part);
|
|
365
|
+
});
|
|
366
|
+
this.profiler.end("worker→host onMessage", pStart, totalBytes);
|
|
367
|
+
return;
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
totalBytes = this.applyRegions(msg.regions);
|
|
371
|
+
this.profiler.end("worker→host onMessage", pStart, totalBytes);
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
// ---------------------------------------------------------------------------
|
|
376
|
+
// Worker-thread side
|
|
377
|
+
// ---------------------------------------------------------------------------
|
|
378
|
+
|
|
379
|
+
/**
|
|
380
|
+
* Worker-thread buffer sync manager.
|
|
381
|
+
*
|
|
382
|
+
* Sends sim data regions to the main thread after each tick batch (event-
|
|
383
|
+
* driven, no polling), and receives input regions from the main thread via
|
|
384
|
+
* onMessage.
|
|
385
|
+
*/
|
|
386
|
+
export class BufferSyncWorker {
|
|
387
|
+
/** Per-region last-synced sequence: buffer name → region name → seq.
|
|
388
|
+
* Tracked per region (not per buffer) so a filtered syncToMain() call
|
|
389
|
+
* can't consume the buffer seq and starve regions it filtered out —
|
|
390
|
+
* e.g. the fast/slow region pattern in sim-worker-base, where a
|
|
391
|
+
* fast-region sync followed by a full sync must still send slow regions. */
|
|
392
|
+
private lastRegionSeqs: Record<string, Record<string, number>> = {};
|
|
393
|
+
private profiler = new SyncProfiler(5000);
|
|
394
|
+
private onAfterReceive: (() => void) | null = null;
|
|
395
|
+
/** Monotonic id for chunked (multi-message) transfers — the host applies
|
|
396
|
+
* a batch atomically once all parts arrive. */
|
|
397
|
+
private batchCounter = 0;
|
|
398
|
+
|
|
399
|
+
constructor(private config: BufferSyncConfig) {}
|
|
400
|
+
|
|
401
|
+
/**
|
|
402
|
+
* Start listening for sync messages from the main thread.
|
|
403
|
+
* @param onAfterReceive - Optional callback fired after each received
|
|
404
|
+
* message is processed. Use this to trigger event-driven work (e.g.
|
|
405
|
+
* the grid builder calls build() here instead of polling on a timer,
|
|
406
|
+
* which avoids timer throttling in workers on some hosts).
|
|
407
|
+
*/
|
|
408
|
+
start(onAfterReceive?: () => void): void {
|
|
409
|
+
this.onAfterReceive = onAfterReceive ?? null;
|
|
410
|
+
self.addEventListener("message", (e: MessageEvent) => {
|
|
411
|
+
this.onMessage(e.data);
|
|
412
|
+
this.onAfterReceive?.();
|
|
413
|
+
});
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
/**
|
|
417
|
+
* Post written regions to the main thread. Called after each tick batch.
|
|
418
|
+
* Copies only the writeRegions of each buffer, transfers the ArrayBuffers.
|
|
419
|
+
* Skips buffers whose sequence hasn't changed (if seqFields declared).
|
|
420
|
+
*
|
|
421
|
+
* @param regionNames - If provided, only sync write regions whose `name`
|
|
422
|
+
* matches one of the given names. This enables throttled sync: sync small
|
|
423
|
+
* "fast" regions (header, entities) every tick, and large "slow" regions
|
|
424
|
+
* (grid data, render buffers) every N ticks. If omitted, sync all regions.
|
|
425
|
+
*/
|
|
426
|
+
syncToMain(regionNames?: string[]): void {
|
|
427
|
+
const transfers: ArrayBuffer[] = [];
|
|
428
|
+
const regions: Record<string, RegionCopy[]> = {};
|
|
429
|
+
const filter = regionNames ? new Set(regionNames) : null;
|
|
430
|
+
const pStart = this.profiler.begin();
|
|
431
|
+
let totalBytes = 0;
|
|
432
|
+
|
|
433
|
+
for (const [name, buf] of Object.entries(this.config.buffers)) {
|
|
434
|
+
const regionDef = this.config.regions[name];
|
|
435
|
+
if (!regionDef || regionDef.writeRegions.length === 0) continue;
|
|
436
|
+
|
|
437
|
+
// Sequence gating is per-region (see below) — read the current seq once.
|
|
438
|
+
const seqField = this.config.seqFields?.[name];
|
|
439
|
+
const seq = seqField ? new Int32Array(buf, seqField.offset, 1)[0] : 0;
|
|
440
|
+
|
|
441
|
+
const copies: RegionCopy[] = [];
|
|
442
|
+
for (let _i = 0, _it = regionDef.writeRegions, _n = _it.length; _i < _n; _i++) { const r = _it[_i];
|
|
443
|
+
// Region name filter: skip regions not in the filter set.
|
|
444
|
+
if (filter && !filter.has(r.name)) continue;
|
|
445
|
+
// Per-region sequence gating: skip if this region's last-synced seq
|
|
446
|
+
// matches the current buffer seq. Regions excluded by `filter` are
|
|
447
|
+
// checked before this point, so a filtered call never consumes seq
|
|
448
|
+
// for regions it didn't send.
|
|
449
|
+
if (seqField) {
|
|
450
|
+
const lastSeqs = (this.lastRegionSeqs[name] ??= {});
|
|
451
|
+
if (lastSeqs[r.name] === seq) continue;
|
|
452
|
+
}
|
|
453
|
+
// Dynamic length: read actual length from a field in the buffer.
|
|
454
|
+
let len = r.length;
|
|
455
|
+
if (r.lengthFieldOffset !== undefined && r.lengthMultiplier) {
|
|
456
|
+
const count = new Uint32Array(buf, r.lengthFieldOffset, 1)[0];
|
|
457
|
+
len = Math.min(r.length, count * r.lengthMultiplier);
|
|
458
|
+
}
|
|
459
|
+
// Chunked transfer: if the region is large, split into chunks
|
|
460
|
+
// and send with setTimeout between them so the main thread
|
|
461
|
+
// can process rAF/render between chunks. This prevents 100-900ms
|
|
462
|
+
// main-thread blocks where SAB is unavailable
|
|
463
|
+
// and postMessage structured clone is ~10MB/s).
|
|
464
|
+
const CHUNK_SIZE = 64 * 1024; // 64KB per chunk — small enough to avoid >50ms blocks
|
|
465
|
+
if (len > CHUNK_SIZE) {
|
|
466
|
+
const numChunks = Math.ceil(len / CHUNK_SIZE);
|
|
467
|
+
for (let i = 0; i < numChunks; i++) {
|
|
468
|
+
const chunkStart = i * CHUNK_SIZE;
|
|
469
|
+
const chunkLen = Math.min(CHUNK_SIZE, len - chunkStart);
|
|
470
|
+
const chunkCopy = new ArrayBuffer(chunkLen);
|
|
471
|
+
new Uint8Array(chunkCopy).set(new Uint8Array(buf, r.offset + chunkStart, chunkLen));
|
|
472
|
+
copies.push({ offset: r.offset + chunkStart, data: chunkCopy });
|
|
473
|
+
transfers.push(chunkCopy);
|
|
474
|
+
totalBytes += chunkLen;
|
|
475
|
+
}
|
|
476
|
+
} else {
|
|
477
|
+
const copy = new ArrayBuffer(len);
|
|
478
|
+
new Uint8Array(copy).set(new Uint8Array(buf, r.offset, len));
|
|
479
|
+
copies.push({ offset: r.offset, data: copy });
|
|
480
|
+
transfers.push(copy);
|
|
481
|
+
totalBytes += len;
|
|
482
|
+
}
|
|
483
|
+
if (seqField) {
|
|
484
|
+
this.lastRegionSeqs[name][r.name] = seq;
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
if (copies.length > 0) regions[name] = copies;
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
if (Object.keys(regions).length > 0) {
|
|
491
|
+
const label = regionNames ? `worker→host syncToMain(${regionNames.join(",")})` : "worker→host syncToMain(all)";
|
|
492
|
+
// Send all chunks in a single postMessage. The host's onMessage
|
|
493
|
+
// handler copies each chunk to the correct offset in the local buffer.
|
|
494
|
+
// We don't use setTimeout between chunks because the postMessage
|
|
495
|
+
// itself is the blocking operation on the main thread — splitting
|
|
496
|
+
// into multiple postMessage calls with setTimeout would allow the
|
|
497
|
+
// main thread to render between them.
|
|
498
|
+
const allCopies = Object.values(regions).flat();
|
|
499
|
+
if (allCopies.length > 1 && totalBytes > 256 * 1024) {
|
|
500
|
+
// Large transfer: send chunks with setTimeout between them so the
|
|
501
|
+
// main thread can render between chunks. Each message carries batch
|
|
502
|
+
// metadata — the receiver buffers parts and applies them atomically
|
|
503
|
+
// once all arrive, so the buffer never renders partially-updated.
|
|
504
|
+
// Precompute chunk→buffer ownership once (was O(chunks×regions) before).
|
|
505
|
+
const chunkOwner: string[] = [];
|
|
506
|
+
for (const [name, regionList] of Object.entries(regions)) {
|
|
507
|
+
for (let i = 0; i < regionList.length; i++) chunkOwner.push(name);
|
|
508
|
+
}
|
|
509
|
+
const batchId = ++this.batchCounter;
|
|
510
|
+
const total = allCopies.length;
|
|
511
|
+
let chunkIdx = 0;
|
|
512
|
+
const sendNextChunk = () => {
|
|
513
|
+
if (chunkIdx >= total) return;
|
|
514
|
+
const copy = allCopies[chunkIdx];
|
|
515
|
+
const batchRegions: Record<string, RegionCopy[]> = {};
|
|
516
|
+
batchRegions[chunkOwner[chunkIdx]] = [copy];
|
|
517
|
+
chunkIdx++;
|
|
518
|
+
(self as any).postMessage(
|
|
519
|
+
{ __bufferSync: true, regions: batchRegions, batch: { id: batchId, index: chunkIdx - 1, total } } as BufferSyncMessage,
|
|
520
|
+
[copy.data],
|
|
521
|
+
);
|
|
522
|
+
if (chunkIdx < total) {
|
|
523
|
+
setTimeout(sendNextChunk, 16); // 16ms delay lets main thread render between chunks
|
|
524
|
+
}
|
|
525
|
+
};
|
|
526
|
+
sendNextChunk();
|
|
527
|
+
this.profiler.end(label, pStart, totalBytes);
|
|
528
|
+
} else {
|
|
529
|
+
(self as any).postMessage({ __bufferSync: true, regions } as BufferSyncMessage, transfers);
|
|
530
|
+
this.profiler.end(label, pStart, totalBytes);
|
|
531
|
+
}
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
/**
|
|
536
|
+
* Receive input regions from the main thread. Copies only the readRegions
|
|
537
|
+
* (regions the other side writes) into the local buffer.
|
|
538
|
+
*/
|
|
539
|
+
private onMessage(msg: unknown): void {
|
|
540
|
+
if (!isBufferSyncMessage(msg)) return;
|
|
541
|
+
|
|
542
|
+
for (const [name, regionList] of Object.entries(msg.regions)) {
|
|
543
|
+
const local = this.config.buffers[name];
|
|
544
|
+
if (!local) continue;
|
|
545
|
+
regionList.forEach(({ offset, data }) => {
|
|
546
|
+
new Uint8Array(local, offset, data.byteLength).set(new Uint8Array(data));
|
|
547
|
+
});
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
}
|