@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
package/src/react/game-state.tsx
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
2
|
+
* Canonical `GameProvider`/`useGame`/`useGameState`/`useWorldObservation`
|
|
3
|
+
* entry for React adapter roots. Also home to `useDebugProvider` and
|
|
4
|
+
* `useDebugCommand`/`useDebugEmit`, the React-facing debug seam.
|
|
5
|
+
*
|
|
6
|
+
* This is a SEPARATE, react-value-importing module under
|
|
6
7
|
* `packages/engine/src/react/` — colocated per REACT-STATE-BRIDGE §3's own
|
|
7
8
|
* "colocate the react-facing hooks with the HUD seam, not the react-free
|
|
8
9
|
* core" rule, just now living IN the engine package rather than only in the
|
|
@@ -11,34 +12,26 @@
|
|
|
11
12
|
* invariant is proved by `packages/engine/test/react-core-import-ban.test.ts`
|
|
12
13
|
* (AC-F1).
|
|
13
14
|
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
* project gets ONE canonical context, while existing projects with their own
|
|
18
|
-
* full copy (their own `createContext`) keep working untouched — adoption of
|
|
19
|
-
* THIS module is an option, never a forced migration (D-Z5).
|
|
20
|
-
*
|
|
21
|
-
* Context-identity landmine (unchanged from the template file's own history,
|
|
22
|
-
* still the reason `loadProjectGameProvider`/the virtual-module plugin exist
|
|
23
|
-
* in `packages/editor/src/adapter-resolver.ts` /
|
|
24
|
-
* `packages/editor/vite-plugin-react-world-provider.ts`): `<GameProvider>`
|
|
25
|
-
* and `useGame()` must resolve against the SAME `createContext()` call. A
|
|
26
|
-
* project that ships its OWN `src/ui/game-state.tsx` (its own
|
|
27
|
-
* `createContext`) must be wrapped by ITS OWN `GameProvider` — wrapping it
|
|
28
|
-
* with THIS module's `GameProvider` instead would split context and
|
|
29
|
-
* `useGame()` would throw "no Game in context" even though a `<GameProvider>`
|
|
30
|
-
* genuinely wraps the tree (proved by
|
|
31
|
-
* `packages/editor/test/game-state-context-split.test.tsx`, AC-F1). This is
|
|
32
|
-
* exactly why the engine-published fallback (`resolveIngestReactAdapter`'s
|
|
33
|
-
* D-Y3 upgrade, `default-react`'s optional fallback) only ever fires when the
|
|
34
|
-
* project's OWN `src/ui/game-state.tsx` is ABSENT — an unmodified foreign
|
|
35
|
-
* entry that imports no vgai hooks has no context to split.
|
|
15
|
+
* Every host and game imports this one module, so provider and hooks share
|
|
16
|
+
* one `createContext()` identity. The engine core outside `src/react/`
|
|
17
|
+
* remains React-free, enforced by `react-core-import-ban.test.ts`.
|
|
36
18
|
*/
|
|
37
19
|
|
|
38
|
-
import {
|
|
20
|
+
import {
|
|
21
|
+
createContext,
|
|
22
|
+
type PropsWithChildren,
|
|
23
|
+
useCallback,
|
|
24
|
+
useContext,
|
|
25
|
+
useEffect,
|
|
26
|
+
useRef,
|
|
27
|
+
useSyncExternalStore,
|
|
28
|
+
} from 'react';
|
|
29
|
+
import type { z } from 'zod';
|
|
39
30
|
import type { WorldStateObserver } from '../adapter';
|
|
31
|
+
import { getDebugRegistry } from '../runtime/debug-registry';
|
|
40
32
|
import { createFrameSelectorCache, type Equals, shallow } from '../runtime/frame-selector-cache';
|
|
41
33
|
import type { Game } from '../runtime/game';
|
|
34
|
+
import type { DebugCommandArgs } from '../runtime/types';
|
|
42
35
|
|
|
43
36
|
/** Re-exported for convenience — the opt-in equality for selectors that
|
|
44
37
|
* return a fresh object/array/tuple every call (default is `Object.is`). */
|
|
@@ -47,10 +40,21 @@ export { shallow };
|
|
|
47
40
|
const GameContext = createContext<Game | null>(null);
|
|
48
41
|
|
|
49
42
|
/** Provide the `Game` to `useGameState`/`useGame` for everything mounted
|
|
50
|
-
* beneath it.
|
|
51
|
-
*
|
|
52
|
-
*
|
|
53
|
-
|
|
43
|
+
* beneath it. Adapter-root hosts install this provider automatically — see the module doc
|
|
44
|
+
* comment above for the context-identity rule this hook family depends on.
|
|
45
|
+
*
|
|
46
|
+
* Props use `PropsWithChildren` (children optional in the TYPE, not
|
|
47
|
+
* runtime-optional in practice — you always want children mounted under
|
|
48
|
+
* the provider) rather than a bare `{ children: ReactNode }` field: a
|
|
49
|
+
* required `children` in `P` makes TS's `createElement<P>(type, props?:
|
|
50
|
+
* Attributes & P, ...children)` overload reject the plain 3-arg call
|
|
51
|
+
* `React.createElement(GameProvider, { game }, child)` (no JSX transform,
|
|
52
|
+
* e.g. a `.ts` main composing a sibling `.tsx` HUD) with "Property
|
|
53
|
+
* 'children' is missing" even though the 3rd arg supplies it — issue #97.
|
|
54
|
+
* Making `children` optional in the type lets that overload resolve; the
|
|
55
|
+
* rest-arg children are still wired through to `children` at runtime by
|
|
56
|
+
* React itself, unchanged. See `test/game-state-create-element-types.test.tsx`. */
|
|
57
|
+
export function GameProvider({ game, children }: PropsWithChildren<{ game: Game }>) {
|
|
54
58
|
return <GameContext.Provider value={game}>{children}</GameContext.Provider>;
|
|
55
59
|
}
|
|
56
60
|
|
|
@@ -109,7 +113,7 @@ export function requireWorldObserver(game: Game, worldId: string): WorldStateObs
|
|
|
109
113
|
const world = game.world(worldId);
|
|
110
114
|
if (!world) {
|
|
111
115
|
throw new Error(
|
|
112
|
-
`useWorldObservation: no world registered with id "${worldId}" — check game.
|
|
116
|
+
`useWorldObservation: no world registered with id "${worldId}" — check game.roots for the ` +
|
|
113
117
|
'ids actually registered.',
|
|
114
118
|
);
|
|
115
119
|
}
|
|
@@ -170,3 +174,102 @@ export function useWorldObservation<T>(
|
|
|
170
174
|
() => cacheRef.current!.get(versionRef.current, () => selector(observer.snapshot())),
|
|
171
175
|
);
|
|
172
176
|
}
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* The debug seam's react-world registration door (Task 1.5,
|
|
180
|
+
* `docs/SYNTHETIC-PLAYER-SPEC.md` §3.1): react roots have no `setup()`/
|
|
181
|
+
* `ctx.debug` of their own, so this hook registers a named state provider
|
|
182
|
+
* into the SAME game-scoped registry every `GameComponent`'s `ctx.debug`
|
|
183
|
+
* feeds (`getDebugRegistry(game)`, `runtime/debug-registry.ts`), readable
|
|
184
|
+
* through `game.systemAdapters.debug.state(name)` exactly like a
|
|
185
|
+
* `ctx.debug.registerStateProvider` call.
|
|
186
|
+
*
|
|
187
|
+
* Registers ONCE per mount (keyed on `name`) and unregisters on unmount —
|
|
188
|
+
* silently, like hot-reload's `strip()`. Re-renders never re-register or
|
|
189
|
+
* re-warn: `fn` is kept in a ref updated every render, so the registered
|
|
190
|
+
* closure always calls the CURRENT `fn` without touching the registry.
|
|
191
|
+
* Outside a `<GameProvider>` (or against a bare test `Game` built without a
|
|
192
|
+
* registry) this is an inert no-op — it never throws, matching the "no seam
|
|
193
|
+
* without a consumer" degrade every optional `ctx.*` surface follows.
|
|
194
|
+
*/
|
|
195
|
+
export function useDebugProvider(
|
|
196
|
+
name: string,
|
|
197
|
+
fn: () => unknown,
|
|
198
|
+
opts?: { tier?: 'observable' | 'assisted' },
|
|
199
|
+
): void {
|
|
200
|
+
const game = useContext(GameContext);
|
|
201
|
+
const fnRef = useRef(fn);
|
|
202
|
+
fnRef.current = fn;
|
|
203
|
+
const tier = opts?.tier;
|
|
204
|
+
|
|
205
|
+
useEffect(() => {
|
|
206
|
+
const registry = game && getDebugRegistry(game);
|
|
207
|
+
if (!registry) return;
|
|
208
|
+
return registry.registerReactProvider(name, () => fnRef.current(), { tier });
|
|
209
|
+
// `tier` is deliberately NOT a dep (same reasoning as `useDebugCommand`'s
|
|
210
|
+
// `spec`) — captured once at mount, so it never forces re-registration.
|
|
211
|
+
}, [game, name]);
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* The command-side counterpart of {@link useDebugProvider} — registers an
|
|
216
|
+
* invokable debug command into the same game-scoped registry, readable
|
|
217
|
+
* through `game.systemAdapters.debug.commands()`/`invoke(name, args)`.
|
|
218
|
+
*
|
|
219
|
+
* Same mount/unmount/ref-latest contract as {@link useDebugProvider}: `spec`
|
|
220
|
+
* (description/args/locus) is captured at registration time, `fn` always
|
|
221
|
+
* calls through to the latest render's closure via a ref, and the hook is an
|
|
222
|
+
* inert no-op with no `<GameProvider>` in scope.
|
|
223
|
+
*
|
|
224
|
+
* Generic over the declared `args` Zod tuple, same as
|
|
225
|
+
* `DebugCtxSurface.registerCommand` ({@link DebugCommandArgs}, dry-run
|
|
226
|
+
* finding — `docs/ACCEPTANCE-DRIVER-BUILD-PLAN.md` Wave 6 ledger): declaring
|
|
227
|
+
* `args: z.tuple([z.number(), z.string()])` types `fn`'s parameters as
|
|
228
|
+
* `(n: number, s: string) => ...` with no `unknown[]` cast; omitting `args`
|
|
229
|
+
* keeps `fn` typed `(...args: unknown[]) => ...` as before.
|
|
230
|
+
*/
|
|
231
|
+
export function useDebugCommand<T extends z.ZodTuple | undefined = undefined>(
|
|
232
|
+
name: string,
|
|
233
|
+
spec: { description?: string; args?: T; locus?: 'client' | 'server' },
|
|
234
|
+
fn: (...args: DebugCommandArgs<T>) => unknown | Promise<unknown>,
|
|
235
|
+
): void {
|
|
236
|
+
const game = useContext(GameContext);
|
|
237
|
+
const fnRef = useRef(fn);
|
|
238
|
+
fnRef.current = fn;
|
|
239
|
+
|
|
240
|
+
useEffect(() => {
|
|
241
|
+
const registry = game && getDebugRegistry(game);
|
|
242
|
+
if (!registry) return;
|
|
243
|
+
return registry.registerReactCommand(name, spec, (...args: DebugCommandArgs<T>) =>
|
|
244
|
+
fnRef.current(...args),
|
|
245
|
+
);
|
|
246
|
+
// `spec` is deliberately NOT a dep (like `equals` above) — captured once
|
|
247
|
+
// at mount, so a fresh inline object literal every render never forces
|
|
248
|
+
// re-registration.
|
|
249
|
+
}, [game, name]);
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
/**
|
|
253
|
+
* The event-side counterpart of {@link useDebugProvider} and
|
|
254
|
+
* {@link useDebugCommand}. Returns a stable callback that writes a
|
|
255
|
+
* tick-stamped event to the game-scoped debug flight recorder:
|
|
256
|
+
*
|
|
257
|
+
* ```tsx
|
|
258
|
+
* const emit = useDebugEmit();
|
|
259
|
+
* emit('score-changed', { score });
|
|
260
|
+
* ```
|
|
261
|
+
*
|
|
262
|
+
* It is an inert no-op outside a `<GameProvider>`, matching the optional
|
|
263
|
+
* behavior of the other React debug hooks. Games never need to import the
|
|
264
|
+
* debug registry or know its internal React provenance id.
|
|
265
|
+
*/
|
|
266
|
+
export function useDebugEmit(): (event: string, detail?: unknown) => void {
|
|
267
|
+
const game = useContext(GameContext);
|
|
268
|
+
return useCallback(
|
|
269
|
+
(event: string, detail?: unknown) => {
|
|
270
|
+
if (!game) return;
|
|
271
|
+
getDebugRegistry(game)?.emitReact(event, detail);
|
|
272
|
+
},
|
|
273
|
+
[game],
|
|
274
|
+
);
|
|
275
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { type ComponentType, createElement } from 'react';
|
|
2
|
+
import { flushSync } from 'react-dom';
|
|
3
|
+
import { createRoot } from 'react-dom/client';
|
|
4
|
+
import type { MountedReactGame, ReactRootAdapter, ReactWorldHost } from '../runtime/create-runtime';
|
|
5
|
+
import { isAdapterRegistered, registerAdapter } from '../runtime/mount-game';
|
|
6
|
+
import { GameProvider } from './game-state';
|
|
7
|
+
|
|
8
|
+
interface ReactEntryModule {
|
|
9
|
+
readonly default?: ComponentType;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/** Construct one canonical React root adapter for direct host composition. */
|
|
13
|
+
export function createReactRootAdapter(id: string, Entry: ComponentType): ReactRootAdapter {
|
|
14
|
+
return {
|
|
15
|
+
id,
|
|
16
|
+
async mount(host: ReactWorldHost): Promise<MountedReactGame> {
|
|
17
|
+
if (!host.game) throw new Error(`React root "${id}" requires a Game host.`);
|
|
18
|
+
const reactRoot = createRoot(host.container);
|
|
19
|
+
flushSync(() => {
|
|
20
|
+
reactRoot.render(createElement(GameProvider, { game: host.game! }, createElement(Entry)));
|
|
21
|
+
});
|
|
22
|
+
return {
|
|
23
|
+
kind: 'react',
|
|
24
|
+
container: host.container,
|
|
25
|
+
drivesOwnLoop: false,
|
|
26
|
+
dispose: () => reactRoot.unmount(),
|
|
27
|
+
};
|
|
28
|
+
},
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Register the engine's React adapter-root factory. This module is an
|
|
34
|
+
* explicit optional React entry point: engine core never imports it, while a
|
|
35
|
+
* React game host imports it once and receives the canonical root lifecycle.
|
|
36
|
+
*/
|
|
37
|
+
export function registerReactAdapter(): void {
|
|
38
|
+
if (isAdapterRegistered('react')) return;
|
|
39
|
+
registerAdapter('react', (root, { entryModule }) => {
|
|
40
|
+
const Entry = (entryModule as ReactEntryModule | undefined)?.default;
|
|
41
|
+
if (!Entry) {
|
|
42
|
+
throw new Error(
|
|
43
|
+
`React root "${root.id}" entry "${root.entry ?? '(missing)'}" must default-export a component.`,
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return { kind: 'react', adapter: createReactRootAdapter(root.id, Entry) };
|
|
48
|
+
});
|
|
49
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
export interface UnmanagedReactRootFinding {
|
|
2
|
+
readonly file: string;
|
|
3
|
+
readonly line: number;
|
|
4
|
+
readonly api: 'createRoot' | 'hydrateRoot' | 'ReactDOM.render';
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
function lineAt(source: string, offset: number): number {
|
|
8
|
+
return source.slice(0, offset).split('\n').length;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Find project-owned React DOM root creation. VGAI hosts React through
|
|
13
|
+
* manifest adapter roots, so any of these calls in game source creates an
|
|
14
|
+
* unmanaged second lifecycle and is a hard validation error.
|
|
15
|
+
*/
|
|
16
|
+
export function detectUnmanagedReactRoots(
|
|
17
|
+
source: string,
|
|
18
|
+
file: string,
|
|
19
|
+
): UnmanagedReactRootFinding[] {
|
|
20
|
+
const findings: UnmanagedReactRootFinding[] = [];
|
|
21
|
+
const aliases = new Map<string, 'createRoot' | 'hydrateRoot'>();
|
|
22
|
+
|
|
23
|
+
for (const match of source.matchAll(/import\s*\{([^}]*)\}\s*from\s*['"]react-dom\/client['"]/g)) {
|
|
24
|
+
for (const member of (match[1] ?? '').split(',')) {
|
|
25
|
+
const parsed = member.trim().match(/^(createRoot|hydrateRoot)(?:\s+as\s+([\w$]+))?$/);
|
|
26
|
+
if (parsed) aliases.set(parsed[2] ?? parsed[1]!, parsed[1] as 'createRoot' | 'hydrateRoot');
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
for (const [alias, api] of aliases) {
|
|
31
|
+
const call = new RegExp(`\\b${alias.replace(/[$]/g, '\\$&')}\\s*\\(`, 'g');
|
|
32
|
+
for (const match of source.matchAll(call)) {
|
|
33
|
+
findings.push({ file, line: lineAt(source, match.index ?? 0), api });
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const namespaceNames = new Set<string>();
|
|
38
|
+
for (const match of source.matchAll(
|
|
39
|
+
/import\s+(?:\*\s+as\s+|)([\w$]+)\s+from\s*['"]react-dom(?:\/client)?['"]/g,
|
|
40
|
+
)) {
|
|
41
|
+
namespaceNames.add(match[1]!);
|
|
42
|
+
}
|
|
43
|
+
namespaceNames.add('ReactDOM');
|
|
44
|
+
for (const name of namespaceNames) {
|
|
45
|
+
for (const api of ['createRoot', 'hydrateRoot', 'render'] as const) {
|
|
46
|
+
const call = new RegExp(`\\b${name}\\.${api}\\s*\\(`, 'g');
|
|
47
|
+
for (const match of source.matchAll(call)) {
|
|
48
|
+
findings.push({
|
|
49
|
+
file,
|
|
50
|
+
line: lineAt(source, match.index ?? 0),
|
|
51
|
+
api: api === 'render' ? 'ReactDOM.render' : api,
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return findings.filter(
|
|
58
|
+
(finding, index) =>
|
|
59
|
+
findings.findIndex(
|
|
60
|
+
(candidate) =>
|
|
61
|
+
candidate.file === finding.file &&
|
|
62
|
+
candidate.line === finding.line &&
|
|
63
|
+
candidate.api === finding.api,
|
|
64
|
+
) === index,
|
|
65
|
+
);
|
|
66
|
+
}
|
package/src/react/use-data.ts
CHANGED
|
@@ -5,11 +5,11 @@
|
|
|
5
5
|
* Lives under `packages/engine/src/react/` deliberately: this is the ONE
|
|
6
6
|
* directory of the engine allowed to value-import react (colocated with
|
|
7
7
|
* `game-state.tsx` per the react-free-core rule proved by
|
|
8
|
-
* `test/react-core-import-ban.test.ts`). Game
|
|
8
|
+
* `test/react-core-import-ban.test.ts`). Game roots that aren't react keep
|
|
9
9
|
* using `DataHandle.get()`/`subscribe()` directly (§2.3).
|
|
10
10
|
*
|
|
11
11
|
* - {@link useData} — subscribe a component to any W1 `DataHandle`; works in
|
|
12
|
-
* project tools, react
|
|
12
|
+
* project tools, react roots, and HUD overlays alike.
|
|
13
13
|
* - {@link writeData} — EDITOR-TOOL plumbing: write a whole `.data.json`
|
|
14
14
|
* back through the editor dev server, closing the live-tuning loop
|
|
15
15
|
* (widget → file write → Vite HMR → `hotSwap` → {@link useData} re-render
|
|
@@ -89,6 +89,16 @@ export async function writeData(
|
|
|
89
89
|
?.replace(/\.data\.json$/, '')}.schema.json`;
|
|
90
90
|
const content = `${JSON.stringify({ $schema: schemaRef, ...rest }, null, 2)}\n`;
|
|
91
91
|
|
|
92
|
+
const transactionalWriter = (
|
|
93
|
+
globalThis as typeof globalThis & {
|
|
94
|
+
__vgaiHistoryWriteData?: (path: string, content: string) => Promise<void>;
|
|
95
|
+
}
|
|
96
|
+
).__vgaiHistoryWriteData;
|
|
97
|
+
if (transactionalWriter) {
|
|
98
|
+
await transactionalWriter(projectRelativePath, content);
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
|
|
92
102
|
let res: Response;
|
|
93
103
|
try {
|
|
94
104
|
res = await fetch('/__editor/data-file', {
|