@vgai/engine 0.5.5 → 0.5.7
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/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,73 @@
|
|
|
1
|
+
import * as THREE from 'three';
|
|
2
|
+
/**
|
|
3
|
+
* Debug drawing utilities for development.
|
|
4
|
+
*
|
|
5
|
+
* Draw lines, spheres, boxes, and arrows for visualizing
|
|
6
|
+
* physics colliders, raycasts, AI paths, etc.
|
|
7
|
+
*
|
|
8
|
+
* All debug objects are added to a dedicated group that can be toggled.
|
|
9
|
+
*/
|
|
10
|
+
export function createDebugDraw(scene) {
|
|
11
|
+
const group = new THREE.Group();
|
|
12
|
+
group.name = 'debug-draw';
|
|
13
|
+
scene.add(group);
|
|
14
|
+
return {
|
|
15
|
+
/** Draw a line between two points */
|
|
16
|
+
line(from, to, color = 0x00ff00) {
|
|
17
|
+
const geometry = new THREE.BufferGeometry().setFromPoints([from, to]);
|
|
18
|
+
const material = new THREE.LineBasicMaterial({ color });
|
|
19
|
+
const line = new THREE.Line(geometry, material);
|
|
20
|
+
group.add(line);
|
|
21
|
+
return line;
|
|
22
|
+
},
|
|
23
|
+
/** Draw a wireframe sphere at a position */
|
|
24
|
+
sphere(center, radius = 0.1, color = 0xff0000) {
|
|
25
|
+
const geo = new THREE.SphereGeometry(radius, 8, 8);
|
|
26
|
+
const mat = new THREE.MeshBasicMaterial({ color, wireframe: true });
|
|
27
|
+
const mesh = new THREE.Mesh(geo, mat);
|
|
28
|
+
mesh.position.copy(center);
|
|
29
|
+
group.add(mesh);
|
|
30
|
+
return mesh;
|
|
31
|
+
},
|
|
32
|
+
/** Draw a wireframe box */
|
|
33
|
+
box(center, size, color = 0x00ffff) {
|
|
34
|
+
const geo = new THREE.BoxGeometry(size.x, size.y, size.z);
|
|
35
|
+
const mat = new THREE.MeshBasicMaterial({ color, wireframe: true });
|
|
36
|
+
const mesh = new THREE.Mesh(geo, mat);
|
|
37
|
+
mesh.position.copy(center);
|
|
38
|
+
group.add(mesh);
|
|
39
|
+
return mesh;
|
|
40
|
+
},
|
|
41
|
+
/** Draw an arrow (direction indicator) */
|
|
42
|
+
arrow(origin, direction, length = 1, color = 0xffff00) {
|
|
43
|
+
// Clone before normalize() — never mutate the caller's vector.
|
|
44
|
+
const dir = direction.clone().normalize();
|
|
45
|
+
const arrow = new THREE.ArrowHelper(dir, origin, length, color);
|
|
46
|
+
group.add(arrow);
|
|
47
|
+
return arrow;
|
|
48
|
+
},
|
|
49
|
+
/** Clear all debug drawings */
|
|
50
|
+
clear() {
|
|
51
|
+
while (group.children.length > 0) {
|
|
52
|
+
const child = group.children[0];
|
|
53
|
+
group.remove(child);
|
|
54
|
+
if (child instanceof THREE.Mesh || child instanceof THREE.Line) {
|
|
55
|
+
// Mesh, Line and LineSegments all own geometry + material.
|
|
56
|
+
child.geometry.dispose();
|
|
57
|
+
child.material.dispose();
|
|
58
|
+
}
|
|
59
|
+
else if (child instanceof THREE.ArrowHelper) {
|
|
60
|
+
// ArrowHelper owns a line + cone; dispose() frees both.
|
|
61
|
+
child.dispose();
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
/** Toggle debug draw visibility */
|
|
66
|
+
set visible(v) {
|
|
67
|
+
group.visible = v;
|
|
68
|
+
},
|
|
69
|
+
get visible() {
|
|
70
|
+
return group.visible;
|
|
71
|
+
},
|
|
72
|
+
};
|
|
73
|
+
}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* THE UNIVERSAL INSTRUMENTS — time scale, pause/frame-step, collider draw and
|
|
3
|
+
* frame time, furnished by the ENGINE for every game before it has written a
|
|
4
|
+
* line.
|
|
5
|
+
*
|
|
6
|
+
* These are physics of the medium, not genre ontology. Time runs; it can run
|
|
7
|
+
* slower or stop; a frame can be stepped; colliders can be drawn; frames take
|
|
8
|
+
* time. None of that is a decision any particular game makes, so none of it
|
|
9
|
+
* belongs in a game's own declarations — and none of it belongs on the game's
|
|
10
|
+
* own dev panel either, which shows ONLY what the game itself declared
|
|
11
|
+
* (`stat()`, `cheat()`). They publish as DOORS: an agent drives them through
|
|
12
|
+
* `game.state()`/`game.command()`, and a human drives the same controls from
|
|
13
|
+
* the editor chrome that already owns them — pause and frame-step on the
|
|
14
|
+
* transport, frame time on the stats overlay, colliders in the play-adopted
|
|
15
|
+
* Scene viewport.
|
|
16
|
+
*
|
|
17
|
+
* WHAT IS NOT HERE, and why: a FREE CAMERA. The editor already ships one
|
|
18
|
+
* (owner, 2026-08-10): play adoption swaps the live game scene into the editor
|
|
19
|
+
* viewport (`enterPlayScene`), so the Scene view during play IS a free orbit
|
|
20
|
+
* camera over the running game — no game-side camera override needed, and the
|
|
21
|
+
* game's own camera writes never fight it because the game keeps rendering
|
|
22
|
+
* through its own canvas untouched. Per the non-redundancy rule that governs
|
|
23
|
+
* this list, a control the editor's own chrome furnishes gets no instrument;
|
|
24
|
+
* agents reach that camera through the editor half of `vgai eval`, not the
|
|
25
|
+
* game registry.
|
|
26
|
+
*
|
|
27
|
+
* ── THE DOOR ────────────────────────────────────────────────────────────────
|
|
28
|
+
* This module is IMPLEMENTATION ONLY. It publishes nothing itself: the dev-menu
|
|
29
|
+
* capability's own registry adopts this list (`installDevMenuInstruments`) and
|
|
30
|
+
* publishes each instrument through the SAME door every declaration in that
|
|
31
|
+
* capability uses — one provider per reading (`instrument.timescale`), one
|
|
32
|
+
* command per action (`instrument.timescale.set`), plus the `dev-menu` index
|
|
33
|
+
* provider. That is deliberate and load-bearing: the registry IS the product,
|
|
34
|
+
* so every reader of an instrument reaches the SAME registration.
|
|
35
|
+
*
|
|
36
|
+
* ── DEGRADING ───────────────────────────────────────────────────────────────
|
|
37
|
+
* An instrument whose subject this game does not have (no physics adapter ⇒ no
|
|
38
|
+
* colliders) READS `null` — honest emptiness rather than a fabricated value.
|
|
39
|
+
* Its ACTION, invoked anyway, THROWS and names what is missing. Silence is the
|
|
40
|
+
* one thing forbidden: an agent that calls `instrument.colliders.toggle` and
|
|
41
|
+
* gets `undefined` back learns nothing.
|
|
42
|
+
*
|
|
43
|
+
* ── RESOURCE OWNERSHIP, STATED ONCE ─────────────────────────────────────────
|
|
44
|
+
* {@link createDevInstruments} owns everything it allocates: the frame-time
|
|
45
|
+
* ring buffer and its ONE `game.onRenderStep` subscription. SHARER: the
|
|
46
|
+
* dev-menu capability's `DevMenuBridge`, which creates one set per mounted
|
|
47
|
+
* game. TEARDOWN: the returned {@link DevInstrumentSet.dispose} — the ONE path
|
|
48
|
+
* that ends it. Nothing else here holds a resource; the time-scale, pause and
|
|
49
|
+
* collider instruments only drive state that `Game` already owns.
|
|
50
|
+
*/
|
|
51
|
+
import { z } from 'zod';
|
|
52
|
+
import type { Game } from '../runtime/game';
|
|
53
|
+
/** What shape an instrument's reading is, and what drives it. Data, not
|
|
54
|
+
* layout: a reader learns how to interpret and actuate an instrument without
|
|
55
|
+
* having to recognise it by name. */
|
|
56
|
+
export type DevInstrumentControl =
|
|
57
|
+
/** A value only. */
|
|
58
|
+
{
|
|
59
|
+
readonly kind: 'reading';
|
|
60
|
+
}
|
|
61
|
+
/** On/off, driven by the named action. */
|
|
62
|
+
| {
|
|
63
|
+
readonly kind: 'toggle';
|
|
64
|
+
readonly action: string;
|
|
65
|
+
}
|
|
66
|
+
/** A continuous value, driven by the named action (one numeric argument). */
|
|
67
|
+
| {
|
|
68
|
+
readonly kind: 'scale';
|
|
69
|
+
readonly action: string;
|
|
70
|
+
readonly min: number;
|
|
71
|
+
readonly max: number;
|
|
72
|
+
readonly step: number;
|
|
73
|
+
}
|
|
74
|
+
/** A {@link FrameTimeReading} — a window of samples, not a scalar. */
|
|
75
|
+
| {
|
|
76
|
+
readonly kind: 'plot';
|
|
77
|
+
};
|
|
78
|
+
/** One instrument verb. Every action declares an args tuple — `z.tuple([])`
|
|
79
|
+
* for a verb that takes none — so the debug registry REJECTS an unexpected
|
|
80
|
+
* argument at the door instead of passing it through to a handler that
|
|
81
|
+
* ignores it. */
|
|
82
|
+
export interface DevInstrumentAction {
|
|
83
|
+
/** Second half of the command name: `instrument.<id>.<this>`. */
|
|
84
|
+
readonly id: string;
|
|
85
|
+
readonly label: string;
|
|
86
|
+
readonly hint: string;
|
|
87
|
+
readonly args: z.ZodTuple;
|
|
88
|
+
run(values: readonly unknown[]): unknown;
|
|
89
|
+
}
|
|
90
|
+
export interface DevInstrument {
|
|
91
|
+
/** Second half of the provider name: `instrument.<this>`. */
|
|
92
|
+
readonly id: string;
|
|
93
|
+
readonly label: string;
|
|
94
|
+
readonly hint: string;
|
|
95
|
+
/** Trailing unit for a scalar reading (`x`, `ms`). */
|
|
96
|
+
readonly unit?: string;
|
|
97
|
+
readonly control: DevInstrumentControl;
|
|
98
|
+
readonly actions: readonly DevInstrumentAction[];
|
|
99
|
+
/** This instant's value, or `null` when this game has no such subject. */
|
|
100
|
+
read(): unknown;
|
|
101
|
+
}
|
|
102
|
+
export interface DevInstrumentSet {
|
|
103
|
+
readonly instruments: readonly DevInstrument[];
|
|
104
|
+
/** See the ownership note above — the ONE teardown path. */
|
|
105
|
+
dispose(): void;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* How many display frames the frame-time reading keeps. ~1 second at 60 Hz —
|
|
109
|
+
* long enough that a hitch is still in the window when you look, short enough
|
|
110
|
+
* that the mean tracks what the game is doing NOW.
|
|
111
|
+
*/
|
|
112
|
+
export declare const FRAME_TIME_WINDOW = 60;
|
|
113
|
+
/** What `instrument.frame-time` reads. `null`s (rather than zeros) before the
|
|
114
|
+
* first sampled frame: a stopped game has no frame time, and `0 ms / 0 fps`
|
|
115
|
+
* would read as a measurement. */
|
|
116
|
+
export interface FrameTimeReading {
|
|
117
|
+
/** Mean wall-clock milliseconds per display frame over the window. */
|
|
118
|
+
readonly ms: number | null;
|
|
119
|
+
/** Frames per second implied by {@link ms}. */
|
|
120
|
+
readonly fps: number | null;
|
|
121
|
+
/** The worst single frame in the window — the hitch the mean hides. */
|
|
122
|
+
readonly worstMs: number | null;
|
|
123
|
+
/** Oldest first, for the plot. */
|
|
124
|
+
readonly samples: readonly number[];
|
|
125
|
+
}
|
|
126
|
+
/** Pure: the whole frame-time reading from a window of samples. */
|
|
127
|
+
export declare function summarizeFrameTimes(samples: readonly number[]): FrameTimeReading;
|
|
128
|
+
/**
|
|
129
|
+
* Build this game's universal instrument set. One call per mounted game; the
|
|
130
|
+
* caller owns the returned {@link DevInstrumentSet.dispose}.
|
|
131
|
+
*/
|
|
132
|
+
export declare function createDevInstruments(game: Game): DevInstrumentSet;
|
|
133
|
+
//# sourceMappingURL=instruments.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"instruments.d.ts","sourceRoot":"","sources":["../../src/dev/instruments.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiDG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAE5C;;sCAEsC;AACtC,MAAM,MAAM,oBAAoB;AAC9B,oBAAoB;AAClB;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAA;CAAE;AAC9B,0CAA0C;GACxC;IAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE;AACtD,6EAA6E;GAC3E;IACE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AACH,sEAAsE;GACpE;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAE9B;;;kBAGkB;AAClB,MAAM,WAAW,mBAAmB;IAClC,iEAAiE;IACjE,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,QAAQ,CAAC;IAC1B,GAAG,CAAC,MAAM,EAAE,SAAS,OAAO,EAAE,GAAG,OAAO,CAAC;CAC1C;AAED,MAAM,WAAW,aAAa;IAC5B,6DAA6D;IAC7D,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,sDAAsD;IACtD,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,OAAO,EAAE,oBAAoB,CAAC;IACvC,QAAQ,CAAC,OAAO,EAAE,SAAS,mBAAmB,EAAE,CAAC;IACjD,0EAA0E;IAC1E,IAAI,IAAI,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,WAAW,EAAE,SAAS,aAAa,EAAE,CAAC;IAC/C,4DAA4D;IAC5D,OAAO,IAAI,IAAI,CAAC;CACjB;AAED;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,KAAK,CAAC;AAEpC;;mCAEmC;AACnC,MAAM,WAAW,gBAAgB;IAC/B,sEAAsE;IACtE,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,+CAA+C;IAC/C,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,uEAAuE;IACvE,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,kCAAkC;IAClC,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;CACrC;AAED,mEAAmE;AACnE,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,GAAG,gBAAgB,CAehF;AAcD;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,IAAI,GAAG,gBAAgB,CAwIjE"}
|
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* THE UNIVERSAL INSTRUMENTS — time scale, pause/frame-step, collider draw and
|
|
3
|
+
* frame time, furnished by the ENGINE for every game before it has written a
|
|
4
|
+
* line.
|
|
5
|
+
*
|
|
6
|
+
* These are physics of the medium, not genre ontology. Time runs; it can run
|
|
7
|
+
* slower or stop; a frame can be stepped; colliders can be drawn; frames take
|
|
8
|
+
* time. None of that is a decision any particular game makes, so none of it
|
|
9
|
+
* belongs in a game's own declarations — and none of it belongs on the game's
|
|
10
|
+
* own dev panel either, which shows ONLY what the game itself declared
|
|
11
|
+
* (`stat()`, `cheat()`). They publish as DOORS: an agent drives them through
|
|
12
|
+
* `game.state()`/`game.command()`, and a human drives the same controls from
|
|
13
|
+
* the editor chrome that already owns them — pause and frame-step on the
|
|
14
|
+
* transport, frame time on the stats overlay, colliders in the play-adopted
|
|
15
|
+
* Scene viewport.
|
|
16
|
+
*
|
|
17
|
+
* WHAT IS NOT HERE, and why: a FREE CAMERA. The editor already ships one
|
|
18
|
+
* (owner, 2026-08-10): play adoption swaps the live game scene into the editor
|
|
19
|
+
* viewport (`enterPlayScene`), so the Scene view during play IS a free orbit
|
|
20
|
+
* camera over the running game — no game-side camera override needed, and the
|
|
21
|
+
* game's own camera writes never fight it because the game keeps rendering
|
|
22
|
+
* through its own canvas untouched. Per the non-redundancy rule that governs
|
|
23
|
+
* this list, a control the editor's own chrome furnishes gets no instrument;
|
|
24
|
+
* agents reach that camera through the editor half of `vgai eval`, not the
|
|
25
|
+
* game registry.
|
|
26
|
+
*
|
|
27
|
+
* ── THE DOOR ────────────────────────────────────────────────────────────────
|
|
28
|
+
* This module is IMPLEMENTATION ONLY. It publishes nothing itself: the dev-menu
|
|
29
|
+
* capability's own registry adopts this list (`installDevMenuInstruments`) and
|
|
30
|
+
* publishes each instrument through the SAME door every declaration in that
|
|
31
|
+
* capability uses — one provider per reading (`instrument.timescale`), one
|
|
32
|
+
* command per action (`instrument.timescale.set`), plus the `dev-menu` index
|
|
33
|
+
* provider. That is deliberate and load-bearing: the registry IS the product,
|
|
34
|
+
* so every reader of an instrument reaches the SAME registration.
|
|
35
|
+
*
|
|
36
|
+
* ── DEGRADING ───────────────────────────────────────────────────────────────
|
|
37
|
+
* An instrument whose subject this game does not have (no physics adapter ⇒ no
|
|
38
|
+
* colliders) READS `null` — honest emptiness rather than a fabricated value.
|
|
39
|
+
* Its ACTION, invoked anyway, THROWS and names what is missing. Silence is the
|
|
40
|
+
* one thing forbidden: an agent that calls `instrument.colliders.toggle` and
|
|
41
|
+
* gets `undefined` back learns nothing.
|
|
42
|
+
*
|
|
43
|
+
* ── RESOURCE OWNERSHIP, STATED ONCE ─────────────────────────────────────────
|
|
44
|
+
* {@link createDevInstruments} owns everything it allocates: the frame-time
|
|
45
|
+
* ring buffer and its ONE `game.onRenderStep` subscription. SHARER: the
|
|
46
|
+
* dev-menu capability's `DevMenuBridge`, which creates one set per mounted
|
|
47
|
+
* game. TEARDOWN: the returned {@link DevInstrumentSet.dispose} — the ONE path
|
|
48
|
+
* that ends it. Nothing else here holds a resource; the time-scale, pause and
|
|
49
|
+
* collider instruments only drive state that `Game` already owns.
|
|
50
|
+
*/
|
|
51
|
+
import { z } from 'zod';
|
|
52
|
+
import { clampTimeScale, TIME_SCALE_RANGE } from '../core/frame-pacing';
|
|
53
|
+
/**
|
|
54
|
+
* How many display frames the frame-time reading keeps. ~1 second at 60 Hz —
|
|
55
|
+
* long enough that a hitch is still in the window when you look, short enough
|
|
56
|
+
* that the mean tracks what the game is doing NOW.
|
|
57
|
+
*/
|
|
58
|
+
export const FRAME_TIME_WINDOW = 60;
|
|
59
|
+
/** Pure: the whole frame-time reading from a window of samples. */
|
|
60
|
+
export function summarizeFrameTimes(samples) {
|
|
61
|
+
if (samples.length === 0)
|
|
62
|
+
return { ms: null, fps: null, worstMs: null, samples: [] };
|
|
63
|
+
let total = 0;
|
|
64
|
+
let worst = 0;
|
|
65
|
+
for (const sample of samples) {
|
|
66
|
+
total += sample;
|
|
67
|
+
if (sample > worst)
|
|
68
|
+
worst = sample;
|
|
69
|
+
}
|
|
70
|
+
const ms = total / samples.length;
|
|
71
|
+
return {
|
|
72
|
+
ms: round(ms, 2),
|
|
73
|
+
fps: ms > 0 ? round(1000 / ms, 1) : null,
|
|
74
|
+
worstMs: round(worst, 2),
|
|
75
|
+
samples: samples.map((sample) => round(sample, 2)),
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
function round(value, places) {
|
|
79
|
+
const factor = 10 ** places;
|
|
80
|
+
return Math.round(value * factor) / factor;
|
|
81
|
+
}
|
|
82
|
+
const NO_COLLIDERS = 'No physics adapter on this game implements setDebugDrawEnabled, so nothing can draw its ' +
|
|
83
|
+
'colliders. A first-party three root with Rapier physics registers one; a game with no ' +
|
|
84
|
+
'physics has no colliders to draw.';
|
|
85
|
+
const NO_ARGS = z.tuple([]);
|
|
86
|
+
/**
|
|
87
|
+
* Build this game's universal instrument set. One call per mounted game; the
|
|
88
|
+
* caller owns the returned {@link DevInstrumentSet.dispose}.
|
|
89
|
+
*/
|
|
90
|
+
export function createDevInstruments(game) {
|
|
91
|
+
// --- Frame time: one subscription, one ring buffer ------------------------
|
|
92
|
+
const samples = [];
|
|
93
|
+
let previousFrameAt = now();
|
|
94
|
+
const stopSampling = game.onRenderStep(() => {
|
|
95
|
+
const at = now();
|
|
96
|
+
samples.push(at - previousFrameAt);
|
|
97
|
+
previousFrameAt = at;
|
|
98
|
+
if (samples.length > FRAME_TIME_WINDOW)
|
|
99
|
+
samples.shift();
|
|
100
|
+
});
|
|
101
|
+
// --- Collider draw: the adapter has a setter and no getter, so the ON/OFF
|
|
102
|
+
// state is ours to remember. It is only ever written through the one action
|
|
103
|
+
// below, which is also the only thing that calls the adapter.
|
|
104
|
+
let collidersDrawn = false;
|
|
105
|
+
const colliderDraw = () => {
|
|
106
|
+
const adapter = game.systemAdapters.physics;
|
|
107
|
+
return adapter?.setDebugDrawEnabled ? adapter : null;
|
|
108
|
+
};
|
|
109
|
+
const instruments = [
|
|
110
|
+
{
|
|
111
|
+
id: 'timescale',
|
|
112
|
+
label: 'Time scale',
|
|
113
|
+
hint: 'Sim speed multiplier. 1 is real time, 0 freezes the simulation while the game keeps drawing.',
|
|
114
|
+
unit: 'x',
|
|
115
|
+
control: {
|
|
116
|
+
kind: 'scale',
|
|
117
|
+
action: 'set',
|
|
118
|
+
min: TIME_SCALE_RANGE.min,
|
|
119
|
+
max: TIME_SCALE_RANGE.max,
|
|
120
|
+
step: 0.05,
|
|
121
|
+
},
|
|
122
|
+
actions: [
|
|
123
|
+
{
|
|
124
|
+
id: 'set',
|
|
125
|
+
label: 'Set',
|
|
126
|
+
hint: `Set the sim speed multiplier (${TIME_SCALE_RANGE.min}–${TIME_SCALE_RANGE.max}).`,
|
|
127
|
+
args: z.tuple([z.number()]),
|
|
128
|
+
run: (values) => {
|
|
129
|
+
// The LOOP clamps and warns; asking for the clamp here too would
|
|
130
|
+
// be a second opinion about the same range. It reads back the
|
|
131
|
+
// value that actually took effect, never the one requested.
|
|
132
|
+
game.loop.timeScale = clampTimeScale(values[0]);
|
|
133
|
+
return game.loop.timeScale;
|
|
134
|
+
},
|
|
135
|
+
},
|
|
136
|
+
],
|
|
137
|
+
read: () => game.loop.timeScale,
|
|
138
|
+
},
|
|
139
|
+
{
|
|
140
|
+
id: 'paused',
|
|
141
|
+
label: 'Paused',
|
|
142
|
+
hint: 'Freeze the simulation. The game keeps drawing, so you can look at a frozen frame.',
|
|
143
|
+
control: { kind: 'toggle', action: 'toggle' },
|
|
144
|
+
actions: [
|
|
145
|
+
{
|
|
146
|
+
id: 'toggle',
|
|
147
|
+
label: 'Toggle',
|
|
148
|
+
hint: 'Pause or resume the simulation.',
|
|
149
|
+
args: NO_ARGS,
|
|
150
|
+
run: () => {
|
|
151
|
+
if (game.play.paused)
|
|
152
|
+
game.play.resume();
|
|
153
|
+
else
|
|
154
|
+
game.play.pause();
|
|
155
|
+
return game.play.paused;
|
|
156
|
+
},
|
|
157
|
+
},
|
|
158
|
+
{
|
|
159
|
+
id: 'step',
|
|
160
|
+
label: 'Step',
|
|
161
|
+
hint: 'Advance exactly one fixed substep. Pauses first if the game is running.',
|
|
162
|
+
args: NO_ARGS,
|
|
163
|
+
run: () => {
|
|
164
|
+
// Frame advance implies pause — `Game.play.step()` is a
|
|
165
|
+
// deliberate whole-call no-op while running, and a button that
|
|
166
|
+
// silently does nothing is the failure this instrument exists to
|
|
167
|
+
// avoid.
|
|
168
|
+
if (!game.play.paused)
|
|
169
|
+
game.play.pause();
|
|
170
|
+
game.play.step();
|
|
171
|
+
return game.play.paused;
|
|
172
|
+
},
|
|
173
|
+
},
|
|
174
|
+
],
|
|
175
|
+
read: () => game.play.paused,
|
|
176
|
+
},
|
|
177
|
+
{
|
|
178
|
+
id: 'colliders',
|
|
179
|
+
label: 'Colliders drawn',
|
|
180
|
+
hint: "Draw the physics colliders over the world, through the game's own physics adapter.",
|
|
181
|
+
control: { kind: 'toggle', action: 'toggle' },
|
|
182
|
+
actions: [
|
|
183
|
+
{
|
|
184
|
+
id: 'toggle',
|
|
185
|
+
label: 'Toggle',
|
|
186
|
+
hint: 'Turn collider wireframes on or off.',
|
|
187
|
+
args: NO_ARGS,
|
|
188
|
+
run: () => {
|
|
189
|
+
const adapter = colliderDraw();
|
|
190
|
+
if (!adapter)
|
|
191
|
+
throw new Error(NO_COLLIDERS);
|
|
192
|
+
collidersDrawn = !collidersDrawn;
|
|
193
|
+
adapter.setDebugDrawEnabled?.(collidersDrawn);
|
|
194
|
+
return collidersDrawn;
|
|
195
|
+
},
|
|
196
|
+
},
|
|
197
|
+
],
|
|
198
|
+
read: () => (colliderDraw() === null ? null : collidersDrawn),
|
|
199
|
+
},
|
|
200
|
+
{
|
|
201
|
+
id: 'frame-time',
|
|
202
|
+
label: 'Frame time',
|
|
203
|
+
hint: 'Wall-clock milliseconds per display frame, newest last. The window is where a hitch shows; the mean hides it.',
|
|
204
|
+
unit: 'ms',
|
|
205
|
+
control: { kind: 'plot' },
|
|
206
|
+
actions: [
|
|
207
|
+
{
|
|
208
|
+
id: 'clear',
|
|
209
|
+
label: 'Clear',
|
|
210
|
+
hint: 'Forget the sampled window and start measuring again.',
|
|
211
|
+
args: NO_ARGS,
|
|
212
|
+
run: () => {
|
|
213
|
+
samples.length = 0;
|
|
214
|
+
return null;
|
|
215
|
+
},
|
|
216
|
+
},
|
|
217
|
+
],
|
|
218
|
+
read: () => summarizeFrameTimes(samples),
|
|
219
|
+
},
|
|
220
|
+
];
|
|
221
|
+
return {
|
|
222
|
+
instruments,
|
|
223
|
+
dispose() {
|
|
224
|
+
stopSampling();
|
|
225
|
+
samples.length = 0;
|
|
226
|
+
},
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
function now() {
|
|
230
|
+
return typeof performance === 'undefined' ? Date.now() : performance.now();
|
|
231
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { LogLayer } from 'loglayer';
|
|
2
|
+
/**
|
|
3
|
+
* Flag set while the engine logger is calling console.* so that the
|
|
4
|
+
* console-bridge and play-mode patches can skip re-forwarding.
|
|
5
|
+
* JS is single-threaded so this is safe.
|
|
6
|
+
*/
|
|
7
|
+
export declare let _engineLogActive: boolean;
|
|
8
|
+
declare const engineLog: LogLayer;
|
|
9
|
+
export interface LogMeta {
|
|
10
|
+
entityId?: string | number | undefined;
|
|
11
|
+
[key: string]: unknown;
|
|
12
|
+
}
|
|
13
|
+
interface SubsystemLogger {
|
|
14
|
+
debug(msg: string, meta?: LogMeta): void;
|
|
15
|
+
info(msg: string, meta?: LogMeta): void;
|
|
16
|
+
warn(msg: string, meta?: LogMeta): void;
|
|
17
|
+
error(msg: string, meta?: LogMeta): void;
|
|
18
|
+
}
|
|
19
|
+
export declare const log: {
|
|
20
|
+
scene: SubsystemLogger;
|
|
21
|
+
physics: SubsystemLogger;
|
|
22
|
+
animation: SubsystemLogger;
|
|
23
|
+
network: SubsystemLogger;
|
|
24
|
+
audio: SubsystemLogger;
|
|
25
|
+
ai: SubsystemLogger;
|
|
26
|
+
input: SubsystemLogger;
|
|
27
|
+
core: SubsystemLogger;
|
|
28
|
+
};
|
|
29
|
+
export { engineLog };
|
|
30
|
+
//# sourceMappingURL=logger.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/dev/logger.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkB,QAAQ,EAAY,MAAM,UAAU,CAAC;AAE9D;;;;GAIG;AACH,eAAO,IAAI,gBAAgB,SAAQ,CAAC;AAWpC,QAAA,MAAM,SAAS,UA4Cb,CAAC;AAKH,MAAM,WAAW,OAAO;IACtB,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;IACvC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,UAAU,eAAe;IACvB,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IACzC,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IACxC,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IACxC,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;CAC1C;AAiBD,eAAO,MAAM,GAAG;;;;;;;;;CASf,CAAC;AAEF,OAAO,EAAE,SAAS,EAAE,CAAC"}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { BlankTransport, LogLayer, LogLevel } from 'loglayer';
|
|
2
|
+
/**
|
|
3
|
+
* Flag set while the engine logger is calling console.* so that the
|
|
4
|
+
* console-bridge and play-mode patches can skip re-forwarding.
|
|
5
|
+
* JS is single-threaded so this is safe.
|
|
6
|
+
*/
|
|
7
|
+
export let _engineLogActive = false;
|
|
8
|
+
const CONSOLE_MAP = {
|
|
9
|
+
trace: 'log',
|
|
10
|
+
debug: 'log',
|
|
11
|
+
info: 'log',
|
|
12
|
+
warn: 'warn',
|
|
13
|
+
error: 'error',
|
|
14
|
+
fatal: 'error',
|
|
15
|
+
};
|
|
16
|
+
const engineLog = new LogLayer({
|
|
17
|
+
transport: new BlankTransport({
|
|
18
|
+
shipToLogger: ({ logLevel, messages, data, hasData }) => {
|
|
19
|
+
const method = CONSOLE_MAP[logLevel] ?? 'log';
|
|
20
|
+
// Extract _sub (subsystem tag) from data, pass the rest as metadata
|
|
21
|
+
let subsystem;
|
|
22
|
+
let metadata;
|
|
23
|
+
if (hasData && data) {
|
|
24
|
+
const { _sub, ...rest } = data;
|
|
25
|
+
subsystem = _sub ? String(_sub) : undefined;
|
|
26
|
+
if (Object.keys(rest).length > 0)
|
|
27
|
+
metadata = rest;
|
|
28
|
+
}
|
|
29
|
+
// Call console for browser devtools
|
|
30
|
+
_engineLogActive = true;
|
|
31
|
+
if (metadata) {
|
|
32
|
+
// biome-ignore lint/suspicious/noConsole: intentional — this IS the logger
|
|
33
|
+
console[method](...messages, metadata);
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
// biome-ignore lint/suspicious/noConsole: intentional — this IS the logger
|
|
37
|
+
console[method](...messages);
|
|
38
|
+
}
|
|
39
|
+
_engineLogActive = false;
|
|
40
|
+
// Post structured message for editor console
|
|
41
|
+
if (typeof window !== 'undefined') {
|
|
42
|
+
window.postMessage({
|
|
43
|
+
type: 'engine-log',
|
|
44
|
+
level: logLevel,
|
|
45
|
+
message: messages.join(' '),
|
|
46
|
+
subsystem,
|
|
47
|
+
metadata,
|
|
48
|
+
timestamp: Date.now(),
|
|
49
|
+
}, '*');
|
|
50
|
+
}
|
|
51
|
+
return messages;
|
|
52
|
+
},
|
|
53
|
+
}),
|
|
54
|
+
prefix: '[engine]',
|
|
55
|
+
});
|
|
56
|
+
// Default to 'info' — debug/trace are off unless explicitly enabled
|
|
57
|
+
engineLog.setLevel(LogLevel.info);
|
|
58
|
+
function createSubsystemLogger(subsystem) {
|
|
59
|
+
return {
|
|
60
|
+
debug: (msg, meta) => engineLog.withMetadata({ ...meta, _sub: subsystem }).debug(`[${subsystem}] ${msg}`),
|
|
61
|
+
info: (msg, meta) => engineLog.withMetadata({ ...meta, _sub: subsystem }).info(`[${subsystem}] ${msg}`),
|
|
62
|
+
warn: (msg, meta) => engineLog.withMetadata({ ...meta, _sub: subsystem }).warn(`[${subsystem}] ${msg}`),
|
|
63
|
+
error: (msg, meta) => engineLog.withMetadata({ ...meta, _sub: subsystem }).error(`[${subsystem}] ${msg}`),
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
// Pre-built subsystem loggers — all share the same LogLayer instance
|
|
67
|
+
// so setLevel() on engineLog affects all of them.
|
|
68
|
+
export const log = {
|
|
69
|
+
scene: createSubsystemLogger('scene'),
|
|
70
|
+
physics: createSubsystemLogger('physics'),
|
|
71
|
+
animation: createSubsystemLogger('animation'),
|
|
72
|
+
network: createSubsystemLogger('network'),
|
|
73
|
+
audio: createSubsystemLogger('audio'),
|
|
74
|
+
ai: createSubsystemLogger('ai'),
|
|
75
|
+
input: createSubsystemLogger('input'),
|
|
76
|
+
core: createSubsystemLogger('core'),
|
|
77
|
+
};
|
|
78
|
+
export { engineLog };
|
|
79
|
+
// Expose to browser devtools: type setEngineLogLevel('debug') in console
|
|
80
|
+
if (typeof window !== 'undefined') {
|
|
81
|
+
window['setEngineLogLevel'] = (level) => {
|
|
82
|
+
engineLog.setLevel(level);
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
// URL param override: ?engineLogLevel=debug
|
|
86
|
+
if (typeof window !== 'undefined') {
|
|
87
|
+
const level = new URLSearchParams(window.location.search).get('engineLogLevel');
|
|
88
|
+
if (level)
|
|
89
|
+
engineLog.setLevel(level);
|
|
90
|
+
}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
export interface PerformanceTiming {
|
|
2
|
+
readonly name: string;
|
|
3
|
+
readonly ms: number;
|
|
4
|
+
/**
|
|
5
|
+
* Offset (ms) from THIS frame's start (`frameStart`) at which the timing
|
|
6
|
+
* began — a MEASURED value (e.g. a phase's `phaseStart - frameStart`), never
|
|
7
|
+
* synthesized. Present on per-frame phase timings (W4b, so a Chrome trace
|
|
8
|
+
* can place each phase span under its frame at the real offset). OMITTED on
|
|
9
|
+
* cross-frame aggregate rollups (`PerformanceSnapshot.phases`/`systems`/
|
|
10
|
+
* `components`), where no single start point exists — absent, never a
|
|
11
|
+
* fabricated 0.
|
|
12
|
+
*/
|
|
13
|
+
readonly startMs?: number;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* One MEASURED span within a frame (W4b) — a system or component invocation,
|
|
17
|
+
* with the phase it ran in and its measured start offset from `frameStart`.
|
|
18
|
+
* Distinct from {@link PerformanceTiming}: a span is a single timed
|
|
19
|
+
* invocation carrying `phase` + always-present `startMs` (the trace/flame
|
|
20
|
+
* unit), whereas a `PerformanceTiming` may be a cross-frame rollup.
|
|
21
|
+
*/
|
|
22
|
+
export interface PerformanceSpan {
|
|
23
|
+
readonly name: string;
|
|
24
|
+
readonly phase: string;
|
|
25
|
+
/** Measured offset (ms) from `frameStart` at which this span began. */
|
|
26
|
+
readonly startMs: number;
|
|
27
|
+
readonly ms: number;
|
|
28
|
+
}
|
|
29
|
+
/** Renderer counters accumulated over a frame (from `renderer.info`). */
|
|
30
|
+
export interface PerformanceRenderStats {
|
|
31
|
+
readonly gpuMs: number | null;
|
|
32
|
+
readonly drawCalls: number;
|
|
33
|
+
readonly triangles: number;
|
|
34
|
+
readonly geometries: number;
|
|
35
|
+
readonly textures: number;
|
|
36
|
+
}
|
|
37
|
+
export interface PerformanceFrame {
|
|
38
|
+
readonly id: number;
|
|
39
|
+
readonly timestamp: number;
|
|
40
|
+
readonly intervalMs: number;
|
|
41
|
+
readonly cpuMs: number;
|
|
42
|
+
readonly phases: readonly PerformanceTiming[];
|
|
43
|
+
/**
|
|
44
|
+
* Per-invocation system spans measured this frame (W4b). Ordered by
|
|
45
|
+
* `startMs` (execution order), NOT accumulated — a system that ran twice
|
|
46
|
+
* (two substeps) appears twice. Empty when the profiler saw no named
|
|
47
|
+
* systems this frame.
|
|
48
|
+
*/
|
|
49
|
+
readonly systems: readonly PerformanceSpan[];
|
|
50
|
+
/**
|
|
51
|
+
* Per-invocation component spans measured this frame (W4b) — populated ONLY
|
|
52
|
+
* while `recording` (component timing is gated on recording, matching
|
|
53
|
+
* `beginComponent`/`endComponent`). Empty otherwise.
|
|
54
|
+
*/
|
|
55
|
+
readonly components: readonly PerformanceSpan[];
|
|
56
|
+
/**
|
|
57
|
+
* Renderer counters reported during this frame (W4b) — a snapshot of the
|
|
58
|
+
* accumulated `reportRender` totals taken at `endFrame`. `gpuMs` is `null`
|
|
59
|
+
* when no GPU timer reported (headless/SwiftShader), never a fabricated 0.
|
|
60
|
+
*/
|
|
61
|
+
readonly render: PerformanceRenderStats;
|
|
62
|
+
}
|
|
63
|
+
export interface PerformanceSnapshot {
|
|
64
|
+
readonly enabled: boolean;
|
|
65
|
+
readonly recording: boolean;
|
|
66
|
+
readonly fps: number;
|
|
67
|
+
readonly cpuMs: number;
|
|
68
|
+
readonly p95Ms: number;
|
|
69
|
+
readonly p99Ms: number;
|
|
70
|
+
readonly frames: readonly PerformanceFrame[];
|
|
71
|
+
readonly phases: readonly PerformanceTiming[];
|
|
72
|
+
readonly systems: readonly PerformanceTiming[];
|
|
73
|
+
readonly components: readonly PerformanceTiming[];
|
|
74
|
+
readonly render: {
|
|
75
|
+
readonly gpuMs: number | null;
|
|
76
|
+
readonly drawCalls: number;
|
|
77
|
+
readonly triangles: number;
|
|
78
|
+
readonly geometries: number;
|
|
79
|
+
readonly textures: number;
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
/** Game-owned, bounded external store for browser-native performance diagnostics. */
|
|
83
|
+
export declare function createPerformanceProfiler(initiallyEnabled?: boolean): {
|
|
84
|
+
enabled: boolean;
|
|
85
|
+
readonly recording: boolean;
|
|
86
|
+
startRecording(): void;
|
|
87
|
+
stopRecording(): void;
|
|
88
|
+
clear(): void;
|
|
89
|
+
beginFrame(): void;
|
|
90
|
+
beginPhase(): void;
|
|
91
|
+
endPhase(name: string): void;
|
|
92
|
+
systemObserver: {
|
|
93
|
+
beginSystem(): void;
|
|
94
|
+
endSystem(scope: string, phase: string, name: string): void;
|
|
95
|
+
};
|
|
96
|
+
beginComponent(): void;
|
|
97
|
+
endComponent(name: string, phase?: string): void;
|
|
98
|
+
reportRender(stats: {
|
|
99
|
+
gpuMs: number | null;
|
|
100
|
+
drawCalls: number;
|
|
101
|
+
triangles: number;
|
|
102
|
+
geometries: number;
|
|
103
|
+
textures: number;
|
|
104
|
+
}): void;
|
|
105
|
+
endFrame(): void;
|
|
106
|
+
subscribe(listener: () => void): () => void;
|
|
107
|
+
getSnapshot(): PerformanceSnapshot;
|
|
108
|
+
exportJSON(): string;
|
|
109
|
+
};
|
|
110
|
+
export type PerformanceProfiler = ReturnType<typeof createPerformanceProfiler>;
|
|
111
|
+
//# sourceMappingURL=performance-profiler.d.ts.map
|