@vgai/engine 0.5.22 → 0.5.24
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-seams.d.ts +5 -0
- package/dist/adapter/ingest/game-contract-seams.d.ts.map +1 -1
- package/dist/adapter/ingest/game-contract-seams.js +1 -0
- package/dist/adapter/ingest/game-contract.d.ts +22 -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/native-debug-module.d.ts +40 -5
- package/dist/adapter/native-debug-module.d.ts.map +1 -1
- package/dist/adapter/native-debug-module.js +36 -9
- 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 +2 -2
- package/dist/adapter/renderer-config.js +2 -2
- 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/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 +5 -6
- package/dist/core/sim-clock.d.ts.map +1 -1
- package/dist/core/sim-clock.js +4 -5
- 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/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 +18 -5
- package/dist/input/input-manager.d.ts.map +1 -1
- package/dist/input/input-manager.js +33 -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/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-bridge.d.ts +12 -0
- package/dist/runtime/debug-bridge.d.ts.map +1 -1
- package/dist/runtime/debug-bridge.js +4 -0
- package/dist/runtime/debug-registry.d.ts +95 -8
- package/dist/runtime/debug-registry.d.ts.map +1 -1
- package/dist/runtime/debug-registry.js +24 -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 +2 -2
- package/dist/runtime/game-input-seams.d.ts.map +1 -1
- package/dist/runtime/game.d.ts +102 -41
- package/dist/runtime/game.d.ts.map +1 -1
- package/dist/runtime/game.js +80 -54
- 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 +8 -39
- 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 +18 -18
- 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/run-ticks-settled.d.ts +34 -0
- package/dist/runtime/run-ticks-settled.d.ts.map +1 -0
- package/dist/runtime/run-ticks-settled.js +59 -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/r3f-root-factory.d.ts +7 -7
- package/dist/world3d-react/r3f-root-factory.js +7 -7
- package/dist/world3d-react/rapier-physics-bridge.d.ts +9 -8
- package/dist/world3d-react/rapier-physics-bridge.d.ts.map +1 -1
- package/dist/world3d-react/rapier-physics-bridge.js +100 -48
- 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-seams.ts +1 -0
- package/src/adapter/ingest/game-contract.ts +22 -3
- package/src/adapter/ingest/scene-capture.ts +190 -39
- package/src/adapter/ingest/visible-capture-window.ts +35 -0
- package/src/adapter/native-debug-module.ts +66 -9
- package/src/adapter/rapier-physics-adapter.ts +76 -20
- package/src/adapter/renderer-config.ts +2 -2
- 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/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 +5 -6
- package/src/core/types.ts +1 -3
- package/src/defaults.ts +6 -14
- 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 +34 -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/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-bridge.ts +16 -0
- package/src/runtime/debug-registry.ts +121 -8
- package/src/runtime/dev-build.ts +2 -2
- package/src/runtime/game-input-seams.ts +2 -2
- package/src/runtime/game.ts +180 -80
- package/src/runtime/mount-game.ts +8 -56
- package/src/runtime/mount-manifest.ts +43 -34
- package/src/runtime/playtest.ts +22 -0
- package/src/runtime/run-ticks-settled.ts +72 -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/r3f-root-factory.tsx +7 -7
- package/src/world3d-react/rapier-physics-bridge.tsx +107 -50
- 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/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
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create-runtime.d.ts","sourceRoot":"","sources":["../../src/runtime/create-runtime.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAqB,cAAc,EAAoB,MAAM,yBAAyB,CAAC;AACnG,OAAO,KAAK,EACV,eAAe,EACf,gBAAgB,EAEhB,gBAAgB,EAChB,WAAW,
|
|
1
|
+
{"version":3,"file":"create-runtime.d.ts","sourceRoot":"","sources":["../../src/runtime/create-runtime.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,54 +1,55 @@
|
|
|
1
1
|
import * as THREE from 'three';
|
|
2
2
|
import { assertNever } from '../adapter/adapter-surface';
|
|
3
|
+
import { createRootBinding } from '../adapter/binding';
|
|
3
4
|
import { createAssetCache } from '../assets';
|
|
4
5
|
import { createGameLoop } from '../core/game-loop';
|
|
5
6
|
import { createHostRenderer } from '../setup/setup-renderer';
|
|
7
|
+
import { getDebugRegistry } from './debug-registry';
|
|
6
8
|
// TYPE-ONLY: `create-runtime.ts` must never value-import `pixi.js` — a canvas
|
|
7
9
|
// `RootMountSpec`'s `adapter` is supplied ALREADY-CONSTRUCTED by the caller, so
|
|
8
10
|
// the host only ever needs the seam's types.
|
|
9
|
-
import { createGame, createRootInstance,
|
|
11
|
+
import { createGame, createRootInstance, } from './game';
|
|
10
12
|
import { createInputRouter, stackOrder } from './input-router';
|
|
11
13
|
import { installRenderControlHarness, isRenderModeRequested } from './render-control';
|
|
12
|
-
/**
|
|
13
|
-
* Register a three world for a freshly-mounted game onto the Game shell. Shared
|
|
14
|
-
* by `createGameRuntime` and every headless test harness
|
|
15
|
-
* (`test/game-root.test.ts`, `test/frame-order.test.ts`,
|
|
16
|
-
* `test/game-two-roots.test.ts`) so there is exactly one code path for this
|
|
17
|
-
* wiring. `physics`/`collisions`/`camera`/`frame` are populated from the mount's
|
|
18
|
-
* first-party `GameContext`/ `MountedSetupThreeRoot` when available, left
|
|
19
|
-
* `undefined` otherwise (an external adapter's mount has none of these
|
|
20
|
-
* first-party handles — `frame` in particular is what makes
|
|
21
|
-
* `GameInternal.runFrame` fall back to a single opaque
|
|
22
|
-
* `mounted.update` call per substep for such a world).
|
|
23
|
-
*/
|
|
24
|
-
function firstPartyExtras(mounted) {
|
|
25
|
-
if (!isFirstPartyMounted(mounted))
|
|
26
|
-
return {};
|
|
27
|
-
return {
|
|
28
|
-
physics: mounted.ctx.physics,
|
|
29
|
-
collisions: mounted.ctx.collisions,
|
|
30
|
-
camera: mounted.ctx.camera,
|
|
31
|
-
frame: mounted.frame,
|
|
32
|
-
};
|
|
33
|
-
}
|
|
34
14
|
/**
|
|
35
15
|
* Register a three world onto the Game shell. `opts.id` defaults to
|
|
36
16
|
* `'main'`; multi-root callers pass an explicit id. This is the one
|
|
37
17
|
* registration path for a three world, whatever its id.
|
|
38
18
|
*/
|
|
39
19
|
export function registerThreeRoot(game, adapter, mounted, opts) {
|
|
20
|
+
const pausable = opts?.pausable ?? true;
|
|
40
21
|
const world = createRootInstance({
|
|
41
22
|
id: opts?.id ?? 'main',
|
|
42
23
|
kind: 'three',
|
|
43
|
-
pausable
|
|
24
|
+
pausable,
|
|
44
25
|
adapter,
|
|
45
26
|
mounted,
|
|
46
27
|
scene: mounted.scene,
|
|
47
|
-
|
|
28
|
+
binding: bindRoot(game, opts?.declaration, {
|
|
29
|
+
surface: 'three',
|
|
30
|
+
adapter: adapter,
|
|
31
|
+
}, mounted, pausable),
|
|
48
32
|
});
|
|
49
33
|
game.registerRoot(world);
|
|
50
34
|
return world;
|
|
51
35
|
}
|
|
36
|
+
/**
|
|
37
|
+
* Complete the root's binding at the first moment it CAN be completed: the
|
|
38
|
+
* declaration is what the resolver knew, `mounted`/`adapter`/`pausable` are
|
|
39
|
+
* what mounting produced, and the debug registry is the game's own. Nothing
|
|
40
|
+
* here loads or fabricates — see `createRootBinding`.
|
|
41
|
+
*/
|
|
42
|
+
function bindRoot(game, declaration, adapter, mounted, pausable) {
|
|
43
|
+
if (!declaration)
|
|
44
|
+
return null;
|
|
45
|
+
return createRootBinding({
|
|
46
|
+
...declaration,
|
|
47
|
+
adapter,
|
|
48
|
+
mounted,
|
|
49
|
+
pausable,
|
|
50
|
+
debugRegistry: getDebugRegistry(game),
|
|
51
|
+
});
|
|
52
|
+
}
|
|
52
53
|
/**
|
|
53
54
|
* Register a canvas world onto the Game shell — the pixi analog of
|
|
54
55
|
* {@link registerThreeRoot}. `adapter` is the seam's own
|
|
@@ -58,13 +59,15 @@ export function registerThreeRoot(game, adapter, mounted, opts) {
|
|
|
58
59
|
*/
|
|
59
60
|
export function registerPixiRoot(game, adapter, mounted, opts) {
|
|
60
61
|
const id = opts?.id ?? 'main';
|
|
62
|
+
const pausable = opts?.pausable ?? true;
|
|
61
63
|
const world = createRootInstance({
|
|
62
64
|
id,
|
|
63
65
|
kind: 'canvas',
|
|
64
|
-
pausable
|
|
66
|
+
pausable,
|
|
65
67
|
adapter,
|
|
66
68
|
mounted,
|
|
67
69
|
stage: mounted.stage,
|
|
70
|
+
binding: bindRoot(game, opts?.declaration, { surface: 'canvas', adapter }, mounted, pausable),
|
|
68
71
|
});
|
|
69
72
|
game.registerRoot(world);
|
|
70
73
|
return world;
|
|
@@ -81,13 +84,15 @@ export function registerPixiRoot(game, adapter, mounted, opts) {
|
|
|
81
84
|
* needs `.id`, so this passes through with zero cast.
|
|
82
85
|
*/
|
|
83
86
|
export function registerReactRoot(game, adapter, mounted, container, opts) {
|
|
87
|
+
const pausable = opts?.pausable ?? true;
|
|
84
88
|
const world = createRootInstance({
|
|
85
89
|
id: opts?.id ?? 'main',
|
|
86
90
|
kind: 'dom',
|
|
87
|
-
pausable
|
|
91
|
+
pausable,
|
|
88
92
|
adapter,
|
|
89
93
|
mounted,
|
|
90
94
|
container,
|
|
95
|
+
binding: bindRoot(game, opts?.declaration, { surface: 'dom', adapter }, mounted, pausable),
|
|
91
96
|
});
|
|
92
97
|
game.registerRoot(world);
|
|
93
98
|
return world;
|
|
@@ -106,9 +111,8 @@ export async function createGameRuntime(config) {
|
|
|
106
111
|
// Universal root host
|
|
107
112
|
// ---------------------------------------------------------------------------
|
|
108
113
|
/** A stand-in `THREE.WebGLRenderer` for headless (`headless:true`) three
|
|
109
|
-
* roots
|
|
110
|
-
*
|
|
111
|
-
* mount never calls a render-phase method on `host.renderer` at all, so
|
|
114
|
+
* roots: a headless mount never calls a render-phase method on
|
|
115
|
+
* `host.renderer` at all, so
|
|
112
116
|
* this only needs to satisfy the handful of calls THIS file itself makes
|
|
113
117
|
* (`setPixelRatio`/`setClearColor`/`setSize` at mount, `dispose`/
|
|
114
118
|
* `forceContextLoss` at teardown) — never a real GL call. Node conformance
|
|
@@ -122,6 +126,46 @@ function createHeadlessRendererStub() {
|
|
|
122
126
|
forceContextLoss() { },
|
|
123
127
|
};
|
|
124
128
|
}
|
|
129
|
+
/**
|
|
130
|
+
* Reclaim ONE mounted root: its adapter, the renderer this file constructed for
|
|
131
|
+
* it (including the WebGL context — a browser keeps only a handful alive, so
|
|
132
|
+
* `dispose()` alone is not enough), and its stacked surface element.
|
|
133
|
+
*
|
|
134
|
+
* ONE body, TWO callers, deliberately: the session's `fullCleanup` (a normal
|
|
135
|
+
* stop) and `mountAllRootSpecs`'s partial-mount ROLLBACK (a later root's mount
|
|
136
|
+
* rejected, so the roots that already mounted must not survive the rejection).
|
|
137
|
+
* Those two must never drift — a rollback that reclaims less than a stop is how
|
|
138
|
+
* a failed play leaves a live renderer and a lost GL context behind with no
|
|
139
|
+
* handle anywhere able to reach it.
|
|
140
|
+
*
|
|
141
|
+
* Throws only what the adapter's own `dispose()` throws; every caller wraps it
|
|
142
|
+
* per entry so one bad root cannot abort the rest of the teardown.
|
|
143
|
+
*/
|
|
144
|
+
function disposeMountedRoot(entry, container) {
|
|
145
|
+
try {
|
|
146
|
+
entry.mounted.dispose();
|
|
147
|
+
}
|
|
148
|
+
finally {
|
|
149
|
+
// Renderer + surface release run even when the adapter's dispose threw:
|
|
150
|
+
// the GL context is the scarce resource, and the caller still sees the
|
|
151
|
+
// error (this rethrows through the `finally`).
|
|
152
|
+
entry.renderer?.dispose();
|
|
153
|
+
entry.renderer?.forceContextLoss();
|
|
154
|
+
// Remove from the element's CURRENT parent, not the mount-time
|
|
155
|
+
// `container`: the editor's Game panel re-parents the live surfaces
|
|
156
|
+
// when its mount element swaps (fill <-> device preset, W2c), and
|
|
157
|
+
// `container.removeChild` would throw NotFoundError after such a move.
|
|
158
|
+
// `container` remains the fallback for hosts whose element stand-ins
|
|
159
|
+
// never wire `parentNode` (headless unit fixtures); an element already
|
|
160
|
+
// detached by such a host is a no-op via the catch.
|
|
161
|
+
try {
|
|
162
|
+
(entry.element.parentNode ?? container).removeChild(entry.element);
|
|
163
|
+
}
|
|
164
|
+
catch {
|
|
165
|
+
/* already detached — nothing to remove */
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
}
|
|
125
169
|
/** Mount one three `RootMountSpec` (canvas + renderer construction, per
|
|
126
170
|
* D5 §1/§4, then `registerThreeRoot`). Split out of
|
|
127
171
|
* `createRootsGameRuntime` purely to keep that function's own branching
|
|
@@ -175,7 +219,11 @@ async function mountOneThreeRoot(spec, ctx) {
|
|
|
175
219
|
game,
|
|
176
220
|
};
|
|
177
221
|
const mounted = await spec.adapter.mount(host);
|
|
178
|
-
registerThreeRoot(game, spec.adapter, mounted, {
|
|
222
|
+
registerThreeRoot(game, spec.adapter, mounted, {
|
|
223
|
+
id: spec.id,
|
|
224
|
+
pausable: spec.pausable,
|
|
225
|
+
declaration: spec.declaration,
|
|
226
|
+
});
|
|
179
227
|
return {
|
|
180
228
|
mountedEntry: { id: spec.id, kind: 'three', element: canvas, mounted, renderer },
|
|
181
229
|
routerEntry: { id: spec.id, zOrder: spec.zOrder ?? 0, canvas, hitTest: spec.hitTest },
|
|
@@ -186,7 +234,7 @@ async function mountOneThreeRoot(spec, ctx) {
|
|
|
186
234
|
* `mountOneThreeRoot` above.
|
|
187
235
|
*
|
|
188
236
|
* Unlike `mountOneThreeRoot`, this needs no explicit `canvas.style.width`/
|
|
189
|
-
* `.height` re-assertion
|
|
237
|
+
* `.height` re-assertion. The canvas surface constructs its
|
|
190
238
|
* `Application` with `autoDensity: true`, which makes PIXI ITSELF re-stamp
|
|
191
239
|
* `canvas.style.width`/`.height` (real CSS px, matching the LOGICAL
|
|
192
240
|
* width/height passed to `resize()`) on every `app.renderer.resize()` call —
|
|
@@ -215,6 +263,7 @@ async function mountOnePixiRoot(spec, ctx) {
|
|
|
215
263
|
registerPixiRoot(game, spec.adapter, mounted, {
|
|
216
264
|
id: spec.id,
|
|
217
265
|
pausable: spec.pausable,
|
|
266
|
+
declaration: spec.declaration,
|
|
218
267
|
});
|
|
219
268
|
return {
|
|
220
269
|
mountedEntry: {
|
|
@@ -271,6 +320,7 @@ layer) {
|
|
|
271
320
|
registerReactRoot(game, spec.adapter, mounted, layer, {
|
|
272
321
|
id: spec.id,
|
|
273
322
|
pausable: spec.pausable,
|
|
323
|
+
declaration: spec.declaration,
|
|
274
324
|
});
|
|
275
325
|
return {
|
|
276
326
|
mountedEntry: {
|
|
@@ -289,8 +339,8 @@ layer) {
|
|
|
289
339
|
* per D5 §1, z-order/ties exactly matching
|
|
290
340
|
* `manifest/load.ts`'s sort, ONE `Game`, and registers every world onto it
|
|
291
341
|
* via `registerThreeRoot`/`registerPixiRoot`/`registerReactRoot` — the
|
|
292
|
-
* SAME wiring `test/
|
|
293
|
-
* three/
|
|
342
|
+
* SAME wiring `test/create-runtime-worlds.test.ts` proves for the
|
|
343
|
+
* three/canvas pair. Worlds MOUNT in `roots` ARRAY order ("manifest
|
|
294
344
|
* declaration order" — the frame/registration axis), independent of
|
|
295
345
|
* `zOrder` (the canvas-stacking/rendering axis) — the two orders can differ
|
|
296
346
|
* and both are honored correctly.
|
|
@@ -344,37 +394,60 @@ function installDefaultRootDevGlobals(game) {
|
|
|
344
394
|
* comment).
|
|
345
395
|
*/
|
|
346
396
|
async function mountAllRootSpecs(mountSpecs, bottomId, inputs) {
|
|
347
|
-
const { surfacesById, ...shared } = inputs;
|
|
397
|
+
const { surfacesById, container, ...shared } = inputs;
|
|
348
398
|
const mountedEntries = [];
|
|
349
399
|
const routerEntries = [];
|
|
350
|
-
|
|
351
|
-
const
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
400
|
+
try {
|
|
401
|
+
for (const spec of mountSpecs) {
|
|
402
|
+
const isBottom = spec.id === bottomId;
|
|
403
|
+
if (spec.kind === 'dom') {
|
|
404
|
+
const layer = surfacesById.get(spec.id);
|
|
405
|
+
const { mountedEntry } = await mountOneReactRoot(spec, shared.game, layer);
|
|
406
|
+
mountedEntries.push(mountedEntry);
|
|
407
|
+
continue;
|
|
408
|
+
}
|
|
409
|
+
const canvas = surfacesById.get(spec.id);
|
|
410
|
+
const oneCtx = { ...shared, canvas, isBottom };
|
|
411
|
+
let mountedEntry;
|
|
412
|
+
let routerEntry;
|
|
413
|
+
if (spec.kind === 'three') {
|
|
414
|
+
({ mountedEntry, routerEntry } = await mountOneThreeRoot(spec, oneCtx));
|
|
415
|
+
}
|
|
416
|
+
else if (spec.kind === 'canvas') {
|
|
417
|
+
({ mountedEntry, routerEntry } = await mountOnePixiRoot(spec, oneCtx));
|
|
418
|
+
}
|
|
419
|
+
else {
|
|
420
|
+
// Exhaustiveness guard (§7.4-2): 'react' was already handled by the
|
|
421
|
+
// early `continue` above, so only a hypothetical 4th `AdapterSurface` can
|
|
422
|
+
// reach here — fail loudly rather than silently defaulting. `spec`
|
|
423
|
+
// itself (not `spec.kind`) is what TS has narrowed to `never`, since
|
|
424
|
+
// `RootMountSpec` is a discriminated union at the object level.
|
|
425
|
+
assertNever(spec, 'create-runtime mount loop');
|
|
426
|
+
}
|
|
355
427
|
mountedEntries.push(mountedEntry);
|
|
356
|
-
|
|
357
|
-
}
|
|
358
|
-
const canvas = surfacesById.get(spec.id);
|
|
359
|
-
const oneCtx = { ...shared, canvas, isBottom };
|
|
360
|
-
let mountedEntry;
|
|
361
|
-
let routerEntry;
|
|
362
|
-
if (spec.kind === 'three') {
|
|
363
|
-
({ mountedEntry, routerEntry } = await mountOneThreeRoot(spec, oneCtx));
|
|
428
|
+
routerEntries.push(routerEntry);
|
|
364
429
|
}
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
430
|
+
}
|
|
431
|
+
catch (err) {
|
|
432
|
+
// PARTIAL MOUNT ROLLBACK. Roots mount sequentially, so a rejection from
|
|
433
|
+
// root N leaves roots 1..N-1 fully live — renderer, WebGL context, R3F
|
|
434
|
+
// tree, adapter registrations — and NOTHING ever gets a handle to them:
|
|
435
|
+
// this function throws instead of returning, so no `GameSession` (and
|
|
436
|
+
// therefore no `stop()`) is ever constructed. Reclaim them here, in
|
|
437
|
+
// REVERSE mount order (the inverse of the order they were built in), then
|
|
438
|
+
// rethrow the ORIGINAL error — the mount failure is what the caller must
|
|
439
|
+
// see, never a teardown error raised while cleaning up after it.
|
|
440
|
+
for (let i = mountedEntries.length - 1; i >= 0; i--) {
|
|
441
|
+
const entry = mountedEntries[i];
|
|
442
|
+
try {
|
|
443
|
+
disposeMountedRoot(entry, container);
|
|
444
|
+
}
|
|
445
|
+
catch (disposeErr) {
|
|
446
|
+
// biome-ignore lint/suspicious/noConsole: a rollback failure must be visible; the original mount error is still what we rethrow
|
|
447
|
+
console.error(`createGameRuntime: rolling back root "${entry.id}" after a mount failure threw:`, disposeErr);
|
|
448
|
+
}
|
|
375
449
|
}
|
|
376
|
-
|
|
377
|
-
routerEntries.push(routerEntry);
|
|
450
|
+
throw err;
|
|
378
451
|
}
|
|
379
452
|
return { mountedEntries, routerEntries };
|
|
380
453
|
}
|
|
@@ -424,6 +497,34 @@ function installSessionRenderHarness(game, location, targetOverride) {
|
|
|
424
497
|
delete target['__vgaiRender'];
|
|
425
498
|
};
|
|
426
499
|
}
|
|
500
|
+
/**
|
|
501
|
+
* Reclaim what `createRootsGameRuntime` built for ITSELF when the mount
|
|
502
|
+
* rejects. `mountAllRootSpecs` has already rolled back every root that DID
|
|
503
|
+
* mount, so what is left is the Game shell (holding whatever registrations
|
|
504
|
+
* those roots made into it) and the stacked surface elements of the roots that
|
|
505
|
+
* never got to mount. Neither is reachable afterwards: the mount throws instead
|
|
506
|
+
* of returning, so no `GameSession` — and therefore no `stop()` — ever exists.
|
|
507
|
+
*
|
|
508
|
+
* Never throws: the MOUNT error is what the caller must see, so a failure while
|
|
509
|
+
* cleaning up after it is reported and swallowed.
|
|
510
|
+
*/
|
|
511
|
+
function reclaimAfterMountFailure(game, surfaces, container) {
|
|
512
|
+
try {
|
|
513
|
+
game.dispose();
|
|
514
|
+
}
|
|
515
|
+
catch (disposeErr) {
|
|
516
|
+
// biome-ignore lint/suspicious/noConsole: a failed rollback must be visible; the original mount error is what the caller gets
|
|
517
|
+
console.error('createGameRuntime: disposing the game after a mount failure threw:', disposeErr);
|
|
518
|
+
}
|
|
519
|
+
for (const surface of surfaces) {
|
|
520
|
+
try {
|
|
521
|
+
(surface.parentNode ?? container).removeChild(surface);
|
|
522
|
+
}
|
|
523
|
+
catch {
|
|
524
|
+
/* already detached by the per-root rollback */
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
}
|
|
427
528
|
async function createRootsGameRuntime(config) {
|
|
428
529
|
const { container, roots: specs, width, height, headless = false, seed, playtest } = config;
|
|
429
530
|
if (specs.length === 0) {
|
|
@@ -514,14 +615,14 @@ async function createRootsGameRuntime(config) {
|
|
|
514
615
|
// host's explicit `simulateSubsteps`/`renderOnce` calls — wall-clock time
|
|
515
616
|
// passing while a screenshot is taken must not move the world.
|
|
516
617
|
externalDrive: renderMode,
|
|
517
|
-
//
|
|
618
|
+
// Sim and presentation are wired to different callbacks here:
|
|
518
619
|
// `update` runs the gameplay phases once per consumed fixed substep with
|
|
519
620
|
// `preRender`/`render` withheld, and `render` runs those two once per real
|
|
520
621
|
// display frame with the interpolation alpha. Both closures are invoked
|
|
521
622
|
// only from the loop's own rAF arm, which `externalDrive` never arms — so
|
|
522
623
|
// a capture/offline-export page (`renderMode`) reaches neither, and its
|
|
523
624
|
// `simulateSubsteps` → `game.runFrame(fixedDt)` path stays frame-exact,
|
|
524
|
-
// rendering inside the substep
|
|
625
|
+
// rendering inside the substep.
|
|
525
626
|
update: (dt) => {
|
|
526
627
|
if (started)
|
|
527
628
|
game.runFrame(dt, { skipRenderPhases: true });
|
|
@@ -537,16 +638,25 @@ async function createRootsGameRuntime(config) {
|
|
|
537
638
|
// `createRootsGameRuntime`'s own cyclomatic complexity down (E4) — same
|
|
538
639
|
// reason `mountOneThreeRoot`/`mountOnePixiRoot` are already split out
|
|
539
640
|
// below.
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
641
|
+
let mounted;
|
|
642
|
+
try {
|
|
643
|
+
mounted = await mountAllRootSpecs(mountSpecs, bottomId, {
|
|
644
|
+
game,
|
|
645
|
+
surfacesById,
|
|
646
|
+
container,
|
|
647
|
+
w,
|
|
648
|
+
h,
|
|
649
|
+
dpr,
|
|
650
|
+
headless,
|
|
651
|
+
assets,
|
|
652
|
+
antialias: config.antialias,
|
|
653
|
+
});
|
|
654
|
+
}
|
|
655
|
+
catch (err) {
|
|
656
|
+
reclaimAfterMountFailure(game, surfacesById.values(), container);
|
|
657
|
+
throw err;
|
|
658
|
+
}
|
|
659
|
+
const { mountedEntries, routerEntries } = mounted;
|
|
550
660
|
// --- Delegating input router (D5 §2a) ---
|
|
551
661
|
const router = createInputRouter(container, routerEntries);
|
|
552
662
|
started = true;
|
|
@@ -566,38 +676,53 @@ async function createRootsGameRuntime(config) {
|
|
|
566
676
|
resolveStopComplete = resolve;
|
|
567
677
|
});
|
|
568
678
|
let stopping = false;
|
|
679
|
+
/**
|
|
680
|
+
* Reclaim EVERYTHING this session owns, and let no single failure stop that.
|
|
681
|
+
*
|
|
682
|
+
* Teardown used to be one `try` over the whole body, so a throwing
|
|
683
|
+
* `entry.mounted.dispose()` on root 1 skipped root 2's disposal, both
|
|
684
|
+
* renderers' `forceContextLoss`, `game.dispose()` and the two global
|
|
685
|
+
* retractions — while `stopComplete` still resolved and the editor still
|
|
686
|
+
* reported the instance reclaimed. Every step is now isolated: a failure is
|
|
687
|
+
* COLLECTED and reported, never allowed to abort the steps after it.
|
|
688
|
+
*/
|
|
569
689
|
function fullCleanup() {
|
|
570
690
|
if (stopping)
|
|
571
691
|
return;
|
|
572
692
|
stopping = true;
|
|
693
|
+
const failures = [];
|
|
694
|
+
/** Run one teardown step; record its failure and keep going. */
|
|
695
|
+
const step = (name, run) => {
|
|
696
|
+
try {
|
|
697
|
+
run();
|
|
698
|
+
}
|
|
699
|
+
catch (error) {
|
|
700
|
+
failures.push({ step: name, error });
|
|
701
|
+
}
|
|
702
|
+
};
|
|
573
703
|
try {
|
|
574
|
-
loop.stop();
|
|
575
|
-
router.dispose();
|
|
704
|
+
step('loop.stop', () => loop.stop());
|
|
705
|
+
step('router.dispose', () => router.dispose());
|
|
576
706
|
for (const entry of mountedEntries) {
|
|
577
|
-
entry.
|
|
578
|
-
entry.renderer?.dispose();
|
|
579
|
-
entry.renderer?.forceContextLoss();
|
|
580
|
-
// Remove from the element's CURRENT parent, not the mount-time
|
|
581
|
-
// `container`: the editor's Game panel re-parents the live surfaces
|
|
582
|
-
// when its mount element swaps (fill <-> device preset, W2c), and
|
|
583
|
-
// `container.removeChild` would throw NotFoundError after such a move.
|
|
584
|
-
// `container` remains the fallback for hosts whose element stand-ins
|
|
585
|
-
// never wire `parentNode` (headless unit fixtures); an element already
|
|
586
|
-
// detached by such a host is a no-op via the catch.
|
|
587
|
-
try {
|
|
588
|
-
(entry.element.parentNode ?? container).removeChild(entry.element);
|
|
589
|
-
}
|
|
590
|
-
catch {
|
|
591
|
-
/* already detached — nothing to remove */
|
|
592
|
-
}
|
|
707
|
+
step(`root "${entry.id}"`, () => disposeMountedRoot(entry, container));
|
|
593
708
|
}
|
|
594
|
-
game.dispose();
|
|
595
|
-
retractDevGlobals();
|
|
596
|
-
retractRenderHarness?.();
|
|
709
|
+
step('game.dispose', () => game.dispose());
|
|
710
|
+
step('dev globals', () => retractDevGlobals());
|
|
711
|
+
step('render harness', () => retractRenderHarness?.());
|
|
597
712
|
}
|
|
598
713
|
finally {
|
|
599
714
|
void Promise.allSettled(mountedEntries.map((entry) => entry.mounted.disposeComplete ?? Promise.resolve())).then(() => resolveStopComplete());
|
|
600
715
|
}
|
|
716
|
+
if (failures.length > 0) {
|
|
717
|
+
// LOUD, and after everything else has been reclaimed. `stop()` is called
|
|
718
|
+
// from hosts that must not be left half-torn-down by an early throw, so
|
|
719
|
+
// the report comes last — but it IS a report: a silent partial teardown
|
|
720
|
+
// is the failure this whole restructure exists to end. The editor's
|
|
721
|
+
// `exitPlayMode` catches it and prints it to the editor console.
|
|
722
|
+
throw new AggregateError(failures.map((f) => f.error), `Game session teardown failed in ${failures.length} step(s): ${failures
|
|
723
|
+
.map((f) => f.step)
|
|
724
|
+
.join(', ')}. Every other step still ran.`);
|
|
725
|
+
}
|
|
601
726
|
}
|
|
602
727
|
return {
|
|
603
728
|
stop: fullCleanup,
|
|
@@ -152,6 +152,18 @@ export interface VgaiDebugHandle {
|
|
|
152
152
|
* silent no-op.
|
|
153
153
|
*/
|
|
154
154
|
runTicks(n: number, opts?: RunTicksOptions): void;
|
|
155
|
+
/**
|
|
156
|
+
* The SETTLED-AWARE variant of {@link runTicks} (`runtime/run-ticks-settled.ts` — one
|
|
157
|
+
* implementation with the editor relay's `run-ticks` case, D17): drives the budget one tick
|
|
158
|
+
* at a time and, before each tick, waits for every registered world-settled probe
|
|
159
|
+
* (`DebugRegistry.registerWorldSettledProbe`, declared by the game's `debug.settled` entry
|
|
160
|
+
* export) — so a tick never races a scene remount's async commit, and WHICH tick first runs
|
|
161
|
+
* a freshly reloaded world is a function of the sim rather than wall timing. Session tick
|
|
162
|
+
* drivers (`@vgai/live`'s fastForward) prefer this door; with no probe registered it behaves
|
|
163
|
+
* exactly like {@link runTicks}. Bounded: throws `WORLD_UNSETTLED_TIMEOUT` if a probe never
|
|
164
|
+
* settles.
|
|
165
|
+
*/
|
|
166
|
+
runTicksSettled(n: number, opts?: RunTicksOptions): Promise<void>;
|
|
155
167
|
/**
|
|
156
168
|
* Collapses `input.setVirtualAction(action, true)` → wait `simSeconds` of
|
|
157
169
|
* REAL sim time (real ticks — deliberately NOT `runTicks`/fast-forward;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"debug-bridge.d.ts","sourceRoot":"","sources":["../../src/runtime/debug-bridge.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAChF,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACtD,OAAO,EAAc,KAAK,aAAa,EAAE,KAAK,eAAe,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"debug-bridge.d.ts","sourceRoot":"","sources":["../../src/runtime/debug-bridge.ts"],"names":[],"mappings":"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"}
|
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
* field whose runtime reader THIS module is).
|
|
16
16
|
*/
|
|
17
17
|
import { DebugError } from './debug-registry';
|
|
18
|
+
import { runTicksWhenSettled } from './run-ticks-settled';
|
|
18
19
|
/** Query-param name that opts a standalone page into the debug bridge (D18) —
|
|
19
20
|
* mirrors `render-seed.ts`'s `RENDER_MODE_QUERY_PARAM` naming/shape, own
|
|
20
21
|
* const because this is a different call site with a different flag. */
|
|
@@ -216,6 +217,9 @@ function buildDebugHandle(opts) {
|
|
|
216
217
|
}
|
|
217
218
|
target.runTicks(n, runTicksOpts);
|
|
218
219
|
},
|
|
220
|
+
runTicksSettled(n, runTicksOpts) {
|
|
221
|
+
return runTicksWhenSettled(registry, n, runTicksOpts);
|
|
222
|
+
},
|
|
219
223
|
async holdFor(action, simSeconds, worldId) {
|
|
220
224
|
const target = requireInputTarget('holdFor', worldId);
|
|
221
225
|
const setResult = target.setVirtualAction(action, true);
|