@vgai/engine 0.5.21 → 0.5.23
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/README.md +6 -3
- package/dist/adapter/adapter-module.d.ts.map +1 -1
- package/dist/adapter/adapter-module.js +2 -4
- package/dist/adapter/adapter-surface.d.ts +1 -1
- package/dist/adapter/adapter-surface.js +1 -1
- package/dist/adapter/authoring.d.ts +19 -21
- package/dist/adapter/authoring.d.ts.map +1 -1
- package/dist/adapter/authoring.js +2 -2
- package/dist/adapter/binding.d.ts +341 -0
- package/dist/adapter/binding.d.ts.map +1 -0
- package/dist/adapter/binding.js +148 -0
- package/dist/adapter/colyseus-networking-adapter.d.ts.map +1 -1
- package/dist/adapter/colyseus-networking-adapter.js +23 -4
- package/dist/adapter/entrypoint-selection-readers.d.ts +24 -0
- package/dist/adapter/entrypoint-selection-readers.d.ts.map +1 -0
- package/dist/adapter/entrypoint-selection-readers.js +63 -0
- package/dist/adapter/entrypoint-selection-source.d.ts.map +1 -1
- package/dist/adapter/entrypoint-selection-source.js +1 -44
- package/dist/adapter/finders/scenes-from-entrypoint-selection.d.ts.map +1 -1
- package/dist/adapter/finders/scenes-from-entrypoint-selection.js +1 -52
- package/dist/adapter/host-context.d.ts +46 -15
- package/dist/adapter/host-context.d.ts.map +1 -1
- package/dist/adapter/host-context.js +2 -9
- package/dist/adapter/index.d.ts +11 -12
- package/dist/adapter/index.d.ts.map +1 -1
- package/dist/adapter/index.js +9 -10
- package/dist/adapter/ingest/game-contract.d.ts +0 -3
- package/dist/adapter/ingest/game-contract.d.ts.map +1 -1
- package/dist/adapter/ingest/game-contract.js +0 -3
- package/dist/adapter/ingest/scene-capture.d.ts +19 -23
- package/dist/adapter/ingest/scene-capture.d.ts.map +1 -1
- package/dist/adapter/ingest/scene-capture.js +143 -17
- package/dist/adapter/ingest/visible-capture-window.d.ts +34 -0
- package/dist/adapter/ingest/visible-capture-window.d.ts.map +1 -1
- package/dist/adapter/manifest-interpreter.d.ts +59 -0
- package/dist/adapter/manifest-interpreter.d.ts.map +1 -0
- package/dist/adapter/manifest-interpreter.js +50 -0
- package/dist/adapter/native-debug-module.d.ts +71 -3
- package/dist/adapter/native-debug-module.d.ts.map +1 -1
- package/dist/adapter/native-debug-module.js +146 -10
- package/dist/adapter/rapier-physics-adapter.d.ts +31 -1
- package/dist/adapter/rapier-physics-adapter.d.ts.map +1 -1
- package/dist/adapter/rapier-physics-adapter.js +50 -36
- package/dist/adapter/renderer-config.d.ts +3 -3
- package/dist/adapter/renderer-config.js +3 -3
- package/dist/adapter/root-adapter.d.ts +7 -7
- package/dist/adapter/root-adapter.js +4 -4
- package/dist/adapter/system-adapter.d.ts +45 -7
- package/dist/adapter/system-adapter.d.ts.map +1 -1
- package/dist/adapter/system-seam-contract.d.ts +3 -3
- package/dist/adapter/system-seam-contract.js +3 -3
- package/dist/adapter/system-slot.d.ts +168 -0
- package/dist/adapter/system-slot.d.ts.map +1 -0
- package/dist/adapter/system-slot.js +229 -0
- package/dist/adapter/transform.d.ts +11 -1
- package/dist/adapter/transform.d.ts.map +1 -1
- package/dist/ai/navigation.d.ts +17 -1
- package/dist/ai/navigation.d.ts.map +1 -1
- package/dist/ai/navigation.js +26 -5
- package/dist/animation/anim-graph-types.d.ts +11 -3
- package/dist/animation/anim-graph-types.d.ts.map +1 -1
- package/dist/animation/theatre-clock-binding.d.ts +4 -4
- package/dist/animation/theatre-clock-binding.js +4 -4
- package/dist/animation/xstate-animation-binding.d.ts.map +1 -1
- package/dist/animation/xstate-animation-binding.js +2 -2
- package/dist/animation/xstate-animation-meta.d.ts +13 -0
- package/dist/animation/xstate-animation-meta.d.ts.map +1 -1
- package/dist/animation/xstate-animation-meta.js +14 -0
- package/dist/asset-formats/index.d.ts +4 -7
- package/dist/asset-formats/index.d.ts.map +1 -1
- package/dist/asset-formats/index.js +4 -7
- package/dist/asset-formats/render-env.d.ts +5 -8
- package/dist/asset-formats/render-env.d.ts.map +1 -1
- package/dist/asset-formats/render-env.js +3 -6
- package/dist/asset-parse-error.d.ts +2 -5
- package/dist/asset-parse-error.d.ts.map +1 -1
- package/dist/asset-parse-error.js +2 -5
- package/dist/audio/bus-mixer.d.ts +101 -0
- package/dist/audio/bus-mixer.d.ts.map +1 -0
- package/dist/audio/bus-mixer.js +115 -0
- package/dist/canvas-react/index.d.ts +5 -12
- package/dist/canvas-react/index.d.ts.map +1 -1
- package/dist/canvas-react/index.js +5 -12
- package/dist/canvas-react/pixi-react-root-factory.d.ts +34 -21
- package/dist/canvas-react/pixi-react-root-factory.d.ts.map +1 -1
- package/dist/canvas-react/pixi-react-root-factory.js +274 -36
- package/dist/core/countdown-timer.d.ts +118 -0
- package/dist/core/countdown-timer.d.ts.map +1 -0
- package/dist/core/countdown-timer.js +137 -0
- package/dist/core/deferred-commands.d.ts +127 -0
- package/dist/core/deferred-commands.d.ts.map +1 -0
- package/dist/core/deferred-commands.js +132 -0
- package/dist/core/frame-pacing.d.ts +1 -1
- package/dist/core/frame-pacing.js +2 -2
- package/dist/core/game-loop.d.ts +1 -3
- package/dist/core/game-loop.d.ts.map +1 -1
- package/dist/core/game-loop.js +1 -3
- package/dist/core/seeded-random.d.ts +1 -1
- package/dist/core/sim-clock.d.ts +19 -8
- package/dist/core/sim-clock.d.ts.map +1 -1
- package/dist/core/sim-clock.js +18 -7
- package/dist/core/types.d.ts +1 -3
- package/dist/core/types.d.ts.map +1 -1
- package/dist/defaults.d.ts +6 -14
- package/dist/defaults.d.ts.map +1 -1
- package/dist/defaults.js +6 -14
- package/dist/dev/instruments.d.ts +38 -11
- package/dist/dev/instruments.d.ts.map +1 -1
- package/dist/dev/instruments.js +81 -11
- package/dist/dev/register-render-vitals.d.ts +1 -4
- package/dist/dev/register-render-vitals.d.ts.map +1 -1
- package/dist/dev/register-render-vitals.js +1 -4
- package/dist/dev/render-debug-adapter.d.ts +2 -3
- package/dist/dev/render-debug-adapter.d.ts.map +1 -1
- package/dist/dev/render-debug-adapter.js +2 -3
- package/dist/dev/render-vitals.d.ts +3 -3
- package/dist/dev/render-vitals.js +3 -3
- package/dist/dev/webgl-frame-capture.d.ts +1 -1
- package/dist/dev/webgl-frame-capture.js +1 -1
- package/dist/index.d.ts +2 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -4
- package/dist/input/host-pointer.d.ts +122 -0
- package/dist/input/host-pointer.d.ts.map +1 -0
- package/dist/input/host-pointer.js +160 -0
- package/dist/input/input-manager.d.ts +33 -5
- package/dist/input/input-manager.d.ts.map +1 -1
- package/dist/input/input-manager.js +48 -13
- package/dist/input/rebind-controller.d.ts.map +1 -1
- package/dist/input/rebind-controller.js +6 -8
- package/dist/input/schema.d.ts.map +1 -1
- package/dist/input/schema.js +56 -28
- package/dist/manifest/filename.d.ts.map +1 -1
- package/dist/manifest/filename.js +8 -12
- package/dist/manifest/load.d.ts +10 -10
- package/dist/manifest/load.d.ts.map +1 -1
- package/dist/manifest/load.js +9 -6
- package/dist/manifest/schema.d.ts +17 -21
- package/dist/manifest/schema.d.ts.map +1 -1
- package/dist/manifest/schema.js +45 -35
- package/dist/physics/collider-dimensions.d.ts +8 -12
- package/dist/physics/collider-dimensions.d.ts.map +1 -1
- package/dist/physics/collider-dimensions.js +8 -12
- package/dist/pixi/scene-capture.d.ts +11 -13
- package/dist/pixi/scene-capture.d.ts.map +1 -1
- package/dist/react/world-state.d.ts +1 -1
- package/dist/react/world-state.d.ts.map +1 -1
- package/dist/render/directional-shadow-fit.d.ts +88 -0
- package/dist/render/directional-shadow-fit.d.ts.map +1 -0
- package/dist/render/directional-shadow-fit.js +133 -0
- package/dist/render/environment-capture.d.ts +68 -0
- package/dist/render/environment-capture.d.ts.map +1 -0
- package/dist/render/environment-capture.js +90 -0
- package/dist/render/ibl-override-material.d.ts +97 -0
- package/dist/render/ibl-override-material.d.ts.map +1 -0
- package/dist/render/ibl-override-material.js +114 -0
- package/dist/render/light-camera-factory.d.ts +5 -7
- package/dist/render/light-camera-factory.d.ts.map +1 -1
- package/dist/render/light-camera-factory.js +8 -11
- package/dist/render/material-factory.js +1 -1
- package/dist/render/render-batch-system.d.ts.map +1 -1
- package/dist/render/render-features.d.ts +17 -6
- package/dist/render/render-features.d.ts.map +1 -1
- package/dist/render/render-features.js +0 -28
- package/dist/runtime/create-runtime.d.ts +34 -25
- package/dist/runtime/create-runtime.d.ts.map +1 -1
- package/dist/runtime/create-runtime.js +218 -93
- package/dist/runtime/debug-registry.d.ts +77 -8
- package/dist/runtime/debug-registry.d.ts.map +1 -1
- package/dist/runtime/debug-registry.js +3 -3
- package/dist/runtime/dev-build.d.ts +2 -2
- package/dist/runtime/dev-build.js +2 -2
- package/dist/runtime/game-input-seams.d.ts +51 -0
- package/dist/runtime/game-input-seams.d.ts.map +1 -0
- package/dist/runtime/game-input-seams.js +86 -0
- package/dist/runtime/game.d.ts +104 -40
- package/dist/runtime/game.d.ts.map +1 -1
- package/dist/runtime/game.js +119 -61
- package/dist/runtime/mount-game.d.ts +0 -16
- package/dist/runtime/mount-game.d.ts.map +1 -1
- package/dist/runtime/mount-game.js +26 -41
- package/dist/runtime/mount-manifest.d.ts +22 -14
- package/dist/runtime/mount-manifest.d.ts.map +1 -1
- package/dist/runtime/mount-manifest.js +22 -20
- package/dist/runtime/playtest.d.ts +22 -0
- package/dist/runtime/playtest.d.ts.map +1 -0
- package/dist/runtime/playtest.js +12 -0
- package/dist/runtime/state-bridge.d.ts +2 -3
- package/dist/runtime/state-bridge.d.ts.map +1 -1
- package/dist/runtime/state-bridge.js +1 -0
- package/dist/setup/setup-audio.d.ts +12 -0
- package/dist/setup/setup-audio.d.ts.map +1 -1
- package/dist/setup/setup-audio.js +9 -10
- package/dist/setup/setup-renderer.d.ts +2 -25
- package/dist/setup/setup-renderer.d.ts.map +1 -1
- package/dist/setup/setup-renderer.js +2 -31
- package/dist/world3d-react/index.d.ts +15 -25
- package/dist/world3d-react/index.d.ts.map +1 -1
- package/dist/world3d-react/index.js +15 -25
- package/dist/world3d-react/r3f-root-factory.d.ts +28 -34
- package/dist/world3d-react/r3f-root-factory.d.ts.map +1 -1
- package/dist/world3d-react/r3f-root-factory.js +403 -57
- package/dist/world3d-react/rapier-physics-bridge.d.ts +30 -17
- package/dist/world3d-react/rapier-physics-bridge.d.ts.map +1 -1
- package/dist/world3d-react/rapier-physics-bridge.js +143 -58
- package/package.json +1 -1
- package/schemas/engine-capabilities.json +16 -14
- package/schemas/vgai-project.schema.json +35 -26
- package/src/adapter/adapter-module.ts +2 -4
- package/src/adapter/adapter-surface.ts +1 -1
- package/src/adapter/authoring.ts +19 -21
- package/src/adapter/binding.ts +468 -0
- package/src/adapter/colyseus-networking-adapter.ts +20 -5
- package/src/adapter/entrypoint-selection-readers.ts +66 -0
- package/src/adapter/entrypoint-selection-source.ts +1 -40
- package/src/adapter/finders/scenes-from-entrypoint-selection.ts +1 -48
- package/src/adapter/host-context.ts +45 -15
- package/src/adapter/index.ts +23 -11
- package/src/adapter/ingest/game-contract.ts +0 -3
- package/src/adapter/ingest/scene-capture.ts +190 -39
- package/src/adapter/ingest/visible-capture-window.ts +35 -0
- package/src/adapter/manifest-interpreter.ts +64 -0
- package/src/adapter/native-debug-module.ts +248 -15
- package/src/adapter/rapier-physics-adapter.ts +76 -20
- package/src/adapter/renderer-config.ts +3 -3
- package/src/adapter/root-adapter.ts +7 -7
- package/src/adapter/system-adapter.ts +43 -8
- package/src/adapter/system-seam-contract.ts +3 -3
- package/src/adapter/system-slot.ts +291 -0
- package/src/adapter/transform.ts +18 -1
- package/src/ai/navigation.ts +30 -3
- package/src/animation/anim-graph-types.ts +11 -3
- package/src/animation/theatre-clock-binding.ts +4 -4
- package/src/animation/xstate-animation-binding.ts +2 -2
- package/src/animation/xstate-animation-meta.ts +16 -0
- package/src/asset-formats/index.ts +4 -7
- package/src/asset-formats/render-env.ts +3 -6
- package/src/asset-parse-error.ts +2 -5
- package/src/audio/bus-mixer.ts +161 -0
- package/src/canvas-react/index.ts +5 -21
- package/src/canvas-react/pixi-react-root-factory.tsx +301 -39
- package/src/core/countdown-timer.ts +188 -0
- package/src/core/deferred-commands.ts +174 -0
- package/src/core/frame-pacing.ts +2 -2
- package/src/core/game-loop.ts +1 -3
- package/src/core/seeded-random.ts +1 -1
- package/src/core/sim-clock.ts +19 -8
- package/src/core/types.ts +1 -3
- package/src/defaults.ts +6 -14
- package/src/dev/instruments.ts +108 -11
- package/src/dev/register-render-vitals.ts +1 -4
- package/src/dev/render-debug-adapter.ts +2 -3
- package/src/dev/render-vitals.ts +3 -3
- package/src/dev/webgl-frame-capture.ts +1 -1
- package/src/index.ts +2 -5
- package/src/input/host-pointer.ts +230 -0
- package/src/input/input-manager.ts +49 -13
- package/src/input/input-types.ts +1 -1
- package/src/input/rebind-controller.ts +6 -8
- package/src/input/schema.ts +216 -188
- package/src/manifest/filename.ts +8 -12
- package/src/manifest/load.ts +17 -13
- package/src/manifest/schema.ts +55 -47
- package/src/physics/collider-dimensions.ts +8 -12
- package/src/pixi/scene-capture.ts +12 -15
- package/src/react/world-state.tsx +1 -1
- package/src/render/directional-shadow-fit.ts +156 -0
- package/src/render/environment-capture.ts +102 -0
- package/src/render/ibl-override-material.ts +170 -0
- package/src/render/light-camera-factory.ts +8 -11
- package/src/render/material-factory.ts +1 -1
- package/src/render/render-batch-system.ts +14 -6
- package/src/render/render-features.ts +17 -35
- package/src/runtime/create-runtime.ts +270 -108
- package/src/runtime/debug-registry.ts +84 -8
- package/src/runtime/dev-build.ts +2 -2
- package/src/runtime/game-input-seams.ts +108 -0
- package/src/runtime/game.ts +231 -85
- package/src/runtime/mount-game.ts +31 -57
- package/src/runtime/mount-manifest.ts +47 -36
- package/src/runtime/playtest.ts +22 -0
- package/src/runtime/state-bridge.ts +3 -3
- package/src/setup/setup-audio.ts +21 -11
- package/src/setup/setup-renderer.ts +2 -61
- package/src/world3d-react/index.ts +15 -31
- package/src/world3d-react/r3f-root-factory.tsx +451 -60
- package/src/world3d-react/rapier-physics-bridge.tsx +154 -58
- package/dist/adapter/setup-three-root-adapter.d.ts +0 -86
- package/dist/adapter/setup-three-root-adapter.d.ts.map +0 -1
- package/dist/adapter/setup-three-root-adapter.js +0 -908
- 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 -31
- package/dist/asset-registry.d.ts +0 -38
- package/dist/asset-registry.d.ts.map +0 -1
- package/dist/asset-registry.js +0 -66
- package/dist/canvas-react/engine-bridge.d.ts +0 -45
- package/dist/canvas-react/engine-bridge.d.ts.map +0 -1
- package/dist/canvas-react/engine-bridge.js +0 -45
- package/dist/canvas-react/pixi-react-adapter.d.ts +0 -77
- package/dist/canvas-react/pixi-react-adapter.d.ts.map +0 -1
- package/dist/canvas-react/pixi-react-adapter.js +0 -294
- package/dist/canvas-react/world-context.d.ts +0 -98
- package/dist/canvas-react/world-context.d.ts.map +0 -1
- package/dist/canvas-react/world-context.js +0 -173
- 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/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/lod.d.ts +0 -13
- package/dist/render/lod.d.ts.map +0 -1
- package/dist/render/lod.js +0 -16
- package/dist/runtime/types.d.ts +0 -303
- package/dist/runtime/types.d.ts.map +0 -1
- package/dist/runtime/types.js +0 -1
- package/dist/world3d-react/engine-bridge.d.ts +0 -47
- package/dist/world3d-react/engine-bridge.d.ts.map +0 -1
- package/dist/world3d-react/engine-bridge.js +0 -73
- package/dist/world3d-react/r3f-adapter.d.ts +0 -58
- package/dist/world3d-react/r3f-adapter.d.ts.map +0 -1
- package/dist/world3d-react/r3f-adapter.js +0 -634
- package/dist/world3d-react/world-context.d.ts +0 -182
- package/dist/world3d-react/world-context.d.ts.map +0 -1
- package/dist/world3d-react/world-context.js +0 -235
- package/src/adapter/setup-three-root-adapter.ts +0 -1032
- package/src/animation/clip-map.ts +0 -34
- package/src/asset-registry.ts +0 -89
- package/src/canvas-react/engine-bridge.ts +0 -59
- package/src/canvas-react/pixi-react-adapter.tsx +0 -356
- package/src/canvas-react/world-context.ts +0 -253
- package/src/dev/debug-draw.ts +0 -80
- package/src/render/auto-batcher.ts +0 -168
- package/src/render/lod.ts +0 -17
- package/src/runtime/types.ts +0 -328
- package/src/world3d-react/engine-bridge.ts +0 -86
- package/src/world3d-react/r3f-adapter.tsx +0 -717
- package/src/world3d-react/world-context.ts +0 -358
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* The game-scoped debug/synthetic-player registry. ONE registry per `Game` root —
|
|
3
|
-
* every world's `ctx.debug` (see
|
|
3
|
+
* every world's `ctx.debug` (see {@link DebugCtxSurface} below) feeds the
|
|
4
4
|
* SAME registry via {@link DebugRegistry.forRoot}, so a name a game registers is
|
|
5
5
|
* visible (and name-collision-checked) across every world, not just the one that
|
|
6
6
|
* registered it. `createGame` (`runtime/game.ts`) constructs the registry
|
|
@@ -10,8 +10,8 @@
|
|
|
10
10
|
* rather than threading it through every call site.
|
|
11
11
|
*
|
|
12
12
|
* Provenance note: a registration's "world" is the MOUNT's adapter id (the
|
|
13
|
-
*
|
|
14
|
-
*
|
|
13
|
+
* id a project's root adapter already carries) rather than the
|
|
14
|
+
* `RootInstance.id` `registerThreeRoot`
|
|
15
15
|
* assigns — that id isn't known until AFTER `mount()` resolves (`create-
|
|
16
16
|
* runtime.ts` calls `registerThreeRoot` with it only once `mount()` returns),
|
|
17
17
|
* which is after every `setup()`-time registration has already run. For the
|
|
@@ -25,7 +25,83 @@ import type { DebugAdapter, DebugCommandInfo, TickStampedEvent } from '../adapte
|
|
|
25
25
|
import { createGameScopedSlot } from '../core/game-scoped-slot';
|
|
26
26
|
import type { GameLoopLiveness } from '../core/types';
|
|
27
27
|
import type { Game } from './game';
|
|
28
|
-
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* The minimal structural shape `ctx.debug.attachRoom` needs from a joined
|
|
31
|
+
* Colyseus room: just enough to send the reserved `__vgai:debugCommand`
|
|
32
|
+
* message and listen for its `__vgai:debugCommandResult` reply. Structural,
|
|
33
|
+
* not a Colyseus type import — the same seam-boundary style every other
|
|
34
|
+
* `DebugCtxSurface` member uses (no wrapper around Colyseus itself, D2).
|
|
35
|
+
* `onMessage`'s return type is `unknown` because Colyseus's own return shape
|
|
36
|
+
* (void in some client versions, an unsubscribe function in others) isn't
|
|
37
|
+
* load-bearing here: the registry calls it defensively (invokes it on detach
|
|
38
|
+
* only if it's actually a function).
|
|
39
|
+
*/
|
|
40
|
+
export interface DebugRoomHandle {
|
|
41
|
+
send(type: string, message?: unknown): void;
|
|
42
|
+
onMessage(type: string, cb: (message: unknown) => void): unknown;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Infers a `registerCommand`/`registerReactCommand`/`useDebugCommand`
|
|
47
|
+
* handler's parameter tuple from its declared Zod `args` tuple (dry-run
|
|
48
|
+
* finding, ledger — "`registerCommand` fn typing forces `unknown[]` casts"):
|
|
49
|
+
* a real `z.ZodTuple` infers its element types (`z.tuple([z.number(),
|
|
50
|
+
* z.string()])` → `(n: number, s: string) => ...`), while omitting `args`
|
|
51
|
+
* (the generic's `undefined` default) resolves to the original permissive
|
|
52
|
+
* `(...args: unknown[]) => ...` shape every command had before this generic
|
|
53
|
+
* existed. That permissive fallback is deliberate, not just a placeholder —
|
|
54
|
+
* it keeps every existing no-schema registration (including ones whose
|
|
55
|
+
* handler reads positional args the runtime never validates, since
|
|
56
|
+
* `invoke()` only parses `args` against a schema when one is declared)
|
|
57
|
+
* compiling byte-for-byte unchanged.
|
|
58
|
+
*/
|
|
59
|
+
export type DebugCommandArgs<T extends z.ZodTuple | undefined = undefined> = T extends z.ZodTuple
|
|
60
|
+
? z.infer<T>
|
|
61
|
+
: unknown[];
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* The authoring half of the debug/synthetic-player seam — the read/actuate half is
|
|
65
|
+
* `SystemAdapters.DebugAdapter` (`adapter/system-adapter.ts`). Callable from any
|
|
66
|
+
* `init` (one file per new provider/command), or from a react world's
|
|
67
|
+
* `useDebugProvider`/`useDebugCommand`/`useDebugEmit` hooks. Every registration feeds the ONE
|
|
68
|
+
* game-scoped registry (`runtime/debug-registry.ts`) — never a per-world accumulator.
|
|
69
|
+
*/
|
|
70
|
+
export interface DebugCtxSurface {
|
|
71
|
+
/** Register (or replace) a named, JSON-serializable state read. Duplicate
|
|
72
|
+
* names from the SAME world replace + warn once; the SAME name from a
|
|
73
|
+
* DIFFERENT world throws (`DebugError` code `DEBUG_NAME_COLLISION`). */
|
|
74
|
+
registerStateProvider(
|
|
75
|
+
name: string,
|
|
76
|
+
fn: () => unknown,
|
|
77
|
+
opts?: { tier?: 'observable' | 'assisted' },
|
|
78
|
+
): void;
|
|
79
|
+
/** Register (or replace) an invokable command. `locus` is REQUIRED once the
|
|
80
|
+
* project declares a Colyseus room (`DebugRegistry.setRoomDeclared`) — a
|
|
81
|
+
* fixture must say whether it mutates authoritative (server) or predicted
|
|
82
|
+
* (client) state.
|
|
83
|
+
*
|
|
84
|
+
* Generic over the declared `args` Zod tuple ({@link DebugCommandArgs}) so
|
|
85
|
+
* `fn`'s parameters INFER from it: `registerCommand('setHp', { args:
|
|
86
|
+
* z.tuple([z.number()]) }, (hp) => ...)` types `hp` as `number` with no
|
|
87
|
+
* cast. Leaving `args` off keeps `fn` typed `(...args: unknown[]) => ...`,
|
|
88
|
+
* same as before this generic existed. */
|
|
89
|
+
registerCommand<T extends z.ZodTuple | undefined = undefined>(
|
|
90
|
+
name: string,
|
|
91
|
+
spec: { description?: string; args?: T; locus?: 'client' | 'server' },
|
|
92
|
+
fn: (...args: DebugCommandArgs<T>) => unknown | Promise<unknown>,
|
|
93
|
+
): void;
|
|
94
|
+
/** Push a tick-stamped event onto the debug event ring (spec §3.3) — the
|
|
95
|
+
* engine stamps `tick`/`simT` at emission, not at read time. */
|
|
96
|
+
emit(event: string, detail?: unknown): void;
|
|
97
|
+
/**
|
|
98
|
+
* Task 2.2 — server-locus command routing (client leg). Call once your
|
|
99
|
+
* game code has joined its Colyseus room, so `locus: 'server'` commands
|
|
100
|
+
* have somewhere to send `__vgai:debugCommand`. Returns a detach function
|
|
101
|
+
* (call on room leave/dispose) — game-scoped, last-attached room wins.
|
|
102
|
+
*/
|
|
103
|
+
attachRoom(room: DebugRoomHandle): () => void;
|
|
104
|
+
}
|
|
29
105
|
|
|
30
106
|
/** Engine-local error for the debug seam — mirrors the `code` + `data` shape
|
|
31
107
|
* `packages/vgai-sdk/src/errors.ts` uses (no import: the engine does not
|
|
@@ -74,7 +150,7 @@ const SERVER_COMMAND_TIMEOUT_MS = 10_000;
|
|
|
74
150
|
* actuates through — the SAME three methods `InputManager` exposes
|
|
75
151
|
* (`setVirtualAction`/`tapVirtualAction`/`clearVirtualActions`, Task 1.4),
|
|
76
152
|
* typed narrowly here so this module never imports `InputManager` itself.
|
|
77
|
-
* Wired once by the hosting adapter (`
|
|
153
|
+
* Wired once by the hosting adapter (`world3d-react/r3f-root-factory.tsx`, at the
|
|
78
154
|
* same seed spot as `setInputActionsSource`) — absent until then. */
|
|
79
155
|
export interface DebugVirtualInputTarget {
|
|
80
156
|
setVirtualAction(
|
|
@@ -187,7 +263,7 @@ interface CommandEntry {
|
|
|
187
263
|
|
|
188
264
|
/** What {@link createDebugRegistry} returns — the adapter half (`DebugAdapter`,
|
|
189
265
|
* for `SystemAdapters.debug`) plus the registration/lifecycle surface the
|
|
190
|
-
* hosting adapter (`
|
|
266
|
+
* hosting adapter (`world3d-react/r3f-root-factory.tsx`) and `createGame` drive. */
|
|
191
267
|
export interface DebugRegistry {
|
|
192
268
|
/** The `SystemAdapters.debug` implementer — one shared instance, seeded
|
|
193
269
|
* onto every world's adapter bag. */
|
|
@@ -238,7 +314,7 @@ export interface DebugRegistry {
|
|
|
238
314
|
* `{version: 1, seed: null, fixedDt: null, ticks: []}`. `seed`/`fixedDt`
|
|
239
315
|
* are the two replay-critical metadata fields the design doc's format
|
|
240
316
|
* sketch (§2.c) calls for beside the raw per-tick deltas — the wiring
|
|
241
|
-
* adapter (`
|
|
317
|
+
* adapter (`world3d-react/r3f-root-factory.tsx`) assembles them from
|
|
242
318
|
* `getSeededRandom(game)?.seed`/`host.game?.loop.fixedDt` alongside
|
|
243
319
|
* `InputManager.getInputTrace()`'s own `{version, ticks}`. An `engine`
|
|
244
320
|
* (package version) stamp remains a KNOWN GAP — no build-time version
|
|
@@ -297,7 +373,7 @@ export interface DebugRegistry {
|
|
|
297
373
|
/** D15/T-D15.3/.5 — the CURRENT shared game tick (the same counter the
|
|
298
374
|
* built-in `time` provider's `tick` field reads), for a per-world
|
|
299
375
|
* `InputManager.poll(tick)` call to key its `scheduleActionAtTick`
|
|
300
|
-
* numbering off — see `
|
|
376
|
+
* numbering off — see `world3d-react/r3f-root-factory.tsx`'s `systems.add('input',
|
|
301
377
|
* ...)` wiring. `0` for a bare `createDebugRegistry()` test stand-in with
|
|
302
378
|
* no real `Game`/tick counter behind it (matching `getTick`'s own
|
|
303
379
|
* constructor-supplied default in that case). */
|
package/src/runtime/dev-build.ts
CHANGED
|
@@ -9,8 +9,8 @@
|
|
|
9
9
|
*
|
|
10
10
|
* Ownership, stated in one place (the build rule):
|
|
11
11
|
* - OWNER: this function. It resolves the answer; nothing else derives it.
|
|
12
|
-
* - SHARERS: the
|
|
13
|
-
*
|
|
12
|
+
* - SHARERS: the three-root adapter (`world3d-react/r3f-root-factory.tsx`),
|
|
13
|
+
* which seeds live render vitals only
|
|
14
14
|
* under it, and the `static-batch` capability's mutation watch and `Frozen`
|
|
15
15
|
* warning. Any future dev-only instrument calls this too, with its own
|
|
16
16
|
* `override`.
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The GAME-SCOPED input wiring one world mount owns — HOST work performed from
|
|
3
|
+
* outside the world's own tree, shared verbatim by the three and canvas lanes
|
|
4
|
+
* (a project has ONE input map and one bot-input doctrine, whatever surface
|
|
5
|
+
* reads them).
|
|
6
|
+
*
|
|
7
|
+
* Two things happen here:
|
|
8
|
+
*
|
|
9
|
+
* 1. the project's input map is loaded through `Game.loadInputMap` (game-owned,
|
|
10
|
+
* load-once), so the actions the project declared exist;
|
|
11
|
+
* 2. this root's seams are registered on the game-scoped debug registry
|
|
12
|
+
* (`setVirtualInputTarget`/`setInputActionsSource`/`setInputTraceSource`),
|
|
13
|
+
* which is what makes `game.input.hold/tap/...` (the bot/`vgai eval` input
|
|
14
|
+
* doctrine) and the built-in `input.actions`/`input.trace` providers
|
|
15
|
+
* resolve to this world instead of throwing `DEBUG_INPUT_UNAVAILABLE`.
|
|
16
|
+
*
|
|
17
|
+
* A world's React tree receives no vgai context — this wiring is precisely the
|
|
18
|
+
* part that never needed one: every closure below reads GAME-scoped state the
|
|
19
|
+
* host owns (`game.input`, `game.loop.fixedDt`, the game's seed).
|
|
20
|
+
*
|
|
21
|
+
* `optionalInputMap` is the CONVENTIONAL-PATH probe used when the project
|
|
22
|
+
* never named a map: an absent file is the ordinary state of a brand-new
|
|
23
|
+
* project, so it resolves quietly instead of printing an error on every boot.
|
|
24
|
+
* A map that exists and fails to parse is as loud as ever.
|
|
25
|
+
*
|
|
26
|
+
* LIFETIME, honestly: `registry.strip(id)` runs on the mount's dispose, but it
|
|
27
|
+
* walks providers/commands only — the three seams set here survive it, keyed
|
|
28
|
+
* by this world's id, until a remount of the same id overwrites them. That
|
|
29
|
+
* residue is inert rather than hidden: every closure reads game-scoped state,
|
|
30
|
+
* so a stale entry actuates exactly what a live one would. What it can still
|
|
31
|
+
* do is name a dead world in `DEBUG_INPUT_WORLD_NOT_FOUND`'s registered list.
|
|
32
|
+
* Do not write "the strip clears the input seams" anywhere without changing
|
|
33
|
+
* `strip` to actually do it.
|
|
34
|
+
*/
|
|
35
|
+
|
|
36
|
+
import type { HostGameHandle } from '../adapter/host-context';
|
|
37
|
+
import { getSeededRandom } from '../core/seeded-random';
|
|
38
|
+
import type { DebugRegistry } from './debug-registry';
|
|
39
|
+
|
|
40
|
+
/** The conventional input-map location every scaffolded project ships
|
|
41
|
+
* (`public/inputmaps/default.inputmap.json`). */
|
|
42
|
+
export const DEFAULT_INPUT_MAP_PATH = '/inputmaps/default.inputmap.json';
|
|
43
|
+
|
|
44
|
+
/** The slice of a host context this wiring reads — satisfied structurally by
|
|
45
|
+
* both `ThreeHostContext` and `CanvasHostContext`. */
|
|
46
|
+
export interface GameInputSeamHost {
|
|
47
|
+
readonly game?: HostGameHandle | null | undefined;
|
|
48
|
+
readonly headless?: boolean | undefined;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export function wireGameInputSeams(
|
|
52
|
+
host: GameInputSeamHost,
|
|
53
|
+
registry: DebugRegistry,
|
|
54
|
+
options: {
|
|
55
|
+
readonly id: string;
|
|
56
|
+
readonly inputMapPath?: string | null | undefined;
|
|
57
|
+
readonly optionalInputMap?: boolean | undefined;
|
|
58
|
+
},
|
|
59
|
+
): Promise<void> {
|
|
60
|
+
const { id, inputMapPath = DEFAULT_INPUT_MAP_PATH, optionalInputMap = false } = options;
|
|
61
|
+
if (!host.game) return Promise.resolve();
|
|
62
|
+
const game = host.game;
|
|
63
|
+
const input = game.input;
|
|
64
|
+
registry.setInputActionsSource(id, () =>
|
|
65
|
+
input.actionNames().map((name) => ({ name, valueType: input.getActionValueType(name) })),
|
|
66
|
+
);
|
|
67
|
+
registry.setInputTraceSource(id, () => {
|
|
68
|
+
const raw = input.getInputTrace();
|
|
69
|
+
return {
|
|
70
|
+
version: raw.version,
|
|
71
|
+
seed: getSeededRandom(game)?.seed ?? null,
|
|
72
|
+
fixedDt: game.loop.fixedDt,
|
|
73
|
+
ticks: raw.ticks,
|
|
74
|
+
};
|
|
75
|
+
});
|
|
76
|
+
registry.setVirtualInputTarget(id, {
|
|
77
|
+
setVirtualAction: (action, value) => input.setVirtualAction(action, value),
|
|
78
|
+
tapVirtualAction: (action) => input.tapVirtualAction(action),
|
|
79
|
+
clearVirtualActions: () => input.clearVirtualActions(),
|
|
80
|
+
scheduleActionAtTick: (tick, action, value) => input.scheduleActionAtTick(tick, action, value),
|
|
81
|
+
startInputRecording: () => input.startInputRecording(),
|
|
82
|
+
stopInputRecording: () => input.stopInputRecording(),
|
|
83
|
+
isInputRecording: () => input.isInputRecording(),
|
|
84
|
+
injectAxis: (sourceId, value) => input.injectAxis(sourceId, value),
|
|
85
|
+
injectVector2: (sourceId, value) => input.injectVector2(sourceId, value),
|
|
86
|
+
injectPointerDelta: (sourceId, delta) => input.injectPointerDelta(sourceId, delta),
|
|
87
|
+
injectPointerPosition: (sourceId, value) => input.injectPointerPosition(sourceId, value),
|
|
88
|
+
});
|
|
89
|
+
if (host.headless || inputMapPath === null) return Promise.resolve();
|
|
90
|
+
// Load-once through the game-owned path (competing paths across roots throw
|
|
91
|
+
// THERE, loudly). A FAILED load (missing/bad file) must not fail the mount:
|
|
92
|
+
// a world with no declared actions is legal. It degrades loudly instead —
|
|
93
|
+
// naming exactly what breaks.
|
|
94
|
+
// The non-optional call passes ONE argument, exactly as it always has — a
|
|
95
|
+
// trailing `undefined` is a different call to any observer of it.
|
|
96
|
+
const load = optionalInputMap
|
|
97
|
+
? game.loadInputMap(inputMapPath, { optional: true })
|
|
98
|
+
: game.loadInputMap(inputMapPath);
|
|
99
|
+
return load.catch((err: unknown) => {
|
|
100
|
+
// biome-ignore lint/suspicious/noConsole: deliberate loud degrade — the documented alternative to failing the mount (see comment above)
|
|
101
|
+
console.error(
|
|
102
|
+
`world "${id}": failed to load input map "${inputMapPath}" — declared input ` +
|
|
103
|
+
'actions and `game.input.*` (bot/virtual input) will not work until a valid map ' +
|
|
104
|
+
`loads. Ship one at the conventional path (${DEFAULT_INPUT_MAP_PATH}). ` +
|
|
105
|
+
`Cause: ${err instanceof Error ? err.message : String(err)}`,
|
|
106
|
+
);
|
|
107
|
+
});
|
|
108
|
+
}
|