@vgai/engine 0.3.0 → 0.4.0-canary.20260715.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +8 -2
- package/schemas/engine-api.json +124 -0
- package/schemas/engine-api.md +53 -0
- package/schemas/engine-capabilities.json +124 -0
- package/schemas/inputmap.schema.json +314 -0
- package/schemas/mat.schema.json +286 -0
- package/schemas/prefab.schema.json +10148 -0
- package/schemas/scn2d.schema.json +475 -0
- package/schemas/vgai-game.schema.json +383 -0
- package/schemas/vscn.schema.json +11007 -0
- package/src/adapter/{world-kind.ts → adapter-surface.ts} +6 -6
- package/src/adapter/authoring.ts +67 -0
- package/src/adapter/game-adapter.ts +8 -8
- package/src/adapter/host-context.ts +2 -4
- package/src/adapter/index.ts +3 -1
- package/src/adapter/system-adapter.ts +73 -0
- package/src/adapter/vgai-scene-game-adapter.ts +239 -180
- package/src/animation/xstate-animation-binding.ts +300 -262
- package/src/animation/xstate-animation-meta.ts +50 -13
- package/src/character/cloth-sim.ts +533 -0
- package/src/character/spring-chain.ts +307 -0
- package/src/core/game-loop.ts +41 -3
- package/src/core/seeded-random.ts +161 -0
- package/src/core/system-runner.ts +20 -3
- package/src/core/types.ts +37 -0
- package/src/data/data-asset.ts +1 -1
- package/src/dev/performance-profiler.ts +213 -0
- package/src/dev/webgl-gpu-timer.ts +53 -0
- package/src/ecs/component-manager.ts +45 -12
- package/src/ecs/game-component.ts +95 -11
- package/src/humanoid/bake.operation.ts +326 -0
- package/src/humanoid/body.ts +663 -0
- package/src/humanoid/clips.ts +149 -0
- package/src/humanoid/compose.ts +209 -0
- package/src/humanoid/generate.ts +189 -0
- package/src/humanoid/index.ts +36 -0
- package/src/humanoid/schema.ts +108 -0
- package/src/humanoid/skeleton.ts +345 -0
- package/src/index.ts +5 -5
- package/src/input/input-manager.ts +701 -22
- package/src/input/input-types.ts +5 -2
- package/src/manifest/index.ts +5 -5
- package/src/manifest/load.ts +125 -72
- package/src/manifest/schema.ts +362 -255
- package/src/react/game-state.tsx +135 -32
- package/src/react/root-adapter.tsx +49 -0
- package/src/react/unmanaged-root-detector.ts +66 -0
- package/src/react/use-data.ts +12 -2
- package/src/runtime/create-runtime.ts +100 -282
- package/src/runtime/debug-bridge.ts +483 -0
- package/src/runtime/debug-registry.ts +856 -0
- package/src/runtime/game.ts +342 -93
- package/src/runtime/gameplay-rng-trap.ts +134 -0
- package/src/runtime/input-router.ts +7 -7
- package/src/runtime/mount-game.ts +40 -38
- package/src/runtime/mount-manifest.ts +169 -37
- package/src/runtime/render-control.ts +13 -13
- package/src/runtime/render-seed.ts +1 -1
- package/src/runtime/state-bridge.ts +24 -10
- package/src/runtime/types.ts +110 -28
- package/src/scene/asset-registry.ts +22 -0
- package/src/scene/component-registry.ts +14 -3
- package/src/scene/defaults.ts +1 -0
- package/src/scene/light-camera-factory.ts +11 -3
- package/src/scene/scene-apply.ts +55 -4
- package/src/scene/scene-loader.ts +10 -27
- package/src/scene/scene-types.ts +0 -1
- package/src/scene/schema/index.ts +0 -34
- package/src/scene/schema/light.ts +16 -1
- package/src/scene/schema/material.ts +96 -91
- package/src/scene/schema/scene-file.ts +1 -7
- package/src/scene/user-data.ts +14 -1
- package/src/setup/setup-renderer.ts +1 -1
- package/src/tools/define-tool.ts +50 -11
- package/src/world2d/authoring-2d.ts +17 -1
- package/src/world2d/collision-2d.ts +1 -1
- package/src/world2d/pixi-game-adapter.ts +19 -17
- package/src/world2d/scene2d-loader.ts +1 -0
- package/src/world2d/types.ts +8 -2
- package/dist/adapter/authoring.d.ts +0 -404
- package/dist/adapter/authoring.d.ts.map +0 -1
- package/dist/adapter/authoring.js +0 -22
- package/dist/adapter/colyseus-networking-adapter.d.ts +0 -43
- package/dist/adapter/colyseus-networking-adapter.d.ts.map +0 -1
- package/dist/adapter/colyseus-networking-adapter.js +0 -38
- package/dist/adapter/first-party-systems.d.ts +0 -38
- package/dist/adapter/first-party-systems.d.ts.map +0 -1
- package/dist/adapter/first-party-systems.js +0 -77
- package/dist/adapter/game-adapter.d.ts +0 -133
- package/dist/adapter/game-adapter.d.ts.map +0 -1
- package/dist/adapter/game-adapter.js +0 -10
- package/dist/adapter/host-context.d.ts +0 -73
- package/dist/adapter/host-context.d.ts.map +0 -1
- package/dist/adapter/host-context.js +0 -16
- package/dist/adapter/index.d.ts +0 -22
- package/dist/adapter/index.d.ts.map +0 -1
- package/dist/adapter/index.js +0 -15
- package/dist/adapter/ingest/game-contract.d.ts +0 -53
- package/dist/adapter/ingest/game-contract.d.ts.map +0 -1
- package/dist/adapter/ingest/game-contract.js +0 -30
- package/dist/adapter/ingest/overlay-applier.d.ts +0 -118
- package/dist/adapter/ingest/overlay-applier.d.ts.map +0 -1
- package/dist/adapter/ingest/overlay-applier.js +0 -132
- package/dist/adapter/ingest/overlay-apply.d.ts +0 -60
- package/dist/adapter/ingest/overlay-apply.d.ts.map +0 -1
- package/dist/adapter/ingest/overlay-apply.js +0 -101
- package/dist/adapter/ingest/overlay-file.d.ts +0 -79
- package/dist/adapter/ingest/overlay-file.d.ts.map +0 -1
- package/dist/adapter/ingest/overlay-file.js +0 -66
- package/dist/adapter/ingest/overlay-report.d.ts +0 -113
- package/dist/adapter/ingest/overlay-report.d.ts.map +0 -1
- package/dist/adapter/ingest/overlay-report.js +0 -103
- package/dist/adapter/ingest/scene-capture.d.ts +0 -97
- package/dist/adapter/ingest/scene-capture.d.ts.map +0 -1
- package/dist/adapter/ingest/scene-capture.js +0 -248
- package/dist/adapter/ingest/upstream-pin.d.ts +0 -47
- package/dist/adapter/ingest/upstream-pin.d.ts.map +0 -1
- package/dist/adapter/ingest/upstream-pin.js +0 -50
- package/dist/adapter/loop-gate-report.d.ts +0 -34
- package/dist/adapter/loop-gate-report.d.ts.map +0 -1
- package/dist/adapter/loop-gate-report.js +0 -37
- package/dist/adapter/rapier-physics-adapter.d.ts +0 -12
- package/dist/adapter/rapier-physics-adapter.d.ts.map +0 -1
- package/dist/adapter/rapier-physics-adapter.js +0 -46
- package/dist/adapter/system-adapter.d.ts +0 -133
- package/dist/adapter/system-adapter.d.ts.map +0 -1
- package/dist/adapter/system-adapter.js +0 -13
- package/dist/adapter/transform.d.ts +0 -18
- package/dist/adapter/transform.d.ts.map +0 -1
- package/dist/adapter/transform.js +0 -1
- package/dist/adapter/vgai-scene-game-adapter.d.ts +0 -116
- package/dist/adapter/vgai-scene-game-adapter.d.ts.map +0 -1
- package/dist/adapter/vgai-scene-game-adapter.js +0 -714
- package/dist/adapter/world-kind.d.ts +0 -30
- package/dist/adapter/world-kind.d.ts.map +0 -1
- package/dist/adapter/world-kind.js +0 -18
- package/dist/ai/navigation.d.ts +0 -64
- package/dist/ai/navigation.d.ts.map +0 -1
- package/dist/ai/navigation.js +0 -133
- package/dist/animation/anim-graph-types.d.ts +0 -25
- package/dist/animation/anim-graph-types.d.ts.map +0 -1
- package/dist/animation/anim-graph-types.js +0 -1
- package/dist/animation/animation-clock.d.ts +0 -213
- package/dist/animation/animation-clock.d.ts.map +0 -1
- package/dist/animation/animation-clock.js +0 -301
- package/dist/animation/blend-node.d.ts +0 -22
- package/dist/animation/blend-node.d.ts.map +0 -1
- package/dist/animation/blend-node.js +0 -97
- package/dist/animation/camera-ownership.d.ts +0 -250
- package/dist/animation/camera-ownership.d.ts.map +0 -1
- package/dist/animation/camera-ownership.js +0 -169
- package/dist/animation/cinematic-cues.d.ts +0 -200
- package/dist/animation/cinematic-cues.d.ts.map +0 -1
- package/dist/animation/cinematic-cues.js +0 -213
- package/dist/animation/clip-map.d.ts +0 -12
- package/dist/animation/clip-map.d.ts.map +0 -1
- package/dist/animation/clip-map.js +0 -37
- package/dist/animation/gsap-registration.d.ts +0 -119
- package/dist/animation/gsap-registration.d.ts.map +0 -1
- package/dist/animation/gsap-registration.js +0 -92
- package/dist/animation/theatre-clock-binding.d.ts +0 -89
- package/dist/animation/theatre-clock-binding.d.ts.map +0 -1
- package/dist/animation/theatre-clock-binding.js +0 -29
- package/dist/animation/theatre-director.d.ts +0 -242
- package/dist/animation/theatre-director.d.ts.map +0 -1
- package/dist/animation/theatre-director.js +0 -235
- package/dist/animation/theatre-object-binding.d.ts +0 -305
- package/dist/animation/theatre-object-binding.d.ts.map +0 -1
- package/dist/animation/theatre-object-binding.js +0 -351
- package/dist/animation/xstate-animation-binding.d.ts +0 -111
- package/dist/animation/xstate-animation-binding.d.ts.map +0 -1
- package/dist/animation/xstate-animation-binding.js +0 -307
- package/dist/animation/xstate-animation-meta.d.ts +0 -228
- package/dist/animation/xstate-animation-meta.d.ts.map +0 -1
- package/dist/animation/xstate-animation-meta.js +0 -221
- package/dist/assets.d.ts +0 -26
- package/dist/assets.d.ts.map +0 -1
- package/dist/assets.js +0 -55
- package/dist/audio/index.d.ts +0 -4
- package/dist/audio/index.d.ts.map +0 -1
- package/dist/audio/index.js +0 -24
- package/dist/audio/tone-clock-binding.d.ts +0 -75
- package/dist/audio/tone-clock-binding.d.ts.map +0 -1
- package/dist/audio/tone-clock-binding.js +0 -29
- package/dist/audio/tone-context.d.ts +0 -114
- package/dist/audio/tone-context.d.ts.map +0 -1
- package/dist/audio/tone-context.js +0 -39
- package/dist/audio/tone-offline-render.d.ts +0 -90
- package/dist/audio/tone-offline-render.d.ts.map +0 -1
- package/dist/audio/tone-offline-render.js +0 -56
- package/dist/audio/wav-encode.d.ts +0 -38
- package/dist/audio/wav-encode.d.ts.map +0 -1
- package/dist/audio/wav-encode.js +0 -97
- package/dist/core/game-loop.d.ts +0 -21
- package/dist/core/game-loop.d.ts.map +0 -1
- package/dist/core/game-loop.js +0 -130
- package/dist/core/system-runner.d.ts +0 -120
- package/dist/core/system-runner.d.ts.map +0 -1
- package/dist/core/system-runner.js +0 -286
- package/dist/core/types.d.ts +0 -58
- package/dist/core/types.d.ts.map +0 -1
- package/dist/core/types.js +0 -25
- package/dist/data/data-asset.d.ts +0 -101
- package/dist/data/data-asset.d.ts.map +0 -1
- package/dist/data/data-asset.js +0 -122
- package/dist/data/data-check-core.d.ts +0 -110
- package/dist/data/data-check-core.d.ts.map +0 -1
- package/dist/data/data-check-core.js +0 -178
- package/dist/data/data-ref.d.ts +0 -79
- package/dist/data/data-ref.d.ts.map +0 -1
- package/dist/data/data-ref.js +0 -130
- package/dist/data/vite-plugin-data.d.ts +0 -79
- package/dist/data/vite-plugin-data.d.ts.map +0 -1
- package/dist/data/vite-plugin-data.js +0 -217
- package/dist/dev/console-bridge.d.ts +0 -22
- package/dist/dev/console-bridge.d.ts.map +0 -1
- package/dist/dev/console-bridge.js +0 -71
- package/dist/dev/debug-draw.d.ts +0 -24
- package/dist/dev/debug-draw.d.ts.map +0 -1
- package/dist/dev/debug-draw.js +0 -73
- package/dist/dev/logger.d.ts +0 -30
- package/dist/dev/logger.d.ts.map +0 -1
- package/dist/dev/logger.js +0 -90
- package/dist/ecs/component-manager.d.ts +0 -189
- package/dist/ecs/component-manager.d.ts.map +0 -1
- package/dist/ecs/component-manager.js +0 -676
- package/dist/ecs/game-component.d.ts +0 -97
- package/dist/ecs/game-component.d.ts.map +0 -1
- package/dist/ecs/game-component.js +0 -80
- package/dist/ecs/hmr-swap-report.d.ts +0 -53
- package/dist/ecs/hmr-swap-report.d.ts.map +0 -1
- package/dist/ecs/hmr-swap-report.js +0 -55
- package/dist/index.d.ts +0 -37
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -30
- package/dist/input/input-manager.d.ts +0 -596
- package/dist/input/input-manager.d.ts.map +0 -1
- package/dist/input/input-manager.js +0 -1564
- package/dist/input/input-types.d.ts +0 -171
- package/dist/input/input-types.d.ts.map +0 -1
- package/dist/input/input-types.js +0 -1
- package/dist/input/prompt-labels.d.ts +0 -21
- package/dist/input/prompt-labels.d.ts.map +0 -1
- package/dist/input/prompt-labels.js +0 -121
- package/dist/input/rebind-controller.d.ts +0 -59
- package/dist/input/rebind-controller.d.ts.map +0 -1
- package/dist/input/rebind-controller.js +0 -85
- package/dist/input/schema.d.ts +0 -16
- package/dist/input/schema.d.ts.map +0 -1
- package/dist/input/schema.js +0 -228
- package/dist/loader.d.ts +0 -43
- package/dist/loader.d.ts.map +0 -1
- package/dist/loader.js +0 -59
- package/dist/manifest/index.d.ts +0 -5
- package/dist/manifest/index.d.ts.map +0 -1
- package/dist/manifest/index.js +0 -8
- package/dist/manifest/load-file.d.ts +0 -4
- package/dist/manifest/load-file.d.ts.map +0 -1
- package/dist/manifest/load-file.js +0 -14
- package/dist/manifest/load.d.ts +0 -117
- package/dist/manifest/load.d.ts.map +0 -1
- package/dist/manifest/load.js +0 -255
- package/dist/manifest/schema.d.ts +0 -173
- package/dist/manifest/schema.d.ts.map +0 -1
- package/dist/manifest/schema.js +0 -302
- package/dist/physics/collision-system.d.ts +0 -41
- package/dist/physics/collision-system.d.ts.map +0 -1
- package/dist/physics/collision-system.js +0 -64
- package/dist/physics/physics-registry.d.ts +0 -45
- package/dist/physics/physics-registry.d.ts.map +0 -1
- package/dist/physics/physics-registry.js +0 -65
- package/dist/physics/transform-writer.d.ts +0 -16
- package/dist/physics/transform-writer.d.ts.map +0 -1
- package/dist/physics/transform-writer.js +0 -38
- package/dist/physics/trigger-dispatch.d.ts +0 -24
- package/dist/physics/trigger-dispatch.d.ts.map +0 -1
- package/dist/physics/trigger-dispatch.js +0 -80
- package/dist/react/game-state.d.ts +0 -105
- package/dist/react/game-state.d.ts.map +0 -1
- package/dist/react/game-state.js +0 -144
- package/dist/react/use-data.d.ts +0 -60
- package/dist/react/use-data.d.ts.map +0 -1
- package/dist/react/use-data.js +0 -96
- package/dist/react/use-selection.d.ts +0 -75
- package/dist/react/use-selection.d.ts.map +0 -1
- package/dist/react/use-selection.js +0 -90
- package/dist/render/auto-batcher.d.ts +0 -34
- package/dist/render/auto-batcher.d.ts.map +0 -1
- package/dist/render/auto-batcher.js +0 -140
- package/dist/render/render-batch-system.d.ts +0 -33
- package/dist/render/render-batch-system.d.ts.map +0 -1
- package/dist/render/render-batch-system.js +0 -230
- package/dist/render/render-features.d.ts +0 -47
- package/dist/render/render-features.d.ts.map +0 -1
- package/dist/render/render-features.js +0 -105
- package/dist/render/render-settings.d.ts +0 -36
- package/dist/render/render-settings.d.ts.map +0 -1
- package/dist/render/render-settings.js +0 -51
- package/dist/runtime/create-runtime.d.ts +0 -280
- package/dist/runtime/create-runtime.d.ts.map +0 -1
- package/dist/runtime/create-runtime.js +0 -795
- package/dist/runtime/frame-selector-cache.d.ts +0 -41
- package/dist/runtime/frame-selector-cache.d.ts.map +0 -1
- package/dist/runtime/frame-selector-cache.js +0 -65
- package/dist/runtime/game.d.ts +0 -433
- package/dist/runtime/game.d.ts.map +0 -1
- package/dist/runtime/game.js +0 -569
- package/dist/runtime/input-router.d.ts +0 -78
- package/dist/runtime/input-router.d.ts.map +0 -1
- package/dist/runtime/input-router.js +0 -171
- package/dist/runtime/mount-game.d.ts +0 -129
- package/dist/runtime/mount-game.d.ts.map +0 -1
- package/dist/runtime/mount-game.js +0 -152
- package/dist/runtime/mount-manifest.d.ts +0 -119
- package/dist/runtime/mount-manifest.d.ts.map +0 -1
- package/dist/runtime/mount-manifest.js +0 -204
- package/dist/runtime/render-audio-control.d.ts +0 -110
- package/dist/runtime/render-audio-control.d.ts.map +0 -1
- package/dist/runtime/render-audio-control.js +0 -111
- package/dist/runtime/render-control.d.ts +0 -291
- package/dist/runtime/render-control.d.ts.map +0 -1
- package/dist/runtime/render-control.js +0 -264
- package/dist/runtime/render-seed.d.ts +0 -57
- package/dist/runtime/render-seed.d.ts.map +0 -1
- package/dist/runtime/render-seed.js +0 -74
- package/dist/runtime/scene-ui-bridge.d.ts +0 -69
- package/dist/runtime/scene-ui-bridge.d.ts.map +0 -1
- package/dist/runtime/scene-ui-bridge.js +0 -23
- package/dist/runtime/scene-ui-data.d.ts +0 -13
- package/dist/runtime/scene-ui-data.d.ts.map +0 -1
- package/dist/runtime/scene-ui-data.js +0 -92
- package/dist/runtime/state-bridge.d.ts +0 -47
- package/dist/runtime/state-bridge.d.ts.map +0 -1
- package/dist/runtime/state-bridge.js +0 -53
- package/dist/runtime/types.d.ts +0 -179
- package/dist/runtime/types.d.ts.map +0 -1
- package/dist/runtime/types.js +0 -1
- package/dist/scene/asset-loaders.d.ts +0 -79
- package/dist/scene/asset-loaders.d.ts.map +0 -1
- package/dist/scene/asset-loaders.js +0 -141
- package/dist/scene/asset-paths.d.ts +0 -11
- package/dist/scene/asset-paths.d.ts.map +0 -1
- package/dist/scene/asset-paths.js +0 -108
- package/dist/scene/asset-ref-check.d.ts +0 -88
- package/dist/scene/asset-ref-check.d.ts.map +0 -1
- package/dist/scene/asset-ref-check.js +0 -214
- package/dist/scene/asset-registry.d.ts +0 -30
- package/dist/scene/asset-registry.d.ts.map +0 -1
- package/dist/scene/asset-registry.js +0 -50
- package/dist/scene/collider-dimensions.d.ts +0 -63
- package/dist/scene/collider-dimensions.d.ts.map +0 -1
- package/dist/scene/collider-dimensions.js +0 -98
- package/dist/scene/component-registry.d.ts +0 -17
- package/dist/scene/component-registry.d.ts.map +0 -1
- package/dist/scene/component-registry.js +0 -28
- package/dist/scene/defaults.d.ts +0 -252
- package/dist/scene/defaults.d.ts.map +0 -1
- package/dist/scene/defaults.js +0 -151
- package/dist/scene/geometries/index.d.ts +0 -8
- package/dist/scene/geometries/index.d.ts.map +0 -1
- package/dist/scene/geometries/index.js +0 -7
- package/dist/scene/geometries/terrain.d.ts +0 -2
- package/dist/scene/geometries/terrain.d.ts.map +0 -1
- package/dist/scene/geometries/terrain.js +0 -37
- package/dist/scene/geometry-registry.d.ts +0 -24
- package/dist/scene/geometry-registry.d.ts.map +0 -1
- package/dist/scene/geometry-registry.js +0 -20
- package/dist/scene/instance-registry.d.ts +0 -36
- package/dist/scene/instance-registry.d.ts.map +0 -1
- package/dist/scene/instance-registry.js +0 -55
- package/dist/scene/instancers/grid.d.ts +0 -2
- package/dist/scene/instancers/grid.d.ts.map +0 -1
- package/dist/scene/instancers/grid.js +0 -36
- package/dist/scene/instancers/index.d.ts +0 -8
- package/dist/scene/instancers/index.d.ts.map +0 -1
- package/dist/scene/instancers/index.js +0 -7
- package/dist/scene/light-camera-factory.d.ts +0 -23
- package/dist/scene/light-camera-factory.d.ts.map +0 -1
- package/dist/scene/light-camera-factory.js +0 -68
- package/dist/scene/material-factory.d.ts +0 -17
- package/dist/scene/material-factory.d.ts.map +0 -1
- package/dist/scene/material-factory.js +0 -197
- package/dist/scene/material-registry.d.ts +0 -40
- package/dist/scene/material-registry.d.ts.map +0 -1
- package/dist/scene/material-registry.js +0 -44
- package/dist/scene/materials/index.d.ts +0 -8
- package/dist/scene/materials/index.d.ts.map +0 -1
- package/dist/scene/materials/index.js +0 -7
- package/dist/scene/materials/water.d.ts +0 -2
- package/dist/scene/materials/water.d.ts.map +0 -1
- package/dist/scene/materials/water.js +0 -54
- package/dist/scene/parse.d.ts +0 -23
- package/dist/scene/parse.d.ts.map +0 -1
- package/dist/scene/parse.js +0 -179
- package/dist/scene/particles-factory.d.ts +0 -33
- package/dist/scene/particles-factory.d.ts.map +0 -1
- package/dist/scene/particles-factory.js +0 -282
- package/dist/scene/scene-apply.d.ts +0 -109
- package/dist/scene/scene-apply.d.ts.map +0 -1
- package/dist/scene/scene-apply.js +0 -326
- package/dist/scene/scene-diff-schema.d.ts +0 -285
- package/dist/scene/scene-diff-schema.d.ts.map +0 -1
- package/dist/scene/scene-diff-schema.js +0 -92
- package/dist/scene/scene-diff-types.d.ts +0 -40
- package/dist/scene/scene-diff-types.d.ts.map +0 -1
- package/dist/scene/scene-diff-types.js +0 -14
- package/dist/scene/scene-loader.d.ts +0 -177
- package/dist/scene/scene-loader.d.ts.map +0 -1
- package/dist/scene/scene-loader.js +0 -1213
- package/dist/scene/scene-query.d.ts +0 -11
- package/dist/scene/scene-query.d.ts.map +0 -1
- package/dist/scene/scene-query.js +0 -63
- package/dist/scene/scene-types.d.ts +0 -10
- package/dist/scene/scene-types.d.ts.map +0 -1
- package/dist/scene/scene-types.js +0 -8
- package/dist/scene/scene-version.d.ts +0 -26
- package/dist/scene/scene-version.d.ts.map +0 -1
- package/dist/scene/scene-version.js +0 -34
- package/dist/scene/schema/animation.d.ts +0 -8
- package/dist/scene/schema/animation.d.ts.map +0 -1
- package/dist/scene/schema/animation.js +0 -42
- package/dist/scene/schema/audio.d.ts +0 -13
- package/dist/scene/schema/audio.d.ts.map +0 -1
- package/dist/scene/schema/audio.js +0 -22
- package/dist/scene/schema/camera.d.ts +0 -28
- package/dist/scene/schema/camera.d.ts.map +0 -1
- package/dist/scene/schema/camera.js +0 -17
- package/dist/scene/schema/collider.d.ts +0 -40
- package/dist/scene/schema/collider.d.ts.map +0 -1
- package/dist/scene/schema/collider.js +0 -55
- package/dist/scene/schema/entity-ref.d.ts +0 -31
- package/dist/scene/schema/entity-ref.d.ts.map +0 -1
- package/dist/scene/schema/entity-ref.js +0 -61
- package/dist/scene/schema/entity.d.ts +0 -1036
- package/dist/scene/schema/entity.d.ts.map +0 -1
- package/dist/scene/schema/entity.js +0 -153
- package/dist/scene/schema/environment.d.ts +0 -425
- package/dist/scene/schema/environment.d.ts.map +0 -1
- package/dist/scene/schema/environment.js +0 -357
- package/dist/scene/schema/index.d.ts +0 -39
- package/dist/scene/schema/index.d.ts.map +0 -1
- package/dist/scene/schema/index.js +0 -20
- package/dist/scene/schema/instances.d.ts +0 -14
- package/dist/scene/schema/instances.d.ts.map +0 -1
- package/dist/scene/schema/instances.js +0 -28
- package/dist/scene/schema/joint.d.ts +0 -23
- package/dist/scene/schema/joint.d.ts.map +0 -1
- package/dist/scene/schema/joint.js +0 -23
- package/dist/scene/schema/light.d.ts +0 -38
- package/dist/scene/schema/light.d.ts.map +0 -1
- package/dist/scene/schema/light.js +0 -26
- package/dist/scene/schema/material.d.ts +0 -199
- package/dist/scene/schema/material.d.ts.map +0 -1
- package/dist/scene/schema/material.js +0 -99
- package/dist/scene/schema/mesh.d.ts +0 -48
- package/dist/scene/schema/mesh.d.ts.map +0 -1
- package/dist/scene/schema/mesh.js +0 -82
- package/dist/scene/schema/particles.d.ts +0 -2178
- package/dist/scene/schema/particles.d.ts.map +0 -1
- package/dist/scene/schema/particles.js +0 -321
- package/dist/scene/schema/physics.d.ts +0 -56
- package/dist/scene/schema/physics.d.ts.map +0 -1
- package/dist/scene/schema/physics.js +0 -37
- package/dist/scene/schema/scene-file.d.ts +0 -304
- package/dist/scene/schema/scene-file.d.ts.map +0 -1
- package/dist/scene/schema/scene-file.js +0 -262
- package/dist/scene/schema/shadow.d.ts +0 -28
- package/dist/scene/schema/shadow.d.ts.map +0 -1
- package/dist/scene/schema/shadow.js +0 -20
- package/dist/scene/schema/spline.d.ts +0 -25
- package/dist/scene/schema/spline.d.ts.map +0 -1
- package/dist/scene/schema/spline.js +0 -15
- package/dist/scene/schema/tuples.d.ts +0 -12
- package/dist/scene/schema/tuples.d.ts.map +0 -1
- package/dist/scene/schema/tuples.js +0 -14
- package/dist/scene/schema/ui.d.ts +0 -880
- package/dist/scene/schema/ui.d.ts.map +0 -1
- package/dist/scene/schema/ui.js +0 -506
- package/dist/scene/user-data.d.ts +0 -171
- package/dist/scene/user-data.d.ts.map +0 -1
- package/dist/scene/user-data.js +0 -137
- package/dist/setup/setup-audio.d.ts +0 -20
- package/dist/setup/setup-audio.d.ts.map +0 -1
- package/dist/setup/setup-audio.js +0 -41
- package/dist/setup/setup-particles.d.ts +0 -17
- package/dist/setup/setup-particles.d.ts.map +0 -1
- package/dist/setup/setup-particles.js +0 -16
- package/dist/setup/setup-physics.d.ts +0 -25
- package/dist/setup/setup-physics.d.ts.map +0 -1
- package/dist/setup/setup-physics.js +0 -51
- package/dist/setup/setup-renderer.d.ts +0 -69
- package/dist/setup/setup-renderer.d.ts.map +0 -1
- package/dist/setup/setup-renderer.js +0 -363
- package/dist/tools/define-tool.d.ts +0 -105
- package/dist/tools/define-tool.d.ts.map +0 -1
- package/dist/tools/define-tool.js +0 -82
- package/dist/world2d/authoring-2d.d.ts +0 -76
- package/dist/world2d/authoring-2d.d.ts.map +0 -1
- package/dist/world2d/authoring-2d.js +0 -176
- package/dist/world2d/capture-to-scene2d.d.ts +0 -5
- package/dist/world2d/capture-to-scene2d.d.ts.map +0 -1
- package/dist/world2d/capture-to-scene2d.js +0 -49
- package/dist/world2d/collision-2d.d.ts +0 -52
- package/dist/world2d/collision-2d.d.ts.map +0 -1
- package/dist/world2d/collision-2d.js +0 -70
- package/dist/world2d/components-2d.d.ts +0 -47
- package/dist/world2d/components-2d.d.ts.map +0 -1
- package/dist/world2d/components-2d.js +0 -77
- package/dist/world2d/index.d.ts +0 -34
- package/dist/world2d/index.d.ts.map +0 -1
- package/dist/world2d/index.js +0 -32
- package/dist/world2d/ingest-iframe-2d.d.ts +0 -82
- package/dist/world2d/ingest-iframe-2d.d.ts.map +0 -1
- package/dist/world2d/ingest-iframe-2d.js +0 -166
- package/dist/world2d/ingest2d.d.ts +0 -97
- package/dist/world2d/ingest2d.d.ts.map +0 -1
- package/dist/world2d/ingest2d.js +0 -40
- package/dist/world2d/physics2d-registry.d.ts +0 -24
- package/dist/world2d/physics2d-registry.d.ts.map +0 -1
- package/dist/world2d/physics2d-registry.js +0 -38
- package/dist/world2d/pixi-game-adapter.d.ts +0 -107
- package/dist/world2d/pixi-game-adapter.d.ts.map +0 -1
- package/dist/world2d/pixi-game-adapter.js +0 -211
- package/dist/world2d/pixi-surface.d.ts +0 -39
- package/dist/world2d/pixi-surface.d.ts.map +0 -1
- package/dist/world2d/pixi-surface.js +0 -47
- package/dist/world2d/scene-capture-2d.d.ts +0 -43
- package/dist/world2d/scene-capture-2d.d.ts.map +0 -1
- package/dist/world2d/scene-capture-2d.js +0 -92
- package/dist/world2d/scene2d-loader.d.ts +0 -27
- package/dist/world2d/scene2d-loader.d.ts.map +0 -1
- package/dist/world2d/scene2d-loader.js +0 -274
- package/dist/world2d/schema/entity2d.d.ts +0 -102
- package/dist/world2d/schema/entity2d.d.ts.map +0 -1
- package/dist/world2d/schema/entity2d.js +0 -119
- package/dist/world2d/schema/physics2d.d.ts +0 -46
- package/dist/world2d/schema/physics2d.d.ts.map +0 -1
- package/dist/world2d/schema/physics2d.js +0 -45
- package/dist/world2d/schema/sprite.d.ts +0 -42
- package/dist/world2d/schema/sprite.d.ts.map +0 -1
- package/dist/world2d/schema/sprite.js +0 -63
- package/dist/world2d/schema/tilemap.d.ts +0 -15
- package/dist/world2d/schema/tilemap.d.ts.map +0 -1
- package/dist/world2d/schema/tilemap.js +0 -19
- package/dist/world2d/schema/tuples2d.d.ts +0 -20
- package/dist/world2d/schema/tuples2d.d.ts.map +0 -1
- package/dist/world2d/schema/tuples2d.js +0 -19
- package/dist/world2d/system-adapters-2d.d.ts +0 -16
- package/dist/world2d/system-adapters-2d.d.ts.map +0 -1
- package/dist/world2d/system-adapters-2d.js +0 -37
- package/dist/world2d/transform-writer-2d.d.ts +0 -16
- package/dist/world2d/transform-writer-2d.d.ts.map +0 -1
- package/dist/world2d/transform-writer-2d.js +0 -22
- package/dist/world2d/types.d.ts +0 -53
- package/dist/world2d/types.d.ts.map +0 -1
- package/dist/world2d/types.js +0 -1
- package/src/runtime/scene-ui-bridge.ts +0 -86
- package/src/runtime/scene-ui-data.ts +0 -119
- package/src/scene/schema/ui.ts +0 -602
|
@@ -2,25 +2,25 @@
|
|
|
2
2
|
// helper: an ENGINE-side generalization of `examples/tri-world/src/main.ts`'s
|
|
3
3
|
// hand-built `WorldMountSpec[]`.
|
|
4
4
|
//
|
|
5
|
-
// `resolveAllWorlds`/`
|
|
5
|
+
// `resolveAllWorlds`/`resolveRootAdapter` (`packages/editor/src/
|
|
6
6
|
// adapter-resolver.ts`) already do this translation for the EDITOR, but they
|
|
7
7
|
// are Vite-coupled by construction (`/@fs/` dynamic imports of project files
|
|
8
8
|
// through the dev server, §0.1/§0.5 of the design doc) — unusable from a
|
|
9
9
|
// plain static build. This module mirrors their per-kind dispatch
|
|
10
10
|
// (`default-three`/`default-pixi`/`default-react`, `{ module }`, `{ ingest }`)
|
|
11
11
|
// but never imports a project file itself: the caller's OWN bundler already
|
|
12
|
-
// resolved whatever module graph the manifest's
|
|
12
|
+
// resolved whatever module graph the manifest's roots need, and hands the
|
|
13
13
|
// already-built pieces in via `entries` (keyed by world id) — no `/@fs/`, no
|
|
14
14
|
// dev server, no editor import.
|
|
15
15
|
//
|
|
16
16
|
// Engine-core react/pixi-free discipline (§0.6, mirrored from
|
|
17
17
|
// `create-runtime.ts`'s own documented rule for its `Pixi2DGameAdapter`/
|
|
18
|
-
// `
|
|
18
|
+
// `ReactRootAdapter` type-only imports): this file never value-imports
|
|
19
19
|
// `pixi.js`, `world2d/pixi-game-adapter.ts`, `react`, or `react-dom` — a
|
|
20
20
|
// pixijs or react world's adapter is ALWAYS supplied already-constructed via
|
|
21
21
|
// `entries[id].adapter` (the caller's own module graph built it, exactly like
|
|
22
22
|
// `tri-world`'s original hand-mount built `new PixiSceneGameAdapter(...)` and
|
|
23
|
-
// a hand-rolled `
|
|
23
|
+
// a hand-rolled `ReactRootAdapter` itself). Threejs is different: `three`/
|
|
24
24
|
// `VgaiSceneGameAdapter` are already unconditional dependencies of every
|
|
25
25
|
// caller of `createGameRuntime`'s legacy path (this same file's sibling,
|
|
26
26
|
// immediately below in this directory), so building a `VgaiSceneGameAdapter`
|
|
@@ -28,21 +28,25 @@
|
|
|
28
28
|
// weight — only pixi/react are avoided.
|
|
29
29
|
|
|
30
30
|
import { fromSetup, VgaiSceneGameAdapter } from '../adapter';
|
|
31
|
+
import { assertNever } from '../adapter/adapter-surface';
|
|
31
32
|
import type { GameAdapter } from '../adapter/game-adapter';
|
|
32
|
-
import { assertNever } from '../adapter/world-kind';
|
|
33
33
|
import {
|
|
34
34
|
loadGameManifest,
|
|
35
|
+
type ResolvedAdapterRoot,
|
|
35
36
|
type ResolvedGameManifest,
|
|
36
|
-
type ResolvedWorldEntry,
|
|
37
37
|
} from '../manifest/load';
|
|
38
38
|
import type { ComponentRegistry } from '../scene/component-registry';
|
|
39
39
|
import {
|
|
40
40
|
createGameRuntime,
|
|
41
41
|
type GameSession,
|
|
42
42
|
type Pixi2DGameAdapter,
|
|
43
|
-
type
|
|
43
|
+
type ReactRootAdapter,
|
|
44
44
|
type WorldMountSpec,
|
|
45
45
|
} from './create-runtime';
|
|
46
|
+
import { type DebugBridgeWindowTarget, maybeInstallDebugBridge } from './debug-bridge';
|
|
47
|
+
import { getDebugRegistry } from './debug-registry';
|
|
48
|
+
import { getGameplayRngTrapControl } from './gameplay-rng-trap';
|
|
49
|
+
import { RENDER_SEED_QUERY_PARAM } from './render-seed';
|
|
46
50
|
import type { GameSetupFn } from './types';
|
|
47
51
|
|
|
48
52
|
// ---------------------------------------------------------------------------
|
|
@@ -96,7 +100,7 @@ export interface PixiMountEntry {
|
|
|
96
100
|
|
|
97
101
|
/**
|
|
98
102
|
* A caller-supplied entry for a `kind: 'react'` world — ALWAYS a
|
|
99
|
-
* fully-constructed {@link
|
|
103
|
+
* fully-constructed {@link ReactRootAdapter} (the caller's own module graph
|
|
100
104
|
* calls `createRoot(host.container).render(<GameProvider game={host.game}>
|
|
101
105
|
* <Entry/></GameProvider>)` itself, exactly like `tri-world`'s original
|
|
102
106
|
* hand-mount did). A standalone build has ONE module graph, so there is no
|
|
@@ -109,7 +113,7 @@ export interface PixiMountEntry {
|
|
|
109
113
|
*/
|
|
110
114
|
export interface ReactMountEntry {
|
|
111
115
|
readonly kind: 'react';
|
|
112
|
-
readonly adapter:
|
|
116
|
+
readonly adapter: ReactRootAdapter;
|
|
113
117
|
}
|
|
114
118
|
|
|
115
119
|
export type MountEntry = ThreeMountEntry | PixiMountEntry | ReactMountEntry;
|
|
@@ -143,6 +147,71 @@ export interface MountManifestOptions {
|
|
|
143
147
|
/** Forwarded to `createGameRuntime` — Node/headless test harnesses only,
|
|
144
148
|
* never a real host. See `WorldsRuntimeConfig.headless`. */
|
|
145
149
|
readonly headless?: boolean | undefined;
|
|
150
|
+
/**
|
|
151
|
+
* Task 2.1 (`docs/ACCEPTANCE-DRIVER-BUILD-PLAN.md`,
|
|
152
|
+
* `docs/SYNTHETIC-PLAYER-SPEC.md` §3.4): overrides for the `?vgai-debug=1`
|
|
153
|
+
* bridge `mountManifestWorlds` installs at the tail of every mount — the
|
|
154
|
+
* engine-owned install point so every standalone project gets it with zero
|
|
155
|
+
* template edits. Omit both in a real host (defaults to `window.location`/
|
|
156
|
+
* `window`); a headless test supplies fakes here instead of touching the
|
|
157
|
+
* global object, mirroring `render-control.ts`'s own `location`/`target`
|
|
158
|
+
* override precedent.
|
|
159
|
+
*/
|
|
160
|
+
readonly debugBridge?:
|
|
161
|
+
| {
|
|
162
|
+
readonly url?: { readonly search: string } | undefined;
|
|
163
|
+
readonly window?: DebugBridgeWindowTarget | undefined;
|
|
164
|
+
}
|
|
165
|
+
| undefined;
|
|
166
|
+
/**
|
|
167
|
+
* D15 (T-D15.1) — the "explicit config" leg of the boot-time seed
|
|
168
|
+
* precedence (`manifest.determinism.defaultSeed` → `?vgai-seed=` → this),
|
|
169
|
+
* highest-precedence, for a caller that already knows the exact seed it
|
|
170
|
+
* wants (a future CLI `--seed`/probe fixture `seed` option, T-D15.6).
|
|
171
|
+
* Ignored entirely unless the manifest declares
|
|
172
|
+
* `determinism.seededRandom` — see `resolveDeterminismSeed` below.
|
|
173
|
+
*/
|
|
174
|
+
readonly seed?: number | undefined;
|
|
175
|
+
/** Where to read `?vgai-seed=` from for the boot-time seed reader. Same
|
|
176
|
+
* override precedent as `debugBridge.url` (defaults to `window.location`
|
|
177
|
+
* when a real `window` exists; a headless caller with no override gets no
|
|
178
|
+
* query-param seed, same as `maybeInstallDebugBridge`'s own url default). */
|
|
179
|
+
readonly seedUrl?: { readonly search: string } | undefined;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* D15 (T-D15.1) boot-time seed reader — resolves the root seed
|
|
184
|
+
* `mountManifestWorlds` threads into `createGameRuntime` (and therefore
|
|
185
|
+
* `createGame`, BEFORE any world's `mount()`/`setup()` runs). Returns
|
|
186
|
+
* `undefined` when the manifest doesn't declare `determinism.seededRandom`
|
|
187
|
+
* at all — `?vgai-seed=` and `defaultSeed` are both ignored in that case
|
|
188
|
+
* (§2.a: "the mount path seeds ctx.random ... iff declared"; an undeclared
|
|
189
|
+
* project's `ctx.random` still exists, just boots from `createGame`'s own
|
|
190
|
+
* fixed default, unaffected by the manifest or the URL).
|
|
191
|
+
*
|
|
192
|
+
* Precedence when declared (highest wins): `explicitSeed` (a caller-supplied
|
|
193
|
+
* config value) → `?vgai-seed=<int>` on `url` → `manifest.determinism
|
|
194
|
+
* .defaultSeed`.
|
|
195
|
+
*/
|
|
196
|
+
export function resolveDeterminismSeed(opts: {
|
|
197
|
+
readonly determinism: ResolvedGameManifest['determinism'];
|
|
198
|
+
readonly explicitSeed: number | undefined;
|
|
199
|
+
readonly url: { readonly search: string } | undefined;
|
|
200
|
+
}): number | undefined {
|
|
201
|
+
if (opts.determinism?.seededRandom !== true) return undefined;
|
|
202
|
+
const querySeed = opts.url ? readSeedQueryParam(opts.url) : undefined;
|
|
203
|
+
return opts.explicitSeed ?? querySeed ?? opts.determinism.defaultSeed;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
function readSeedQueryParam(url: { readonly search: string }): number | undefined {
|
|
207
|
+
const raw = new URLSearchParams(url.search).get(RENDER_SEED_QUERY_PARAM);
|
|
208
|
+
if (raw === null || raw === '') return undefined;
|
|
209
|
+
const parsed = Number(raw);
|
|
210
|
+
return Number.isFinite(parsed) ? parsed : undefined;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
function hasRealWindow(): boolean {
|
|
214
|
+
return typeof window !== 'undefined';
|
|
146
215
|
}
|
|
147
216
|
|
|
148
217
|
// `mountManifestWorlds` returns the SAME `GameSession` shape
|
|
@@ -159,24 +228,24 @@ export type MountedManifestSession = GameSession;
|
|
|
159
228
|
/**
|
|
160
229
|
* Distinguish an already-`loadGameManifest`d {@link ResolvedGameManifest}
|
|
161
230
|
* from a raw (pre-Zod-parse) manifest value. The two shapes differ in
|
|
162
|
-
* exactly one load-bearing way for this check: a `
|
|
231
|
+
* exactly one load-bearing way for this check: a `ResolvedAdapterRoot.adapter`
|
|
163
232
|
* is `{ type: 'default' | 'module' | 'ingest', identity, ... }`, while a raw
|
|
164
|
-
* `
|
|
233
|
+
* `AdapterRoot.adapter` is the literal string `'default'` or a bare `{module}`/
|
|
165
234
|
* `{ingest}` object with NO `type`/`identity` fields (`schema.ts`'s
|
|
166
|
-
* `
|
|
235
|
+
* `RootAdapterSchema`). An empty `roots` array is treated as "not resolved"
|
|
167
236
|
* (falls through to `loadGameManifest`, whose own Zod validation reports the
|
|
168
237
|
* empty-array error, if any, more precisely than a guess here could).
|
|
169
238
|
*/
|
|
170
239
|
function looksAlreadyResolved(value: unknown): value is ResolvedGameManifest {
|
|
171
240
|
if (typeof value !== 'object' || value === null) return false;
|
|
172
|
-
const
|
|
173
|
-
if (!Array.isArray(
|
|
174
|
-
return
|
|
241
|
+
const roots = (value as { roots?: unknown }).roots;
|
|
242
|
+
if (!Array.isArray(roots) || roots.length === 0) return false;
|
|
243
|
+
return roots.every((world) => {
|
|
175
244
|
if (typeof world !== 'object' || world === null) return false;
|
|
176
245
|
const adapter = (world as { adapter?: unknown }).adapter;
|
|
177
246
|
if (typeof adapter !== 'object' || adapter === null) return false;
|
|
178
247
|
const type = (adapter as { type?: unknown }).type;
|
|
179
|
-
return type === '
|
|
248
|
+
return type === 'builtin' || type === 'module' || type === 'ingest';
|
|
180
249
|
});
|
|
181
250
|
}
|
|
182
251
|
|
|
@@ -192,12 +261,12 @@ export function resolveManifest(raw: unknown): ResolvedGameManifest {
|
|
|
192
261
|
}
|
|
193
262
|
|
|
194
263
|
// ---------------------------------------------------------------------------
|
|
195
|
-
// Per-kind entry -> adapter resolution (mirrors `
|
|
264
|
+
// Per-kind entry -> adapter resolution (mirrors `resolveRootAdapter`'s
|
|
196
265
|
// per-identity dispatch, `packages/editor/src/adapter-resolver.ts`)
|
|
197
266
|
// ---------------------------------------------------------------------------
|
|
198
267
|
|
|
199
268
|
function resolveThreeAdapter(
|
|
200
|
-
world:
|
|
269
|
+
world: ResolvedAdapterRoot,
|
|
201
270
|
entry: ThreeMountEntry | undefined,
|
|
202
271
|
): GameAdapter {
|
|
203
272
|
if (entry?.adapter) return entry.adapter;
|
|
@@ -213,7 +282,7 @@ function resolveThreeAdapter(
|
|
|
213
282
|
if (world.adapter.type === 'ingest') {
|
|
214
283
|
throw new Error(
|
|
215
284
|
`mountManifestWorlds: world "${world.id}" (threejs) declares an { ingest } adapter — ` +
|
|
216
|
-
"ingest
|
|
285
|
+
"ingest roots require the editor's dev-server-backed mount machinery (an EditorStore " +
|
|
217
286
|
"plus iframe/DOM capture, see adapter-resolver.ts's resolveIngestThreeAdapter) and are " +
|
|
218
287
|
'not supported by mountManifestWorlds (docs/WAVE3-ADAPTER-PLUMBING-DESIGN.md D-Z7 — no ' +
|
|
219
288
|
'porting aids, no hosted ingest routes).',
|
|
@@ -249,7 +318,7 @@ function resolveThreeAdapter(
|
|
|
249
318
|
}
|
|
250
319
|
|
|
251
320
|
function resolvePixiAdapter(
|
|
252
|
-
world:
|
|
321
|
+
world: ResolvedAdapterRoot,
|
|
253
322
|
entry: PixiMountEntry | undefined,
|
|
254
323
|
): Pixi2DGameAdapter {
|
|
255
324
|
if (entry?.adapter) return entry.adapter;
|
|
@@ -263,13 +332,13 @@ function resolvePixiAdapter(
|
|
|
263
332
|
}
|
|
264
333
|
|
|
265
334
|
function resolveReactAdapter(
|
|
266
|
-
world:
|
|
335
|
+
world: ResolvedAdapterRoot,
|
|
267
336
|
entry: ReactMountEntry | undefined,
|
|
268
|
-
):
|
|
337
|
+
): ReactRootAdapter {
|
|
269
338
|
if (entry?.adapter) return entry.adapter;
|
|
270
339
|
throw new Error(
|
|
271
340
|
`mountManifestWorlds: world "${world.id}" (react) has no entries["${world.id}"] — a react ` +
|
|
272
|
-
'world always needs a caller-supplied, already-constructed `
|
|
341
|
+
'world always needs a caller-supplied, already-constructed `ReactRootAdapter` ' +
|
|
273
342
|
`(entries["${world.id}"] = { kind: 'react', adapter }, mounting via your own already-imported ` +
|
|
274
343
|
'react-dom `createRoot` + your own `<GameProvider>`) — mountManifestWorlds never ' +
|
|
275
344
|
"value-imports react/react-dom (mirrors create-runtime.ts's own react-free-core discipline; " +
|
|
@@ -278,13 +347,13 @@ function resolveReactAdapter(
|
|
|
278
347
|
}
|
|
279
348
|
|
|
280
349
|
function buildWorldMountSpec(
|
|
281
|
-
world:
|
|
350
|
+
world: ResolvedAdapterRoot,
|
|
282
351
|
entry: MountEntry | undefined,
|
|
283
352
|
): WorldMountSpec {
|
|
284
|
-
if (entry !== undefined && entry.kind !== world.
|
|
353
|
+
if (entry !== undefined && entry.kind !== world.surface) {
|
|
285
354
|
throw new Error(
|
|
286
355
|
`mountManifestWorlds: entries["${world.id}"] declares kind "${entry.kind}" but the ` +
|
|
287
|
-
`manifest's
|
|
356
|
+
`manifest's root "${world.id}" uses surface "${world.surface}" — fix the entries key (or the ` +
|
|
288
357
|
'manifest) so the two agree.',
|
|
289
358
|
);
|
|
290
359
|
}
|
|
@@ -300,23 +369,23 @@ function buildWorldMountSpec(
|
|
|
300
369
|
// above (or `entry` is `undefined`) — TS can't narrow a `Record` lookup
|
|
301
370
|
// through that runtime check, so each branch casts to its own entry shape;
|
|
302
371
|
// the actual safety comes from the mismatch guard, not from the cast.
|
|
303
|
-
if (world.
|
|
372
|
+
if (world.surface === 'threejs') {
|
|
304
373
|
const threeEntry = entry as ThreeMountEntry | undefined;
|
|
305
374
|
return { ...base, kind: 'threejs', adapter: resolveThreeAdapter(world, threeEntry) };
|
|
306
375
|
}
|
|
307
|
-
if (world.
|
|
376
|
+
if (world.surface === 'pixijs') {
|
|
308
377
|
const pixiEntry = entry as PixiMountEntry | undefined;
|
|
309
378
|
return { ...base, kind: 'pixijs', adapter: resolvePixiAdapter(world, pixiEntry) };
|
|
310
379
|
}
|
|
311
|
-
if (world.
|
|
380
|
+
if (world.surface === 'react') {
|
|
312
381
|
const reactEntry = entry as ReactMountEntry | undefined;
|
|
313
382
|
return { ...base, kind: 'react', adapter: resolveReactAdapter(world, reactEntry) };
|
|
314
383
|
}
|
|
315
384
|
// Exhaustiveness guard (§7.4-2, same idiom as `resolveAllWorlds`'s own
|
|
316
|
-
// dispatch loop): `world.kind` is the closed `
|
|
385
|
+
// dispatch loop): `world.kind` is the closed `AdapterRoot['kind']` union
|
|
317
386
|
// (`z.enum(['threejs','pixijs','react'])`), so a hypothetical 4th kind
|
|
318
387
|
// must fail to compile here, not silently fall through.
|
|
319
|
-
return assertNever(world.
|
|
388
|
+
return assertNever(world.surface, 'mountManifestWorlds');
|
|
320
389
|
}
|
|
321
390
|
|
|
322
391
|
// ---------------------------------------------------------------------------
|
|
@@ -328,7 +397,7 @@ function buildWorldMountSpec(
|
|
|
328
397
|
* standalone — no editor, no dev server. The generalization of
|
|
329
398
|
* `examples/tri-world/src/main.ts`'s hand-built `WorldMountSpec[]` (D-Z2,
|
|
330
399
|
* docs/WAVE3-ADAPTER-PLUMBING-DESIGN.md). Reuses the pure `loadGameManifest`
|
|
331
|
-
* + `createGameRuntime({
|
|
400
|
+
* + `createGameRuntime({ roots })` and mirrors `resolveAllWorlds`'s per-kind
|
|
332
401
|
* dispatch — but every entry the manifest needs beyond what a `default`-
|
|
333
402
|
* adapter scene/entry can express on its own comes from the caller's OWN
|
|
334
403
|
* already-imported module graph (`opts.entries`), never a dynamic import
|
|
@@ -342,20 +411,83 @@ function buildWorldMountSpec(
|
|
|
342
411
|
*/
|
|
343
412
|
export async function mountManifestWorlds(opts: MountManifestOptions): Promise<GameSession> {
|
|
344
413
|
const manifest = resolveManifest(opts.manifest);
|
|
345
|
-
if (manifest.
|
|
346
|
-
throw new Error('mountManifestWorlds: manifest declares no
|
|
414
|
+
if (manifest.roots.length === 0) {
|
|
415
|
+
throw new Error('mountManifestWorlds: manifest declares no roots — nothing to mount.');
|
|
347
416
|
}
|
|
348
417
|
const entries = opts.entries ?? {};
|
|
349
418
|
|
|
350
|
-
const
|
|
419
|
+
const roots: WorldMountSpec[] = manifest.roots.map((world) =>
|
|
351
420
|
buildWorldMountSpec(world, entries[world.id]),
|
|
352
421
|
);
|
|
353
422
|
|
|
354
|
-
|
|
423
|
+
// D15 (T-D15.1) — resolved BEFORE `createGameRuntime` (which constructs the
|
|
424
|
+
// Game, and therefore `ctx.random`, before any world's `mount()`/`setup()`
|
|
425
|
+
// runs — see `createGame`'s own doc comment): the seed must be baked in at
|
|
426
|
+
// construction time, not patched in afterward, or a world's `setup()`
|
|
427
|
+
// would already have drawn from the wrong (default) sequence before any
|
|
428
|
+
// post-hoc reseed could take effect.
|
|
429
|
+
const seedUrl = opts.seedUrl ?? (hasRealWindow() ? window.location : undefined);
|
|
430
|
+
const resolvedSeed = resolveDeterminismSeed({
|
|
431
|
+
determinism: manifest.determinism,
|
|
432
|
+
explicitSeed: opts.seed,
|
|
433
|
+
url: seedUrl,
|
|
434
|
+
});
|
|
435
|
+
|
|
436
|
+
const session = await createGameRuntime({
|
|
355
437
|
container: opts.container,
|
|
356
|
-
|
|
438
|
+
roots,
|
|
357
439
|
width: opts.width ?? manifest.resolution?.width,
|
|
358
440
|
height: opts.height ?? manifest.resolution?.height,
|
|
359
441
|
headless: opts.headless,
|
|
442
|
+
seed: resolvedSeed,
|
|
360
443
|
});
|
|
444
|
+
|
|
445
|
+
// D15 (T-D15.3) — the dev-mode Math.random phase trap: only while the
|
|
446
|
+
// manifest declares the contract AND this is a dev build (mirrors D18's
|
|
447
|
+
// debug-bridge gate — `import.meta.env.DEV`, never a production build
|
|
448
|
+
// unless something ELSE explicitly opts in, which this trap has no
|
|
449
|
+
// opt-in for at all: it is dev-only, full stop). `getGameplayRngTrapControl`
|
|
450
|
+
// returns `null` only for a bare `Game`-shaped test stand-in predating
|
|
451
|
+
// T7.1 — real mounts always have one (same precedent as `getDebugRegistry`
|
|
452
|
+
// just below).
|
|
453
|
+
if (manifest.determinism?.seededRandom === true && Boolean(import.meta.env?.DEV)) {
|
|
454
|
+
getGameplayRngTrapControl(session.game)?.setEnabled(true);
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
// Task 2.1 — install the `?vgai-debug=1` bridge at the TAIL of every
|
|
458
|
+
// manifest mount (engine-owned, so a standalone project gets it with zero
|
|
459
|
+
// template edits). `getDebugRegistry` returns `null` only for a bare
|
|
460
|
+
// `Game`-shaped test stand-in predating T7.1 — real mounts always have one.
|
|
461
|
+
const debugRegistry = getDebugRegistry(session.game);
|
|
462
|
+
if (debugRegistry) {
|
|
463
|
+
// Defect 3 fix: `setRoomDeclared` (the locus-required rule — a project
|
|
464
|
+
// with a Colyseus room must declare `locus: 'client' | 'server'` on every
|
|
465
|
+
// debug command, docs/SYNTHETIC-PLAYER-SPEC.md §3.1) was never actually
|
|
466
|
+
// called from a real mount path — this is that wiring. `manifest.server`
|
|
467
|
+
// (`ResolvedGameManifest.server`, `manifest/load.ts`) is `{ room, module }
|
|
468
|
+
// | undefined`; its mere presence is the "this project declares a room"
|
|
469
|
+
// signal, independent of whether/when the game actually joins it.
|
|
470
|
+
if (manifest.server) {
|
|
471
|
+
debugRegistry.setRoomDeclared(true);
|
|
472
|
+
}
|
|
473
|
+
// Defect 5 fix: `maybeInstallDebugBridge` adds `window` listeners and
|
|
474
|
+
// publishes `window.__vgai` with no way to undo either — wire its
|
|
475
|
+
// `uninstall()` into THIS session's own `stop()` so a caller that tears
|
|
476
|
+
// this mount down doesn't leave the bridge (and its listeners) live.
|
|
477
|
+
const bridgeHandle = maybeInstallDebugBridge({
|
|
478
|
+
registry: debugRegistry,
|
|
479
|
+
manifest,
|
|
480
|
+
url: opts.debugBridge?.url,
|
|
481
|
+
window: opts.debugBridge?.window,
|
|
482
|
+
});
|
|
483
|
+
if (bridgeHandle) {
|
|
484
|
+
const stopSession = session.stop;
|
|
485
|
+
session.stop = () => {
|
|
486
|
+
bridgeHandle.uninstall();
|
|
487
|
+
stopSession();
|
|
488
|
+
};
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
return session;
|
|
361
493
|
}
|
|
@@ -10,10 +10,10 @@
|
|
|
10
10
|
* that deliberately drives `game.runFrame(fixedDt)` instead).
|
|
11
11
|
*
|
|
12
12
|
* This module does NOT reuse `PlayState.step()` (`Game.play.step()`) — that
|
|
13
|
-
* surface only advances the currently-FROZEN (paused) set of
|
|
13
|
+
* surface only advances the currently-FROZEN (paused) set of roots and is a
|
|
14
14
|
* whole-call no-op while unpaused (see its doc comment in `runtime/game.ts`);
|
|
15
15
|
* the spec review explicitly flagged it as the wrong seam. `renderOnce`
|
|
16
|
-
* instead walks `game.
|
|
16
|
+
* instead walks `game.roots` directly and calls each world's own
|
|
17
17
|
* `WorldFrameHooks.runPhase` for exactly two phases.
|
|
18
18
|
*
|
|
19
19
|
* Also does NOT install anything by default — a caller must explicitly call
|
|
@@ -197,7 +197,7 @@ export interface VgaiRenderHarness {
|
|
|
197
197
|
* {@link renderOnce}'s `renderableWorlds` skips, described here as policy
|
|
198
198
|
* rather than merely warned about once to the console). Declared entries
|
|
199
199
|
* come first, in declaration order; world-exclusion entries follow, in
|
|
200
|
-
* `game.
|
|
200
|
+
* `game.roots` declaration order.
|
|
201
201
|
*/
|
|
202
202
|
excludedFromDeterminism(): string[];
|
|
203
203
|
/**
|
|
@@ -279,9 +279,9 @@ const RENDER_ONLY_PHASES = [SystemPhase.PRE_RENDER, SystemPhase.RENDER] as const
|
|
|
279
279
|
* `prePhysics`, `physics`, `postPhysics`, `gameLogic`, or `animation` phase
|
|
280
280
|
* is ever touched, which is what makes this safe to call from a paused-or-
|
|
281
281
|
* stopped clock without silently ticking gameplay. Phases are run as global
|
|
282
|
-
* barriers across
|
|
282
|
+
* barriers across roots (mirroring `GameInternal.runFrame`'s own phase-then-
|
|
283
283
|
* world nesting in `runtime/game.ts`): every world's `preRender` runs before
|
|
284
|
-
* any world's `render`, in `game.
|
|
284
|
+
* any world's `render`, in `game.roots` declaration order.
|
|
285
285
|
*
|
|
286
286
|
* Ordering within a phase mirrors `GameInternal.runFrame` EXACTLY (see its
|
|
287
287
|
* doc comment in `runtime/game.ts`): the game-scoped `SystemRunner`
|
|
@@ -304,12 +304,12 @@ const RENDER_ONLY_PHASES = [SystemPhase.PRE_RENDER, SystemPhase.RENDER] as const
|
|
|
304
304
|
* too, so warning twice would just be noise.
|
|
305
305
|
*/
|
|
306
306
|
async function renderOnce(game: Game): Promise<void> {
|
|
307
|
-
const
|
|
307
|
+
const roots = renderableWorlds(game);
|
|
308
308
|
for (const phase of RENDER_ONLY_PHASES) {
|
|
309
309
|
// Game-scoped systems first, then per-world frame hooks — the SAME order
|
|
310
310
|
// GameInternal.runFrame uses (runtime/game.ts). See doc comment above.
|
|
311
311
|
game.systems.runPhase(phase, 0);
|
|
312
|
-
for (const world of
|
|
312
|
+
for (const world of roots) {
|
|
313
313
|
world.frame.runPhase(phase, 0);
|
|
314
314
|
}
|
|
315
315
|
}
|
|
@@ -321,13 +321,13 @@ interface RenderableWorld {
|
|
|
321
321
|
readonly frame: WorldFrameHooks;
|
|
322
322
|
}
|
|
323
323
|
|
|
324
|
-
/** Filter `game.
|
|
324
|
+
/** Filter `game.roots` down to the ones {@link renderOnce} can actually
|
|
325
325
|
* drive (host-driven, with real `WorldFrameHooks`) — see that function's
|
|
326
326
|
* doc comment for why an excluded world is warned about loudly, not
|
|
327
327
|
* silently dropped. */
|
|
328
328
|
function renderableWorlds(game: Game): RenderableWorld[] {
|
|
329
329
|
const result: RenderableWorld[] = [];
|
|
330
|
-
for (const world of game.
|
|
330
|
+
for (const world of game.roots) {
|
|
331
331
|
if (world.mounted.drivesOwnLoop) {
|
|
332
332
|
warnUnrenderable(
|
|
333
333
|
world.id,
|
|
@@ -357,12 +357,12 @@ function warnUnrenderable(worldLabel: string, reason: string): void {
|
|
|
357
357
|
/**
|
|
358
358
|
* I5 AC 5 policy text for the two conditions {@link renderableWorlds} skips —
|
|
359
359
|
* shared so {@link VgaiRenderHarness.excludedFromDeterminism} names the SAME
|
|
360
|
-
*
|
|
360
|
+
* roots `renderOnce()` warns about, in the SAME words, rather than
|
|
361
361
|
* maintaining a second, driftable description of the same two checks.
|
|
362
362
|
*/
|
|
363
363
|
function computeWorldExclusionReasons(game: Game): string[] {
|
|
364
364
|
const reasons: string[] = [];
|
|
365
|
-
for (const world of game.
|
|
365
|
+
for (const world of game.roots) {
|
|
366
366
|
if (world.mounted.drivesOwnLoop) {
|
|
367
367
|
reasons.push(
|
|
368
368
|
`world "${world.id}" drives its own loop — cannot be frame-gated for deterministic ` +
|
|
@@ -494,12 +494,12 @@ export function installRenderControlHarness(
|
|
|
494
494
|
}
|
|
495
495
|
|
|
496
496
|
/**
|
|
497
|
-
* Defensive assertion for the I2 AC "Pixi
|
|
497
|
+
* Defensive assertion for the I2 AC "Pixi roots are pinned to the WebGL
|
|
498
498
|
* renderer (not WebGPU) in render mode". In THIS engine that invariant
|
|
499
499
|
* already holds unconditionally — `world2d/pixi-surface.ts`'s
|
|
500
500
|
* `createPixiSurface` hardcodes `preference: 'webgl'` on every
|
|
501
501
|
* `Application.init()` call it makes, and `setup/setup-renderer.ts` never
|
|
502
|
-
* constructs a `WebGPURenderer` for threejs
|
|
502
|
+
* constructs a `WebGPURenderer` for threejs roots either — so there is no
|
|
503
503
|
* live WebGPU code path for a first-party render-mode page to disable.
|
|
504
504
|
* This helper exists for a render-mode installer that mounts a CUSTOM/
|
|
505
505
|
* foreign pixi adapter (`create-runtime.ts`'s `{ module }` pixi path) this
|
|
@@ -46,7 +46,7 @@ export function createMulberry32(seed: number): () => number {
|
|
|
46
46
|
* Replace the global `Math.random` with a seeded, deterministic generator.
|
|
47
47
|
* Idempotent to call more than once (each call re-seeds from scratch — the
|
|
48
48
|
* last call wins), which matters for HMR-style re-execution the same way
|
|
49
|
-
* `main.ts`'s `
|
|
49
|
+
* `main.ts`'s `registerAdapterSurface` guard does elsewhere in this runtime.
|
|
50
50
|
*/
|
|
51
51
|
export function installDeterministicRandom(seed: number): void {
|
|
52
52
|
Math.random = createMulberry32(seed);
|
|
@@ -12,26 +12,40 @@
|
|
|
12
12
|
*
|
|
13
13
|
* This file is plain, react-free TypeScript any consumer could use — no
|
|
14
14
|
* react import here, or anywhere under `runtime/` (the react-facing
|
|
15
|
-
* `useGameState` hook, which DOES import
|
|
16
|
-
*
|
|
17
|
-
*
|
|
15
|
+
* `useGameState` hook, which DOES import React, lives at
|
|
16
|
+
* `packages/engine/src/react/game-state.tsx`).
|
|
17
|
+
*
|
|
18
|
+
* SECOND trigger for `bump()` (`Game.registerWorld`, `runtime/game.ts`): the
|
|
19
|
+
* `roots` list is also state a `useGameState` selector can read
|
|
20
|
+
* (`g.roots.map(...)`, the T6.2 two-world-compose gate), and it changes
|
|
21
|
+
* OUTSIDE the frame loop — `registerWorld` is called as each world finishes
|
|
22
|
+
* mounting, which can happen well before the host's loop has ticked even
|
|
23
|
+
* once. Without an immediate notification here, a selector that first reads
|
|
24
|
+
* `g.roots` before every world has registered stays stuck on that stale
|
|
25
|
+
* snapshot until the next completed frame — which, on a slow/contended host
|
|
26
|
+
* or a backgrounded tab, may be arbitrarily delayed. See `registerWorld`'s
|
|
27
|
+
* own doc comment for the concrete CI failure this closes.
|
|
18
28
|
*/
|
|
19
29
|
|
|
20
30
|
/** Frame-versioned, react-free subscription surface — `docs/REACT-STATE-BRIDGE.md` §2. */
|
|
21
31
|
export interface GameStateBridge {
|
|
22
|
-
/** Monotonic; bumped once per completed `runFrame
|
|
23
|
-
*
|
|
32
|
+
/** Monotonic; bumped once per completed `runFrame`, AND once per
|
|
33
|
+
* `Game.registerWorld` call (world-list changes are observable state too
|
|
34
|
+
* — see this file's module doc comment). Starts at 0 before the first of
|
|
35
|
+
* either has happened. Never treat this as a literal frame COUNT — only
|
|
36
|
+
* "did it change" is a contract any consumer may rely on. */
|
|
24
37
|
readonly frameVersion: number;
|
|
25
|
-
/** Notified at most once per frame, after ALL phases of ALL
|
|
38
|
+
/** Notified at most once per frame, after ALL phases of ALL roots (and
|
|
26
39
|
* their `endFrame` hooks) have run. Returns an unsubscribe function. */
|
|
27
40
|
subscribe(onFrame: () => void): () => void;
|
|
28
41
|
}
|
|
29
42
|
|
|
30
|
-
/** Host-internal extension of {@link GameStateBridge}: adds `bump`,
|
|
31
|
-
*
|
|
32
|
-
*
|
|
43
|
+
/** Host-internal extension of {@link GameStateBridge}: adds `bump`, called
|
|
44
|
+
* both by `GameInternal.runFrame` at its tail AND by `Game.registerWorld`
|
|
45
|
+
* when the world list changes (see this file's module doc comment). NOT
|
|
46
|
+
* part of the game-facing `Game.state` surface (typed as the narrower
|
|
33
47
|
* `GameStateBridge` there) — games/components/hooks never call `bump`
|
|
34
|
-
* directly; only the frame executor
|
|
48
|
+
* directly; only the frame executor and the world registry do. */
|
|
35
49
|
export interface GameStateBridgeInternal extends GameStateBridge {
|
|
36
50
|
/** Bump `frameVersion` by one and notify every current subscriber, in
|
|
37
51
|
* subscription order. Subscriber errors are isolated (per-subscriber
|