@vgai/engine 0.5.0 → 0.5.2
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 +1 -1
- package/schemas/engine-capabilities.json +4 -4
- package/schemas/vgai-game.schema.json +2 -2
- package/src/adapter/authoring.ts +42 -0
- package/src/adapter/index.ts +3 -0
- package/src/adapter/ingest/overlay-apply.ts +50 -6
- package/src/adapter/ingest/scene-capture.ts +51 -2
- package/src/adapter/vgai-scene-game-adapter.ts +24 -0
- package/src/manifest/schema.ts +7 -3
- package/src/runtime/create-runtime.ts +97 -0
- package/src/runtime/game.ts +11 -1
- package/src/scene/asset-ref-check.ts +1 -1
- package/src/scene/scene-loader.ts +2 -2
- package/src/scene/user-data.ts +18 -0
- package/src/world3d-react/behavior.tsx +19 -11
- package/src/world3d-react/r3f-adapter.tsx +8 -0
- package/dist/adapter/adapter-surface.d.ts +0 -30
- package/dist/adapter/adapter-surface.d.ts.map +0 -1
- package/dist/adapter/adapter-surface.js +0 -18
- package/dist/adapter/authoring.d.ts +0 -461
- 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 -71
- 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 -206
- 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 -108
- package/dist/adapter/vgai-scene-game-adapter.d.ts.map +0 -1
- package/dist/adapter/vgai-scene-game-adapter.js +0 -762
- 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 -56
- package/dist/animation/xstate-animation-binding.d.ts.map +0 -1
- package/dist/animation/xstate-animation-binding.js +0 -331
- package/dist/animation/xstate-animation-meta.d.ts +0 -266
- package/dist/animation/xstate-animation-meta.d.ts.map +0 -1
- package/dist/animation/xstate-animation-meta.js +0 -252
- 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/character/cloth-sim.d.ts +0 -179
- package/dist/character/cloth-sim.d.ts.map +0 -1
- package/dist/character/cloth-sim.js +0 -334
- package/dist/character/spring-chain.d.ts +0 -135
- package/dist/character/spring-chain.d.ts.map +0 -1
- package/dist/character/spring-chain.js +0 -165
- package/dist/core/game-loop.d.ts +0 -42
- package/dist/core/game-loop.d.ts.map +0 -1
- package/dist/core/game-loop.js +0 -167
- package/dist/core/seeded-random.d.ts +0 -69
- package/dist/core/seeded-random.d.ts.map +0 -1
- package/dist/core/seeded-random.js +0 -121
- 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 -297
- package/dist/core/types.d.ts +0 -92
- 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/dev/performance-profiler.d.ts +0 -60
- package/dist/dev/performance-profiler.d.ts.map +0 -1
- package/dist/dev/performance-profiler.js +0 -181
- package/dist/dev/webgl-gpu-timer.d.ts +0 -8
- package/dist/dev/webgl-gpu-timer.d.ts.map +0 -1
- package/dist/dev/webgl-gpu-timer.js +0 -52
- package/dist/ecs/component-manager.d.ts +0 -205
- package/dist/ecs/component-manager.d.ts.map +0 -1
- package/dist/ecs/component-manager.js +0 -706
- package/dist/ecs/game-component.d.ts +0 -146
- package/dist/ecs/game-component.d.ts.map +0 -1
- package/dist/ecs/game-component.js +0 -141
- 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/humanoid/bake.operation.d.ts +0 -119
- package/dist/humanoid/bake.operation.d.ts.map +0 -1
- package/dist/humanoid/bake.operation.js +0 -228
- package/dist/humanoid/body.d.ts +0 -101
- package/dist/humanoid/body.d.ts.map +0 -1
- package/dist/humanoid/body.js +0 -530
- package/dist/humanoid/clips.d.ts +0 -62
- package/dist/humanoid/clips.d.ts.map +0 -1
- package/dist/humanoid/clips.js +0 -121
- package/dist/humanoid/compose.d.ts +0 -75
- package/dist/humanoid/compose.d.ts.map +0 -1
- package/dist/humanoid/compose.js +0 -176
- package/dist/humanoid/generate.d.ts +0 -92
- package/dist/humanoid/generate.d.ts.map +0 -1
- package/dist/humanoid/generate.js +0 -124
- package/dist/humanoid/index.d.ts +0 -24
- package/dist/humanoid/index.d.ts.map +0 -1
- package/dist/humanoid/index.js +0 -18
- package/dist/humanoid/schema.d.ts +0 -35
- package/dist/humanoid/schema.d.ts.map +0 -1
- package/dist/humanoid/schema.js +0 -87
- package/dist/humanoid/skeleton.d.ts +0 -103
- package/dist/humanoid/skeleton.d.ts.map +0 -1
- package/dist/humanoid/skeleton.js +0 -289
- 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 -945
- package/dist/input/input-manager.d.ts.map +0 -1
- package/dist/input/input-manager.js +0 -2207
- package/dist/input/input-types.d.ts +0 -174
- 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 -144
- package/dist/manifest/load.d.ts.map +0 -1
- package/dist/manifest/load.js +0 -273
- package/dist/manifest/schema.d.ts +0 -230
- package/dist/manifest/schema.d.ts.map +0 -1
- package/dist/manifest/schema.js +0 -394
- 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 -156
- package/dist/react/game-state.d.ts.map +0 -1
- package/dist/react/game-state.js +0 -222
- package/dist/react/root-adapter.d.ts +0 -11
- package/dist/react/root-adapter.d.ts.map +0 -1
- package/dist/react/root-adapter.js +0 -41
- package/dist/react/unmanaged-root-detector.d.ts +0 -12
- package/dist/react/unmanaged-root-detector.d.ts.map +0 -1
- package/dist/react/unmanaged-root-detector.js +0 -45
- 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 -101
- 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 -249
- package/dist/runtime/create-runtime.d.ts.map +0 -1
- package/dist/runtime/create-runtime.js +0 -641
- package/dist/runtime/debug-bridge.d.ts +0 -257
- package/dist/runtime/debug-bridge.d.ts.map +0 -1
- package/dist/runtime/debug-bridge.js +0 -224
- package/dist/runtime/debug-registry.d.ts +0 -288
- package/dist/runtime/debug-registry.d.ts.map +0 -1
- package/dist/runtime/debug-registry.js +0 -513
- 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 -496
- package/dist/runtime/game.d.ts.map +0 -1
- package/dist/runtime/game.js +0 -741
- package/dist/runtime/gameplay-rng-trap.d.ts +0 -48
- package/dist/runtime/gameplay-rng-trap.d.ts.map +0 -1
- package/dist/runtime/gameplay-rng-trap.js +0 -96
- 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 -173
- package/dist/runtime/mount-manifest.d.ts.map +0 -1
- package/dist/runtime/mount-manifest.js +0 -297
- 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/state-bridge.d.ts +0 -61
- package/dist/runtime/state-bridge.d.ts.map +0 -1
- package/dist/runtime/state-bridge.js +0 -63
- package/dist/runtime/types.d.ts +0 -253
- 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 -38
- package/dist/scene/asset-registry.d.ts.map +0 -1
- package/dist/scene/asset-registry.js +0 -66
- 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 -22
- package/dist/scene/component-registry.d.ts.map +0 -1
- package/dist/scene/component-registry.js +0 -37
- 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 -370
- 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 -167
- package/dist/scene/scene-loader.d.ts.map +0 -1
- package/dist/scene/scene-loader.js +0 -1211
- 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 -37
- package/dist/scene/schema/index.d.ts.map +0 -1
- package/dist/scene/schema/index.js +0 -19
- 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 -103
- 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 -303
- package/dist/scene/schema/scene-file.d.ts.map +0 -1
- package/dist/scene/schema/scene-file.js +0 -256
- 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/user-data.d.ts +0 -185
- package/dist/scene/user-data.d.ts.map +0 -1
- package/dist/scene/user-data.js +0 -144
- 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 -130
- package/dist/tools/define-tool.d.ts.map +0 -1
- package/dist/tools/define-tool.js +0 -96
- package/dist/world2d/authoring-2d.d.ts +0 -80
- package/dist/world2d/authoring-2d.d.ts.map +0 -1
- package/dist/world2d/authoring-2d.js +0 -195
- 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 -210
- 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 -275
- 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 -59
- package/dist/world2d/types.d.ts.map +0 -1
- package/dist/world2d/types.js +0 -1
|
@@ -1,297 +0,0 @@
|
|
|
1
|
-
import { PHASE_ORDER, } from './types';
|
|
2
|
-
/**
|
|
3
|
-
* Ordered system execution by named phase.
|
|
4
|
-
*
|
|
5
|
-
* Systems are registered with a phase name. When `run(dt)` is called, all
|
|
6
|
-
* phases execute in `PHASE_ORDER` via `runPhase(phase, dt)`. Within a phase,
|
|
7
|
-
* `runPhase` executes three ordered buckets (GAME-ROOT-DESIGN.md §4, T7.1
|
|
8
|
-
* slice 2):
|
|
9
|
-
*
|
|
10
|
-
* 1. **engine** — everything `add()`/`register()`ed at or before the last
|
|
11
|
-
* `markEngineBoundary()` call, or EVERYTHING if no boundary has ever
|
|
12
|
-
* been marked (the world2d-silo case: it never calls
|
|
13
|
-
* `markEngineBoundary`, so its systems are all "engine").
|
|
14
|
-
* 2. **componentTick** — the single per-phase slot set via
|
|
15
|
-
* `setComponentTick(phase, fn)`. Component ticks are engine
|
|
16
|
-
* infrastructure: they always run after every engine system and before
|
|
17
|
-
* every game system in that phase, REGARDLESS of when
|
|
18
|
-
* `setComponentTick` was called relative to other `add()` calls. This
|
|
19
|
-
* is what makes "engine systems run before component ticks" a
|
|
20
|
-
* structural guarantee rather than a registration-order convention
|
|
21
|
-
* (see `component-manager.ts`, which registers its tick this way).
|
|
22
|
-
* 3. **game** — everything `add()`/`register()`ed AFTER the last
|
|
23
|
-
* `markEngineBoundary()` call.
|
|
24
|
-
*
|
|
25
|
-
* Within each bucket, systems run in registration order.
|
|
26
|
-
*/
|
|
27
|
-
export function createSystemRunner(observer, scope = 'world') {
|
|
28
|
-
const systems = new Map();
|
|
29
|
-
const registered = [];
|
|
30
|
-
const componentTicks = new Map();
|
|
31
|
-
const labels = new Map();
|
|
32
|
-
let anonymousId = 0;
|
|
33
|
-
// Initialize all phases with empty arrays / no component tick.
|
|
34
|
-
for (const phase of PHASE_ORDER) {
|
|
35
|
-
systems.set(phase, []);
|
|
36
|
-
componentTicks.set(phase, null);
|
|
37
|
-
}
|
|
38
|
-
// Membership bookkeeping for `markEngineBoundary()` (T7.2 review fix —
|
|
39
|
-
// replaces the old length/index-snapshot bookkeeping, which broke if a
|
|
40
|
-
// pre-boundary "engine" entry was ever removed: shrinking the list would
|
|
41
|
-
// shift a later "game" entry underneath the recorded length, misclassifying
|
|
42
|
-
// it as engine). `engineFns`/`engineRegistered` instead record WHICH
|
|
43
|
-
// specific function/system was present at the last `markEngineBoundary()`
|
|
44
|
-
// call — membership survives arbitrary removal of any other entry,
|
|
45
|
-
// regardless of position. `boundaryMarked` is false until the first mark
|
|
46
|
-
// (mirrors the old `boundary === null`: everything is "engine" pre-mark —
|
|
47
|
-
// the world2d-silo case, which never marks a boundary). Component-tick
|
|
48
|
-
// slots (`setComponentTick`) are NOT part of this bookkeeping at all — they
|
|
49
|
-
// are engine infrastructure and survive `removeAllNonEngine()`
|
|
50
|
-
// unconditionally.
|
|
51
|
-
let boundaryMarked = false;
|
|
52
|
-
const engineFns = new Map();
|
|
53
|
-
for (const phase of PHASE_ORDER)
|
|
54
|
-
engineFns.set(phase, new Set());
|
|
55
|
-
const engineRegistered = new Set();
|
|
56
|
-
/** Run one system function, isolating a throw so it never wedges the frame. */
|
|
57
|
-
function runOne(fn, phase, dt) {
|
|
58
|
-
const label = labels.get(fn) ?? fn.name ?? `anonymous-${++anonymousId}`;
|
|
59
|
-
labels.set(fn, label);
|
|
60
|
-
observer?.beginSystem(scope, phase, label);
|
|
61
|
-
try {
|
|
62
|
-
fn(dt);
|
|
63
|
-
}
|
|
64
|
-
catch (err) {
|
|
65
|
-
const label = fn.name ? `"${fn.name}"` : '(anonymous)';
|
|
66
|
-
console.error(`[system-runner] system ${label} in phase "${phase}" threw:`, err);
|
|
67
|
-
}
|
|
68
|
-
finally {
|
|
69
|
-
observer?.endSystem(scope, phase, label);
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
return {
|
|
73
|
-
/**
|
|
74
|
-
* Register a bare system function in a specific phase.
|
|
75
|
-
* Systems within the same phase run in the order they were added.
|
|
76
|
-
*/
|
|
77
|
-
add(phase, fn, options) {
|
|
78
|
-
const list = systems.get(phase);
|
|
79
|
-
if (!list) {
|
|
80
|
-
throw new Error(`Unknown phase: ${phase}. Valid phases: ${PHASE_ORDER.join(', ')}`);
|
|
81
|
-
}
|
|
82
|
-
list.push(fn);
|
|
83
|
-
labels.set(fn, options?.name ?? fn.name ?? `anonymous-${++anonymousId}`);
|
|
84
|
-
},
|
|
85
|
-
/**
|
|
86
|
-
* Remove a bare system function from a phase. Also drops it from the
|
|
87
|
-
* engine-membership set (if present) — the fix for the length-based
|
|
88
|
-
* bookkeeping bug: removing this has no effect on how any OTHER entry
|
|
89
|
-
* (before or after it) is classified, since classification is now
|
|
90
|
-
* per-function membership, not position.
|
|
91
|
-
*/
|
|
92
|
-
remove(phase, fn) {
|
|
93
|
-
const list = systems.get(phase);
|
|
94
|
-
if (!list)
|
|
95
|
-
return;
|
|
96
|
-
const idx = list.indexOf(fn);
|
|
97
|
-
if (idx !== -1)
|
|
98
|
-
list.splice(idx, 1);
|
|
99
|
-
engineFns.get(phase)?.delete(fn);
|
|
100
|
-
},
|
|
101
|
-
/**
|
|
102
|
-
* Register a lifecycle system. Adds its update to the correct phase.
|
|
103
|
-
* Call runInit() after all systems are registered to invoke init hooks.
|
|
104
|
-
*/
|
|
105
|
-
register(system) {
|
|
106
|
-
const list = systems.get(system.phase);
|
|
107
|
-
if (!list) {
|
|
108
|
-
throw new Error(`Unknown phase: ${system.phase}. Valid phases: ${PHASE_ORDER.join(', ')}`);
|
|
109
|
-
}
|
|
110
|
-
list.push(system.update);
|
|
111
|
-
labels.set(system.update, system.name ?? system.update.name ?? `anonymous-${++anonymousId}`);
|
|
112
|
-
registered.push(system);
|
|
113
|
-
},
|
|
114
|
-
/**
|
|
115
|
-
* Unregister a lifecycle system. Removes its update and calls dispose.
|
|
116
|
-
*/
|
|
117
|
-
unregister(system) {
|
|
118
|
-
const list = systems.get(system.phase);
|
|
119
|
-
if (list) {
|
|
120
|
-
const idx = list.indexOf(system.update);
|
|
121
|
-
if (idx !== -1)
|
|
122
|
-
list.splice(idx, 1);
|
|
123
|
-
}
|
|
124
|
-
engineFns.get(system.phase)?.delete(system.update);
|
|
125
|
-
const regIdx = registered.indexOf(system);
|
|
126
|
-
if (regIdx !== -1)
|
|
127
|
-
registered.splice(regIdx, 1);
|
|
128
|
-
engineRegistered.delete(system);
|
|
129
|
-
system.dispose?.();
|
|
130
|
-
},
|
|
131
|
-
/**
|
|
132
|
-
* Register the ONE component-tick function for a phase (T7.1 slice 2).
|
|
133
|
-
* Component ticks are engine infrastructure, not a bare `add()`ed
|
|
134
|
-
* system: they always execute after every engine-bucket system and
|
|
135
|
-
* before every game-bucket system in that phase (see `runPhase`),
|
|
136
|
-
* they are never touched by `removeAllNonEngine()`, and they do not
|
|
137
|
-
* count toward `markEngineBoundary()`'s bookkeeping. Throws if a tick
|
|
138
|
-
* is already set for this phase — at most one component manager may
|
|
139
|
-
* own a phase's tick slot.
|
|
140
|
-
*/
|
|
141
|
-
setComponentTick(phase, fn) {
|
|
142
|
-
if (!componentTicks.has(phase)) {
|
|
143
|
-
throw new Error(`Unknown phase: ${phase}. Valid phases: ${PHASE_ORDER.join(', ')}`);
|
|
144
|
-
}
|
|
145
|
-
if (componentTicks.get(phase)) {
|
|
146
|
-
throw new Error(`[system-runner] setComponentTick: phase "${phase}" already has a component tick registered`);
|
|
147
|
-
}
|
|
148
|
-
componentTicks.set(phase, fn);
|
|
149
|
-
labels.set(fn, `components.${phase}`);
|
|
150
|
-
},
|
|
151
|
-
/**
|
|
152
|
-
* Call init() on all registered lifecycle systems, in phase order.
|
|
153
|
-
* Call once after scene load, before the first game loop tick.
|
|
154
|
-
*/
|
|
155
|
-
runInit() {
|
|
156
|
-
const sorted = [...registered].sort((a, b) => PHASE_ORDER.indexOf(a.phase) - PHASE_ORDER.indexOf(b.phase));
|
|
157
|
-
for (const sys of sorted) {
|
|
158
|
-
sys.init?.();
|
|
159
|
-
}
|
|
160
|
-
},
|
|
161
|
-
/**
|
|
162
|
-
* Call dispose() on all registered lifecycle systems and remove them.
|
|
163
|
-
*/
|
|
164
|
-
runDispose() {
|
|
165
|
-
for (const sys of registered) {
|
|
166
|
-
const list = systems.get(sys.phase);
|
|
167
|
-
if (list) {
|
|
168
|
-
const idx = list.indexOf(sys.update);
|
|
169
|
-
if (idx !== -1)
|
|
170
|
-
list.splice(idx, 1);
|
|
171
|
-
}
|
|
172
|
-
sys.dispose?.();
|
|
173
|
-
}
|
|
174
|
-
registered.length = 0;
|
|
175
|
-
},
|
|
176
|
-
/**
|
|
177
|
-
* Run ONE phase's three ordered buckets — engine, componentTick, game
|
|
178
|
-
* (see the module doc comment). Each system call is isolated: a
|
|
179
|
-
* throwing system is loudly logged (never swallowed) but does not stop
|
|
180
|
-
* its siblings in the same bucket, a later bucket in this phase, or a
|
|
181
|
-
* later phase, from running this frame.
|
|
182
|
-
*
|
|
183
|
-
* Public — the Game root's frame executor (`runtime/game.ts`) calls this
|
|
184
|
-
* directly per (phase, world); `run(dt)` below is just a loop over it,
|
|
185
|
-
* preserved for the world2d silo and any direct caller.
|
|
186
|
-
*/
|
|
187
|
-
runPhase(phase, dt) {
|
|
188
|
-
const list = systems.get(phase);
|
|
189
|
-
if (!list) {
|
|
190
|
-
throw new Error(`Unknown phase: ${phase}. Valid phases: ${PHASE_ORDER.join(', ')}`);
|
|
191
|
-
}
|
|
192
|
-
// Partition by MEMBERSHIP, not position: everything in this phase's
|
|
193
|
-
// `engineFns` set (or, if no boundary has ever been marked, everything —
|
|
194
|
-
// the world2d-silo case) runs immediately, in list order, as it's
|
|
195
|
-
// encountered; everything else is queued into `gameFns` (also in list
|
|
196
|
-
// order) and run after the component tick. Because classification is
|
|
197
|
-
// per-function rather than "index < some remembered length", removing
|
|
198
|
-
// ANY entry via `remove()` — including a pre-boundary "engine" one —
|
|
199
|
-
// cannot shift a later game system into the engine bucket.
|
|
200
|
-
const engineSet = engineFns.get(phase);
|
|
201
|
-
const gameFns = [];
|
|
202
|
-
for (const fn of list) {
|
|
203
|
-
if (boundaryMarked && !engineSet.has(fn)) {
|
|
204
|
-
gameFns.push(fn);
|
|
205
|
-
}
|
|
206
|
-
else {
|
|
207
|
-
runOne(fn, phase, dt);
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
const tick = componentTicks.get(phase);
|
|
211
|
-
if (tick)
|
|
212
|
-
runOne(tick, phase, dt);
|
|
213
|
-
for (const fn of gameFns) {
|
|
214
|
-
runOne(fn, phase, dt);
|
|
215
|
-
}
|
|
216
|
-
},
|
|
217
|
-
/**
|
|
218
|
-
* Run all phases in order, via `runPhase`.
|
|
219
|
-
*/
|
|
220
|
-
run(dt) {
|
|
221
|
-
for (const phase of PHASE_ORDER) {
|
|
222
|
-
this.runPhase(phase, dt);
|
|
223
|
-
}
|
|
224
|
-
},
|
|
225
|
-
/**
|
|
226
|
-
* Mark everything registered so far (via `add()`/`register()`, in every
|
|
227
|
-
* phase) as "engine" — infrastructure that must survive a warm restart.
|
|
228
|
-
* Call once, right after mount finishes wiring engine-level systems and
|
|
229
|
-
* BEFORE any game (`setup()`/scene load) registers its own. `hotReload`
|
|
230
|
-
* calls `removeAllNonEngine()` on every restart, which only ever removes
|
|
231
|
-
* what was added after this mark. Component-tick slots (`setComponentTick`)
|
|
232
|
-
* are unaffected — they are never part of this boundary.
|
|
233
|
-
*/
|
|
234
|
-
markEngineBoundary() {
|
|
235
|
-
for (const phase of PHASE_ORDER) {
|
|
236
|
-
const set = engineFns.get(phase);
|
|
237
|
-
for (const fn of systems.get(phase))
|
|
238
|
-
set.add(fn);
|
|
239
|
-
}
|
|
240
|
-
for (const sys of registered)
|
|
241
|
-
engineRegistered.add(sys);
|
|
242
|
-
boundaryMarked = true;
|
|
243
|
-
},
|
|
244
|
-
/**
|
|
245
|
-
* Bulk-remove every system registered after the last `markEngineBoundary()`
|
|
246
|
-
* call — both bare `add()`ed functions and lifecycle `register()`ed systems
|
|
247
|
-
* (the latter get `dispose()`d, mirroring `unregister()`). A no-op if no
|
|
248
|
-
* boundary has been marked. Idempotent: calling it again with nothing new
|
|
249
|
-
* registered since is a safe no-op. Component-tick slots are NEVER cleared
|
|
250
|
-
* by this — they are engine infrastructure, not game content.
|
|
251
|
-
*
|
|
252
|
-
* This is what makes a warm restart (`hotReload`) safe to call N times
|
|
253
|
-
* without accumulating duplicate systems/listeners — each restart's
|
|
254
|
-
* outgoing game systems are fully removed before the new one registers its
|
|
255
|
-
* own, while the engine systems (input/physics/render/the ComponentManager
|
|
256
|
-
* tick/...) registered before the boundary are never touched.
|
|
257
|
-
*/
|
|
258
|
-
removeAllNonEngine() {
|
|
259
|
-
if (!boundaryMarked)
|
|
260
|
-
return;
|
|
261
|
-
// Membership-based, same reasoning as runPhase: partition by whether
|
|
262
|
-
// each entry is in the engine set, not by a remembered length/index.
|
|
263
|
-
const keptRegistered = registered.filter((sys) => engineRegistered.has(sys));
|
|
264
|
-
const removedRegistered = registered.filter((sys) => !engineRegistered.has(sys));
|
|
265
|
-
registered.length = 0;
|
|
266
|
-
registered.push(...keptRegistered);
|
|
267
|
-
for (const sys of removedRegistered) {
|
|
268
|
-
sys.dispose?.();
|
|
269
|
-
}
|
|
270
|
-
for (const phase of PHASE_ORDER) {
|
|
271
|
-
const list = systems.get(phase);
|
|
272
|
-
const engineSet = engineFns.get(phase);
|
|
273
|
-
const kept = list.filter((fn) => engineSet.has(fn));
|
|
274
|
-
list.length = 0;
|
|
275
|
-
list.push(...kept);
|
|
276
|
-
}
|
|
277
|
-
},
|
|
278
|
-
/**
|
|
279
|
-
* Total system-function count, optionally scoped to one phase. Includes
|
|
280
|
-
* component-tick slots (a set slot counts as 1 per phase it occupies).
|
|
281
|
-
* Test/introspection helper — used to assert a warm restart doesn't
|
|
282
|
-
* accumulate systems (see `removeAllNonEngine`).
|
|
283
|
-
*/
|
|
284
|
-
count(phase) {
|
|
285
|
-
if (phase) {
|
|
286
|
-
return (systems.get(phase)?.length ?? 0) + (componentTicks.get(phase) ? 1 : 0);
|
|
287
|
-
}
|
|
288
|
-
let total = 0;
|
|
289
|
-
for (const [p, list] of systems) {
|
|
290
|
-
total += list.length;
|
|
291
|
-
if (componentTicks.get(p))
|
|
292
|
-
total += 1;
|
|
293
|
-
}
|
|
294
|
-
return total;
|
|
295
|
-
},
|
|
296
|
-
};
|
|
297
|
-
}
|
package/dist/core/types.d.ts
DELETED
|
@@ -1,92 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* System execution phases, in order.
|
|
3
|
-
* Each frame, systems run in this exact sequence.
|
|
4
|
-
*/
|
|
5
|
-
export declare const SystemPhase: {
|
|
6
|
-
readonly INPUT: "input";
|
|
7
|
-
readonly PRE_PHYSICS: "prePhysics";
|
|
8
|
-
readonly PHYSICS: "physics";
|
|
9
|
-
readonly POST_PHYSICS: "postPhysics";
|
|
10
|
-
readonly GAME_LOGIC: "gameLogic";
|
|
11
|
-
readonly ANIMATION: "animation";
|
|
12
|
-
readonly PRE_RENDER: "preRender";
|
|
13
|
-
readonly RENDER: "render";
|
|
14
|
-
};
|
|
15
|
-
export type SystemPhaseName = (typeof SystemPhase)[keyof typeof SystemPhase];
|
|
16
|
-
/** Order of phase execution */
|
|
17
|
-
export declare const PHASE_ORDER: SystemPhaseName[];
|
|
18
|
-
/** A system is just a function that takes delta time */
|
|
19
|
-
export type SystemFn = (dt: number) => void;
|
|
20
|
-
export interface SystemOptions {
|
|
21
|
-
/** Stable diagnostic label; falls back to the function name. */
|
|
22
|
-
readonly name?: string;
|
|
23
|
-
}
|
|
24
|
-
export interface SystemRunObserver {
|
|
25
|
-
beginSystem(scope: string, phase: SystemPhaseName, name: string): void;
|
|
26
|
-
endSystem(scope: string, phase: SystemPhaseName, name: string): void;
|
|
27
|
-
}
|
|
28
|
-
/** A lifecycle system with init/update/dispose hooks. */
|
|
29
|
-
export interface SystemDef {
|
|
30
|
-
/** Stable diagnostic label; falls back to the update function name. */
|
|
31
|
-
readonly name?: string;
|
|
32
|
-
/** Which phase the update function runs in */
|
|
33
|
-
phase: SystemPhaseName;
|
|
34
|
-
/** One-time setup after all entities are spawned, before the first frame */
|
|
35
|
-
init?(): void;
|
|
36
|
-
/** Per-frame update */
|
|
37
|
-
update: SystemFn;
|
|
38
|
-
/** Cleanup when the system is removed or the scene unloads */
|
|
39
|
-
dispose?(): void;
|
|
40
|
-
}
|
|
41
|
-
export interface GameLoopConfig {
|
|
42
|
-
/** Fixed timestep in seconds (default: 1/60) */
|
|
43
|
-
fixedTimestep?: number;
|
|
44
|
-
/** Max physics substeps per frame to prevent spiral of death (default: 8) */
|
|
45
|
-
maxSubSteps?: number;
|
|
46
|
-
/**
|
|
47
|
-
* Called once per consumed fixed substep. Rendering (the `render` phase,
|
|
48
|
-
* last in `PHASE_ORDER`) runs *inside* this call — rendering is
|
|
49
|
-
* deliberately fixed-rate (decided — D1, `docs/DECISIONS-PENDING.md`),
|
|
50
|
-
* not a separate per-real-frame step. A real frame whose accumulator
|
|
51
|
-
* produces zero substeps calls `update` zero times and renders zero times.
|
|
52
|
-
*/
|
|
53
|
-
update: (dt: number) => void;
|
|
54
|
-
/**
|
|
55
|
-
* External-drive mode (I2, `docs/AI-NATIVE-AUTHORING-IMPLEMENTATION-SPEC.md`
|
|
56
|
-
* §15 I2): when `true`, `start()` never arms a `requestAnimationFrame`
|
|
57
|
-
* chain and never installs the `visibilitychange`/`document.hidden`
|
|
58
|
-
* auto-stop handler — so a headless/backgrounded capture page cannot have
|
|
59
|
-
* its loop silently killed by the tab-hidden guard, and `config.update`
|
|
60
|
-
* is never invoked by wall-clock/RAF timing at all. The caller (a render
|
|
61
|
-
* harness) drives frames itself instead — see `runtime/render-control.ts`,
|
|
62
|
-
* which calls a world's phase hooks directly rather than going through
|
|
63
|
-
* this loop's `update` callback. Default `false` (normal wall-clock RAF
|
|
64
|
-
* playback, unchanged).
|
|
65
|
-
*/
|
|
66
|
-
externalDrive?: boolean;
|
|
67
|
-
}
|
|
68
|
-
/**
|
|
69
|
-
* Truthful liveness classification for `createGameLoop`'s returned loop
|
|
70
|
-
* (issue #175 — "state must never claim health it cannot observe"). See
|
|
71
|
-
* `GameLoop.liveness`'s doc comment in `game-loop.ts` for the full contract;
|
|
72
|
-
* exported here (rather than only inline on the loop's return type) so
|
|
73
|
-
* callers elsewhere in the engine (`runtime/game.ts`, `runtime/
|
|
74
|
-
* debug-registry.ts`) can name the union without importing `game-loop.ts`
|
|
75
|
-
* as a value.
|
|
76
|
-
*
|
|
77
|
-
* - `'running'` — the rAF chain is armed and `config.update` is being
|
|
78
|
-
* driven by real frames (or, for an `externalDrive` loop, `start()` has
|
|
79
|
-
* been called — see that mode's own liveness note below).
|
|
80
|
-
* - `'hidden-paused'` — the T2.1 idle throttle stopped the loop because
|
|
81
|
-
* `document.hidden` is true; this is deliberate and reversible (resumes
|
|
82
|
-
* automatically on visibility), but ZERO ticks are advancing right now.
|
|
83
|
-
* - `'stopped'` — `stop()` was called, or `start()` was never called.
|
|
84
|
-
*
|
|
85
|
-
* `isRunning` collapses `'hidden-paused'` and `'stopped'` into the same
|
|
86
|
-
* `false` — exactly the ambiguity that let a hidden-paused game report as
|
|
87
|
-
* healthy ("playing") through every consumer that only read `isRunning`/
|
|
88
|
-
* store-level play state. Read `liveness` wherever "is this game actually
|
|
89
|
-
* advancing" matters.
|
|
90
|
-
*/
|
|
91
|
-
export type GameLoopLiveness = 'running' | 'hidden-paused' | 'stopped';
|
|
92
|
-
//# sourceMappingURL=types.d.ts.map
|
package/dist/core/types.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/core/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,eAAO,MAAM,WAAW;;;;;;;;;CASd,CAAC;AAEX,MAAM,MAAM,eAAe,GAAG,CAAC,OAAO,WAAW,CAAC,CAAC,MAAM,OAAO,WAAW,CAAC,CAAC;AAE7E,+BAA+B;AAC/B,eAAO,MAAM,WAAW,EAAE,eAAe,EASxC,CAAC;AAEF,wDAAwD;AACxD,MAAM,MAAM,QAAQ,GAAG,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;AAE5C,MAAM,WAAW,aAAa;IAC5B,gEAAgE;IAChE,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,iBAAiB;IAChC,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,eAAe,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACvE,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,eAAe,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;CACtE;AAED,yDAAyD;AACzD,MAAM,WAAW,SAAS;IACxB,uEAAuE;IACvE,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,8CAA8C;IAC9C,KAAK,EAAE,eAAe,CAAC;IACvB,4EAA4E;IAC5E,IAAI,CAAC,IAAI,IAAI,CAAC;IACd,uBAAuB;IACvB,MAAM,EAAE,QAAQ,CAAC;IACjB,8DAA8D;IAC9D,OAAO,CAAC,IAAI,IAAI,CAAC;CAClB;AAED,MAAM,WAAW,cAAc;IAC7B,gDAAgD;IAChD,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,6EAA6E;IAC7E,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;;;OAMG;IACH,MAAM,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7B;;;;;;;;;;;OAWG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,MAAM,gBAAgB,GAAG,SAAS,GAAG,eAAe,GAAG,SAAS,CAAC"}
|
package/dist/core/types.js
DELETED
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* System execution phases, in order.
|
|
3
|
-
* Each frame, systems run in this exact sequence.
|
|
4
|
-
*/
|
|
5
|
-
export const SystemPhase = {
|
|
6
|
-
INPUT: 'input',
|
|
7
|
-
PRE_PHYSICS: 'prePhysics',
|
|
8
|
-
PHYSICS: 'physics',
|
|
9
|
-
POST_PHYSICS: 'postPhysics',
|
|
10
|
-
GAME_LOGIC: 'gameLogic',
|
|
11
|
-
ANIMATION: 'animation',
|
|
12
|
-
PRE_RENDER: 'preRender',
|
|
13
|
-
RENDER: 'render',
|
|
14
|
-
};
|
|
15
|
-
/** Order of phase execution */
|
|
16
|
-
export const PHASE_ORDER = [
|
|
17
|
-
SystemPhase.INPUT,
|
|
18
|
-
SystemPhase.PRE_PHYSICS,
|
|
19
|
-
SystemPhase.PHYSICS,
|
|
20
|
-
SystemPhase.POST_PHYSICS,
|
|
21
|
-
SystemPhase.GAME_LOGIC,
|
|
22
|
-
SystemPhase.ANIMATION,
|
|
23
|
-
SystemPhase.PRE_RENDER,
|
|
24
|
-
SystemPhase.RENDER,
|
|
25
|
-
];
|
|
@@ -1,101 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Data assets — W1 of `docs/DATA-TOOLS-DESIGN.md` (§2.3 consumption API).
|
|
3
|
-
*
|
|
4
|
-
* A data asset is designer-tunable game data: a JSON file in the project's
|
|
5
|
-
* `src/data/`, governed by a Zod schema (`*.schema.ts`, engineer-owned) whose
|
|
6
|
-
* emitted JSON Schema (`*.schema.json`, see {@link toDataJsonSchema}) gives
|
|
7
|
-
* VS Code validation via the data file's `"$schema"` first line. Data assets
|
|
8
|
-
* are immutable at runtime — definitions, not state (§2.1).
|
|
9
|
-
*
|
|
10
|
-
* The blessed consumption shape, scaffolded working-at-birth by the project
|
|
11
|
-
* template (`src/data/` there is the worked example — §6.2):
|
|
12
|
-
*
|
|
13
|
-
* ```ts
|
|
14
|
-
* import raw from './tuning.data.json';
|
|
15
|
-
* import { TuningSchema } from './tuning.schema';
|
|
16
|
-
* import { defineData } from '@engine/data/data-asset';
|
|
17
|
-
*
|
|
18
|
-
* export const tuning = defineData(TuningSchema, raw, 'src/data/tuning.data.json');
|
|
19
|
-
* // Vite HMR needs the literal dep path in THIS module (static analysis) —
|
|
20
|
-
* // this one line is the entire live-tuning wiring (['default'] not .default:
|
|
21
|
-
* // strict tsconfigs index-signature ModuleNamespace):
|
|
22
|
-
* import.meta.hot?.accept('./tuning.data.json', (m) => tuning.hotSwap(m?.['default']));
|
|
23
|
-
* ```
|
|
24
|
-
*
|
|
25
|
-
* Game code reads `tuning.get()` inside its update loop (never cache fields
|
|
26
|
-
* across frames) or `subscribe()`s; an edit to the `.data.json` — from
|
|
27
|
-
* VS Code, an agent, or the future editor Data tab (W2) — flows through Vite
|
|
28
|
-
* HMR into the running game with no remount. React roots/tools get a
|
|
29
|
-
* `useData` hook with W3's tool-hooks package (deferred with it: the engine
|
|
30
|
-
* core stays React-free).
|
|
31
|
-
*/
|
|
32
|
-
import { z } from 'zod';
|
|
33
|
-
/**
|
|
34
|
-
* A live handle to one data asset (§2.3). `get`/`subscribe` are the whole
|
|
35
|
-
* runtime surface; `hotSwap` exists only for the owning module's
|
|
36
|
-
* `import.meta.hot.accept` callback.
|
|
37
|
-
*/
|
|
38
|
-
export interface DataHandle<T> {
|
|
39
|
-
/** Current parsed values. Read every frame — HMR swaps them under you. */
|
|
40
|
-
get(): T;
|
|
41
|
-
/**
|
|
42
|
-
* Called with the new value after every successful hot swap (NOT with the
|
|
43
|
-
* initial value). Returns an unsubscribe function.
|
|
44
|
-
*/
|
|
45
|
-
subscribe(fn: (value: T) => void): () => void;
|
|
46
|
-
/**
|
|
47
|
-
* HMR entry point — call from the owning module's
|
|
48
|
-
* `import.meta.hot.accept('<file>.data.json', (m) => handle.hotSwap(m?.default))`.
|
|
49
|
-
* Parses like load, but a FAILING edit keeps the last good value and
|
|
50
|
-
* `console.error`s instead of throwing: a typo mid-live-tune must not
|
|
51
|
-
* crash the running game. Fix the file and save again.
|
|
52
|
-
*/
|
|
53
|
-
hotSwap(next: unknown): void;
|
|
54
|
-
/**
|
|
55
|
-
* The project-relative path this handle was defined with (`defineData`'s
|
|
56
|
-
* own `sourcePath` argument, populated automatically below) — OPTIONAL so
|
|
57
|
-
* any hand-rolled structural implementer stays valid. `getRef`
|
|
58
|
-
* (`./data-ref.ts`) reads this to catch a `getRef(wrongHandle, "stem#key")`
|
|
59
|
-
* mismatch with a teaching error instead of silently resolving against the
|
|
60
|
-
* wrong asset; without it, `getRef` just skips that one check.
|
|
61
|
-
*/
|
|
62
|
-
readonly sourcePath?: string;
|
|
63
|
-
}
|
|
64
|
-
/**
|
|
65
|
-
* Define a data asset from its Zod schema, the statically imported JSON, and
|
|
66
|
-
* its project-relative path (used verbatim in error messages, so pass the
|
|
67
|
-
* real one). Parse-on-load: an invalid file fails loud at import time, naming
|
|
68
|
-
* the file, every bad path, and the fix (§2.3, §6.5 "errors teach").
|
|
69
|
-
*
|
|
70
|
-
* Schema fields should carry `.min/.max/.default/.describe` — the same
|
|
71
|
-
* annotations `GameComponent.static schema` uses — so the emitted JSON Schema
|
|
72
|
-
* documents the file and (W2+) the editor renders real widgets.
|
|
73
|
-
*/
|
|
74
|
-
export declare function defineData<S extends z.ZodType>(schema: S, initial: unknown, sourcePath: string): DataHandle<z.output<S>>;
|
|
75
|
-
/**
|
|
76
|
-
* Emit the JSON Schema interchange artifact for a data asset's Zod schema
|
|
77
|
-
* (§2.1: `*.schema.json` is EMITTED, never hand-written; D4: generated and
|
|
78
|
-
* committed by default so VS Code works with no dev server running).
|
|
79
|
-
*
|
|
80
|
-
* Wraps `z.toJSONSchema` with `io: 'input'` — the one non-obvious knob:
|
|
81
|
-
* defaulted fields must be OPTIONAL in the file schema (a data file may omit
|
|
82
|
-
* them), whereas the default output mode would mark every field `required`
|
|
83
|
-
* and make VS Code reject valid files. The template's root `emit-schemas.ts`
|
|
84
|
-
* is the blessed caller (`npm run emit-schemas`).
|
|
85
|
-
*
|
|
86
|
-
* The emitted root schema also explicitly ALLOWS the `"$schema"` string
|
|
87
|
-
* property, mirroring the parse-side strip below: without it, a TABLE
|
|
88
|
-
* asset's emitted schema (`z.record` → `additionalProperties: <rowSchema>`)
|
|
89
|
-
* makes VS Code flag the data file's own `"$schema"` line as an invalid row.
|
|
90
|
-
*/
|
|
91
|
-
export declare function toDataJsonSchema(schema: z.ZodType): Record<string, unknown>;
|
|
92
|
-
/**
|
|
93
|
-
* Parse a raw `.data.json` payload: strips the `"$schema"` interchange line,
|
|
94
|
-
* validates through the Zod schema, throws the teaching error on failure.
|
|
95
|
-
* `defineData` uses this internally on load and hot swap; it is exported for
|
|
96
|
-
* emit/doctor-style scripts (the template's `emit-schemas.ts` validates every
|
|
97
|
-
* data file through it, so file validation and runtime validation can never
|
|
98
|
-
* disagree).
|
|
99
|
-
*/
|
|
100
|
-
export declare function parseDataJson<S extends z.ZodType>(schema: S, data: unknown, sourcePath: string): z.output<S>;
|
|
101
|
-
//# sourceMappingURL=data-asset.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"data-asset.d.ts","sourceRoot":"","sources":["../../src/data/data-asset.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;;GAIG;AACH,MAAM,WAAW,UAAU,CAAC,CAAC;IAC3B,0EAA0E;IAC1E,GAAG,IAAI,CAAC,CAAC;IACT;;;OAGG;IACH,SAAS,CAAC,EAAE,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC;IAC9C;;;;;;OAMG;IACH,OAAO,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,CAAC;IAC7B;;;;;;;OAOG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED;;;;;;;;;GASG;AACH,wBAAgB,UAAU,CAAC,CAAC,SAAS,CAAC,CAAC,OAAO,EAC5C,MAAM,EAAE,CAAC,EACT,OAAO,EAAE,OAAO,EAChB,UAAU,EAAE,MAAM,GACjB,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAwBzB;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAQ3E;AAED;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,CAAC,SAAS,CAAC,CAAC,OAAO,EAC/C,MAAM,EAAE,CAAC,EACT,IAAI,EAAE,OAAO,EACb,UAAU,EAAE,MAAM,GACjB,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAsBb"}
|
package/dist/data/data-asset.js
DELETED
|
@@ -1,122 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Data assets — W1 of `docs/DATA-TOOLS-DESIGN.md` (§2.3 consumption API).
|
|
3
|
-
*
|
|
4
|
-
* A data asset is designer-tunable game data: a JSON file in the project's
|
|
5
|
-
* `src/data/`, governed by a Zod schema (`*.schema.ts`, engineer-owned) whose
|
|
6
|
-
* emitted JSON Schema (`*.schema.json`, see {@link toDataJsonSchema}) gives
|
|
7
|
-
* VS Code validation via the data file's `"$schema"` first line. Data assets
|
|
8
|
-
* are immutable at runtime — definitions, not state (§2.1).
|
|
9
|
-
*
|
|
10
|
-
* The blessed consumption shape, scaffolded working-at-birth by the project
|
|
11
|
-
* template (`src/data/` there is the worked example — §6.2):
|
|
12
|
-
*
|
|
13
|
-
* ```ts
|
|
14
|
-
* import raw from './tuning.data.json';
|
|
15
|
-
* import { TuningSchema } from './tuning.schema';
|
|
16
|
-
* import { defineData } from '@engine/data/data-asset';
|
|
17
|
-
*
|
|
18
|
-
* export const tuning = defineData(TuningSchema, raw, 'src/data/tuning.data.json');
|
|
19
|
-
* // Vite HMR needs the literal dep path in THIS module (static analysis) —
|
|
20
|
-
* // this one line is the entire live-tuning wiring (['default'] not .default:
|
|
21
|
-
* // strict tsconfigs index-signature ModuleNamespace):
|
|
22
|
-
* import.meta.hot?.accept('./tuning.data.json', (m) => tuning.hotSwap(m?.['default']));
|
|
23
|
-
* ```
|
|
24
|
-
*
|
|
25
|
-
* Game code reads `tuning.get()` inside its update loop (never cache fields
|
|
26
|
-
* across frames) or `subscribe()`s; an edit to the `.data.json` — from
|
|
27
|
-
* VS Code, an agent, or the future editor Data tab (W2) — flows through Vite
|
|
28
|
-
* HMR into the running game with no remount. React roots/tools get a
|
|
29
|
-
* `useData` hook with W3's tool-hooks package (deferred with it: the engine
|
|
30
|
-
* core stays React-free).
|
|
31
|
-
*/
|
|
32
|
-
import { z } from 'zod';
|
|
33
|
-
/**
|
|
34
|
-
* Define a data asset from its Zod schema, the statically imported JSON, and
|
|
35
|
-
* its project-relative path (used verbatim in error messages, so pass the
|
|
36
|
-
* real one). Parse-on-load: an invalid file fails loud at import time, naming
|
|
37
|
-
* the file, every bad path, and the fix (§2.3, §6.5 "errors teach").
|
|
38
|
-
*
|
|
39
|
-
* Schema fields should carry `.min/.max/.default/.describe` — the same
|
|
40
|
-
* annotations `GameComponent.static schema` uses — so the emitted JSON Schema
|
|
41
|
-
* documents the file and (W2+) the editor renders real widgets.
|
|
42
|
-
*/
|
|
43
|
-
export function defineData(schema, initial, sourcePath) {
|
|
44
|
-
let current = parseDataJson(schema, initial, sourcePath);
|
|
45
|
-
const subscribers = new Set();
|
|
46
|
-
return {
|
|
47
|
-
get: () => current,
|
|
48
|
-
sourcePath,
|
|
49
|
-
subscribe(fn) {
|
|
50
|
-
subscribers.add(fn);
|
|
51
|
-
return () => subscribers.delete(fn);
|
|
52
|
-
},
|
|
53
|
-
hotSwap(next) {
|
|
54
|
-
let parsed;
|
|
55
|
-
try {
|
|
56
|
-
parsed = parseDataJson(schema, next, sourcePath);
|
|
57
|
-
}
|
|
58
|
-
catch (err) {
|
|
59
|
-
// Keep the last good value alive — see the JSDoc on DataHandle.hotSwap.
|
|
60
|
-
// biome-ignore lint/suspicious/noConsole: deliberate, greppable — a rejected live-tune edit must be loud without crashing the running game (mirrors overlay-report.ts's direct console use)
|
|
61
|
-
console.error(`[data] hot edit rejected, keeping previous values.\n${String(err)}`);
|
|
62
|
-
return;
|
|
63
|
-
}
|
|
64
|
-
current = parsed;
|
|
65
|
-
for (const fn of subscribers)
|
|
66
|
-
fn(current);
|
|
67
|
-
},
|
|
68
|
-
};
|
|
69
|
-
}
|
|
70
|
-
/**
|
|
71
|
-
* Emit the JSON Schema interchange artifact for a data asset's Zod schema
|
|
72
|
-
* (§2.1: `*.schema.json` is EMITTED, never hand-written; D4: generated and
|
|
73
|
-
* committed by default so VS Code works with no dev server running).
|
|
74
|
-
*
|
|
75
|
-
* Wraps `z.toJSONSchema` with `io: 'input'` — the one non-obvious knob:
|
|
76
|
-
* defaulted fields must be OPTIONAL in the file schema (a data file may omit
|
|
77
|
-
* them), whereas the default output mode would mark every field `required`
|
|
78
|
-
* and make VS Code reject valid files. The template's root `emit-schemas.ts`
|
|
79
|
-
* is the blessed caller (`npm run emit-schemas`).
|
|
80
|
-
*
|
|
81
|
-
* The emitted root schema also explicitly ALLOWS the `"$schema"` string
|
|
82
|
-
* property, mirroring the parse-side strip below: without it, a TABLE
|
|
83
|
-
* asset's emitted schema (`z.record` → `additionalProperties: <rowSchema>`)
|
|
84
|
-
* makes VS Code flag the data file's own `"$schema"` line as an invalid row.
|
|
85
|
-
*/
|
|
86
|
-
export function toDataJsonSchema(schema) {
|
|
87
|
-
const emitted = z.toJSONSchema(schema, { io: 'input' });
|
|
88
|
-
if (emitted['type'] === 'object') {
|
|
89
|
-
const properties = (emitted['properties'] ?? {});
|
|
90
|
-
properties['$schema'] ??= { type: 'string' };
|
|
91
|
-
emitted['properties'] = properties;
|
|
92
|
-
}
|
|
93
|
-
return emitted;
|
|
94
|
-
}
|
|
95
|
-
/**
|
|
96
|
-
* Parse a raw `.data.json` payload: strips the `"$schema"` interchange line,
|
|
97
|
-
* validates through the Zod schema, throws the teaching error on failure.
|
|
98
|
-
* `defineData` uses this internally on load and hot swap; it is exported for
|
|
99
|
-
* emit/doctor-style scripts (the template's `emit-schemas.ts` validates every
|
|
100
|
-
* data file through it, so file validation and runtime validation can never
|
|
101
|
-
* disagree).
|
|
102
|
-
*/
|
|
103
|
-
export function parseDataJson(schema, data, sourcePath) {
|
|
104
|
-
// Strip the data file's `"$schema"` interchange line before validating —
|
|
105
|
-
// singleton (z.object, strip-mode) schemas ignored it by luck, but a TABLE
|
|
106
|
-
// asset (z.record) would try to validate it as a row and fail.
|
|
107
|
-
const payload = data !== null && typeof data === 'object' && !Array.isArray(data) && '$schema' in data
|
|
108
|
-
? Object.fromEntries(Object.entries(data).filter(([key]) => key !== '$schema'))
|
|
109
|
-
: data;
|
|
110
|
-
const result = schema.safeParse(payload);
|
|
111
|
-
if (!result.success) {
|
|
112
|
-
const issues = result.error.issues
|
|
113
|
-
.map((issue) => ` - ${issue.path.join('.') || '(root)'}: ${issue.message}`)
|
|
114
|
-
.join('\n');
|
|
115
|
-
throw new Error(`Data asset "${sourcePath}" failed its schema:\n${issues}\n` +
|
|
116
|
-
`Fix the JSON to match the Zod schema (its emitted twin, ` +
|
|
117
|
-
`"${sourcePath.replace(/\.data\.json$/, '.schema.json')}", documents every field — ` +
|
|
118
|
-
`re-emit with \`npm run emit-schemas\` if the schema changed). ` +
|
|
119
|
-
`Worked example: the template's src/data/.`);
|
|
120
|
-
}
|
|
121
|
-
return result.data;
|
|
122
|
-
}
|