@downdraft/engine 0.0.0 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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 +123 -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,411 @@
|
|
|
1
|
+
// ============================================================================
|
|
2
|
+
// WasmPluginLoader — loads `wasm` format (native-tier) plugins.
|
|
3
|
+
//
|
|
4
|
+
// WASM plugins ALWAYS run in their own dedicated worker (stability isolation).
|
|
5
|
+
// The loader:
|
|
6
|
+
// 1. Fetches the .wasm file.
|
|
7
|
+
// 2. Instantiates it with the host import module (env namespace).
|
|
8
|
+
// 3. Calls the module's `register` export.
|
|
9
|
+
// 4. Forwards tick calls + event dispatch to the module's exports.
|
|
10
|
+
// 5. On dispose, calls the module's `dispose` export.
|
|
11
|
+
//
|
|
12
|
+
// For testing, an in-process variant (`InlineWasmPluginLoader`) instantiates
|
|
13
|
+
// the WASM module directly on the current thread.
|
|
14
|
+
// ============================================================================
|
|
15
|
+
|
|
16
|
+
import { createLogger } from "../util/logger";
|
|
17
|
+
import type { NativePluginContext, ScriptPluginContext } from "./context";
|
|
18
|
+
import type { PluginLoader } from "./host";
|
|
19
|
+
import type { PluginManifest } from "./manifest";
|
|
20
|
+
import type { PermissionGrant } from "./permissions";
|
|
21
|
+
import {
|
|
22
|
+
readStringFromMemory,
|
|
23
|
+
writeBytesToMemory,
|
|
24
|
+
writeStringToMemory,
|
|
25
|
+
type WasmPluginExports,
|
|
26
|
+
type WasmPluginImports,
|
|
27
|
+
} from "./wasm-abi";
|
|
28
|
+
|
|
29
|
+
const log = createLogger("info");
|
|
30
|
+
|
|
31
|
+
/** A pending host-call request, tracked by request id. */
|
|
32
|
+
interface PendingHostCall {
|
|
33
|
+
resolve: (value: unknown) => void;
|
|
34
|
+
reject: (err: Error) => void;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Build the host import module (`env` namespace) for a WASM plugin.
|
|
39
|
+
* The imports bridge the plugin's WASM calls to the ScriptPluginContext /
|
|
40
|
+
* NativePluginContext. v3 host-call imports forward to the NativePluginContext
|
|
41
|
+
* host-call bridge and post results back via `on_host_call_result`.
|
|
42
|
+
*
|
|
43
|
+
* Exported for testing (so tests can instantiate a WASM module directly
|
|
44
|
+
* without going through the loader's fetch path).
|
|
45
|
+
*/
|
|
46
|
+
export function buildImports(
|
|
47
|
+
ctx: ScriptPluginContext | NativePluginContext,
|
|
48
|
+
exports: () => WasmPluginExports,
|
|
49
|
+
subscriptions: Map<number, (data: unknown) => void>,
|
|
50
|
+
pending: Map<number, PendingHostCall>,
|
|
51
|
+
): WasmPluginImports {
|
|
52
|
+
const readStr = (ptr: number, len: number): string => readStringFromMemory(exports(), ptr, len);
|
|
53
|
+
// Host-call bridge: only available on NativePluginContext. For script-tier
|
|
54
|
+
// (QuickJS) contexts, host calls reject with a clear error.
|
|
55
|
+
const hostCalls = (ctx as NativePluginContext).spawnProp
|
|
56
|
+
? (ctx as NativePluginContext)
|
|
57
|
+
: undefined;
|
|
58
|
+
let nextReqId = 1;
|
|
59
|
+
const dispatchHostCall = <T>(p: Promise<T>, requestId: number): void => {
|
|
60
|
+
p.then((result) => {
|
|
61
|
+
const exp = exports();
|
|
62
|
+
if (!exp.on_host_call_result) return;
|
|
63
|
+
if (result === undefined) {
|
|
64
|
+
exp.on_host_call_result(requestId, 0, 0, 0, 0);
|
|
65
|
+
} else {
|
|
66
|
+
const json = JSON.stringify(result);
|
|
67
|
+
const [ptr, len] = writeBytesToMemory(exp, new TextEncoder().encode(json)) ?? [0, 0];
|
|
68
|
+
exp.on_host_call_result(requestId, ptr, len, 0, 0);
|
|
69
|
+
}
|
|
70
|
+
}).catch((err: Error) => {
|
|
71
|
+
const exp = exports();
|
|
72
|
+
if (!exp.on_host_call_result) return;
|
|
73
|
+
const [ptr, len] = writeStringToMemory(exp, err.message) ?? [0, 0];
|
|
74
|
+
exp.on_host_call_result(requestId, 0, 0, ptr, len);
|
|
75
|
+
});
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
return {
|
|
79
|
+
env: {
|
|
80
|
+
log_info: (ptr, len) => ctx.log.info(readStr(ptr, len)),
|
|
81
|
+
log_warn: (ptr, len) => ctx.log.warn(readStr(ptr, len)),
|
|
82
|
+
log_error: (ptr, len) => ctx.log.error(readStr(ptr, len)),
|
|
83
|
+
log_debug: (ptr, len) => ctx.log.debug(readStr(ptr, len)),
|
|
84
|
+
|
|
85
|
+
state_get: (keyPtr, keyLen) => {
|
|
86
|
+
const key = readStr(keyPtr, keyLen);
|
|
87
|
+
const val = ctx.state.get(key);
|
|
88
|
+
if (val === undefined) return 0;
|
|
89
|
+
// Write the value as JSON into memory. Store length as u32 before the ptr.
|
|
90
|
+
const json = JSON.stringify(val);
|
|
91
|
+
const [ptr, len] = writeBytesToMemory(exports(), new TextEncoder().encode(json)) ?? [0, 0];
|
|
92
|
+
if (ptr === 0) return 0;
|
|
93
|
+
// Write the length 4 bytes before the pointer.
|
|
94
|
+
const mem = exports().memory!;
|
|
95
|
+
const dv = new DataView(mem.buffer, ptr - 4, 4);
|
|
96
|
+
dv.setUint32(0, len, true);
|
|
97
|
+
return ptr;
|
|
98
|
+
},
|
|
99
|
+
state_set: (keyPtr, keyLen, valPtr, valLen) => {
|
|
100
|
+
const key = readStr(keyPtr, keyLen);
|
|
101
|
+
const json = readStr(valPtr, valLen);
|
|
102
|
+
try { ctx.state.set(key, JSON.parse(json)); } catch { ctx.state.set(key, json); }
|
|
103
|
+
},
|
|
104
|
+
state_delete: (keyPtr, keyLen) => {
|
|
105
|
+
ctx.state.delete(readStr(keyPtr, keyLen));
|
|
106
|
+
},
|
|
107
|
+
|
|
108
|
+
event_publish: (namePtr, nameLen, dataPtr, dataLen) => {
|
|
109
|
+
const name = readStr(namePtr, nameLen);
|
|
110
|
+
const json = readStr(dataPtr, dataLen);
|
|
111
|
+
try { ctx.events.publish(name, JSON.parse(json)); } catch { ctx.events.publish(name, json); }
|
|
112
|
+
},
|
|
113
|
+
event_subscribe: (namePtr, nameLen) => {
|
|
114
|
+
const name = readStr(namePtr, nameLen);
|
|
115
|
+
const subId = subscriptions.size + 1;
|
|
116
|
+
const handler = (data: unknown) => {
|
|
117
|
+
const exp = exports();
|
|
118
|
+
if (!exp.on_event) return;
|
|
119
|
+
const json = JSON.stringify(data);
|
|
120
|
+
const [ptr, len] = writeBytesToMemory(exp, new TextEncoder().encode(json)) ?? [0, 0];
|
|
121
|
+
if (ptr !== 0) exp.on_event(subId, ptr, len);
|
|
122
|
+
};
|
|
123
|
+
const unsub = ctx.events.subscribe(name, handler);
|
|
124
|
+
subscriptions.set(subId, unsub as any);
|
|
125
|
+
// Store the unsub for cleanup.
|
|
126
|
+
(subscriptions as any)[`unsub_${subId}`] = unsub;
|
|
127
|
+
return subId;
|
|
128
|
+
},
|
|
129
|
+
event_unsubscribe: (subId) => {
|
|
130
|
+
const unsub = (subscriptions as any)[`unsub_${subId}`];
|
|
131
|
+
if (typeof unsub === "function") unsub();
|
|
132
|
+
subscriptions.delete(subId);
|
|
133
|
+
},
|
|
134
|
+
|
|
135
|
+
// ── Host-call bridge (v3) ──
|
|
136
|
+
spawn_prop: (contentIdPtr, contentIdLen, x, y, z, qx, qy, qz, qw, scale) => {
|
|
137
|
+
const reqId = nextReqId++;
|
|
138
|
+
const contentId = readStr(contentIdPtr, contentIdLen);
|
|
139
|
+
if (!hostCalls?.spawnProp) {
|
|
140
|
+
dispatchHostCall(Promise.reject(new Error("spawnProp: no host-call bridge wired")), reqId);
|
|
141
|
+
return reqId;
|
|
142
|
+
}
|
|
143
|
+
const desc = {
|
|
144
|
+
contentId,
|
|
145
|
+
position: [x, y, z] as [number, number, number],
|
|
146
|
+
rotation: [qx, qy, qz, qw] as [number, number, number, number],
|
|
147
|
+
scale,
|
|
148
|
+
};
|
|
149
|
+
dispatchHostCall(hostCalls.spawnProp(desc), reqId);
|
|
150
|
+
return reqId;
|
|
151
|
+
},
|
|
152
|
+
remove_prop: (entityId) => {
|
|
153
|
+
const reqId = nextReqId++;
|
|
154
|
+
if (!hostCalls?.removeProp) {
|
|
155
|
+
dispatchHostCall(Promise.reject(new Error("removeProp: no host-call bridge wired")), reqId);
|
|
156
|
+
return reqId;
|
|
157
|
+
}
|
|
158
|
+
dispatchHostCall(hostCalls.removeProp(entityId), reqId);
|
|
159
|
+
return reqId;
|
|
160
|
+
},
|
|
161
|
+
set_physics: (entityId, mass, restitution, friction, gravityScale) => {
|
|
162
|
+
const reqId = nextReqId++;
|
|
163
|
+
if (!hostCalls?.setPhysics) {
|
|
164
|
+
dispatchHostCall(Promise.reject(new Error("setPhysics: no host-call bridge wired")), reqId);
|
|
165
|
+
return reqId;
|
|
166
|
+
}
|
|
167
|
+
const desc: Record<string, number> = {};
|
|
168
|
+
if (!Number.isNaN(mass)) desc.mass = mass;
|
|
169
|
+
if (!Number.isNaN(restitution)) desc.restitution = restitution;
|
|
170
|
+
if (!Number.isNaN(friction)) desc.friction = friction;
|
|
171
|
+
if (!Number.isNaN(gravityScale)) desc.gravityScale = gravityScale;
|
|
172
|
+
dispatchHostCall(hostCalls.setPhysics(entityId, desc), reqId);
|
|
173
|
+
return reqId;
|
|
174
|
+
},
|
|
175
|
+
get_physics: (entityId) => {
|
|
176
|
+
const reqId = nextReqId++;
|
|
177
|
+
if (!hostCalls?.getPhysics) {
|
|
178
|
+
dispatchHostCall(Promise.reject(new Error("getPhysics: no host-call bridge wired")), reqId);
|
|
179
|
+
return reqId;
|
|
180
|
+
}
|
|
181
|
+
dispatchHostCall(hostCalls.getPhysics(entityId), reqId);
|
|
182
|
+
return reqId;
|
|
183
|
+
},
|
|
184
|
+
apply_impulse: (entityId, x, y, z) => {
|
|
185
|
+
const reqId = nextReqId++;
|
|
186
|
+
if (!hostCalls?.applyImpulse) {
|
|
187
|
+
dispatchHostCall(Promise.reject(new Error("applyImpulse: no host-call bridge wired")), reqId);
|
|
188
|
+
return reqId;
|
|
189
|
+
}
|
|
190
|
+
dispatchHostCall(hostCalls.applyImpulse(entityId, [x, y, z]), reqId);
|
|
191
|
+
return reqId;
|
|
192
|
+
},
|
|
193
|
+
apply_torque: (entityId, x, y, z) => {
|
|
194
|
+
const reqId = nextReqId++;
|
|
195
|
+
if (!hostCalls?.applyTorque) {
|
|
196
|
+
dispatchHostCall(Promise.reject(new Error("applyTorque: no host-call bridge wired")), reqId);
|
|
197
|
+
return reqId;
|
|
198
|
+
}
|
|
199
|
+
dispatchHostCall(hostCalls.applyTorque(entityId, [x, y, z]), reqId);
|
|
200
|
+
return reqId;
|
|
201
|
+
},
|
|
202
|
+
get_asset_ref: (assetIdPtr, assetIdLen) => {
|
|
203
|
+
const reqId = nextReqId++;
|
|
204
|
+
const assetId = readStr(assetIdPtr, assetIdLen);
|
|
205
|
+
if (!hostCalls?.getAssetRef) {
|
|
206
|
+
dispatchHostCall(Promise.reject(new Error("getAssetRef: no host-call bridge wired")), reqId);
|
|
207
|
+
return reqId;
|
|
208
|
+
}
|
|
209
|
+
dispatchHostCall(hostCalls.getAssetRef(assetId), reqId);
|
|
210
|
+
return reqId;
|
|
211
|
+
},
|
|
212
|
+
},
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
/** Resolve the plugin exports from a WebAssembly instance. */
|
|
217
|
+
function resolveExports(instance: WebAssembly.Instance): WasmPluginExports {
|
|
218
|
+
const exp = instance.exports as Record<string, any>;
|
|
219
|
+
return {
|
|
220
|
+
alloc: exp.alloc,
|
|
221
|
+
register: exp.register,
|
|
222
|
+
tick: exp.tick,
|
|
223
|
+
dispose: exp.dispose,
|
|
224
|
+
on_event: exp.on_event,
|
|
225
|
+
on_host_call_result: exp.on_host_call_result,
|
|
226
|
+
memory: exp.memory,
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* In-process WASM plugin loader. Instantiates the WASM module directly on the
|
|
232
|
+
* current thread. Used for tests and for renderer-thread WASM plugins (though
|
|
233
|
+
* WASM plugins are always supposed to run in their own worker per the spec).
|
|
234
|
+
*/
|
|
235
|
+
export class InlineWasmPluginLoader implements PluginLoader {
|
|
236
|
+
readonly format = "wasm" as const;
|
|
237
|
+
|
|
238
|
+
async load(
|
|
239
|
+
manifest: PluginManifest,
|
|
240
|
+
ctx: ScriptPluginContext | NativePluginContext,
|
|
241
|
+
_granted: PermissionGrant,
|
|
242
|
+
): Promise<(() => void) | void> {
|
|
243
|
+
const entryUrl = manifest.entry!;
|
|
244
|
+
const resp = await fetch(entryUrl);
|
|
245
|
+
if (!resp.ok) throw new Error(`Failed to fetch WASM plugin "${entryUrl}": HTTP ${resp.status}`);
|
|
246
|
+
const bytes = new Uint8Array(await resp.arrayBuffer());
|
|
247
|
+
|
|
248
|
+
const subscriptions = new Map<number, (data: unknown) => void>();
|
|
249
|
+
const pending = new Map<number, PendingHostCall>();
|
|
250
|
+
let exportsRef: WasmPluginExports = { alloc: () => 0, register: () => {} };
|
|
251
|
+
|
|
252
|
+
const imports = buildImports(ctx, () => exportsRef, subscriptions, pending);
|
|
253
|
+
const result = await WebAssembly.instantiate(bytes, imports as unknown as WebAssembly.Imports);
|
|
254
|
+
exportsRef = resolveExports(result.instance);
|
|
255
|
+
|
|
256
|
+
if (typeof exportsRef.register !== "function") {
|
|
257
|
+
throw new Error(`WASM plugin "${manifest.id}" has no register() export`);
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
// Call register.
|
|
261
|
+
exportsRef.register();
|
|
262
|
+
|
|
263
|
+
// Wire tick if the plugin exports it.
|
|
264
|
+
if (typeof exportsRef.tick === "function") {
|
|
265
|
+
const tickFn = exportsRef.tick;
|
|
266
|
+
const unsub = ctx.tick.onTick((dt, t) => tickFn(dt, t));
|
|
267
|
+
(subscriptions as any).__tickUnsub = unsub;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
log.info("InlineWasmPluginLoader", `Loaded WASM plugin "${manifest.id}"`);
|
|
271
|
+
|
|
272
|
+
return () => {
|
|
273
|
+
const unsubTick = (subscriptions as any).__tickUnsub;
|
|
274
|
+
if (typeof unsubTick === "function") unsubTick();
|
|
275
|
+
for (const [, unsub] of subscriptions.entries()) {
|
|
276
|
+
if (typeof unsub === "function") (unsub as any)();
|
|
277
|
+
}
|
|
278
|
+
subscriptions.clear();
|
|
279
|
+
try { exportsRef.dispose?.(); } catch { /* swallow */ }
|
|
280
|
+
};
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
/**
|
|
285
|
+
* Worker-based WASM plugin loader. Spawns a dedicated worker per WASM plugin.
|
|
286
|
+
* The worker instantiates the WASM module and bridges the host API.
|
|
287
|
+
*
|
|
288
|
+
* CRITICAL: Vite requires `new Worker(new URL("./wasm-worker.ts", import.meta.url))`
|
|
289
|
+
* to appear literally at the call site. It does here.
|
|
290
|
+
*/
|
|
291
|
+
export class WasmPluginLoader implements PluginLoader {
|
|
292
|
+
readonly format = "wasm" as const;
|
|
293
|
+
private workers = new Map<string, Worker>();
|
|
294
|
+
|
|
295
|
+
async load(
|
|
296
|
+
manifest: PluginManifest,
|
|
297
|
+
ctx: ScriptPluginContext | NativePluginContext,
|
|
298
|
+
_granted: PermissionGrant,
|
|
299
|
+
): Promise<(() => void) | void> {
|
|
300
|
+
const entryUrl = manifest.entry!;
|
|
301
|
+
const worker = new Worker(new URL("./wasm-worker.ts", import.meta.url), {
|
|
302
|
+
type: "module",
|
|
303
|
+
});
|
|
304
|
+
this.workers.set(manifest.id, worker);
|
|
305
|
+
|
|
306
|
+
const ready = new Promise<void>((resolve, reject) => {
|
|
307
|
+
const onReady = (ev: MessageEvent) => {
|
|
308
|
+
const msg = ev.data;
|
|
309
|
+
if (msg?.__wasmReady && msg.pluginId === manifest.id) {
|
|
310
|
+
worker.removeEventListener("message", onReady);
|
|
311
|
+
resolve();
|
|
312
|
+
}
|
|
313
|
+
if (msg?.__wasmError) {
|
|
314
|
+
worker.removeEventListener("message", onReady);
|
|
315
|
+
reject(new Error(msg.error));
|
|
316
|
+
}
|
|
317
|
+
};
|
|
318
|
+
worker.addEventListener("message", onReady);
|
|
319
|
+
});
|
|
320
|
+
|
|
321
|
+
worker.onerror = (e) => {
|
|
322
|
+
log.error("WasmPluginLoader", `worker error for "${manifest.id}": ${e.message}`);
|
|
323
|
+
};
|
|
324
|
+
|
|
325
|
+
// Send init message with the WASM URL.
|
|
326
|
+
worker.postMessage({
|
|
327
|
+
__wasmInit: true,
|
|
328
|
+
pluginId: manifest.id,
|
|
329
|
+
entryUrl,
|
|
330
|
+
});
|
|
331
|
+
|
|
332
|
+
// Forward host-side calls when the worker posts bridge requests.
|
|
333
|
+
// Explicit dispatch table — arbitrary ctx[method] strings are NOT
|
|
334
|
+
// forwarded; only the methods the wasm worker protocol uses.
|
|
335
|
+
const eventSubs = new Map<number, () => void>();
|
|
336
|
+
const wasmHostCalls = ctx as unknown as Record<string, ((...a: unknown[]) => Promise<unknown>) | undefined>;
|
|
337
|
+
const dispatchBridge = (method: string, args: unknown[]): unknown => {
|
|
338
|
+
switch (method) {
|
|
339
|
+
case "log": {
|
|
340
|
+
const level = args[0] as "info" | "warn" | "error" | "debug";
|
|
341
|
+
return ctx.log[level]?.(String(args[1]));
|
|
342
|
+
}
|
|
343
|
+
case "state.load": return ctx.state.load?.();
|
|
344
|
+
case "state.keys": return ctx.state.keys();
|
|
345
|
+
case "state.get": return ctx.state.get(args[0] as string);
|
|
346
|
+
case "state.set": return ctx.state.set(args[0] as string, args[1]);
|
|
347
|
+
case "state.delete": return ctx.state.delete(args[0] as string);
|
|
348
|
+
case "events.publish": return ctx.events.publish(args[0] as string, args[1]);
|
|
349
|
+
case "events.subscribe": {
|
|
350
|
+
const name = args[0] as string;
|
|
351
|
+
const subId = args[1] as number;
|
|
352
|
+
const unsub = ctx.events.subscribe(name, (data: unknown) => {
|
|
353
|
+
worker.postMessage({ __wasmEvent: true, subId, data });
|
|
354
|
+
});
|
|
355
|
+
eventSubs.set(subId, unsub);
|
|
356
|
+
return subId;
|
|
357
|
+
}
|
|
358
|
+
case "events.unsubscribe": {
|
|
359
|
+
const unsub = eventSubs.get(args[0] as number);
|
|
360
|
+
eventSubs.delete(args[0] as number);
|
|
361
|
+
unsub?.();
|
|
362
|
+
return undefined;
|
|
363
|
+
}
|
|
364
|
+
case "hostCall": {
|
|
365
|
+
// v3 host calls — native-tier context methods only (permission-
|
|
366
|
+
// gated inside the context itself).
|
|
367
|
+
const [name, ...rest] = args as [string, ...unknown[]];
|
|
368
|
+
const allowed = ["spawnProp", "removeProp", "setPhysics", "getPhysics", "applyImpulse", "applyTorque", "getAssetRef"];
|
|
369
|
+
if (!allowed.includes(name)) {
|
|
370
|
+
throw new Error(`hostCall "${name}" is not allowed`);
|
|
371
|
+
}
|
|
372
|
+
const fn = wasmHostCalls[name];
|
|
373
|
+
if (typeof fn !== "function") {
|
|
374
|
+
throw new Error(`hostCall "${name}" unavailable (no native context)`);
|
|
375
|
+
}
|
|
376
|
+
return fn.apply(ctx, rest);
|
|
377
|
+
}
|
|
378
|
+
default:
|
|
379
|
+
throw new Error(`unknown bridge method "${method}"`);
|
|
380
|
+
}
|
|
381
|
+
};
|
|
382
|
+
worker.addEventListener("message", (ev: MessageEvent) => {
|
|
383
|
+
const msg = ev.data;
|
|
384
|
+
if (msg?.__wasmBridge) {
|
|
385
|
+
const { method, args } = msg as { method: string; args: unknown[] };
|
|
386
|
+
Promise.resolve()
|
|
387
|
+
.then(() => dispatchBridge(method, args))
|
|
388
|
+
.then((result) => {
|
|
389
|
+
worker.postMessage({ __wasmBridgeResult: true, callId: msg.callId, result });
|
|
390
|
+
})
|
|
391
|
+
.catch((e) => {
|
|
392
|
+
worker.postMessage({ __wasmBridgeResult: true, callId: msg.callId, error: (e as Error).message });
|
|
393
|
+
});
|
|
394
|
+
}
|
|
395
|
+
});
|
|
396
|
+
|
|
397
|
+
await ready;
|
|
398
|
+
log.info("WasmPluginLoader", `Loaded WASM plugin "${manifest.id}" in dedicated worker`);
|
|
399
|
+
|
|
400
|
+
return () => {
|
|
401
|
+
worker.postMessage({ __wasmDispose: true });
|
|
402
|
+
setTimeout(() => worker.terminate(), 100);
|
|
403
|
+
this.workers.delete(manifest.id);
|
|
404
|
+
};
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
disposeAll(): void {
|
|
408
|
+
for (const [, w] of this.workers.entries()) w.terminate();
|
|
409
|
+
this.workers.clear();
|
|
410
|
+
}
|
|
411
|
+
}
|
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
// ============================================================================
|
|
2
|
+
// WorkerPluginLoader — loads `worker-js` format plugins in a sandboxed Web Worker.
|
|
3
|
+
//
|
|
4
|
+
// For `thread: "own-worker"` plugins, this loader spawns a dedicated
|
|
5
|
+
// `sandbox-worker.ts` per plugin, sends the init message (entry URL + granted
|
|
6
|
+
// perms), and forwards host↔worker bridge calls.
|
|
7
|
+
//
|
|
8
|
+
// For `thread: "sim"` plugins, the host forwards the manifest to the sim
|
|
9
|
+
// worker's own PluginHost (which uses the in-process loader path that imports
|
|
10
|
+
// the entry directly into the sim worker's module graph). This loader only
|
|
11
|
+
// handles the `own-worker` case on the renderer/sim-host side.
|
|
12
|
+
//
|
|
13
|
+
// Bridge protocol (`__bridgeCall` / `__bridgeResponse`):
|
|
14
|
+
// - Every call carries a `callId` so responses correlate with requests.
|
|
15
|
+
// - Only an allowlist of methods may cross the boundary — the worker can
|
|
16
|
+
// never invoke arbitrary context members. Permission enforcement happens
|
|
17
|
+
// inside the context itself (makeScriptContext/makeNativeContext gate
|
|
18
|
+
// each API on the granted set), so a denied call rejects with a
|
|
19
|
+
// permission error that is forwarded back to the worker.
|
|
20
|
+
// - Results are awaited before responding — async context methods work.
|
|
21
|
+
//
|
|
22
|
+
// CRITICAL: Vite requires `new Worker(new URL("./sandbox-worker.ts", import.meta.url))`
|
|
23
|
+
// to appear literally at the call site. It does here.
|
|
24
|
+
// ============================================================================
|
|
25
|
+
|
|
26
|
+
import { createLogger } from "../util/logger";
|
|
27
|
+
import type { NativePluginContext, ScriptPluginContext } from "./context";
|
|
28
|
+
import type { PluginHost, PluginLoader } from "./host";
|
|
29
|
+
import type { PluginManifest, PluginPermission } from "./manifest";
|
|
30
|
+
import type { PermissionGrant } from "./permissions";
|
|
31
|
+
|
|
32
|
+
const log = createLogger("info");
|
|
33
|
+
|
|
34
|
+
/** How long to wait for a plugin worker's __sandboxReady before giving up. */
|
|
35
|
+
const READY_TIMEOUT_MS = 15_000;
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Methods a sandboxed worker may invoke across the bridge. Anything not in
|
|
39
|
+
* this list is rejected — the worker can never reach arbitrary ctx members.
|
|
40
|
+
* Permission checks are enforced inside the context methods themselves.
|
|
41
|
+
*/
|
|
42
|
+
const BRIDGE_METHODS = new Set([
|
|
43
|
+
"events.publish",
|
|
44
|
+
"events.subscribe",
|
|
45
|
+
"state.save",
|
|
46
|
+
"state.load",
|
|
47
|
+
// Host-call bridge (game mutation) — only present on native-tier contexts;
|
|
48
|
+
// each method is additionally permission-gated inside the context.
|
|
49
|
+
"spawnProp",
|
|
50
|
+
"removeProp",
|
|
51
|
+
"setPhysics",
|
|
52
|
+
"getPhysics",
|
|
53
|
+
"applyImpulse",
|
|
54
|
+
"applyTorque",
|
|
55
|
+
"getAssetRef",
|
|
56
|
+
]);
|
|
57
|
+
|
|
58
|
+
export class WorkerPluginLoader implements PluginLoader {
|
|
59
|
+
readonly format = "worker-js" as const;
|
|
60
|
+
private workers = new Map<string, Worker>();
|
|
61
|
+
private host: PluginHost | null = null;
|
|
62
|
+
|
|
63
|
+
bindHost(host: PluginHost): void {
|
|
64
|
+
this.host = host;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
async load(
|
|
68
|
+
manifest: PluginManifest,
|
|
69
|
+
ctx: ScriptPluginContext | NativePluginContext,
|
|
70
|
+
granted: PermissionGrant,
|
|
71
|
+
): Promise<(() => void) | void> {
|
|
72
|
+
if (manifest.thread !== "own-worker") {
|
|
73
|
+
// sim-thread worker-js plugins are loaded by the sim worker's own host
|
|
74
|
+
// via direct dynamic import (not this loader). Renderer-side host skips.
|
|
75
|
+
log.info(
|
|
76
|
+
"WorkerPluginLoader",
|
|
77
|
+
`plugin "${manifest.id}" thread=${manifest.thread} — skipping on this host (sim-side host loads it)`,
|
|
78
|
+
);
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
const entryUrl = manifest.entry!;
|
|
82
|
+
const worker = new Worker(new URL("./sandbox-worker.ts", import.meta.url), {
|
|
83
|
+
type: "module",
|
|
84
|
+
});
|
|
85
|
+
this.workers.set(manifest.id, worker);
|
|
86
|
+
|
|
87
|
+
const ready = new Promise<void>((resolve, reject) => {
|
|
88
|
+
const timer = setTimeout(() => {
|
|
89
|
+
cleanup();
|
|
90
|
+
worker.terminate();
|
|
91
|
+
this.workers.delete(manifest.id);
|
|
92
|
+
reject(new Error(`plugin "${manifest.id}" timed out waiting for __sandboxReady (${READY_TIMEOUT_MS}ms)`));
|
|
93
|
+
}, READY_TIMEOUT_MS);
|
|
94
|
+
const cleanup = () => {
|
|
95
|
+
clearTimeout(timer);
|
|
96
|
+
worker.removeEventListener("message", onReady);
|
|
97
|
+
worker.onerror = null;
|
|
98
|
+
};
|
|
99
|
+
const onReady = (ev: MessageEvent) => {
|
|
100
|
+
const msg = ev.data;
|
|
101
|
+
if (msg?.__sandboxReady && msg.contextId === manifest.id) {
|
|
102
|
+
cleanup();
|
|
103
|
+
resolve();
|
|
104
|
+
}
|
|
105
|
+
if (msg?.__sandboxError) {
|
|
106
|
+
cleanup();
|
|
107
|
+
reject(new Error(msg.error));
|
|
108
|
+
}
|
|
109
|
+
};
|
|
110
|
+
worker.addEventListener("message", onReady);
|
|
111
|
+
worker.onerror = (e) => {
|
|
112
|
+
cleanup();
|
|
113
|
+
this.workers.delete(manifest.id);
|
|
114
|
+
reject(new Error(`worker error for "${manifest.id}": ${e.message}`));
|
|
115
|
+
};
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
worker.postMessage({
|
|
119
|
+
__sandboxInit: true,
|
|
120
|
+
entryUrl,
|
|
121
|
+
granted: [...granted.granted] as PluginPermission[],
|
|
122
|
+
contextId: manifest.id,
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
// Forward host-side ctx calls when the worker posts __bridgeCall.
|
|
126
|
+
worker.addEventListener("message", (ev: MessageEvent) => {
|
|
127
|
+
const msg = ev.data;
|
|
128
|
+
if (msg?.__bridgeCall) {
|
|
129
|
+
void this.handleBridgeCall(worker, manifest.id, ctx, msg);
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
if (msg?.__pluginLog) {
|
|
133
|
+
const level = (msg.level ?? "info") as "info" | "warn" | "error" | "debug";
|
|
134
|
+
log[level]?.("WorkerPluginLoader", `[plugin:${manifest.id}] ${msg.msg}`);
|
|
135
|
+
}
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
await ready;
|
|
139
|
+
return () => {
|
|
140
|
+
worker.postMessage({ __dispose: true });
|
|
141
|
+
setTimeout(() => worker.terminate(), 100);
|
|
142
|
+
this.workers.delete(manifest.id);
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Dispatch an allowlisted bridge call. Async results are awaited before
|
|
148
|
+
* the response is posted, so async context methods (host calls, state
|
|
149
|
+
* save/load) propagate correctly.
|
|
150
|
+
*/
|
|
151
|
+
private async handleBridgeCall(
|
|
152
|
+
worker: Worker,
|
|
153
|
+
pluginId: string,
|
|
154
|
+
ctx: ScriptPluginContext | NativePluginContext,
|
|
155
|
+
msg: { callId?: number; method?: string; args?: unknown[] },
|
|
156
|
+
): Promise<void> {
|
|
157
|
+
const { callId, method, args = [] } = msg;
|
|
158
|
+
let result: unknown;
|
|
159
|
+
let error: string | undefined;
|
|
160
|
+
try {
|
|
161
|
+
if (!method || !BRIDGE_METHODS.has(method)) {
|
|
162
|
+
throw new Error(`bridge method "${method}" is not allowed`);
|
|
163
|
+
}
|
|
164
|
+
switch (method) {
|
|
165
|
+
case "events.publish":
|
|
166
|
+
ctx.events.publish(args[0] as string, args[1]);
|
|
167
|
+
break;
|
|
168
|
+
case "events.subscribe": {
|
|
169
|
+
// Subscribe the worker to the shared bus; fan out via __event posts.
|
|
170
|
+
// ctx.events is permission-gated, so a plugin without the "events"
|
|
171
|
+
// permission throws here and the error is bridged back.
|
|
172
|
+
const event = args[0] as string;
|
|
173
|
+
const unsub = ctx.events.subscribe(event, (data) => {
|
|
174
|
+
worker.postMessage({ __event: true, event, data });
|
|
175
|
+
});
|
|
176
|
+
this.host?.trackDispose(pluginId, unsub);
|
|
177
|
+
break;
|
|
178
|
+
}
|
|
179
|
+
case "state.save": {
|
|
180
|
+
// Worker pushes its KV entries; host persists via its own store.
|
|
181
|
+
(args[0] as Array<[string, unknown]>).forEach(([k, v]) => {
|
|
182
|
+
ctx.state.set(k, v);
|
|
183
|
+
});
|
|
184
|
+
await ctx.state.save();
|
|
185
|
+
break;
|
|
186
|
+
}
|
|
187
|
+
case "state.load": {
|
|
188
|
+
await ctx.state.load();
|
|
189
|
+
result = ctx.state.keys().map((k) => [k, ctx.state.get(k)]);
|
|
190
|
+
break;
|
|
191
|
+
}
|
|
192
|
+
default: {
|
|
193
|
+
// Host calls (spawnProp, setPhysics, ...) — present only on
|
|
194
|
+
// native-tier contexts; each is permission-gated internally.
|
|
195
|
+
const fn = (ctx as unknown as Record<string, unknown>)[method];
|
|
196
|
+
if (typeof fn !== "function") {
|
|
197
|
+
throw new Error(`bridge method "${method}" is not available on this context`);
|
|
198
|
+
}
|
|
199
|
+
result = await (fn as (...a: unknown[]) => unknown)(...args);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
} catch (e) {
|
|
203
|
+
error = (e as Error).message;
|
|
204
|
+
}
|
|
205
|
+
worker.postMessage({ __bridgeResponse: true, contextId: pluginId, callId, result, error });
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
/** Forward a host tick to every worker plugin (drives ctx.tick.onTick). */
|
|
209
|
+
tick(dt: number, elapsedTime: number): void {
|
|
210
|
+
for (const [, worker] of this.workers.entries()) {
|
|
211
|
+
worker.postMessage({ __tick: true, dt, elapsedTime });
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
disposeAll(): void {
|
|
216
|
+
for (const [, w] of this.workers.entries()) w.terminate();
|
|
217
|
+
this.workers.clear();
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
/**
|
|
222
|
+
* In-process loader for worker-js plugins that run on the SAME thread as the
|
|
223
|
+
* host (e.g. sim-thread plugins loaded by the sim worker's PluginHost, or
|
|
224
|
+
* renderer-thread plugins in tests). Restricts globals via the shim then
|
|
225
|
+
* dynamically imports the entry.
|
|
226
|
+
*
|
|
227
|
+
* The returned dispose fn restores the globals that restrictGlobals trapped,
|
|
228
|
+
* so unloading a plugin doesn't leave the host thread's global environment
|
|
229
|
+
* permanently degraded (e.g. a plugin denied `network` would otherwise trap
|
|
230
|
+
* `fetch` for the entire sim worker forever).
|
|
231
|
+
*/
|
|
232
|
+
export class InlinePluginLoader implements PluginLoader {
|
|
233
|
+
readonly format = "worker-js" as const;
|
|
234
|
+
|
|
235
|
+
async load(
|
|
236
|
+
manifest: PluginManifest,
|
|
237
|
+
ctx: ScriptPluginContext | NativePluginContext,
|
|
238
|
+
granted: PermissionGrant,
|
|
239
|
+
): Promise<(() => void) | void> {
|
|
240
|
+
// Restrict globals in-process (affects everything on this thread — only
|
|
241
|
+
// safe in a dedicated worker context like the sim worker, where the
|
|
242
|
+
// plugin runs alongside the sim but the sim owns the thread).
|
|
243
|
+
const { restrictGlobals } = await import("./sandbox-shim");
|
|
244
|
+
const { restore } = restrictGlobals(granted.granted);
|
|
245
|
+
const mod = await import(/* @vite-ignore */ manifest.entry!);
|
|
246
|
+
const entry = mod.default ?? mod;
|
|
247
|
+
if (typeof entry.register !== "function") {
|
|
248
|
+
throw new Error(`Plugin "${manifest.id}" entry has no register() function`);
|
|
249
|
+
}
|
|
250
|
+
try {
|
|
251
|
+
await entry.register(ctx);
|
|
252
|
+
} catch (e) {
|
|
253
|
+
// Plugin never activated — restore the host thread's globals now.
|
|
254
|
+
restore();
|
|
255
|
+
throw e;
|
|
256
|
+
}
|
|
257
|
+
return () => {
|
|
258
|
+
restore();
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
}
|