@vgai/engine 0.5.4 → 0.5.6
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/dist/adapter/adapter-surface.d.ts +30 -0
- package/dist/adapter/adapter-surface.d.ts.map +1 -0
- package/dist/adapter/adapter-surface.js +18 -0
- package/dist/adapter/authoring.d.ts +597 -0
- package/dist/adapter/authoring.d.ts.map +1 -0
- package/dist/adapter/authoring.js +22 -0
- package/dist/adapter/colyseus-networking-adapter.d.ts +77 -0
- package/dist/adapter/colyseus-networking-adapter.d.ts.map +1 -0
- package/dist/adapter/colyseus-networking-adapter.js +76 -0
- package/dist/adapter/first-party-systems.d.ts +23 -0
- package/dist/adapter/first-party-systems.d.ts.map +1 -0
- package/dist/adapter/first-party-systems.js +196 -0
- package/dist/adapter/host-context.d.ts +194 -0
- package/dist/adapter/host-context.d.ts.map +1 -0
- package/dist/adapter/host-context.js +80 -0
- package/dist/adapter/index.d.ts +33 -0
- package/dist/adapter/index.d.ts.map +1 -0
- package/dist/adapter/index.js +25 -0
- package/dist/adapter/ingest/game-contract.d.ts +53 -0
- package/dist/adapter/ingest/game-contract.d.ts.map +1 -0
- package/dist/adapter/ingest/game-contract.js +30 -0
- package/dist/adapter/ingest/scene-capture.d.ts +121 -0
- package/dist/adapter/ingest/scene-capture.d.ts.map +1 -0
- package/dist/adapter/ingest/scene-capture.js +270 -0
- package/dist/adapter/ingest/structural-ids.d.ts +64 -0
- package/dist/adapter/ingest/structural-ids.d.ts.map +1 -0
- package/dist/adapter/ingest/structural-ids.js +110 -0
- package/dist/adapter/ingest/upstream-pin.d.ts +44 -0
- package/dist/adapter/ingest/upstream-pin.d.ts.map +1 -0
- package/dist/adapter/ingest/upstream-pin.js +47 -0
- package/dist/adapter/loop-gate-report.d.ts +34 -0
- package/dist/adapter/loop-gate-report.d.ts.map +1 -0
- package/dist/adapter/loop-gate-report.js +37 -0
- package/dist/adapter/rapier-physics-adapter.d.ts +69 -0
- package/dist/adapter/rapier-physics-adapter.d.ts.map +1 -0
- package/dist/adapter/rapier-physics-adapter.js +135 -0
- package/dist/adapter/root-adapter.d.ts +195 -0
- package/dist/adapter/root-adapter.d.ts.map +1 -0
- package/dist/adapter/root-adapter.js +25 -0
- package/dist/adapter/setup-three-root-adapter.d.ts +87 -0
- package/dist/adapter/setup-three-root-adapter.d.ts.map +1 -0
- package/dist/adapter/setup-three-root-adapter.js +791 -0
- package/dist/adapter/system-adapter.d.ts +453 -0
- package/dist/adapter/system-adapter.d.ts.map +1 -0
- package/dist/adapter/system-adapter.js +13 -0
- package/dist/adapter/transform.d.ts +18 -0
- package/dist/adapter/transform.d.ts.map +1 -0
- package/dist/adapter/transform.js +1 -0
- package/dist/ai/navigation.d.ts +78 -0
- package/dist/ai/navigation.d.ts.map +1 -0
- package/dist/ai/navigation.js +152 -0
- package/dist/animation/anim-graph-types.d.ts +25 -0
- package/dist/animation/anim-graph-types.d.ts.map +1 -0
- package/dist/animation/anim-graph-types.js +1 -0
- package/dist/animation/animation-clock.d.ts +213 -0
- package/dist/animation/animation-clock.d.ts.map +1 -0
- package/dist/animation/animation-clock.js +301 -0
- package/dist/animation/blend-node.d.ts +22 -0
- package/dist/animation/blend-node.d.ts.map +1 -0
- package/dist/animation/blend-node.js +97 -0
- package/dist/animation/camera-ownership.d.ts +249 -0
- package/dist/animation/camera-ownership.d.ts.map +1 -0
- package/dist/animation/camera-ownership.js +169 -0
- package/dist/animation/cinematic-cues.d.ts +200 -0
- package/dist/animation/cinematic-cues.d.ts.map +1 -0
- package/dist/animation/cinematic-cues.js +213 -0
- package/dist/animation/clip-map.d.ts +12 -0
- package/dist/animation/clip-map.d.ts.map +1 -0
- package/dist/animation/clip-map.js +31 -0
- package/dist/animation/cubic-spline-interpolant.d.ts +54 -0
- package/dist/animation/cubic-spline-interpolant.d.ts.map +1 -0
- package/dist/animation/cubic-spline-interpolant.js +111 -0
- package/dist/animation/theatre-clock-binding.d.ts +89 -0
- package/dist/animation/theatre-clock-binding.d.ts.map +1 -0
- package/dist/animation/theatre-clock-binding.js +29 -0
- package/dist/animation/theatre-director.d.ts +277 -0
- package/dist/animation/theatre-director.d.ts.map +1 -0
- package/dist/animation/theatre-director.js +248 -0
- package/dist/animation/theatre-object-binding.d.ts +305 -0
- package/dist/animation/theatre-object-binding.d.ts.map +1 -0
- package/dist/animation/theatre-object-binding.js +351 -0
- package/dist/animation/xstate-animation-binding.d.ts +119 -0
- package/dist/animation/xstate-animation-binding.d.ts.map +1 -0
- package/dist/animation/xstate-animation-binding.js +349 -0
- package/dist/animation/xstate-animation-meta.d.ts +266 -0
- package/dist/animation/xstate-animation-meta.d.ts.map +1 -0
- package/dist/animation/xstate-animation-meta.js +252 -0
- package/dist/asset-formats/camera.d.ts +15 -0
- package/dist/asset-formats/camera.d.ts.map +1 -0
- package/dist/asset-formats/camera.js +15 -0
- package/dist/asset-formats/collider.d.ts +21 -0
- package/dist/asset-formats/collider.d.ts.map +1 -0
- package/dist/asset-formats/collider.js +53 -0
- package/dist/asset-formats/index.d.ts +46 -0
- package/dist/asset-formats/index.d.ts.map +1 -0
- package/dist/asset-formats/index.js +36 -0
- package/dist/asset-formats/instances.d.ts +17 -0
- package/dist/asset-formats/instances.d.ts.map +1 -0
- package/dist/asset-formats/instances.js +31 -0
- package/dist/asset-formats/light.d.ts +21 -0
- package/dist/asset-formats/light.d.ts.map +1 -0
- package/dist/asset-formats/light.js +35 -0
- package/dist/asset-formats/material.d.ts +129 -0
- package/dist/asset-formats/material.d.ts.map +1 -0
- package/dist/asset-formats/material.js +88 -0
- package/dist/asset-formats/mesh.d.ts +22 -0
- package/dist/asset-formats/mesh.d.ts.map +1 -0
- package/dist/asset-formats/mesh.js +64 -0
- package/dist/asset-formats/parse.d.ts +20 -0
- package/dist/asset-formats/parse.d.ts.map +1 -0
- package/dist/asset-formats/parse.js +34 -0
- package/dist/asset-formats/particles.d.ts +1390 -0
- package/dist/asset-formats/particles.d.ts.map +1 -0
- package/dist/asset-formats/particles.js +319 -0
- package/dist/asset-formats/render-env.d.ts +387 -0
- package/dist/asset-formats/render-env.d.ts.map +1 -0
- package/dist/asset-formats/render-env.js +300 -0
- package/dist/asset-formats/tuples.d.ts +12 -0
- package/dist/asset-formats/tuples.d.ts.map +1 -0
- package/dist/asset-formats/tuples.js +14 -0
- package/dist/asset-loaders.d.ts +97 -0
- package/dist/asset-loaders.d.ts.map +1 -0
- package/dist/asset-loaders.js +209 -0
- package/dist/asset-parse-error.d.ts +24 -0
- package/dist/asset-parse-error.d.ts.map +1 -0
- package/dist/asset-parse-error.js +29 -0
- package/dist/asset-registry.d.ts +38 -0
- package/dist/asset-registry.d.ts.map +1 -0
- package/dist/asset-registry.js +66 -0
- package/dist/assets.d.ts +26 -0
- package/dist/assets.d.ts.map +1 -0
- package/dist/assets.js +55 -0
- package/dist/audio/wav-encode.d.ts +38 -0
- package/dist/audio/wav-encode.d.ts.map +1 -0
- package/dist/audio/wav-encode.js +97 -0
- package/dist/canvas-react/engine-bridge.d.ts +45 -0
- package/dist/canvas-react/engine-bridge.d.ts.map +1 -0
- package/dist/canvas-react/engine-bridge.js +45 -0
- package/dist/canvas-react/index.d.ts +42 -0
- package/dist/canvas-react/index.d.ts.map +1 -0
- package/dist/canvas-react/index.js +41 -0
- package/dist/canvas-react/pixi-primitive.d.ts +85 -0
- package/dist/canvas-react/pixi-primitive.d.ts.map +1 -0
- package/dist/canvas-react/pixi-primitive.js +181 -0
- package/dist/canvas-react/pixi-react-adapter.d.ts +71 -0
- package/dist/canvas-react/pixi-react-adapter.d.ts.map +1 -0
- package/dist/canvas-react/pixi-react-adapter.js +229 -0
- package/dist/canvas-react/pixi-react-root-factory.d.ts +56 -0
- package/dist/canvas-react/pixi-react-root-factory.d.ts.map +1 -0
- package/dist/canvas-react/pixi-react-root-factory.js +73 -0
- package/dist/canvas-react/world-context.d.ts +88 -0
- package/dist/canvas-react/world-context.d.ts.map +1 -0
- package/dist/canvas-react/world-context.js +212 -0
- package/dist/config.d.ts +9 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +8 -0
- package/dist/core/frame-pacing.d.ts +90 -0
- package/dist/core/frame-pacing.d.ts.map +1 -0
- package/dist/core/frame-pacing.js +89 -0
- package/dist/core/game-loop.d.ts +62 -0
- package/dist/core/game-loop.d.ts.map +1 -0
- package/dist/core/game-loop.js +189 -0
- package/dist/core/seeded-random.d.ts +69 -0
- package/dist/core/seeded-random.d.ts.map +1 -0
- package/dist/core/seeded-random.js +121 -0
- package/dist/core/sim-clock.d.ts +199 -0
- package/dist/core/sim-clock.d.ts.map +1 -0
- package/dist/core/sim-clock.js +291 -0
- package/dist/core/system-runner.d.ts +96 -0
- package/dist/core/system-runner.d.ts.map +1 -0
- package/dist/core/system-runner.js +253 -0
- package/dist/core/types.d.ts +111 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +25 -0
- package/dist/data/data-asset.d.ts +101 -0
- package/dist/data/data-asset.d.ts.map +1 -0
- package/dist/data/data-asset.js +122 -0
- package/dist/data/data-check-core.d.ts +109 -0
- package/dist/data/data-check-core.d.ts.map +1 -0
- package/dist/data/data-check-core.js +177 -0
- package/dist/data/data-ref.d.ts +79 -0
- package/dist/data/data-ref.d.ts.map +1 -0
- package/dist/data/data-ref.js +130 -0
- package/dist/data/vite-plugin-data.d.ts +79 -0
- package/dist/data/vite-plugin-data.d.ts.map +1 -0
- package/dist/data/vite-plugin-data.js +217 -0
- package/dist/defaults.d.ts +233 -0
- package/dist/defaults.d.ts.map +1 -0
- package/dist/defaults.js +137 -0
- package/dist/dev/chrome-trace.d.ts +45 -0
- package/dist/dev/chrome-trace.d.ts.map +1 -0
- package/dist/dev/chrome-trace.js +114 -0
- package/dist/dev/console-bridge.d.ts +22 -0
- package/dist/dev/console-bridge.d.ts.map +1 -0
- package/dist/dev/console-bridge.js +71 -0
- package/dist/dev/debug-draw.d.ts +24 -0
- package/dist/dev/debug-draw.d.ts.map +1 -0
- package/dist/dev/debug-draw.js +73 -0
- package/dist/dev/instruments.d.ts +133 -0
- package/dist/dev/instruments.d.ts.map +1 -0
- package/dist/dev/instruments.js +231 -0
- package/dist/dev/logger.d.ts +30 -0
- package/dist/dev/logger.d.ts.map +1 -0
- package/dist/dev/logger.js +90 -0
- package/dist/dev/performance-profiler.d.ts +111 -0
- package/dist/dev/performance-profiler.d.ts.map +1 -0
- package/dist/dev/performance-profiler.js +215 -0
- package/dist/dev/render-debug-adapter.d.ts +57 -0
- package/dist/dev/render-debug-adapter.d.ts.map +1 -0
- package/dist/dev/render-debug-adapter.js +141 -0
- package/dist/dev/render-memory.d.ts +53 -0
- package/dist/dev/render-memory.d.ts.map +1 -0
- package/dist/dev/render-memory.js +190 -0
- package/dist/dev/webgl-frame-capture.d.ts +134 -0
- package/dist/dev/webgl-frame-capture.d.ts.map +1 -0
- package/dist/dev/webgl-frame-capture.js +270 -0
- package/dist/dev/webgl-gpu-timer.d.ts +8 -0
- package/dist/dev/webgl-gpu-timer.d.ts.map +1 -0
- package/dist/dev/webgl-gpu-timer.js +52 -0
- package/dist/ecs/scene-index.d.ts +179 -0
- package/dist/ecs/scene-index.d.ts.map +1 -0
- package/dist/ecs/scene-index.js +331 -0
- package/dist/ecs/scene-query.d.ts +6 -0
- package/dist/ecs/scene-query.d.ts.map +1 -0
- package/dist/ecs/scene-query.js +40 -0
- package/dist/ecs/user-data.d.ts +193 -0
- package/dist/ecs/user-data.d.ts.map +1 -0
- package/dist/ecs/user-data.js +145 -0
- package/dist/index.d.ts +35 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +29 -0
- package/dist/input/input-manager.d.ts +944 -0
- package/dist/input/input-manager.d.ts.map +1 -0
- package/dist/input/input-manager.js +2209 -0
- package/dist/input/input-types.d.ts +174 -0
- package/dist/input/input-types.d.ts.map +1 -0
- package/dist/input/input-types.js +1 -0
- package/dist/input/prompt-labels.d.ts +21 -0
- package/dist/input/prompt-labels.d.ts.map +1 -0
- package/dist/input/prompt-labels.js +121 -0
- package/dist/input/rebind-controller.d.ts +59 -0
- package/dist/input/rebind-controller.d.ts.map +1 -0
- package/dist/input/rebind-controller.js +85 -0
- package/dist/input/schema.d.ts +16 -0
- package/dist/input/schema.d.ts.map +1 -0
- package/dist/input/schema.js +228 -0
- package/dist/loader.d.ts +76 -0
- package/dist/loader.d.ts.map +1 -0
- package/dist/loader.js +114 -0
- package/dist/manifest/editor-port.d.ts +53 -0
- package/dist/manifest/editor-port.d.ts.map +1 -0
- package/dist/manifest/editor-port.js +67 -0
- package/dist/manifest/filename.d.ts +14 -0
- package/dist/manifest/filename.d.ts.map +1 -0
- package/dist/manifest/filename.js +43 -0
- package/dist/manifest/index.d.ts +6 -0
- package/dist/manifest/index.d.ts.map +1 -0
- package/dist/manifest/index.js +9 -0
- package/dist/manifest/load-file.d.ts +7 -0
- package/dist/manifest/load-file.d.ts.map +1 -0
- package/dist/manifest/load-file.js +23 -0
- package/dist/manifest/load.d.ts +161 -0
- package/dist/manifest/load.d.ts.map +1 -0
- package/dist/manifest/load.js +269 -0
- package/dist/manifest/locate.d.ts +24 -0
- package/dist/manifest/locate.d.ts.map +1 -0
- package/dist/manifest/locate.js +48 -0
- package/dist/manifest/schema.d.ts +293 -0
- package/dist/manifest/schema.d.ts.map +1 -0
- package/dist/manifest/schema.js +633 -0
- package/dist/physics/collider-dimensions.d.ts +63 -0
- package/dist/physics/collider-dimensions.d.ts.map +1 -0
- package/dist/physics/collider-dimensions.js +98 -0
- package/dist/physics/collision-system.d.ts +41 -0
- package/dist/physics/collision-system.d.ts.map +1 -0
- package/dist/physics/collision-system.js +64 -0
- package/dist/physics/physics-registry.d.ts +45 -0
- package/dist/physics/physics-registry.d.ts.map +1 -0
- package/dist/physics/physics-registry.js +65 -0
- package/dist/physics/transform-writer.d.ts +16 -0
- package/dist/physics/transform-writer.d.ts.map +1 -0
- package/dist/physics/transform-writer.js +38 -0
- package/dist/pixi/authoring.d.ts +93 -0
- package/dist/pixi/authoring.d.ts.map +1 -0
- package/dist/pixi/authoring.js +207 -0
- package/dist/pixi/index.d.ts +16 -0
- package/dist/pixi/index.d.ts.map +1 -0
- package/dist/pixi/index.js +15 -0
- package/dist/pixi/ingest-iframe.d.ts +82 -0
- package/dist/pixi/ingest-iframe.d.ts.map +1 -0
- package/dist/pixi/ingest-iframe.js +166 -0
- package/dist/pixi/ingest.d.ts +97 -0
- package/dist/pixi/ingest.d.ts.map +1 -0
- package/dist/pixi/ingest.js +40 -0
- package/dist/pixi/physics-registry.d.ts +24 -0
- package/dist/pixi/physics-registry.d.ts.map +1 -0
- package/dist/pixi/physics-registry.js +38 -0
- package/dist/pixi/scene-capture.d.ts +43 -0
- package/dist/pixi/scene-capture.d.ts.map +1 -0
- package/dist/pixi/scene-capture.js +92 -0
- package/dist/pixi/system-adapters.d.ts +16 -0
- package/dist/pixi/system-adapters.d.ts.map +1 -0
- package/dist/pixi/system-adapters.js +37 -0
- package/dist/react/unmanaged-root-detector.d.ts +18 -0
- package/dist/react/unmanaged-root-detector.d.ts.map +1 -0
- package/dist/react/unmanaged-root-detector.js +70 -0
- package/dist/react/use-data.d.ts +60 -0
- package/dist/react/use-data.d.ts.map +1 -0
- package/dist/react/use-data.js +101 -0
- package/dist/react/use-selection.d.ts +54 -0
- package/dist/react/use-selection.d.ts.map +1 -0
- package/dist/react/use-selection.js +71 -0
- package/dist/react/world-state.d.ts +154 -0
- package/dist/react/world-state.d.ts.map +1 -0
- package/dist/react/world-state.js +220 -0
- package/dist/render/auto-batcher.d.ts +34 -0
- package/dist/render/auto-batcher.d.ts.map +1 -0
- package/dist/render/auto-batcher.js +140 -0
- package/dist/render/instance-mesh.d.ts +5 -0
- package/dist/render/instance-mesh.d.ts.map +1 -0
- package/dist/render/instance-mesh.js +19 -0
- package/dist/render/light-camera-factory.d.ts +24 -0
- package/dist/render/light-camera-factory.d.ts.map +1 -0
- package/dist/render/light-camera-factory.js +71 -0
- package/dist/render/lod.d.ts +13 -0
- package/dist/render/lod.d.ts.map +1 -0
- package/dist/render/lod.js +16 -0
- package/dist/render/material-factory.d.ts +15 -0
- package/dist/render/material-factory.d.ts.map +1 -0
- package/dist/render/material-factory.js +186 -0
- package/dist/render/mesh-shadow.d.ts +11 -0
- package/dist/render/mesh-shadow.d.ts.map +1 -0
- package/dist/render/mesh-shadow.js +19 -0
- package/dist/render/particles-factory.d.ts +99 -0
- package/dist/render/particles-factory.d.ts.map +1 -0
- package/dist/render/particles-factory.js +361 -0
- package/dist/render/render-batch-system.d.ts +33 -0
- package/dist/render/render-batch-system.d.ts.map +1 -0
- package/dist/render/render-batch-system.js +223 -0
- package/dist/render/render-features.d.ts +47 -0
- package/dist/render/render-features.d.ts.map +1 -0
- package/dist/render/render-features.js +105 -0
- package/dist/render/render-settings.d.ts +35 -0
- package/dist/render/render-settings.d.ts.map +1 -0
- package/dist/render/render-settings.js +51 -0
- package/dist/render/spark-renderer-lifecycle.d.ts +18 -0
- package/dist/render/spark-renderer-lifecycle.d.ts.map +1 -0
- package/dist/render/spark-renderer-lifecycle.js +57 -0
- package/dist/render/viewport-shading.d.ts +17 -0
- package/dist/render/viewport-shading.d.ts.map +1 -0
- package/dist/render/viewport-shading.js +87 -0
- package/dist/runtime/create-runtime.d.ts +259 -0
- package/dist/runtime/create-runtime.d.ts.map +1 -0
- package/dist/runtime/create-runtime.js +666 -0
- package/dist/runtime/debug-bridge.d.ts +288 -0
- package/dist/runtime/debug-bridge.d.ts.map +1 -0
- package/dist/runtime/debug-bridge.js +277 -0
- package/dist/runtime/debug-registry.d.ts +287 -0
- package/dist/runtime/debug-registry.d.ts.map +1 -0
- package/dist/runtime/debug-registry.js +528 -0
- package/dist/runtime/dev-layers.d.ts +34 -0
- package/dist/runtime/dev-layers.d.ts.map +1 -0
- package/dist/runtime/dev-layers.js +40 -0
- package/dist/runtime/frame-selector-cache.d.ts +41 -0
- package/dist/runtime/frame-selector-cache.d.ts.map +1 -0
- package/dist/runtime/frame-selector-cache.js +65 -0
- package/dist/runtime/game.d.ts +576 -0
- package/dist/runtime/game.d.ts.map +1 -0
- package/dist/runtime/game.js +1003 -0
- package/dist/runtime/gameplay-rng-trap.d.ts +47 -0
- package/dist/runtime/gameplay-rng-trap.d.ts.map +1 -0
- package/dist/runtime/gameplay-rng-trap.js +95 -0
- package/dist/runtime/input-router.d.ts +78 -0
- package/dist/runtime/input-router.d.ts.map +1 -0
- package/dist/runtime/input-router.js +171 -0
- package/dist/runtime/mount-game.d.ts +126 -0
- package/dist/runtime/mount-game.d.ts.map +1 -0
- package/dist/runtime/mount-game.js +159 -0
- package/dist/runtime/mount-manifest.d.ts +174 -0
- package/dist/runtime/mount-manifest.d.ts.map +1 -0
- package/dist/runtime/mount-manifest.js +304 -0
- package/dist/runtime/presentation.d.ts +85 -0
- package/dist/runtime/presentation.d.ts.map +1 -0
- package/dist/runtime/presentation.js +92 -0
- package/dist/runtime/render-audio-control.d.ts +126 -0
- package/dist/runtime/render-audio-control.d.ts.map +1 -0
- package/dist/runtime/render-audio-control.js +116 -0
- package/dist/runtime/render-control.d.ts +347 -0
- package/dist/runtime/render-control.d.ts.map +1 -0
- package/dist/runtime/render-control.js +317 -0
- package/dist/runtime/render-seed.d.ts +56 -0
- package/dist/runtime/render-seed.d.ts.map +1 -0
- package/dist/runtime/render-seed.js +73 -0
- package/dist/runtime/state-bridge.d.ts +60 -0
- package/dist/runtime/state-bridge.d.ts.map +1 -0
- package/dist/runtime/state-bridge.js +62 -0
- package/dist/runtime/types.d.ts +285 -0
- package/dist/runtime/types.d.ts.map +1 -0
- package/dist/runtime/types.js +1 -0
- package/dist/runtime/unexported-game-trap.d.ts +36 -0
- package/dist/runtime/unexported-game-trap.d.ts.map +1 -0
- package/dist/runtime/unexported-game-trap.js +80 -0
- package/dist/setup/setup-audio.d.ts +20 -0
- package/dist/setup/setup-audio.d.ts.map +1 -0
- package/dist/setup/setup-audio.js +41 -0
- package/dist/setup/setup-particles.d.ts +17 -0
- package/dist/setup/setup-particles.d.ts.map +1 -0
- package/dist/setup/setup-particles.js +16 -0
- package/dist/setup/setup-physics.d.ts +25 -0
- package/dist/setup/setup-physics.d.ts.map +1 -0
- package/dist/setup/setup-physics.js +51 -0
- package/dist/setup/setup-renderer.d.ts +82 -0
- package/dist/setup/setup-renderer.d.ts.map +1 -0
- package/dist/setup/setup-renderer.js +381 -0
- package/dist/world3d-react/engine-bridge.d.ts +47 -0
- package/dist/world3d-react/engine-bridge.d.ts.map +1 -0
- package/dist/world3d-react/engine-bridge.js +48 -0
- package/dist/world3d-react/index.d.ts +47 -0
- package/dist/world3d-react/index.d.ts.map +1 -0
- package/dist/world3d-react/index.js +46 -0
- package/dist/world3d-react/r3f-adapter.d.ts +51 -0
- package/dist/world3d-react/r3f-adapter.d.ts.map +1 -0
- package/dist/world3d-react/r3f-adapter.js +368 -0
- package/dist/world3d-react/r3f-root-factory.d.ts +62 -0
- package/dist/world3d-react/r3f-root-factory.d.ts.map +1 -0
- package/dist/world3d-react/r3f-root-factory.js +79 -0
- package/dist/world3d-react/rapier-physics-bridge.d.ts +76 -0
- package/dist/world3d-react/rapier-physics-bridge.d.ts.map +1 -0
- package/dist/world3d-react/rapier-physics-bridge.js +120 -0
- package/dist/world3d-react/renderer-config.d.ts +58 -0
- package/dist/world3d-react/renderer-config.d.ts.map +1 -0
- package/dist/world3d-react/renderer-config.js +96 -0
- package/dist/world3d-react/world-context.d.ts +123 -0
- package/dist/world3d-react/world-context.d.ts.map +1 -0
- package/dist/world3d-react/world-context.js +204 -0
- package/dist-config/config.js +303 -0
- package/dist-config/config.js.map +7 -0
- package/package.json +14 -3
- package/src/adapter/rapier-physics-adapter.ts +77 -34
- package/src/config.ts +8 -0
- package/src/core/frame-pacing.ts +26 -0
- package/src/core/game-loop.ts +4 -3
- package/src/dev/instruments.ts +302 -0
- package/src/runtime/mount-game.ts +6 -0
- package/src/runtime/unexported-game-trap.ts +82 -0
- package/src/setup/setup-renderer.ts +2 -0
- package/src/world3d-react/index.ts +9 -0
- package/src/world3d-react/rapier-physics-bridge.tsx +137 -0
|
@@ -0,0 +1,368 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `createR3FAdapter` — wraps a react-three-fiber tree as a first-party
|
|
3
|
+
* `RootAdapter` so an R3F scene mounts as an ordinary `kind: "three"`
|
|
4
|
+
* world: the engine hands `mount()` a `ThreeHostContext` (ITS OWN renderer +
|
|
5
|
+
* canvas + gated loop, per `../adapter/host-context.ts`); this returns a
|
|
6
|
+
* `MountedThreeRoot` (`../adapter/root-adapter.ts`) whose `scene`/`camera`
|
|
7
|
+
* are fiber's REAL `THREE.Scene`/`THREE.Camera` instances.
|
|
8
|
+
*
|
|
9
|
+
* Upstreamed from `examples/r3f-first-party/src/r3f-adapter.tsx` (R4 — the
|
|
10
|
+
* `@engine/world3d-react` opt-in module, mirroring how `pixi/` is the
|
|
11
|
+
* PixiJS surface's opt-in home). The mount semantics
|
|
12
|
+
* are byte-for-byte the example's live-proven Phase-1 bridge. External adopters
|
|
13
|
+
* (alien-stories-style) keep the exact same calling contract.
|
|
14
|
+
*
|
|
15
|
+
* three.js identity: this module never imports `three` itself for scene objects
|
|
16
|
+
* — fiber's internal `import * as THREE from 'three'` must resolve to the SAME
|
|
17
|
+
* instance the engine's `ThreeHostContext.three` points at, which the importing
|
|
18
|
+
* project guarantees via its Vite `resolve.dedupe: ['three', 'react',
|
|
19
|
+
* 'react-dom']` (see `examples/r3f-first-party/vite.config.ts`).
|
|
20
|
+
*/
|
|
21
|
+
import { advance, createRoot, extend, events as pointerEvents, } from '@react-three/fiber';
|
|
22
|
+
import { createElement } from 'react';
|
|
23
|
+
import { WorldProvider } from '../react/world-state';
|
|
24
|
+
import { EngineBridge } from './engine-bridge';
|
|
25
|
+
import { applyWorldRendererConfig } from './renderer-config';
|
|
26
|
+
import { createR3FRootContext } from './world-context';
|
|
27
|
+
/**
|
|
28
|
+
* Build a `RootAdapter` that mounts `options.content` through
|
|
29
|
+
* react-three-fiber, gated entirely by the host's own loop and rendering
|
|
30
|
+
* through the host's own `WebGLRenderer` — never a second renderer, never a
|
|
31
|
+
* second `requestAnimationFrame` loop (design §1.C).
|
|
32
|
+
*/
|
|
33
|
+
export function createR3FAdapter(options) {
|
|
34
|
+
const { id, content, inputMapPath, renderer: rendererConfig } = options;
|
|
35
|
+
return {
|
|
36
|
+
id,
|
|
37
|
+
async mount(host) {
|
|
38
|
+
// Headless honesty — every `mount()` must work headless: the
|
|
39
|
+
// conformance kit / CI
|
|
40
|
+
// runs `mount()` in Node — no canvas, no WebGL, no fiber reconciler.
|
|
41
|
+
// Guard the ENTIRE fiber mount behind `!host.headless` and return a
|
|
42
|
+
// bare, real scene + camera instead (still `instanceof
|
|
43
|
+
// host.three.Scene` / `.Camera` — the identity rule holds even here,
|
|
44
|
+
// since this uses the host's own `three` instance, not a fresh
|
|
45
|
+
// import). Residual: the hierarchy is empty under headless
|
|
46
|
+
// conformance — recorded as design O2, not hidden; a react-nil-style
|
|
47
|
+
// headless reconciler mount is the known fix, out of scope for v1.
|
|
48
|
+
if (host.headless) {
|
|
49
|
+
const scene = new host.three.Scene();
|
|
50
|
+
const camera = new host.three.PerspectiveCamera();
|
|
51
|
+
return {
|
|
52
|
+
kind: 'three',
|
|
53
|
+
scene,
|
|
54
|
+
camera,
|
|
55
|
+
drivesOwnLoop: false,
|
|
56
|
+
dispose() {
|
|
57
|
+
/* nothing was ever mounted */
|
|
58
|
+
},
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
// Fiber v9 made the THREE catalogue tree-shakeable: `<Canvas>` calls
|
|
62
|
+
// `extend(THREE)` for you, a bare `createRoot` does NOT — without this,
|
|
63
|
+
// the FIRST three intrinsic in the tree (`<color>`, `<ambientLight>`,
|
|
64
|
+
// …) throws "X is not part of the THREE namespace! Did you forget to
|
|
65
|
+
// extend?" at reconcile time. Extending with `host.three` (not a fresh
|
|
66
|
+
// `import * as THREE`) keeps the catalogue on the host's deduped three
|
|
67
|
+
// instance — the same identity rule the returned scene/camera rely on.
|
|
68
|
+
// `extend` merges into a module-global catalogue, so calling it once
|
|
69
|
+
// per mount is idempotent.
|
|
70
|
+
extend(host.three);
|
|
71
|
+
// The engine runtime this world OWNS: a real SystemRunner,
|
|
72
|
+
// provided to the R3F tree via `EngineBridge`.
|
|
73
|
+
// `update(dt)` below runs the phases under the host loop, so registered
|
|
74
|
+
// systems tick in engine phase order and freeze under
|
|
75
|
+
// pause exactly like `useFrame` work does.
|
|
76
|
+
//
|
|
77
|
+
// HONESTY NOTE: the manager's ctx is an `R3FGameContext`, not the full
|
|
78
|
+
// `GameContext`. The shared game-scoped subsystems are REAL
|
|
79
|
+
// classic-adapter parity (`./world-context.ts`):
|
|
80
|
+
// `ctx.debug`/`ctx.random`/`ctx.game`/`ctx.roots`, and `ctx.input` (the
|
|
81
|
+
// game-owned InputManager, with this world's virtual-input/actions/trace
|
|
82
|
+
// debug seams registered and the project's input map loaded). The
|
|
83
|
+
// subsystems an R3F world genuinely does not build (Rapier, composer,
|
|
84
|
+
// audio, particles, debugDraw) are absent from that TYPE, so reaching
|
|
85
|
+
// for one is a compile error rather than anything that can happen at
|
|
86
|
+
// runtime. `scene`/`camera` are backfilled right after fiber's first
|
|
87
|
+
// commit resolves them, before any tick can run.
|
|
88
|
+
const runtime = createR3FRootContext(host, { id, inputMapPath });
|
|
89
|
+
const { systems } = runtime;
|
|
90
|
+
// `ctx` rides the bridge so ordinary components can reach engine
|
|
91
|
+
// services through `useGameContext()`.
|
|
92
|
+
const bridge = { ctx: runtime.ctx };
|
|
93
|
+
// Actions must exist before any component's init()/first frame reads
|
|
94
|
+
// them — wait for the (never-rejecting) input-map load before the first
|
|
95
|
+
// commit.
|
|
96
|
+
await runtime.inputMapReady;
|
|
97
|
+
// The world's own colour pipeline. Applied AFTER `root.configure()` below — see the comment
|
|
98
|
+
// at its call site for why "before" is the version that silently does nothing.
|
|
99
|
+
let restoreRendererConfig = () => { };
|
|
100
|
+
const canvas = host.surface.canvas;
|
|
101
|
+
const root = createRoot(canvas);
|
|
102
|
+
// `RootState` (the live scene/camera/gl fiber built) only arrives via
|
|
103
|
+
// the `onCreated` callback — `root.render()`'s return value is
|
|
104
|
+
// TECHNICALLY the same store, but `onCreated` is the hook the design
|
|
105
|
+
// doc's §1.C sketch names, and waiting for it (rather than assuming
|
|
106
|
+
// the first commit already ran synchronously) is the honest choice
|
|
107
|
+
// under React 19's concurrent renderer, which does not guarantee a
|
|
108
|
+
// synchronous first commit the way legacy ReactDOM.render did.
|
|
109
|
+
let resolveState;
|
|
110
|
+
const statePromise = new Promise((resolve) => {
|
|
111
|
+
resolveState = resolve;
|
|
112
|
+
});
|
|
113
|
+
// `root.configure()` is ASYNC in fiber v9 (`Promise<ReconcilerRoot>`)
|
|
114
|
+
// — the design doc's §1.C sketch shows it called synchronously; the
|
|
115
|
+
// real v9 API (verified against
|
|
116
|
+
// `node_modules/@react-three/fiber/dist/declarations/src/core/index.d.ts`)
|
|
117
|
+
// requires awaiting it before `render()`.
|
|
118
|
+
await root.configure({
|
|
119
|
+
// The engine's renderer, not a second one (design §1.C) — fiber
|
|
120
|
+
// renders THROUGH `host.renderer` instead of constructing its own
|
|
121
|
+
// `WebGLRenderer`.
|
|
122
|
+
gl: host.renderer,
|
|
123
|
+
// …and the host's shadow map, not fiber's.
|
|
124
|
+
//
|
|
125
|
+
// `configure()` runs `gl.shadowMap.enabled = !!shadows`
|
|
126
|
+
// UNCONDITIONALLY, against its own default of `false`. Passing nothing
|
|
127
|
+
// therefore does not mean "leave it alone" — it means "turn shadows
|
|
128
|
+
// off on the renderer the host just configured". Every three root
|
|
129
|
+
// silently did that (FX-5): `applyRendererSettings` sets
|
|
130
|
+
// `shadowMap.enabled` from the `shadows` render feature, which
|
|
131
|
+
// defaults ON, and the setting had no surviving reader on this path —
|
|
132
|
+
// so `castShadow`/`receiveShadow` all over a world produced nothing
|
|
133
|
+
// and the scene read flat, with no error anywhere.
|
|
134
|
+
//
|
|
135
|
+
// Reading it back off the renderer is exactly "don't clobber": a
|
|
136
|
+
// boolean also pins `shadowMap.type` to `PCFSoftShadowMap`, which is
|
|
137
|
+
// what `createHostRenderer` already sets, so the round trip is
|
|
138
|
+
// lossless and the HOST stays the one deciding.
|
|
139
|
+
//
|
|
140
|
+
// Optional-chained even though `WebGLRenderer.shadowMap` is not
|
|
141
|
+
// optional: a headless/stub host renderer is a real shape in this
|
|
142
|
+
// repo's tests, and fiber's own `if (gl.shadowMap)` guard means the
|
|
143
|
+
// value it reads there is ignored anyway.
|
|
144
|
+
shadows: host.renderer.shadowMap?.enabled ?? false,
|
|
145
|
+
// The engine's gated loop is the ONLY loop — fiber must never run
|
|
146
|
+
// its own rAF (that would defeat editor pause; design §1.C's
|
|
147
|
+
// `drivesOwnLoop: false` contract, guide §2's loop-model note).
|
|
148
|
+
frameloop: 'never',
|
|
149
|
+
// `RenderProps.size` types as the FULL `Size` (width/height/top/left),
|
|
150
|
+
// not `Partial<Size>` — the design sketch's `{ width, height }` alone
|
|
151
|
+
// does not satisfy fiber v9's real type, so `top`/`left` are pinned
|
|
152
|
+
// to 0 (this bridge always fills its whole canvas; no offset
|
|
153
|
+
// viewport in v1).
|
|
154
|
+
size: { width: host.surface.width, height: host.surface.height, top: 0, left: 0 },
|
|
155
|
+
// Fiber's pointer-event manager, passed EXPLICITLY.
|
|
156
|
+
//
|
|
157
|
+
// This comment used to say `events` was "deliberately left at fiber's
|
|
158
|
+
// default (binds to `gl.domElement`)". That was false, and it cost
|
|
159
|
+
// every R3F world in this engine its mesh-level pointer props —
|
|
160
|
+
// `onClick`, `onPointerOver`, `onPointerMissed` were dead everywhere.
|
|
161
|
+
// There IS no default for a bare `createRoot`: the
|
|
162
|
+
// `events = createPointerEvents` default lives in the `<Canvas>`
|
|
163
|
+
// COMPONENT, which this bridge does not use, and `configure` gates on
|
|
164
|
+
// `if (events && !state.events.handlers)`. With `events` undefined the
|
|
165
|
+
// store kept its initial `{ priority, enabled, connected: false }` —
|
|
166
|
+
// no handlers, nothing bound to the canvas, no error.
|
|
167
|
+
//
|
|
168
|
+
// Found by the WO-P6 builder, whose control experiment isolated the
|
|
169
|
+
// variable properly: the same stub renderer, the same
|
|
170
|
+
// `frameloop: 'never'`, the same jsdom canvas and pointer sequence,
|
|
171
|
+
// differing ONLY in passing `events` — and `onClick` fired. Fiber is
|
|
172
|
+
// fine under a host-driven loop; we omitted one property.
|
|
173
|
+
//
|
|
174
|
+
// (Design O1's open question about a delegating multi-canvas input
|
|
175
|
+
// router still only matters for a shell+net composite; this bridge is
|
|
176
|
+
// the single-canvas world O1 says is unaffected.)
|
|
177
|
+
events: pointerEvents,
|
|
178
|
+
onCreated: (state) => resolveState(state),
|
|
179
|
+
});
|
|
180
|
+
// THE WORLD'S OWN COLOUR PIPELINE — and it must land HERE, after `configure()`.
|
|
181
|
+
//
|
|
182
|
+
// `configure()` writes `outputColorSpace` and `toneMapping` onto the renderer
|
|
183
|
+
// UNCONDITIONALLY, from its own `linear`/`flat` props whose defaults are `false`/`false` —
|
|
184
|
+
// i.e. sRGB output and ACES. That is the SAME trap as the `shadows` note above, and it is
|
|
185
|
+
// silent: applying a world's config before `configure()` leaves every field set and every
|
|
186
|
+
// pixel unchanged (measured on the squash-the-creeps Godot port — the ground stayed at byte
|
|
187
|
+
// 138 with `toneMapping: 'none'` declared and applied).
|
|
188
|
+
//
|
|
189
|
+
// Applying it here is still before any frame: `advance()` only runs from `update()` below,
|
|
190
|
+
// and `render()` on the next line merely reconciles.
|
|
191
|
+
if (rendererConfig !== undefined) {
|
|
192
|
+
restoreRendererConfig = applyWorldRendererConfig(host.three, host.renderer, rendererConfig);
|
|
193
|
+
}
|
|
194
|
+
// No `<StrictMode>` (design §1.C: "no StrictMode: host mounts once")
|
|
195
|
+
// — this bridge mounts exactly once per `mount()` call; StrictMode's
|
|
196
|
+
// deliberate double-invoke of effects would double-subscribe
|
|
197
|
+
// `useFrame` callbacks against a host loop that only ticks once per
|
|
198
|
+
// frame. The `EngineBridge` provider threads the component runtime
|
|
199
|
+
// (above) into the tree (W3), where `useGameContext()` reads it.
|
|
200
|
+
// R3F IS React, so the React seam every dom root already has —
|
|
201
|
+
// `useWorldState`, `useDebugProvider`/`useDebugCommand`/`useDebugEmit`
|
|
202
|
+
// (`../react/world-state`) — should work identically inside a three root.
|
|
203
|
+
// Without this provider a behavior-as-a-hook could only reach the debug
|
|
204
|
+
// registry by destructuring `useGameContext()` and calling
|
|
205
|
+
// `debug?.registerStateProvider(...)` by hand, which has no unmount
|
|
206
|
+
// story: the template's follow-camera hook leaked a provider per remount
|
|
207
|
+
// until this landed. `host.game` is genuinely absent in bare/headless
|
|
208
|
+
// hosts, so the provider is conditional and those hooks stay the inert
|
|
209
|
+
// no-ops they already document themselves to be.
|
|
210
|
+
const game = runtime.ctx.game;
|
|
211
|
+
root.render(createElement(EngineBridge.Provider, { value: bridge }, game ? createElement(WorldProvider, { game }, content) : content));
|
|
212
|
+
// A reconcile-time crash (e.g. a missing `extend` catalogue entry)
|
|
213
|
+
// surfaces as an uncaught window error and `onCreated` never fires —
|
|
214
|
+
// without this guard, `mount()` would await `statePromise` FOREVER and
|
|
215
|
+
// silently wedge every world declared after this one (roots mount
|
|
216
|
+
// sequentially). Convert that class of failure into a loud mount error.
|
|
217
|
+
const state = await new Promise((resolve, reject) => {
|
|
218
|
+
const onError = (event) => {
|
|
219
|
+
cleanup();
|
|
220
|
+
root.unmount();
|
|
221
|
+
runtime.dispose();
|
|
222
|
+
restoreRendererConfig();
|
|
223
|
+
reject(new Error(`r3f-adapter: fiber crashed before its first commit — ${event.message} ` +
|
|
224
|
+
'(mount() fails loudly instead of hanging on onCreated)'));
|
|
225
|
+
};
|
|
226
|
+
const timer = setTimeout(() => {
|
|
227
|
+
cleanup();
|
|
228
|
+
root.unmount();
|
|
229
|
+
runtime.dispose();
|
|
230
|
+
restoreRendererConfig();
|
|
231
|
+
reject(new Error('r3f-adapter: onCreated did not fire within 10s — the R3F tree never reached ' +
|
|
232
|
+
'its first commit (mount() fails loudly instead of hanging)'));
|
|
233
|
+
}, 10_000);
|
|
234
|
+
const cleanup = () => {
|
|
235
|
+
clearTimeout(timer);
|
|
236
|
+
window.removeEventListener('error', onError);
|
|
237
|
+
};
|
|
238
|
+
window.addEventListener('error', onError);
|
|
239
|
+
void statePromise.then((s) => {
|
|
240
|
+
cleanup();
|
|
241
|
+
resolve(s);
|
|
242
|
+
});
|
|
243
|
+
});
|
|
244
|
+
// Clock hardening (field-proven by the first external adopter,
|
|
245
|
+
// alien-stories' proto): fiber's internal `update()` calls
|
|
246
|
+
// `state.clock.getDelta()` BEFORE its `frameloop:'never'` branch, and a
|
|
247
|
+
// RUNNING (or autoStart) `THREE.Clock` accumulates WALL time into
|
|
248
|
+
// `elapsedTime` as a side effect — skewing the deltas the 'never'
|
|
249
|
+
// branch derives from the game timestamps `update(dt)` feeds below.
|
|
250
|
+
// Stopped + autoStart=false makes `getDelta()` a pure no-op, so
|
|
251
|
+
// `useFrame` deltas come from game time alone.
|
|
252
|
+
state.clock.autoStart = false;
|
|
253
|
+
state.clock.stop();
|
|
254
|
+
// Backfill the component runtime's ctx with fiber's real scene/camera
|
|
255
|
+
// (W3 — see the HONESTY NOTE above). This happens before the first
|
|
256
|
+
// `update(dt)` tick, so no component ever observes them missing.
|
|
257
|
+
runtime.setSceneCamera(state.scene, state.camera);
|
|
258
|
+
// THE STORE IS THE TRUTH, NOT THE `onCreated` SNAPSHOT.
|
|
259
|
+
//
|
|
260
|
+
// `state` is one immutable zustand snapshot: fiber's store is
|
|
261
|
+
// `create<RootState>()`, and every `set(...)` produces a NEW state
|
|
262
|
+
// object rather than mutating this one. So a world that legitimately
|
|
263
|
+
// REPLACES the default camera — `useThree(s => s.set)({ camera })`,
|
|
264
|
+
// which is exactly what drei's `makeDefault` does — never reaches
|
|
265
|
+
// anything read off `state` directly.
|
|
266
|
+
//
|
|
267
|
+
// That is not cosmetic: fiber's own `update()` renders
|
|
268
|
+
// `state.gl.render(state.scene, state.camera)` off the state object it
|
|
269
|
+
// is HANDED, so `advance(t, true, state)` below pinned the render
|
|
270
|
+
// camera to fiber's default `PerspectiveCamera` at (0, 0, 5) forever.
|
|
271
|
+
// Measured on the squash-the-creeps Godot port (WO-G14): the world set
|
|
272
|
+
// its authored `OrthographicCamera` and the frame still rendered from
|
|
273
|
+
// (0, 0, 5) — a point INSIDE that game's 60x2x60 ground box, so every
|
|
274
|
+
// ground polygon was back-facing, was culled, and the "ground" was the
|
|
275
|
+
// cleared canvas. Nothing anywhere reported an error; edit mode looked
|
|
276
|
+
// right because the editor renders with its own camera.
|
|
277
|
+
//
|
|
278
|
+
// `state.get()` is fiber's own `StoreApi.getState`, carried on
|
|
279
|
+
// `RootState` for precisely this reason, so reading it per frame is the
|
|
280
|
+
// supported way to see the live root. It is a plain map read.
|
|
281
|
+
const live = () => state.get();
|
|
282
|
+
// The engine drives every `useFrame` through the mounted world's
|
|
283
|
+
// `update(dt)` hook, never off a raw host-loop callback. That is the
|
|
284
|
+
// whole pause story: `runFrameImpl` (`runtime/game.ts`) calls
|
|
285
|
+
// `mounted.update?.(dt)` per substep for a host-driven
|
|
286
|
+
// (`drivesOwnLoop: false`) world and SKIPS it while that world is
|
|
287
|
+
// frozen, and `Game.play.step()` ticks it exactly once — whereas any
|
|
288
|
+
// callback run outside `game.runFrame`'s gate would fire
|
|
289
|
+
// unconditionally, pause or not. Advancing fiber from such a callback
|
|
290
|
+
// LOOKS right and silently breaks acceptance gate 2 — proven by the
|
|
291
|
+
// 36-r3f-first-party e2e, whose paused instance-matrix samples kept
|
|
292
|
+
// moving until this moved to `update`. (The former `ThreeHostContext.loop`
|
|
293
|
+
// seam that made the wrong path reachable was deleted, zero consumers.)
|
|
294
|
+
//
|
|
295
|
+
// `advance(timestamp, runGlobalEffects, state)`'s `timestamp` is
|
|
296
|
+
// consumed as `THREE.Clock.elapsedTime` DIRECTLY when
|
|
297
|
+
// `frameloop:'never'` (verified against fiber's `update()`
|
|
298
|
+
// implementation, not just its `.d.ts` — the declared signature alone
|
|
299
|
+
// doesn't say this): `delta = timestamp - clock.elapsedTime;
|
|
300
|
+
// clock.elapsedTime = timestamp`. So `timestamp` must be a
|
|
301
|
+
// monotonically increasing SECONDS value — GAME time, not wall time:
|
|
302
|
+
// `update` simply isn't called while this world is frozen, so
|
|
303
|
+
// accumulating its `dt` (seconds; the loop runs a fixed 1/60 timestep)
|
|
304
|
+
// means fiber's clock does not advance across a pause. Wall clock
|
|
305
|
+
// (`performance.now()`) would leak the pause duration into the first
|
|
306
|
+
// resumed frame as one giant `useFrame` delta — the exact "time passed
|
|
307
|
+
// while frozen" illusion acceptance gate 2 forbids.
|
|
308
|
+
let elapsed = 0;
|
|
309
|
+
/** The camera `ctx` was last backfilled with — see `update()`. */
|
|
310
|
+
let backfilledCamera = state.camera;
|
|
311
|
+
return {
|
|
312
|
+
kind: 'three',
|
|
313
|
+
// Fiber's REAL `THREE.Scene`/`THREE.Camera`. Checkout development
|
|
314
|
+
// dedupes `three`; a registry-installed project and the prebundled
|
|
315
|
+
// editor can legitimately have distinct constructor identities, so
|
|
316
|
+
// editor boundaries recognize Three's stable structural brands
|
|
317
|
+
// (`isScene`, `isCamera`) rather than relying only on `instanceof`.
|
|
318
|
+
// `state.camera`'s type (`Camera = (OrthographicCamera |
|
|
319
|
+
// PerspectiveCamera) & { manual?: boolean }`) is a structural subtype
|
|
320
|
+
// of `THREE.Camera`, so no cast is needed.
|
|
321
|
+
//
|
|
322
|
+
// Both are GETTERS over the live store, not snapshot fields: the host
|
|
323
|
+
// and the editor must see the camera the world actually renders
|
|
324
|
+
// through, including one the world swapped in after the first commit
|
|
325
|
+
// (see `live` above).
|
|
326
|
+
get scene() {
|
|
327
|
+
return live().scene;
|
|
328
|
+
},
|
|
329
|
+
get camera() {
|
|
330
|
+
return live().camera;
|
|
331
|
+
},
|
|
332
|
+
drivesOwnLoop: false,
|
|
333
|
+
// Adapter surface: `debug` pre-seeded (the shared game registry's
|
|
334
|
+
// adapter); game code adds capabilities via
|
|
335
|
+
// `ctx.registerSystemAdapter` exactly as in a classic world.
|
|
336
|
+
systems: runtime.systemAdapters,
|
|
337
|
+
update(dt) {
|
|
338
|
+
elapsed += dt;
|
|
339
|
+
const current = live();
|
|
340
|
+
// A world that swapped the default camera gets it onto `ctx` too —
|
|
341
|
+
// `ctx.camera` and the rendered camera are the same fact, and a
|
|
342
|
+
// component reading one while the frame uses the other is the
|
|
343
|
+
// silent kind of wrong. Identity-gated, so this is one comparison
|
|
344
|
+
// per frame in the overwhelmingly common no-swap case.
|
|
345
|
+
if (current.camera !== backfilledCamera) {
|
|
346
|
+
backfilledCamera = current.camera;
|
|
347
|
+
runtime.setSceneCamera(current.scene, current.camera);
|
|
348
|
+
}
|
|
349
|
+
// Engine phases FIRST (registered systems mutate transforms),
|
|
350
|
+
// then fiber's advance (useFrame callbacks + the actual render see
|
|
351
|
+
// the fresh state). Both are host-gated: neither runs while frozen.
|
|
352
|
+
systems.run(dt);
|
|
353
|
+
advance(elapsed, true, current);
|
|
354
|
+
},
|
|
355
|
+
resize(width, height) {
|
|
356
|
+
live().setSize(width, height);
|
|
357
|
+
},
|
|
358
|
+
dispose() {
|
|
359
|
+
// Unmount FIRST so component effect cleanups run, then tear the
|
|
360
|
+
// runtime down (scoped debug-registry strip).
|
|
361
|
+
root.unmount();
|
|
362
|
+
runtime.dispose();
|
|
363
|
+
restoreRendererConfig();
|
|
364
|
+
},
|
|
365
|
+
};
|
|
366
|
+
},
|
|
367
|
+
};
|
|
368
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `r3fRootFactory` — mount a `three` root whose entry module DEFAULT-EXPORTS a
|
|
3
|
+
* React component.
|
|
4
|
+
*
|
|
5
|
+
* The idiomatic-shape fix (D26). A model asked for an R3F world writes:
|
|
6
|
+
*
|
|
7
|
+
* ```tsx
|
|
8
|
+
* export default function World() {
|
|
9
|
+
* return <><ambientLight /><mesh>…</mesh></>;
|
|
10
|
+
* }
|
|
11
|
+
* ```
|
|
12
|
+
*
|
|
13
|
+
* It does NOT write `export const adapter = createR3FAdapter({ id, content })`.
|
|
14
|
+
* That export is pure vgai ceremony wrapped around a component the author
|
|
15
|
+
* already wrote, and it is the second-largest non-idiomatic thing left in a
|
|
16
|
+
* world file (the largest is the missing `<Canvas>`, which is a separate
|
|
17
|
+
* question about who owns the canvas — see D26).
|
|
18
|
+
*
|
|
19
|
+
* The `dom` root already settled this convention: its factory reads
|
|
20
|
+
* `entryModule.default` and wraps it. This is the same contract for three
|
|
21
|
+
* roots, so both surfaces answer "what do I export?" the same way.
|
|
22
|
+
*
|
|
23
|
+
* ## Why this is NOT in `mount-game.ts`
|
|
24
|
+
*
|
|
25
|
+
* `defaultThreeAdapterFactory` lives beside the registry, and the registry
|
|
26
|
+
* module is deliberately dependency-free: its own doc notes threejs is safe to
|
|
27
|
+
* ship there because `three` is already an unconditional engine dependency.
|
|
28
|
+
* `@react-three/fiber` is NOT — it is the PROJECT's dependency, and
|
|
29
|
+
* `world3d-react` is the opt-in module that owns it. Putting this factory
|
|
30
|
+
* there would make R3F unconditional for every game, including ones with no
|
|
31
|
+
* React at all.
|
|
32
|
+
*
|
|
33
|
+
* ## Compatibility
|
|
34
|
+
*
|
|
35
|
+
* An `adapter` export still wins, so existing worlds are untouched and a game
|
|
36
|
+
* needing full control over its own `RootAdapter` keeps it.
|
|
37
|
+
*/
|
|
38
|
+
import type { RootAdapter } from '../adapter/root-adapter';
|
|
39
|
+
import type { AdapterSurfaceFactory } from '../runtime/mount-game';
|
|
40
|
+
/**
|
|
41
|
+
* What a three entry module MEANS, in one place.
|
|
42
|
+
*
|
|
43
|
+
* Two callers need this answer and must never disagree about it: the runtime
|
|
44
|
+
* mount ({@link r3fRootFactory}, below) and the EDITOR's design session
|
|
45
|
+
* (`packages/editor/src/authoring/r3f-design-session.ts`), which design-mounts
|
|
46
|
+
* the same entry so edit mode authors the live fiber scene. When only the
|
|
47
|
+
* runtime knew about the default-export shape, the converted starter played
|
|
48
|
+
* fine under `npm run game` and edit mode showed "(no scene loaded)".
|
|
49
|
+
*
|
|
50
|
+
* Returns `null` when the module is neither shape — the callers differ on what
|
|
51
|
+
* to do about that (the factory throws, the design session declines the world
|
|
52
|
+
* and leaves existing paths alone).
|
|
53
|
+
*/
|
|
54
|
+
export declare function resolveR3FEntryAdapter(entryModule: unknown, rootId: string): RootAdapter | null;
|
|
55
|
+
/**
|
|
56
|
+
* Register with `registerAdapter('three', r3fRootFactory)`.
|
|
57
|
+
*
|
|
58
|
+
* Resolution order mirrors `defaultThreeAdapterFactory`'s (explicit adapter
|
|
59
|
+
* wins) and then accepts the default-exported component.
|
|
60
|
+
*/
|
|
61
|
+
export declare const r3fRootFactory: AdapterSurfaceFactory;
|
|
62
|
+
//# sourceMappingURL=r3f-root-factory.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"r3f-root-factory.d.ts","sourceRoot":"","sources":["../../src/world3d-react/r3f-root-factory.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AAGH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAUnE;;;;;;;;;;;;;GAaG;AACH,wBAAgB,sBAAsB,CAAC,WAAW,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI,CAU/F;AAED;;;;;GAKG;AACH,eAAO,MAAM,cAAc,EAAE,qBAQ5B,CAAC"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `r3fRootFactory` — mount a `three` root whose entry module DEFAULT-EXPORTS a
|
|
3
|
+
* React component.
|
|
4
|
+
*
|
|
5
|
+
* The idiomatic-shape fix (D26). A model asked for an R3F world writes:
|
|
6
|
+
*
|
|
7
|
+
* ```tsx
|
|
8
|
+
* export default function World() {
|
|
9
|
+
* return <><ambientLight /><mesh>…</mesh></>;
|
|
10
|
+
* }
|
|
11
|
+
* ```
|
|
12
|
+
*
|
|
13
|
+
* It does NOT write `export const adapter = createR3FAdapter({ id, content })`.
|
|
14
|
+
* That export is pure vgai ceremony wrapped around a component the author
|
|
15
|
+
* already wrote, and it is the second-largest non-idiomatic thing left in a
|
|
16
|
+
* world file (the largest is the missing `<Canvas>`, which is a separate
|
|
17
|
+
* question about who owns the canvas — see D26).
|
|
18
|
+
*
|
|
19
|
+
* The `dom` root already settled this convention: its factory reads
|
|
20
|
+
* `entryModule.default` and wraps it. This is the same contract for three
|
|
21
|
+
* roots, so both surfaces answer "what do I export?" the same way.
|
|
22
|
+
*
|
|
23
|
+
* ## Why this is NOT in `mount-game.ts`
|
|
24
|
+
*
|
|
25
|
+
* `defaultThreeAdapterFactory` lives beside the registry, and the registry
|
|
26
|
+
* module is deliberately dependency-free: its own doc notes threejs is safe to
|
|
27
|
+
* ship there because `three` is already an unconditional engine dependency.
|
|
28
|
+
* `@react-three/fiber` is NOT — it is the PROJECT's dependency, and
|
|
29
|
+
* `world3d-react` is the opt-in module that owns it. Putting this factory
|
|
30
|
+
* there would make R3F unconditional for every game, including ones with no
|
|
31
|
+
* React at all.
|
|
32
|
+
*
|
|
33
|
+
* ## Compatibility
|
|
34
|
+
*
|
|
35
|
+
* An `adapter` export still wins, so existing worlds are untouched and a game
|
|
36
|
+
* needing full control over its own `RootAdapter` keeps it.
|
|
37
|
+
*/
|
|
38
|
+
import { createElement } from 'react';
|
|
39
|
+
import { createR3FAdapter } from './r3f-adapter';
|
|
40
|
+
/**
|
|
41
|
+
* What a three entry module MEANS, in one place.
|
|
42
|
+
*
|
|
43
|
+
* Two callers need this answer and must never disagree about it: the runtime
|
|
44
|
+
* mount ({@link r3fRootFactory}, below) and the EDITOR's design session
|
|
45
|
+
* (`packages/editor/src/authoring/r3f-design-session.ts`), which design-mounts
|
|
46
|
+
* the same entry so edit mode authors the live fiber scene. When only the
|
|
47
|
+
* runtime knew about the default-export shape, the converted starter played
|
|
48
|
+
* fine under `npm run game` and edit mode showed "(no scene loaded)".
|
|
49
|
+
*
|
|
50
|
+
* Returns `null` when the module is neither shape — the callers differ on what
|
|
51
|
+
* to do about that (the factory throws, the design session declines the world
|
|
52
|
+
* and leaves existing paths alone).
|
|
53
|
+
*/
|
|
54
|
+
export function resolveR3FEntryAdapter(entryModule, rootId) {
|
|
55
|
+
const mod = entryModule;
|
|
56
|
+
if (mod?.adapter)
|
|
57
|
+
return mod.adapter;
|
|
58
|
+
if (typeof mod?.default === 'function') {
|
|
59
|
+
return createR3FAdapter({
|
|
60
|
+
id: rootId,
|
|
61
|
+
content: createElement(mod.default),
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
return null;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Register with `registerAdapter('three', r3fRootFactory)`.
|
|
68
|
+
*
|
|
69
|
+
* Resolution order mirrors `defaultThreeAdapterFactory`'s (explicit adapter
|
|
70
|
+
* wins) and then accepts the default-exported component.
|
|
71
|
+
*/
|
|
72
|
+
export const r3fRootFactory = (root, ctx) => {
|
|
73
|
+
const adapter = resolveR3FEntryAdapter(ctx.entryModule, root.id);
|
|
74
|
+
if (adapter)
|
|
75
|
+
return { kind: 'three', adapter };
|
|
76
|
+
throw new Error(`r3fRootFactory: entry module "${root.entry ?? '(none)'}" for root "${root.id}" must ` +
|
|
77
|
+
'default-export a React component (`export default function World() { … }`) — or export ' +
|
|
78
|
+
'an `adapter` for full control.');
|
|
79
|
+
};
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `<RapierPhysicsBridge>` — the one line that makes an R3F world's
|
|
3
|
+
* `@react-three/rapier` physics VISIBLE to the engine's editor/dev seams.
|
|
4
|
+
*
|
|
5
|
+
* WHY IT EXISTS. `SystemAdapters.physics` is what the editor's transform
|
|
6
|
+
* coordination (`freeze → apply → unfreeze`) and the dev menu's universal
|
|
7
|
+
* "Colliders drawn" instrument (`@engine/dev/instruments`) read. The
|
|
8
|
+
* first-party imperative three root registers one from
|
|
9
|
+
* `../adapter/setup-three-root-adapter.ts`; an R3F world builds no first-party
|
|
10
|
+
* Rapier runtime at all (see `R3FGameContext`'s doc comment) — it does physics
|
|
11
|
+
* with `@react-three/rapier` INSIDE the fiber tree, where nothing engine-side
|
|
12
|
+
* can see it. Result, before this: the colliders instrument read `null` (an
|
|
13
|
+
* em-dash) and its toggle threw "no physics adapter" in every shipped example
|
|
14
|
+
* and every scaffolded game.
|
|
15
|
+
*
|
|
16
|
+
* NOT A WRAPPER. This registers an adapter and gets out of the way: the world
|
|
17
|
+
* still writes `<Physics>` itself, with the library's own props, and every
|
|
18
|
+
* `<RigidBody>`/collider call stays `@react-three/rapier`'s own API. The one
|
|
19
|
+
* thing it cannot do for you is flip the library's debug rendering, because
|
|
20
|
+
* `@react-three/rapier@2` exposes that ONLY as the `debug` boolean PROP on
|
|
21
|
+
* `<Physics>` (its `<Debug>` component is internal and unexported). A prop is
|
|
22
|
+
* the parent's to own, so the world holds the state and this bridge hands the
|
|
23
|
+
* setter to the instrument — which is why `onDebugChange` is required:
|
|
24
|
+
*
|
|
25
|
+
* ```tsx
|
|
26
|
+
* const [physicsDebug, setPhysicsDebug] = useState(false);
|
|
27
|
+
* // …
|
|
28
|
+
* <Physics debug={physicsDebug}>
|
|
29
|
+
* <RapierPhysicsBridge onDebugChange={setPhysicsDebug} />
|
|
30
|
+
* …
|
|
31
|
+
* </Physics>
|
|
32
|
+
* ```
|
|
33
|
+
*
|
|
34
|
+
* Nothing draws colliders here: the wireframes are the library's own
|
|
35
|
+
* `world.debugRender()` output, rendered by its own component.
|
|
36
|
+
*
|
|
37
|
+
* ANTI-SHIM. `debugDraw()` and `contactPoints()` are OMITTED, not stubbed —
|
|
38
|
+
* the library owns its debug line segments inside the tree and hands out no
|
|
39
|
+
* handle to them, so claiming the capability would be a fabrication. Absence
|
|
40
|
+
* is how a `SystemAdapters` member says "not supported".
|
|
41
|
+
*
|
|
42
|
+
* ── RESOURCE OWNERSHIP, STATED ONCE ─────────────────────────────────────────
|
|
43
|
+
* OWNER: this component owns exactly ONE `SystemAdapters.physics` registration,
|
|
44
|
+
* on the R3F root it is mounted in. It allocates nothing else — no timers, no
|
|
45
|
+
* subscriptions, no per-frame work (see the phase note below), and no Rapier
|
|
46
|
+
* objects: the bodies it edits belong to `<Physics>`.
|
|
47
|
+
* SHARERS: every reader of `game.systemAdapters.physics` — the dev menu's
|
|
48
|
+
* colliders instrument, the editor's transform coordination. They read; they
|
|
49
|
+
* never dispose.
|
|
50
|
+
* TEARDOWN: the effect's cleanup, and nothing else — it clears the SAME key it
|
|
51
|
+
* set (`registerSystemAdapter('physics', undefined)`, which
|
|
52
|
+
* `Game.computeSystemAdapters` skips), so a play stop/start, a hot restart, or
|
|
53
|
+
* a world that unmounts `<Physics>` leaves no stale adapter behind. Two
|
|
54
|
+
* bridges in one root would fight over that one key; mount exactly one.
|
|
55
|
+
*
|
|
56
|
+
* PHASE ORDERING: none to respect — this component registers pull-only
|
|
57
|
+
* callbacks and runs no per-frame work. Every method it exposes is invoked
|
|
58
|
+
* BETWEEN frames, by an editor gesture or a dev-menu command, never from a
|
|
59
|
+
* phase.
|
|
60
|
+
*/
|
|
61
|
+
export interface RapierPhysicsBridgeProps {
|
|
62
|
+
/**
|
|
63
|
+
* Set the `debug` prop of the SAME `<Physics>` this bridge is mounted in.
|
|
64
|
+
* The dev menu's "Colliders drawn" toggle calls it; the world's own state is
|
|
65
|
+
* what `<Physics debug={…}>` reads, so the library's debug rendering is the
|
|
66
|
+
* only thing that ever draws a collider.
|
|
67
|
+
*/
|
|
68
|
+
readonly onDebugChange: (debug: boolean) => void;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Register this R3F world's `@react-three/rapier` physics as the game's
|
|
72
|
+
* `SystemAdapters.physics`. Mount it once, INSIDE `<Physics>` (it reads
|
|
73
|
+
* `useRapier()`). Renders nothing.
|
|
74
|
+
*/
|
|
75
|
+
export declare function RapierPhysicsBridge({ onDebugChange }: RapierPhysicsBridgeProps): null;
|
|
76
|
+
//# sourceMappingURL=rapier-physics-bridge.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rapier-physics-bridge.d.ts","sourceRoot":"","sources":["../../src/world3d-react/rapier-physics-bridge.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2DG;AAYH,MAAM,WAAW,wBAAwB;IACvC;;;;;OAKG;IACH,QAAQ,CAAC,aAAa,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;CAClD;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,EAAE,aAAa,EAAE,EAAE,wBAAwB,GAAG,IAAI,CAkDrF"}
|