@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,653 @@
|
|
|
1
|
+
// ============================================================================
|
|
2
|
+
// Plugin manifest — the plugin.json contract for user-authored plugins.
|
|
3
|
+
//
|
|
4
|
+
// A plugin is a runtime-loadable extension authored by an end user / modder
|
|
5
|
+
// (distinct from the compile-time `Module` system). Each plugin ships a
|
|
6
|
+
// `plugin.json` manifest that declares its identity, format, capability tier,
|
|
7
|
+
// requested permissions, target thread, and dependency graph.
|
|
8
|
+
//
|
|
9
|
+
// Validation rules enforce the tier/format/thread/permission matrix described
|
|
10
|
+
// in the plan. Validation is hand-rolled (no zod) to match the existing
|
|
11
|
+
// `validateManifest` style in `../assets/manifest.ts`.
|
|
12
|
+
// ============================================================================
|
|
13
|
+
|
|
14
|
+
/** The four supported plugin formats. */
|
|
15
|
+
export type PluginFormat = "worker-js" | "wasm" | "quickjs" | "asset";
|
|
16
|
+
|
|
17
|
+
/** The three capability tiers. See plan §"Tiered capability surface". */
|
|
18
|
+
export type PluginTier = "data" | "script" | "native";
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Where the plugin's code executes.
|
|
22
|
+
* - `sim` — inside the game's existing sim Web Worker.
|
|
23
|
+
* - `renderer` — in-process on the renderer (main) thread.
|
|
24
|
+
* - `own-worker`— a dedicated Web Worker spawned for this plugin (WASM is
|
|
25
|
+
* always forced to this for crash isolation).
|
|
26
|
+
*/
|
|
27
|
+
export type PluginThread = "sim" | "renderer" | "own-worker";
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Permissions a plugin may request. Each maps to a set of globals/capabilities
|
|
31
|
+
* the sandbox shim keeps (vs. strips) before the plugin code runs. See
|
|
32
|
+
* `permissions.ts` for the global-allowlist mapping.
|
|
33
|
+
*/
|
|
34
|
+
export type PluginPermission =
|
|
35
|
+
| "ecs" // register ECS systems/components (native tier, sim thread)
|
|
36
|
+
| "sab" // allocate SharedArrayBuffer channels
|
|
37
|
+
| "gpu" // register renderer passes / GPU access (native tier, renderer/own-worker)
|
|
38
|
+
| "events" // subscribe/publish on the game event bus
|
|
39
|
+
| "state" // per-plugin KV state store
|
|
40
|
+
| "tick" // register per-frame tick callbacks
|
|
41
|
+
| "storage" // persist plugin state to OPFS
|
|
42
|
+
| "network" // fetch / WebSocket / XMLHttpRequest
|
|
43
|
+
| "log" // structured logging (rate-limited)
|
|
44
|
+
| "physics" // mutate physics bodies via host-call bridge (native tier)
|
|
45
|
+
| "assets"; // resolve + reference asset handles via host-call bridge (native tier)
|
|
46
|
+
|
|
47
|
+
// ── Mod (pack) extension types ──
|
|
48
|
+
//
|
|
49
|
+
// A `mod.json` declares a pack of extensions in addition to (or instead of)
|
|
50
|
+
// the legacy single-format fields. Each extension is declarative data
|
|
51
|
+
// registered by the host; the optional `logic` extension is code (worker-js
|
|
52
|
+
// or wasm) that runs sandboxed and may mutate the game via host calls.
|
|
53
|
+
|
|
54
|
+
/** Logic extension — the code entry of a mod. Either worker-js (TS) or wasm.
|
|
55
|
+
* Not required: a mod can be pure data (assets/shaders/maps/physics). */
|
|
56
|
+
export interface ModLogic {
|
|
57
|
+
/** Code format. `quickjs` is kept for legacy `plugin.json` compat. */
|
|
58
|
+
format: PluginFormat;
|
|
59
|
+
/** Where the code runs. wasm is always forced to `own-worker`. */
|
|
60
|
+
thread: PluginThread;
|
|
61
|
+
/** Entry path relative to the mod dir. */
|
|
62
|
+
entry: string;
|
|
63
|
+
/** Requested permissions (validated against the native-tier set). */
|
|
64
|
+
permissions?: PluginPermission[];
|
|
65
|
+
/** QuickJS-specific config (only valid when `format: "quickjs"`). */
|
|
66
|
+
quickjs?: { instructionBudget?: number };
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/** Asset extension kinds registered into the AssetManager + content catalog. */
|
|
70
|
+
export interface ModAssetExtension {
|
|
71
|
+
kind: "mesh" | "texture" | "pbr-material" | "texture-pipeline";
|
|
72
|
+
/** Logical asset id (namespaced, e.g. "my-mod:crate"). */
|
|
73
|
+
id: string;
|
|
74
|
+
/** Path to the file relative to the mod dir. */
|
|
75
|
+
path: string;
|
|
76
|
+
/** pbr-material: descriptor fields (baseColor, metallic, roughness, texture refs). */
|
|
77
|
+
/** texture-pipeline: pipeline descriptor. Extra fields are pass-through. */
|
|
78
|
+
[key: string]: unknown;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/** Map extension — a JSON scene graph loaded into the MapRegistry. */
|
|
82
|
+
export interface ModMapExtension {
|
|
83
|
+
kind: "map";
|
|
84
|
+
id: string;
|
|
85
|
+
path: string;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/** Physics extension — global physics overrides + material table. */
|
|
89
|
+
export interface ModPhysicsExtension {
|
|
90
|
+
kind: "physics";
|
|
91
|
+
id: string;
|
|
92
|
+
path: string;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/** Postfx shader extension — a custom WGSL fragment effect for the PostProcessStack chain. */
|
|
96
|
+
export interface ModShaderPostfxExtension {
|
|
97
|
+
kind: "shader-postfx";
|
|
98
|
+
/** Effect id (namespaced, e.g. "my-mod:acid"). */
|
|
99
|
+
id: string;
|
|
100
|
+
/** Display name. */
|
|
101
|
+
name: string;
|
|
102
|
+
/** Path to the WGSL fragment shader relative to the mod dir. */
|
|
103
|
+
wgsl: string;
|
|
104
|
+
/** Bind group layout the shader expects. */
|
|
105
|
+
layout: "cc" | "cd" | "cvvh" | "cvd" | "dnfn";
|
|
106
|
+
/** Where in the chain this effect runs. */
|
|
107
|
+
order: "hdr" | "color-grading" | "camera" | "stylized";
|
|
108
|
+
/** Uniform buffer size in bytes (if the shader needs a uniform). */
|
|
109
|
+
uniforms?: number;
|
|
110
|
+
/** User-configurable settings shown in the Mods panel. */
|
|
111
|
+
settings?: ModSetting[];
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/** A user-configurable setting for a mod effect/material. */
|
|
115
|
+
export interface ModSetting {
|
|
116
|
+
/** Setting key — used as the uniform field name. */
|
|
117
|
+
key: string;
|
|
118
|
+
/** Display label. */
|
|
119
|
+
label: string;
|
|
120
|
+
/** Setting type. */
|
|
121
|
+
type: "slider" | "toggle" | "select";
|
|
122
|
+
/** Default value. */
|
|
123
|
+
default: number | boolean | string;
|
|
124
|
+
/** For "slider": min, max, step. */
|
|
125
|
+
min?: number;
|
|
126
|
+
max?: number;
|
|
127
|
+
step?: number;
|
|
128
|
+
/** For "select": available options. */
|
|
129
|
+
options?: Array<{ label: string; value: string }>;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/** Material shader extension — a custom WGSL material for spawned props. */
|
|
133
|
+
export interface ModShaderMaterialExtension {
|
|
134
|
+
kind: "shader-material";
|
|
135
|
+
/** Material id (namespaced, e.g. "my-mod:iridescent"). */
|
|
136
|
+
id: string;
|
|
137
|
+
/** Path to the WGSL material shader relative to the mod dir. */
|
|
138
|
+
wgsl: string;
|
|
139
|
+
/** Uniform buffer size in bytes. */
|
|
140
|
+
uniforms?: number;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/** The bucketed extensions object on a mod.json. All fields optional. */
|
|
144
|
+
export interface ModExtensions {
|
|
145
|
+
/** Asset entries (meshes, textures, PBR materials, texture pipelines). */
|
|
146
|
+
assets?: ModAssetExtension[];
|
|
147
|
+
/** Map scene graphs. */
|
|
148
|
+
maps?: ModMapExtension[];
|
|
149
|
+
/** Physics override descriptors. */
|
|
150
|
+
physics?: ModPhysicsExtension[];
|
|
151
|
+
/** Shader extensions (postfx chain effects + per-prop materials). */
|
|
152
|
+
shaders?: {
|
|
153
|
+
postfx?: ModShaderPostfxExtension[];
|
|
154
|
+
materials?: ModShaderMaterialExtension[];
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/** The buckets an ExtensionLoader can handle. */
|
|
159
|
+
export type ModExtensionBucket =
|
|
160
|
+
| "assets"
|
|
161
|
+
| "maps"
|
|
162
|
+
| "physics"
|
|
163
|
+
| "shader-postfx"
|
|
164
|
+
| "shader-material";
|
|
165
|
+
|
|
166
|
+
/** A flattened extension with its bucket tag, for dispatch. */
|
|
167
|
+
export interface ModExtensionDispatch {
|
|
168
|
+
bucket: ModExtensionBucket;
|
|
169
|
+
extension: Record<string, unknown>;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/** Asset-pack section (only valid when `format: "asset"`). */
|
|
173
|
+
export interface AssetPluginManifest {
|
|
174
|
+
/** Map of logical asset id → file path within the plugin dir. */
|
|
175
|
+
files: Record<string, string>;
|
|
176
|
+
/** Optional: textures to register into the AssetManager texture catalog. */
|
|
177
|
+
textures?: string[];
|
|
178
|
+
/** Optional: audio files to register into the audio loader. */
|
|
179
|
+
audio?: string[];
|
|
180
|
+
/** Optional: mesh/model files (glb/gltf) to register. */
|
|
181
|
+
meshes?: string[];
|
|
182
|
+
/** Optional: arbitrary JSON data files exposed to game code. */
|
|
183
|
+
data?: string[];
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/** The full `plugin.json` manifest. */
|
|
187
|
+
export interface PluginManifest {
|
|
188
|
+
/** Unique plugin id, kebab-case (e.g. "overburden-bronze-blocks"). */
|
|
189
|
+
id: string;
|
|
190
|
+
/** Human-readable display name. */
|
|
191
|
+
name: string;
|
|
192
|
+
/** Semver version string. */
|
|
193
|
+
version: string;
|
|
194
|
+
/** Author string. */
|
|
195
|
+
author?: string;
|
|
196
|
+
/** Short description. */
|
|
197
|
+
description?: string;
|
|
198
|
+
/** Semver range against the engine version (e.g. "^0.1.0"). Required. */
|
|
199
|
+
engineVersion: string;
|
|
200
|
+
/** Target game appId (e.g. "overburden"). Required so a plugin can't load into the wrong game. */
|
|
201
|
+
game: string;
|
|
202
|
+
/** Plugin format. */
|
|
203
|
+
format: PluginFormat;
|
|
204
|
+
/** Capability tier. */
|
|
205
|
+
tier: PluginTier;
|
|
206
|
+
/** Target thread. WASM is always forced to `own-worker`. */
|
|
207
|
+
thread: PluginThread;
|
|
208
|
+
/** Entry path relative to the plugin dir. Forbidden for `data` tier. */
|
|
209
|
+
entry?: string;
|
|
210
|
+
/** Requested permissions. Validated against the tier's allowed set. */
|
|
211
|
+
permissions?: PluginPermission[];
|
|
212
|
+
/** Stringly-typed plugin resource keys this plugin provides (namespace `game:kind/name`). */
|
|
213
|
+
provides?: string[];
|
|
214
|
+
/** Stringly-typed plugin resource keys this plugin requires. */
|
|
215
|
+
requires?: string[];
|
|
216
|
+
/** Other plugin ids (with optional `@version`) this plugin depends on. */
|
|
217
|
+
dependencies?: string[];
|
|
218
|
+
/** Asset section — only valid when `format: "asset"`. */
|
|
219
|
+
assets?: AssetPluginManifest;
|
|
220
|
+
/** QuickJS-specific config. Only valid when `format: "quickjs"`. */
|
|
221
|
+
quickjs?: {
|
|
222
|
+
/** Max instructions per eval/tick before the interrupt handler fires.
|
|
223
|
+
* Default: 1,000,000. */
|
|
224
|
+
instructionBudget?: number;
|
|
225
|
+
};
|
|
226
|
+
// ── Mod (pack) fields ──
|
|
227
|
+
/** Logic extension (code entry). Mutually exclusive with the legacy
|
|
228
|
+
* single-format shape: a mod.json uses `logic` + `extensions`; a legacy
|
|
229
|
+
* plugin.json uses `format`/`tier`/`thread`/`entry`/`assets`. The
|
|
230
|
+
* normalizer populates `logic` from the legacy fields so both work. */
|
|
231
|
+
logic?: ModLogic;
|
|
232
|
+
/** Declarative extensions (assets, maps, physics, shaders). */
|
|
233
|
+
extensions?: ModExtensions;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/** Result of manifest validation. */
|
|
237
|
+
export interface PluginManifestValidation {
|
|
238
|
+
valid: boolean;
|
|
239
|
+
errors: string[];
|
|
240
|
+
/** A normalized copy of the manifest with host-enforced rewrites applied
|
|
241
|
+
* (e.g. `thread: own-worker` for wasm). Only present when valid. */
|
|
242
|
+
normalized?: PluginManifest;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
// ── Permission sets per tier (single source of truth; permissions.ts mirrors) ──
|
|
246
|
+
|
|
247
|
+
const SCRIPT_ALLOWED: ReadonlySet<PluginPermission> = new Set([
|
|
248
|
+
"events",
|
|
249
|
+
"state",
|
|
250
|
+
"tick",
|
|
251
|
+
"storage",
|
|
252
|
+
"log",
|
|
253
|
+
]);
|
|
254
|
+
|
|
255
|
+
const NATIVE_ALLOWED: ReadonlySet<PluginPermission> = new Set([
|
|
256
|
+
"ecs",
|
|
257
|
+
"sab",
|
|
258
|
+
"gpu",
|
|
259
|
+
"events",
|
|
260
|
+
"state",
|
|
261
|
+
"tick",
|
|
262
|
+
"storage",
|
|
263
|
+
"network",
|
|
264
|
+
"log",
|
|
265
|
+
"physics",
|
|
266
|
+
"assets",
|
|
267
|
+
]);
|
|
268
|
+
|
|
269
|
+
// ── Helpers ──
|
|
270
|
+
|
|
271
|
+
const KEBAB_RE = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
|
|
272
|
+
|
|
273
|
+
// Minimal semver range check: accepts "^1.2.3", "~1.2.3", "1.2.3", ">=1.0.0",
|
|
274
|
+
// "*", "x". Not a full semver implementation — good enough to reject garbage.
|
|
275
|
+
const SEMVER_RANGE_RE = /^(\^|~|>=?|=)?\s*(\d+|x|X)(?:\.(\d+|x|X))?(?:\.(\d+|x|X))?(?:[-+].+)?$/;
|
|
276
|
+
const SEMVER_PLAIN_RE = /^\d+\.\d+\.\d+(?:[-+].+)?$/;
|
|
277
|
+
|
|
278
|
+
function isSemverRange(s: string): boolean {
|
|
279
|
+
return s === "*" || SEMVER_RANGE_RE.test(s);
|
|
280
|
+
}
|
|
281
|
+
function isSemverPlain(s: string): boolean {
|
|
282
|
+
return SEMVER_PLAIN_RE.test(s);
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
/** Validate a plugin manifest. Returns a list of errors (empty if valid). */
|
|
286
|
+
export function validatePluginManifest(raw: unknown): PluginManifestValidation {
|
|
287
|
+
const errors: string[] = [];
|
|
288
|
+
if (!raw || typeof raw !== "object") {
|
|
289
|
+
return { valid: false, errors: ["manifest must be a JSON object"] };
|
|
290
|
+
}
|
|
291
|
+
const m = raw as Record<string, unknown>;
|
|
292
|
+
|
|
293
|
+
// Required string fields
|
|
294
|
+
if (typeof m.id !== "string" || !m.id) {
|
|
295
|
+
errors.push("id: required string (kebab-case)");
|
|
296
|
+
} else if (!KEBAB_RE.test(m.id)) {
|
|
297
|
+
errors.push(`id: "${m.id}" must be kebab-case (lowercase, hyphen-separated)`);
|
|
298
|
+
}
|
|
299
|
+
if (typeof m.name !== "string" || !m.name) errors.push("name: required string");
|
|
300
|
+
if (typeof m.version !== "string" || !isSemverPlain(m.version)) {
|
|
301
|
+
errors.push(`version: required semver (e.g. "1.0.0"), got "${m.version}"`);
|
|
302
|
+
}
|
|
303
|
+
if (typeof m.engineVersion !== "string" || !isSemverRange(m.engineVersion)) {
|
|
304
|
+
errors.push(`engineVersion: required semver range (e.g. "^0.1.0"), got "${m.engineVersion}"`);
|
|
305
|
+
}
|
|
306
|
+
if (typeof m.game !== "string" || !m.game) {
|
|
307
|
+
errors.push("game: required string (target game appId)");
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
// format
|
|
311
|
+
const format = m.format;
|
|
312
|
+
const VALID_FORMATS: PluginFormat[] = ["worker-js", "wasm", "quickjs", "asset"];
|
|
313
|
+
if (typeof format !== "string" || !VALID_FORMATS.includes(format as PluginFormat)) {
|
|
314
|
+
errors.push(`format: required one of ${VALID_FORMATS.join("|")}, got "${format}"`);
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
// tier
|
|
318
|
+
const tier = m.tier;
|
|
319
|
+
const VALID_TIERS: PluginTier[] = ["data", "script", "native"];
|
|
320
|
+
if (typeof tier !== "string" || !VALID_TIERS.includes(tier as PluginTier)) {
|
|
321
|
+
errors.push(`tier: required one of ${VALID_TIERS.join("|")}, got "${tier}"`);
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
// thread
|
|
325
|
+
const thread = m.thread;
|
|
326
|
+
const VALID_THREADS: PluginThread[] = ["sim", "renderer", "own-worker"];
|
|
327
|
+
if (typeof thread !== "string" || !VALID_THREADS.includes(thread as PluginThread)) {
|
|
328
|
+
errors.push(`thread: required one of ${VALID_THREADS.join("|")}, got "${thread}"`);
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
// permissions
|
|
332
|
+
const perms = m.permissions;
|
|
333
|
+
let permList: PluginPermission[] = [];
|
|
334
|
+
if (perms !== undefined) {
|
|
335
|
+
if (!Array.isArray(perms) || !perms.every((p) => typeof p === "string")) {
|
|
336
|
+
errors.push("permissions: must be an array of strings");
|
|
337
|
+
} else {
|
|
338
|
+
permList = perms as PluginPermission[];
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
// entry
|
|
343
|
+
if (m.entry !== undefined && typeof m.entry !== "string") {
|
|
344
|
+
errors.push("entry: must be a string path");
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
// provides / requires / dependencies
|
|
348
|
+
(["provides", "requires", "dependencies"] as const).forEach((field) => {
|
|
349
|
+
const v = m[field];
|
|
350
|
+
if (v !== undefined && (!Array.isArray(v) || !v.every((x) => typeof x === "string"))) {
|
|
351
|
+
errors.push(`${field}: must be an array of strings`);
|
|
352
|
+
}
|
|
353
|
+
});
|
|
354
|
+
|
|
355
|
+
// assets
|
|
356
|
+
if (m.assets !== undefined) {
|
|
357
|
+
if (typeof m.assets !== "object") {
|
|
358
|
+
errors.push("assets: must be an object");
|
|
359
|
+
} else {
|
|
360
|
+
const a = m.assets as Record<string, unknown>;
|
|
361
|
+
if (typeof a.files !== "object" || a.files === null) {
|
|
362
|
+
errors.push("assets.files: required object (asset id → path)");
|
|
363
|
+
} else {
|
|
364
|
+
for (const [k, v] of Object.entries(a.files)) {
|
|
365
|
+
if (typeof v !== "string") errors.push(`assets.files["${k}"]: must be a string path`);
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
(["textures", "audio", "meshes", "data"] as const).forEach((sub) => {
|
|
369
|
+
if (a[sub] !== undefined && (!Array.isArray(a[sub]) || !a[sub].every((x) => typeof x === "string"))) {
|
|
370
|
+
errors.push(`assets.${sub}: must be an array of strings`);
|
|
371
|
+
}
|
|
372
|
+
});
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
// ── Mod (pack) fields: logic + extensions ──
|
|
377
|
+
if (m.logic !== undefined) {
|
|
378
|
+
validateModLogic(m.logic as Record<string, unknown>, errors);
|
|
379
|
+
}
|
|
380
|
+
if (m.extensions !== undefined) {
|
|
381
|
+
validateModExtensions(m.extensions as Record<string, unknown>, errors);
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
// ── Cross-field rules (only run if basic shape is OK) ──
|
|
385
|
+
if (errors.length === 0) {
|
|
386
|
+
const t = tier as PluginTier;
|
|
387
|
+
const f = format as PluginFormat;
|
|
388
|
+
let th = thread as PluginThread;
|
|
389
|
+
const logic = m.logic as { entry?: unknown; permissions?: unknown; format?: unknown; thread?: unknown } | undefined;
|
|
390
|
+
const hasLogic = !!logic;
|
|
391
|
+
// When logic is present, the entry lives on logic.entry and permissions
|
|
392
|
+
// on logic.permissions; the top-level entry/permissions may be omitted.
|
|
393
|
+
const effectiveEntry = m.entry ?? logic?.entry;
|
|
394
|
+
const effectivePerms = (logic?.permissions as PluginPermission[] | undefined) ?? permList;
|
|
395
|
+
|
|
396
|
+
// wasm always own-worker (check both top-level and logic thread)
|
|
397
|
+
if (f === "wasm" && th !== "own-worker") {
|
|
398
|
+
errors.push(`format "wasm" must use thread "own-worker" (got "${th}") — host will force it`);
|
|
399
|
+
}
|
|
400
|
+
if (hasLogic && logic!.format === "wasm" && logic!.thread !== "own-worker") {
|
|
401
|
+
errors.push(`logic.format "wasm" must use thread "own-worker" (got "${logic!.thread}") — host will force it`);
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
// data tier ⇒ format asset, no perms, no entry, no logic
|
|
405
|
+
if (t === "data") {
|
|
406
|
+
if (f !== "asset") {
|
|
407
|
+
errors.push(`tier "data" requires format "asset" (got "${f}")`);
|
|
408
|
+
}
|
|
409
|
+
if (effectivePerms.length > 0) {
|
|
410
|
+
errors.push(`tier "data" must not request permissions (got [${effectivePerms.join(", ")}])`);
|
|
411
|
+
}
|
|
412
|
+
if (effectiveEntry !== undefined) {
|
|
413
|
+
errors.push(`tier "data" must not declare an entry (got "${effectiveEntry}")`);
|
|
414
|
+
}
|
|
415
|
+
if (hasLogic) {
|
|
416
|
+
errors.push(`tier "data" must not declare a "logic" extension`);
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
// asset format ⇒ data tier
|
|
421
|
+
if (f === "asset" && t !== "data") {
|
|
422
|
+
errors.push(`format "asset" requires tier "data" (got "${t}")`);
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
// script tier permissions subset
|
|
426
|
+
if (t === "script") {
|
|
427
|
+
const bad = effectivePerms.filter((p) => !SCRIPT_ALLOWED.has(p));
|
|
428
|
+
if (bad.length > 0) {
|
|
429
|
+
errors.push(
|
|
430
|
+
`tier "script" allows only [${[...SCRIPT_ALLOWED].join(", ")}] — disallowed: [${bad.join(", ")}]`,
|
|
431
|
+
);
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
// native tier: any permission allowed but must be explicit (no implicit grant).
|
|
436
|
+
// (Nothing to enforce here beyond "must be a known permission", already checked.)
|
|
437
|
+
if (t === "native") {
|
|
438
|
+
const bad = effectivePerms.filter((p) => !NATIVE_ALLOWED.has(p));
|
|
439
|
+
if (bad.length > 0) {
|
|
440
|
+
errors.push(`tier "native" disallows unknown permissions: [${bad.join(", ")}]`);
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
// code-bearing formats require an entry (top-level OR logic.entry)
|
|
445
|
+
if ((f === "worker-js" || f === "wasm" || f === "quickjs") && effectiveEntry === undefined) {
|
|
446
|
+
errors.push(`format "${f}" requires an "entry" path`);
|
|
447
|
+
}
|
|
448
|
+
// asset format: entry forbidden, assets OR extensions required
|
|
449
|
+
if (f === "asset") {
|
|
450
|
+
if (effectiveEntry !== undefined) errors.push(`format "asset" must not declare an entry`);
|
|
451
|
+
if (!m.assets && !m.extensions) errors.push(`format "asset" requires an "assets" section or "extensions"`);
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
if (errors.length > 0) return { valid: false, errors };
|
|
456
|
+
|
|
457
|
+
// ── Normalize ──
|
|
458
|
+
const normalized: PluginManifest = { ...(raw as PluginManifest) };
|
|
459
|
+
if (normalized.format === "wasm") normalized.thread = "own-worker";
|
|
460
|
+
// Populate logic + extensions from legacy fields if not already set, so the
|
|
461
|
+
// host's extension dispatch works for both mod.json and legacy plugin.json.
|
|
462
|
+
normalizeLogicAndExtensions(normalized);
|
|
463
|
+
return { valid: true, errors: [], normalized };
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
// ── Mod logic validation ──
|
|
467
|
+
|
|
468
|
+
function validateModLogic(l: Record<string, unknown>, errors: string[]): void {
|
|
469
|
+
const VALID_LOGIC_FORMATS: PluginFormat[] = ["worker-js", "wasm", "quickjs"];
|
|
470
|
+
if (typeof l.format !== "string" || !VALID_LOGIC_FORMATS.includes(l.format as PluginFormat)) {
|
|
471
|
+
errors.push(`logic.format: required one of ${VALID_LOGIC_FORMATS.join("|")}, got "${l.format}"`);
|
|
472
|
+
}
|
|
473
|
+
const VALID_THREADS: PluginThread[] = ["sim", "renderer", "own-worker"];
|
|
474
|
+
if (typeof l.thread !== "string" || !VALID_THREADS.includes(l.thread as PluginThread)) {
|
|
475
|
+
errors.push(`logic.thread: required one of ${VALID_THREADS.join("|")}, got "${l.thread}"`);
|
|
476
|
+
}
|
|
477
|
+
if (typeof l.entry !== "string" || !l.entry) {
|
|
478
|
+
errors.push(`logic.entry: required string path, got "${l.entry}"`);
|
|
479
|
+
}
|
|
480
|
+
if (l.permissions !== undefined) {
|
|
481
|
+
if (!Array.isArray(l.permissions) || !l.permissions.every((p) => typeof p === "string")) {
|
|
482
|
+
errors.push("logic.permissions: must be an array of strings");
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
// ── Mod extensions validation ──
|
|
488
|
+
|
|
489
|
+
function validateModExtensions(e: Record<string, unknown>, errors: string[]): void {
|
|
490
|
+
if (typeof e !== "object" || e === null) {
|
|
491
|
+
errors.push("extensions: must be an object");
|
|
492
|
+
return;
|
|
493
|
+
}
|
|
494
|
+
if (e.assets !== undefined) {
|
|
495
|
+
if (!Array.isArray(e.assets)) {
|
|
496
|
+
errors.push("extensions.assets: must be an array");
|
|
497
|
+
} else {
|
|
498
|
+
e.assets.forEach((a, i) => validateAssetExtension(a, i, errors));
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
if (e.maps !== undefined) {
|
|
502
|
+
if (!Array.isArray(e.maps)) {
|
|
503
|
+
errors.push("extensions.maps: must be an array");
|
|
504
|
+
} else {
|
|
505
|
+
e.maps.forEach((mp, i) => {
|
|
506
|
+
if (!mp || typeof mp !== "object") return errors.push(`extensions.maps[${i}]: must be an object`);
|
|
507
|
+
if (typeof mp.id !== "string") errors.push(`extensions.maps[${i}].id: required string`);
|
|
508
|
+
if (typeof mp.path !== "string") errors.push(`extensions.maps[${i}].path: required string`);
|
|
509
|
+
});
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
if (e.physics !== undefined) {
|
|
513
|
+
if (!Array.isArray(e.physics)) {
|
|
514
|
+
errors.push("extensions.physics: must be an array");
|
|
515
|
+
} else {
|
|
516
|
+
e.physics.forEach((p, i) => {
|
|
517
|
+
if (!p || typeof p !== "object") return errors.push(`extensions.physics[${i}]: must be an object`);
|
|
518
|
+
if (typeof p.id !== "string") errors.push(`extensions.physics[${i}].id: required string`);
|
|
519
|
+
if (typeof p.path !== "string") errors.push(`extensions.physics[${i}].path: required string`);
|
|
520
|
+
});
|
|
521
|
+
}
|
|
522
|
+
}
|
|
523
|
+
if (e.shaders !== undefined) {
|
|
524
|
+
if (typeof e.shaders !== "object" || e.shaders === null) {
|
|
525
|
+
errors.push("extensions.shaders: must be an object");
|
|
526
|
+
} else {
|
|
527
|
+
const s = e.shaders as Record<string, unknown>;
|
|
528
|
+
if (s.postfx !== undefined) {
|
|
529
|
+
if (!Array.isArray(s.postfx)) {
|
|
530
|
+
errors.push("extensions.shaders.postfx: must be an array");
|
|
531
|
+
} else {
|
|
532
|
+
s.postfx.forEach((fx, i) => validatePostfxExtension(fx, i, errors));
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
if (s.materials !== undefined) {
|
|
536
|
+
if (!Array.isArray(s.materials)) {
|
|
537
|
+
errors.push("extensions.shaders.materials: must be an array");
|
|
538
|
+
} else {
|
|
539
|
+
s.materials.forEach((mat, i) => {
|
|
540
|
+
if (!mat || typeof mat !== "object") return errors.push(`extensions.shaders.materials[${i}]: must be an object`);
|
|
541
|
+
if (typeof mat.id !== "string") errors.push(`extensions.shaders.materials[${i}].id: required string`);
|
|
542
|
+
if (typeof mat.wgsl !== "string") errors.push(`extensions.shaders.materials[${i}].wgsl: required string path`);
|
|
543
|
+
if (mat.uniforms !== undefined && typeof mat.uniforms !== "number") errors.push(`extensions.shaders.materials[${i}].uniforms: must be a number`);
|
|
544
|
+
});
|
|
545
|
+
}
|
|
546
|
+
}
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
function validateAssetExtension(a: unknown, i: number, errors: string[]): void {
|
|
552
|
+
if (!a || typeof a !== "object") {
|
|
553
|
+
errors.push(`extensions.assets[${i}]: must be an object`);
|
|
554
|
+
return;
|
|
555
|
+
}
|
|
556
|
+
const ext = a as Record<string, unknown>;
|
|
557
|
+
const VALID_KINDS = ["mesh", "texture", "pbr-material", "texture-pipeline"];
|
|
558
|
+
if (typeof ext.kind !== "string" || !VALID_KINDS.includes(ext.kind)) {
|
|
559
|
+
errors.push(`extensions.assets[${i}].kind: required one of ${VALID_KINDS.join("|")}, got "${ext.kind}"`);
|
|
560
|
+
}
|
|
561
|
+
if (typeof ext.id !== "string" || !ext.id) {
|
|
562
|
+
errors.push(`extensions.assets[${i}].id: required string`);
|
|
563
|
+
}
|
|
564
|
+
if (typeof ext.path !== "string" || !ext.path) {
|
|
565
|
+
errors.push(`extensions.assets[${i}].path: required string`);
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
function validatePostfxExtension(fx: unknown, i: number, errors: string[]): void {
|
|
570
|
+
if (!fx || typeof fx !== "object") {
|
|
571
|
+
errors.push(`extensions.shaders.postfx[${i}]: must be an object`);
|
|
572
|
+
return;
|
|
573
|
+
}
|
|
574
|
+
const ext = fx as Record<string, unknown>;
|
|
575
|
+
if (typeof ext.id !== "string" || !ext.id) errors.push(`extensions.shaders.postfx[${i}].id: required string`);
|
|
576
|
+
if (typeof ext.name !== "string") errors.push(`extensions.shaders.postfx[${i}].name: required string`);
|
|
577
|
+
if (typeof ext.wgsl !== "string") errors.push(`extensions.shaders.postfx[${i}].wgsl: required string path`);
|
|
578
|
+
const VALID_LAYOUTS = ["cc", "cd", "cvvh", "cvd", "dnfn"];
|
|
579
|
+
if (typeof ext.layout !== "string" || !VALID_LAYOUTS.includes(ext.layout)) {
|
|
580
|
+
errors.push(`extensions.shaders.postfx[${i}].layout: required one of ${VALID_LAYOUTS.join("|")}, got "${ext.layout}"`);
|
|
581
|
+
}
|
|
582
|
+
const VALID_ORDERS = ["hdr", "color-grading", "camera", "stylized"];
|
|
583
|
+
if (typeof ext.order !== "string" || !VALID_ORDERS.includes(ext.order)) {
|
|
584
|
+
errors.push(`extensions.shaders.postfx[${i}].order: required one of ${VALID_ORDERS.join("|")}, got "${ext.order}"`);
|
|
585
|
+
}
|
|
586
|
+
if (ext.uniforms !== undefined && typeof ext.uniforms !== "number") {
|
|
587
|
+
errors.push(`extensions.shaders.postfx[${i}].uniforms: must be a number`);
|
|
588
|
+
}
|
|
589
|
+
}
|
|
590
|
+
|
|
591
|
+
// ── Normalizer: populate logic + extensions from legacy plugin.json fields ──
|
|
592
|
+
//
|
|
593
|
+
// A legacy plugin.json uses `format`/`tier`/`thread`/`entry`/`permissions`/
|
|
594
|
+
// `assets`. A mod.json uses `logic`/`extensions`. This populates whichever is
|
|
595
|
+
// missing so the host's extension dispatch works uniformly for both shapes.
|
|
596
|
+
// The legacy fields are preserved (existing loaders still read them).
|
|
597
|
+
|
|
598
|
+
function normalizeLogicAndExtensions(m: PluginManifest): void {
|
|
599
|
+
// When logic is present, ensure the top-level format/thread/entry/permissions
|
|
600
|
+
// mirror it (so legacy loaders that read m.format / m.entry keep working).
|
|
601
|
+
if (m.logic) {
|
|
602
|
+
if (!m.format) m.format = m.logic.format;
|
|
603
|
+
if (!m.thread) m.thread = m.logic.thread;
|
|
604
|
+
if (!m.entry) m.entry = m.logic.entry;
|
|
605
|
+
if (!m.permissions && m.logic.permissions) m.permissions = m.logic.permissions;
|
|
606
|
+
if (m.logic.format === "wasm") m.thread = "own-worker";
|
|
607
|
+
}
|
|
608
|
+
// Populate `logic` from legacy fields when not already present and the
|
|
609
|
+
// manifest is a code-bearing format.
|
|
610
|
+
if (!m.logic && m.format && m.format !== "asset" && m.entry) {
|
|
611
|
+
m.logic = {
|
|
612
|
+
format: m.format,
|
|
613
|
+
thread: m.thread,
|
|
614
|
+
entry: m.entry,
|
|
615
|
+
permissions: m.permissions,
|
|
616
|
+
...(m.quickjs ? { quickjs: m.quickjs } : {}),
|
|
617
|
+
};
|
|
618
|
+
}
|
|
619
|
+
// Populate `extensions.assets` from the legacy `assets` section when not
|
|
620
|
+
// already present (data-tier asset plugins).
|
|
621
|
+
if (!m.extensions && m.assets) {
|
|
622
|
+
const assets: ModAssetExtension[] = [];
|
|
623
|
+
(m.assets.meshes ?? []).forEach((meshPath) => {
|
|
624
|
+
assets.push({ kind: "mesh", id: meshPath, path: meshPath });
|
|
625
|
+
});
|
|
626
|
+
(m.assets.textures ?? []).forEach((texPath) => {
|
|
627
|
+
assets.push({ kind: "texture", id: texPath, path: texPath });
|
|
628
|
+
});
|
|
629
|
+
(m.assets.data ?? []).forEach((dataPath) => {
|
|
630
|
+
// Legacy data files are registered as textures of kind "texture" only if
|
|
631
|
+
// they're image files; otherwise they're opaque data. Keep them as
|
|
632
|
+
// texture-kind entries with the data path so the asset loader can
|
|
633
|
+
// dispatch by extension.
|
|
634
|
+
assets.push({ kind: "texture", id: dataPath, path: dataPath });
|
|
635
|
+
});
|
|
636
|
+
if (assets.length > 0) m.extensions = { assets };
|
|
637
|
+
}
|
|
638
|
+
}
|
|
639
|
+
|
|
640
|
+
/** Flatten a manifest's extensions into a dispatch list (bucket + extension).
|
|
641
|
+
* Returns extensions in a stable order: assets, maps, physics, shader-postfx,
|
|
642
|
+
* shader-material. Used by the host to drive ExtensionLoaders. */
|
|
643
|
+
export function flattenExtensions(m: PluginManifest): ModExtensionDispatch[] {
|
|
644
|
+
const out: ModExtensionDispatch[] = [];
|
|
645
|
+
const ext = m.extensions;
|
|
646
|
+
if (!ext) return out;
|
|
647
|
+
(ext.assets ?? []).forEach((a) => { out.push({ bucket: "assets", extension: a as unknown as Record<string, unknown> });; });
|
|
648
|
+
(ext.maps ?? []).forEach((mp) => { out.push({ bucket: "maps", extension: mp as unknown as Record<string, unknown> });; });
|
|
649
|
+
(ext.physics ?? []).forEach((p) => { out.push({ bucket: "physics", extension: p as unknown as Record<string, unknown> });; });
|
|
650
|
+
(ext.shaders?.postfx ?? []).forEach((fx) => { out.push({ bucket: "shader-postfx", extension: fx as unknown as Record<string, unknown> });; });
|
|
651
|
+
(ext.shaders?.materials ?? []).forEach((mat) => { out.push({ bucket: "shader-material", extension: mat as unknown as Record<string, unknown> });; });
|
|
652
|
+
return out;
|
|
653
|
+
}
|