@vgai/engine 0.5.23 → 0.5.25
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/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 -0
- package/dist/adapter/ingest/game-contract.d.ts.map +1 -1
- package/dist/adapter/native-debug-module.d.ts +9 -0
- package/dist/adapter/native-debug-module.d.ts.map +1 -1
- package/dist/adapter/native-debug-module.js +11 -2
- 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 +18 -0
- package/dist/runtime/debug-registry.d.ts.map +1 -1
- package/dist/runtime/debug-registry.js +21 -0
- package/dist/runtime/game.d.ts +12 -0
- package/dist/runtime/game.d.ts.map +1 -1
- 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/package.json +1 -1
- package/src/adapter/ingest/game-contract-seams.ts +1 -0
- package/src/adapter/ingest/game-contract.ts +22 -0
- package/src/adapter/native-debug-module.ts +23 -2
- package/src/runtime/debug-bridge.ts +16 -0
- package/src/runtime/debug-registry.ts +37 -0
- package/src/runtime/game.ts +12 -0
- package/src/runtime/run-ticks-settled.ts +72 -0
|
@@ -59,6 +59,11 @@ export declare const GAME_LIFECYCLE_SHAPE: {
|
|
|
59
59
|
readonly kind: "function";
|
|
60
60
|
readonly required: "effect";
|
|
61
61
|
};
|
|
62
|
+
readonly dispose: {
|
|
63
|
+
readonly optional: true;
|
|
64
|
+
readonly kind: "function";
|
|
65
|
+
readonly required: "effect";
|
|
66
|
+
};
|
|
62
67
|
};
|
|
63
68
|
export declare const GAME_SCENES_SHAPE: {
|
|
64
69
|
readonly list: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"game-contract-seams.d.ts","sourceRoot":"","sources":["../../../src/adapter/ingest/game-contract-seams.ts"],"names":[],"mappings":"AAAA;;sEAEsE;AAgBtE,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAS9B,CAAC;AAEH,eAAO,MAAM,oBAAoB
|
|
1
|
+
{"version":3,"file":"game-contract-seams.d.ts","sourceRoot":"","sources":["../../../src/adapter/ingest/game-contract-seams.ts"],"names":[],"mappings":"AAAA;;sEAEsE;AAgBtE,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAS9B,CAAC;AAEH,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;CAK/B,CAAC;AAEH,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;CAI5B,CAAC;AAEH,eAAO,MAAM,gBAAgB;;;;;;;;;;;CAG3B,CAAC;AAEH,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;CAK7B,CAAC;AAEH,eAAO,MAAM,yBAAyB;;;;;;;;;;;;;;;;CAIpC,CAAC;AAEH,eAAO,MAAM,0BAA0B;;;;;;;;;;;;;;;;CAIrC,CAAC;AAEH,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;CAK7B,CAAC;AAEH,eAAO,MAAM,0BAA0B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAOrC,CAAC;AAEH,eAAO,MAAM,uBAAuB;;;;;;;;;;;CAGlC,CAAC"}
|
|
@@ -16,6 +16,7 @@ export const GAME_LIFECYCLE_SHAPE = defineSeamShape()({
|
|
|
16
16
|
start: { optional: true, kind: 'function', required: 'effect' },
|
|
17
17
|
pause: { optional: true, kind: 'function', required: 'effect' },
|
|
18
18
|
resume: { optional: true, kind: 'function', required: 'effect' },
|
|
19
|
+
dispose: { optional: true, kind: 'function', required: 'effect' },
|
|
19
20
|
});
|
|
20
21
|
export const GAME_SCENES_SHAPE = defineSeamShape()({
|
|
21
22
|
list: { optional: false, kind: 'function', required: 'operation' },
|
|
@@ -32,6 +32,28 @@ export interface VgaiGameLifecycle {
|
|
|
32
32
|
start?(): void;
|
|
33
33
|
pause?(): void;
|
|
34
34
|
resume?(): void;
|
|
35
|
+
/**
|
|
36
|
+
* END this session: unmount the game's root, stop its frame loop, release
|
|
37
|
+
* what its boot created. The host calls it FIRST at ingest teardown, before
|
|
38
|
+
* its own reclamation — the game's own way out always outranks the host's.
|
|
39
|
+
*
|
|
40
|
+
* Why this slot exists (measured on racing-game): a self-booting R3F game's
|
|
41
|
+
* fiber loop is not the host's to stop — the game never calls
|
|
42
|
+
* `renderer.setAnimationLoop` (the loop-gate's own warning says it cannot
|
|
43
|
+
* hold it) and fiber is a shared bare dependency the realm scheduler does
|
|
44
|
+
* not wrap — so after teardown the DEAD mount's `useFrame` kept ticking
|
|
45
|
+
* against React-nulled refs, one `TypeError` per frame (~490 per walk)
|
|
46
|
+
* until the page reloaded. Only the code that created the root can end it,
|
|
47
|
+
* and for a vendored game that code is the host-added entry shim, which
|
|
48
|
+
* publishes the unmount for the contract shim to declare here.
|
|
49
|
+
*
|
|
50
|
+
* A game that declares nothing keeps today's behavior — host-side
|
|
51
|
+
* reclamation only, with its loop's ungovernability remaining the
|
|
52
|
+
* loop-gate's named standing warning. A CANVAS ingest whose module-scope
|
|
53
|
+
* `Application` survives teardown BY DESIGN (the warm-remount contract —
|
|
54
|
+
* see `resolve-three.ts`'s `remountEpochs` doc) simply does not declare it.
|
|
55
|
+
*/
|
|
56
|
+
dispose?(): void;
|
|
35
57
|
}
|
|
36
58
|
/** One of the game's own scenes, as {@link VgaiGameScenes} lists it. `id` is the
|
|
37
59
|
* game's OWN identifier for it — the string `current()` reports and `goTo()`
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"game-contract.d.ts","sourceRoot":"","sources":["../../../src/adapter/ingest/game-contract.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EACV,YAAY,EACZ,aAAa,EACb,iBAAiB,EACjB,iBAAiB,EACjB,cAAc,EACd,kBAAkB,EACnB,MAAM,mBAAmB,CAAC;AAG3B;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,iBAAiB;IAChC,KAAK,CAAC,IAAI,IAAI,CAAC;IACf,KAAK,CAAC,IAAI,IAAI,CAAC;IACf,MAAM,CAAC,IAAI,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"game-contract.d.ts","sourceRoot":"","sources":["../../../src/adapter/ingest/game-contract.ts"],"names":[],"mappings":"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"}
|
|
@@ -56,6 +56,15 @@ export interface NativeDebugModule {
|
|
|
56
56
|
readonly events?: {
|
|
57
57
|
readonly subscribe: (listener: (event: string, detail?: unknown) => void) => () => void;
|
|
58
58
|
};
|
|
59
|
+
/**
|
|
60
|
+
* `false` while the app is intentionally BETWEEN worlds — a scene remount in flight (a
|
|
61
|
+
* `reload_current_scene`-style restart unmounts the running scene and the fresh one arrives
|
|
62
|
+
* on an ASYNC React commit). Session tick drivers (`runTicksWhenSettled`, behind both
|
|
63
|
+
* run-ticks doors) wait for `true` before each tick, so which tick first runs the fresh
|
|
64
|
+
* world is a function of the sim, never of wall timing between driver calls. Omitted =
|
|
65
|
+
* always settled.
|
|
66
|
+
*/
|
|
67
|
+
readonly settled?: () => boolean;
|
|
59
68
|
}
|
|
60
69
|
export interface NativeDebugBinding {
|
|
61
70
|
readonly rootId: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"native-debug-module.d.ts","sourceRoot":"","sources":["../../src/adapter/native-debug-module.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAQH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAEL,KAAK,eAAe,EACpB,KAAK,uBAAuB,EAE7B,MAAM,mCAAmC,CAAC;AAE3C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAEvD,eAAO,MAAM,wBAAwB,8EAM3B,CAAC;AACX,MAAM,MAAM,oBAAoB,GAAG,CAAC,OAAO,wBAAwB,CAAC,CAAC,MAAM,CAAC,CAAC;AAC7E,MAAM,MAAM,gBAAgB,GAAG,OAAO,GAAG,MAAM,GAAG;IAAE,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAE7F;;;;2BAI2B;AAC3B,KAAK,WAAW,CAAC,CAAC,IAAI,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;AAExF;;;YAGY;AACZ,MAAM,MAAM,kBAAkB,GAC1B,CAAC,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,CAAC,GACjC;IAAE,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,GAAG,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,CAAA;CAAE,CAAC;AAErF,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,QAAQ,CAAC,EAAE,WAAW,CAAC,kBAAkB,CAAC,CAAC;IACpD,QAAQ,CAAC,KAAK,CAAC,EAAE,WAAW,CAAC,MAAM,OAAO,CAAC,CAAC;IAC5C,QAAQ,CAAC,KAAK,CAAC,EAAE;QACf;;0EAEkE;QAClE,QAAQ,CAAC,OAAO,EACZ,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAC,GAC9C,CAAC,MAAM,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAC,CAAC,CAAC;QAC3D,QAAQ,CAAC,GAAG,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,gBAAgB,KAAK,IAAI,CAAC;QAChE,QAAQ,CAAC,KAAK,EAAE,MAAM,IAAI,CAAC;QAC3B,8EAA8E;QAC9E,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;QACxC,gFAAgF;QAChF,QAAQ,CAAC,cAAc,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,gBAAgB,KAAK,IAAI,CAAC;KAC3F,CAAC;IACF;;uEAEmE;IACnE,QAAQ,CAAC,MAAM,CAAC,EAAE;QAChB,QAAQ,CAAC,SAAS,EAAE,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,KAAK,IAAI,KAAK,MAAM,IAAI,CAAC;KACzF,CAAC;
|
|
1
|
+
{"version":3,"file":"native-debug-module.d.ts","sourceRoot":"","sources":["../../src/adapter/native-debug-module.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAQH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAEL,KAAK,eAAe,EACpB,KAAK,uBAAuB,EAE7B,MAAM,mCAAmC,CAAC;AAE3C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAEvD,eAAO,MAAM,wBAAwB,8EAM3B,CAAC;AACX,MAAM,MAAM,oBAAoB,GAAG,CAAC,OAAO,wBAAwB,CAAC,CAAC,MAAM,CAAC,CAAC;AAC7E,MAAM,MAAM,gBAAgB,GAAG,OAAO,GAAG,MAAM,GAAG;IAAE,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAE7F;;;;2BAI2B;AAC3B,KAAK,WAAW,CAAC,CAAC,IAAI,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;AAExF;;;YAGY;AACZ,MAAM,MAAM,kBAAkB,GAC1B,CAAC,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,CAAC,GACjC;IAAE,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,GAAG,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,CAAA;CAAE,CAAC;AAErF,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,QAAQ,CAAC,EAAE,WAAW,CAAC,kBAAkB,CAAC,CAAC;IACpD,QAAQ,CAAC,KAAK,CAAC,EAAE,WAAW,CAAC,MAAM,OAAO,CAAC,CAAC;IAC5C,QAAQ,CAAC,KAAK,CAAC,EAAE;QACf;;0EAEkE;QAClE,QAAQ,CAAC,OAAO,EACZ,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAC,GAC9C,CAAC,MAAM,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAC,CAAC,CAAC;QAC3D,QAAQ,CAAC,GAAG,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,gBAAgB,KAAK,IAAI,CAAC;QAChE,QAAQ,CAAC,KAAK,EAAE,MAAM,IAAI,CAAC;QAC3B,8EAA8E;QAC9E,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;QACxC,gFAAgF;QAChF,QAAQ,CAAC,cAAc,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,gBAAgB,KAAK,IAAI,CAAC;KAC3F,CAAC;IACF;;uEAEmE;IACnE,QAAQ,CAAC,MAAM,CAAC,EAAE;QAChB,QAAQ,CAAC,SAAS,EAAE,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,KAAK,IAAI,KAAK,MAAM,IAAI,CAAC;KACzF,CAAC;IACF;;;;;;;OAOG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,OAAO,CAAC;CAClC;AAID,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,iBAAiB,CAAC;CACnC;AAmFD,gFAAgF;AAChF,wBAAgB,iCAAiC,CAC/C,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,OAAO,GACnB,kBAAkB,GAAG,IAAI,CAgD3B;AA4KD,gFAAgF;AAChF,wBAAgB,0BAA0B,CACxC,IAAI,EAAE,IAAI,EACV,QAAQ,EAAE,SAAS,kBAAkB,EAAE,GACtC,IAAI,CAoCN;AAyBD,8EAA8E;AAC9E,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC;IAClD;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,MAAM,EAAE,SAAS,uBAAuB,EAAE,CAAC;CACrD;AAED;;;;GAIG;AACH,wBAAgB,mCAAmC,CACjD,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,OAAO,EACpB,OAAO,CAAC,EAAE,eAAe,GAAG,SAAS,GACpC,oBAAoB,GAAG,IAAI,CAqB7B;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,4BAA4B,CAC1C,IAAI,EAAE,IAAI,EACV,QAAQ,EAAE,SAAS,oBAAoB,EAAE,GACxC,IAAI,CAsBN"}
|
|
@@ -107,7 +107,7 @@ export function nativeDebugBindingFromEntryModule(rootId, entryModule) {
|
|
|
107
107
|
throw new Error(`Root "${rootId}" exports \`debug\`, but it is not an object.`);
|
|
108
108
|
}
|
|
109
109
|
const raw = entryModule['debug'];
|
|
110
|
-
rejectUnknownKeys(raw, ['commands', 'state', 'input', 'events'], `Root "${rootId}" debug export`);
|
|
110
|
+
rejectUnknownKeys(raw, ['commands', 'state', 'input', 'events', 'settled'], `Root "${rootId}" debug export`);
|
|
111
111
|
// A thunk table defers to install time (see {@link NativeTable}); a plain
|
|
112
112
|
// record validates here, where the error can still name the export.
|
|
113
113
|
const parseTable = (value, at) => {
|
|
@@ -132,7 +132,11 @@ export function nativeDebugBindingFromEntryModule(rootId, entryModule) {
|
|
|
132
132
|
const state = parseTable(raw['state'], 'debug.state');
|
|
133
133
|
const input = raw['input'] === undefined ? undefined : parseInput(raw['input']);
|
|
134
134
|
const events = raw['events'] === undefined ? undefined : parseEvents(raw['events']);
|
|
135
|
-
|
|
135
|
+
const settled = raw['settled'];
|
|
136
|
+
if (settled !== undefined && typeof settled !== 'function') {
|
|
137
|
+
throw new Error('debug.settled must be a function returning a boolean.');
|
|
138
|
+
}
|
|
139
|
+
if (!commands && !state && !input && !events && !settled) {
|
|
136
140
|
throw new Error(`Root "${rootId}" exports an empty \`debug\` object.`);
|
|
137
141
|
}
|
|
138
142
|
return {
|
|
@@ -142,6 +146,7 @@ export function nativeDebugBindingFromEntryModule(rootId, entryModule) {
|
|
|
142
146
|
...(state ? { state } : {}),
|
|
143
147
|
...(input ? { input } : {}),
|
|
144
148
|
...(events ? { events } : {}),
|
|
149
|
+
...(settled ? { settled: settled } : {}),
|
|
145
150
|
},
|
|
146
151
|
};
|
|
147
152
|
}
|
|
@@ -303,6 +308,10 @@ export function installNativeDebugBindings(game, bindings) {
|
|
|
303
308
|
// subscription's disposer is deliberately dropped: it lives exactly as
|
|
304
309
|
// long as this Game's registry does.
|
|
305
310
|
binding.debug.events?.subscribe((event, detail) => root.emit(event, detail));
|
|
311
|
+
// The app's own between-worlds truth → the session's tick gate
|
|
312
|
+
// (`runTicksWhenSettled`). Same lifetime rule as the event subscription.
|
|
313
|
+
if (binding.debug.settled)
|
|
314
|
+
registry.registerWorldSettledProbe(binding.debug.settled);
|
|
306
315
|
}
|
|
307
316
|
}
|
|
308
317
|
/**
|
|
@@ -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":"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;AAGxF;;yEAEyE;AACzE,eAAO,MAAM,sBAAsB,eAAe,CAAC;AAEnD;;;kBAGkB;AAClB,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,KAAK,CAAC,EAAE;QAAE,QAAQ,CAAC,iBAAiB,EAAE,OAAO,CAAA;KAAE,GAAG,SAAS,CAAC;CACtE;AAED;;;;;;;;2EAQ2E;AAC3E,MAAM,WAAW,oBAAoB;IACnC,gBAAgB,CACd,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,EAClD,OAAO,CAAC,EAAE,MAAM,GACf;QAAE,SAAS,EAAE,OAAO,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC3C,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG;QAAE,SAAS,EAAE,OAAO,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC5F,mBAAmB,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5C;;;;;;;;;;;;;;;;;;OAkBG;IACH,oBAAoB,CAClB,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,EAClD,OAAO,CAAC,EAAE,MAAM,GACf,IAAI,CAAC;IACR;;;+CAG2C;IAC3C,cAAc,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvC,oEAAoE;IACpE,aAAa,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtC,+CAA+C;IAC/C,WAAW,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IACvC;;;;;mDAK+C;IAC/C,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9F;;;;iFAI6E;IAC7E,qBAAqB,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAClG;AAED;;;6BAG6B;AAC7B,MAAM,WAAW,iBAAiB;IAChC;;;;6CAIyC;IACzC,IAAI,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,gBAAgB,GAAG,IAAI,CAAA;KAAE,CAAC;IAClF,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,MAAM,EAAE,gBAAgB,EAAE,CAAC;IAC3B,UAAU,EAAE,MAAM,EAAE,CAAC;CACtB;AAED;;;0EAG0E;AAC1E,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC;IACpB,SAAS,EAAE,YAAY,CAAC,WAAW,CAAC,CAAC;IACrC,KAAK,EAAE,YAAY,CAAC,OAAO,CAAC,CAAC;IAC7B,QAAQ,EAAE,YAAY,CAAC,UAAU,CAAC,CAAC;IACnC,QAAQ,EAAE,YAAY,CAAC,UAAU,CAAC,CAAC;IACnC,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACxD,MAAM,EAAE,YAAY,CAAC,QAAQ,CAAC,CAAC;IAC/B,KAAK,EAAE,oBAAoB,CAAC;IAC5B;;;4BAGwB;IACxB,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,iBAAiB,CAAC;IAC/C;;;;;;;;;OASG;IACH,QAAQ,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,eAAe,GAAG,IAAI,CAAC;IAClD;;;;;;;;;;OAUG;IACH,eAAe,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAClE;;;;;;;;;;;;;;;;;;;;;;;OAuBG;IACH,OAAO,CACL,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC;QAAE,SAAS,EAAE,OAAO,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACpD;;;;;;;OAOG;IACH,SAAS,IAAI,IAAI,CAAC;CACnB;AAED;;8EAE8E;AAC9E,MAAM,WAAW,uBAAuB;IACtC,gBAAgB,CAAC,CACf,IAAI,EAAE,OAAO,GAAG,oBAAoB,EACpC,QAAQ,EAAE,CAAC,KAAK,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,OAAO,CAAC;QAAC,MAAM,CAAC,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,GACjF,IAAI,CAAC;IACR;;;qDAGiD;IACjD,mBAAmB,CAAC,CAClB,IAAI,EAAE,OAAO,GAAG,oBAAoB,EACpC,QAAQ,EAAE,CAAC,KAAK,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,OAAO,CAAC;QAAC,MAAM,CAAC,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,GACjF,IAAI,CAAC;IACR,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,8BAA8B;IAC7C;;yDAEqD;IACrD,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAC;IACjC,QAAQ,CAAC,QAAQ,EAAE,mBAAmB,CAAC;IACvC;;yEAEqE;IACrE,QAAQ,CAAC,GAAG,CAAC,EAAE;QAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;KAAE,GAAG,SAAS,CAAC;IACvD;;qDAEiD;IACjD,QAAQ,CAAC,MAAM,CAAC,EAAE,uBAAuB,GAAG,SAAS,CAAC;CACvD;AA6BD;;;;;cAKc;AACd,eAAO,MAAM,6BAA6B,QAInB,CAAC;AAUxB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AACH,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,YAAY,EACrB,UAAU,EAAE,MAAM,EAClB,iBAAiB,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,GACtC,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,oBAAoB,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC,CAqC/D;AAiKD;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,8BAA8B,GACnC,eAAe,GAAG,SAAS,CAwB7B"}
|
|
@@ -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);
|
|
@@ -294,6 +294,24 @@ export interface DebugRegistry {
|
|
|
294
294
|
* error in that case rather than silently no-op-ing — see
|
|
295
295
|
* `debug-bridge.ts`'s `runTicks` method. */
|
|
296
296
|
getRunTicksTarget(): RunTicksTarget | null;
|
|
297
|
+
/**
|
|
298
|
+
* Register a WORLD-SETTLED probe: `false` while this game is intentionally
|
|
299
|
+
* between worlds — a scene remount in flight (`reload_current_scene`'s
|
|
300
|
+
* React remount commits asynchronously). The game declares it through the
|
|
301
|
+
* `settled` key of its `debug` entry export (`native-debug-module.ts`);
|
|
302
|
+
* session tick drivers ({@link runTicksWhenSettled} behind BOTH run-ticks
|
|
303
|
+
* doors) wait for every probe to answer `true` before each tick, so WHICH
|
|
304
|
+
* tick first runs a freshly remounted scene is a function of the sim, not
|
|
305
|
+
* of wall timing between driver calls — measured before this seam: the
|
|
306
|
+
* same drive script produced 7 or 8 post-respawn walked ticks depending on
|
|
307
|
+
* how long the driver idled between ticks. Returns the deregistration.
|
|
308
|
+
*/
|
|
309
|
+
registerWorldSettledProbe(probe: () => boolean): () => void;
|
|
310
|
+
/** `true` when every registered probe answers `true` (and vacuously with
|
|
311
|
+
* none registered). A probe that THROWS counts as settled=false — a
|
|
312
|
+
* broken probe must stall the driver loudly (its bounded wait names the
|
|
313
|
+
* timeout), never silently un-gate it. */
|
|
314
|
+
worldSettled(): boolean;
|
|
297
315
|
/** D15/T-D15.3/.5 — the CURRENT shared game tick (the same counter the
|
|
298
316
|
* built-in `time` provider's `tick` field reads), for a per-world
|
|
299
317
|
* `InputManager.poll(tick)` call to key its `scheduleActionAtTick`
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"debug-registry.d.ts","sourceRoot":"","sources":["../../src/runtime/debug-registry.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"debug-registry.d.ts","sourceRoot":"","sources":["../../src/runtime/debug-registry.ts"],"names":[],"mappings":"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"}
|
|
@@ -116,6 +116,7 @@ export function createDebugRegistry(opts) {
|
|
|
116
116
|
const inputTraceSources = new Map();
|
|
117
117
|
const virtualInputTargets = new Map();
|
|
118
118
|
let runTicksTarget = null;
|
|
119
|
+
const worldSettledProbes = new Set();
|
|
119
120
|
let attachedRoom = null;
|
|
120
121
|
const pendingServerCommands = new Map();
|
|
121
122
|
let requestCounter = 0;
|
|
@@ -487,6 +488,26 @@ export function createDebugRegistry(opts) {
|
|
|
487
488
|
getRunTicksTarget() {
|
|
488
489
|
return runTicksTarget;
|
|
489
490
|
},
|
|
491
|
+
registerWorldSettledProbe(probe) {
|
|
492
|
+
worldSettledProbes.add(probe);
|
|
493
|
+
return () => {
|
|
494
|
+
worldSettledProbes.delete(probe);
|
|
495
|
+
};
|
|
496
|
+
},
|
|
497
|
+
worldSettled() {
|
|
498
|
+
for (const probe of worldSettledProbes) {
|
|
499
|
+
try {
|
|
500
|
+
if (!probe())
|
|
501
|
+
return false;
|
|
502
|
+
}
|
|
503
|
+
catch {
|
|
504
|
+
// A throwing probe stalls the driver LOUDLY (the bounded wait's
|
|
505
|
+
// timeout names it) rather than silently un-gating the tick.
|
|
506
|
+
return false;
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
return true;
|
|
510
|
+
},
|
|
490
511
|
getGameTick() {
|
|
491
512
|
return opts.getTick();
|
|
492
513
|
},
|
package/dist/runtime/game.d.ts
CHANGED
|
@@ -536,6 +536,18 @@ export interface GameInternal extends Game {
|
|
|
536
536
|
* absorbs it exactly as it would absorb any other slow-frame gap (up to
|
|
537
537
|
* 8 substeps, additional time dropped) — `runTicks` does not need to
|
|
538
538
|
* (and does not) touch the accumulator itself to make this safe.
|
|
539
|
+
* One consequence worth its own sentence: because the burst is one
|
|
540
|
+
* synchronous JS turn, no React commit can interleave it — a scene
|
|
541
|
+
* RELOAD triggered inside the burst (a translated
|
|
542
|
+
* `reload_current_scene`, a `SceneManager.LoadScene`) leaves the
|
|
543
|
+
* incoming world unmounted for the burst's remaining ticks, which the
|
|
544
|
+
* outgoing world's replacement therefore never simulates. Measured on
|
|
545
|
+
* the starter-kit port: a 20-tick burst spanning a reload left the
|
|
546
|
+
* fresh scene with zero ticks (its census had no player), while the
|
|
547
|
+
* same 20 ticks driven as 1-tick calls interleaved the commit and
|
|
548
|
+
* matched the source engine, whose reloads happen between frames. A
|
|
549
|
+
* caller that can trigger remounts mid-window drives 1-tick bursts
|
|
550
|
+
* (the fidelity driver's `advanceTicks` is the worked example).
|
|
539
551
|
* - **`opts.render`** (default `'last'`): `'last'` skips the `preRender`/
|
|
540
552
|
* `render` phases for ticks `0..n-2` and runs the full phase list
|
|
541
553
|
* (including `preRender`/`render`) on the final tick only — the GGPO
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"game.d.ts","sourceRoot":"","sources":["../../src/runtime/game.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"game.d.ts","sourceRoot":"","sources":["../../src/runtime/game.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `runTicksWhenSettled` — the settled-aware tick driver behind BOTH session run-ticks doors
|
|
3
|
+
* (the bridge's `window.__vgai.runTicksSettled`, the editor relay's `run-ticks` case), one
|
|
4
|
+
* implementation with byte-identical semantics across doors, exactly as `runTicks` itself is
|
|
5
|
+
* shared (D17).
|
|
6
|
+
*
|
|
7
|
+
* Why it exists: `Game.runTicks` is deliberately SYNCHRONOUS, but a game may be intentionally
|
|
8
|
+
* BETWEEN worlds when a tick arrives — `reload_current_scene` unmounts the running scene and
|
|
9
|
+
* the fresh one arrives on an ASYNC React commit. A tick driven into that gap runs against
|
|
10
|
+
* nothing, and WHICH tick first runs the fresh world then depends on wall timing between
|
|
11
|
+
* driver calls — measured on the starter-kit fidelity drive: the same script produced 7 or 8
|
|
12
|
+
* post-respawn walked ticks depending on how long the driver idled between ticks. The fidelity
|
|
13
|
+
* contract (docs/MIGRATE-FIDELITY.md) treats a nondeterministic channel as a MECHANISM defect,
|
|
14
|
+
* and this is the mechanism: ticks must not race remounts.
|
|
15
|
+
*
|
|
16
|
+
* So this driver runs the budget ONE tick at a time and, before each tick, waits for every
|
|
17
|
+
* registered world-settled probe ({@link DebugRegistry.registerWorldSettledProbe} — declared by
|
|
18
|
+
* the game through its `debug.settled` entry export) to answer `true`. The wall-clock poll is
|
|
19
|
+
* sound because the OUTCOME no longer depends on timing: however long the commit takes, the
|
|
20
|
+
* next tick is always the fresh world's first. A game that registers no probe gets the old
|
|
21
|
+
* behavior exactly (every wait resolves immediately).
|
|
22
|
+
*
|
|
23
|
+
* The wait is BOUNDED and loud: a remount that never settles is a real defect, and
|
|
24
|
+
* `WORLD_UNSETTLED_TIMEOUT` names it rather than letting the driver hang.
|
|
25
|
+
*/
|
|
26
|
+
import { type DebugRegistry, type RunTicksOptions } from './debug-registry';
|
|
27
|
+
export declare function runTicksWhenSettled(registry: Pick<DebugRegistry, 'worldSettled' | 'getRunTicksTarget'>, n: number, opts?: RunTicksOptions,
|
|
28
|
+
/** Test-only overrides — real callers leave this unset (the same seam
|
|
29
|
+
* convention as fast-forward's `batchTicks`). */
|
|
30
|
+
waits?: {
|
|
31
|
+
timeoutMs?: number;
|
|
32
|
+
pollMs?: number;
|
|
33
|
+
}): Promise<void>;
|
|
34
|
+
//# sourceMappingURL=run-ticks-settled.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run-ticks-settled.d.ts","sourceRoot":"","sources":["../../src/runtime/run-ticks-settled.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,OAAO,EAAc,KAAK,aAAa,EAAE,KAAK,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAQxF,wBAAsB,mBAAmB,CACvC,QAAQ,EAAE,IAAI,CAAC,aAAa,EAAE,cAAc,GAAG,mBAAmB,CAAC,EACnE,CAAC,EAAE,MAAM,EACT,IAAI,CAAC,EAAE,eAAe;AACtB;kDACkD;AAClD,KAAK,CAAC,EAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,GAC9C,OAAO,CAAC,IAAI,CAAC,CA+Bf"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `runTicksWhenSettled` — the settled-aware tick driver behind BOTH session run-ticks doors
|
|
3
|
+
* (the bridge's `window.__vgai.runTicksSettled`, the editor relay's `run-ticks` case), one
|
|
4
|
+
* implementation with byte-identical semantics across doors, exactly as `runTicks` itself is
|
|
5
|
+
* shared (D17).
|
|
6
|
+
*
|
|
7
|
+
* Why it exists: `Game.runTicks` is deliberately SYNCHRONOUS, but a game may be intentionally
|
|
8
|
+
* BETWEEN worlds when a tick arrives — `reload_current_scene` unmounts the running scene and
|
|
9
|
+
* the fresh one arrives on an ASYNC React commit. A tick driven into that gap runs against
|
|
10
|
+
* nothing, and WHICH tick first runs the fresh world then depends on wall timing between
|
|
11
|
+
* driver calls — measured on the starter-kit fidelity drive: the same script produced 7 or 8
|
|
12
|
+
* post-respawn walked ticks depending on how long the driver idled between ticks. The fidelity
|
|
13
|
+
* contract (docs/MIGRATE-FIDELITY.md) treats a nondeterministic channel as a MECHANISM defect,
|
|
14
|
+
* and this is the mechanism: ticks must not race remounts.
|
|
15
|
+
*
|
|
16
|
+
* So this driver runs the budget ONE tick at a time and, before each tick, waits for every
|
|
17
|
+
* registered world-settled probe ({@link DebugRegistry.registerWorldSettledProbe} — declared by
|
|
18
|
+
* the game through its `debug.settled` entry export) to answer `true`. The wall-clock poll is
|
|
19
|
+
* sound because the OUTCOME no longer depends on timing: however long the commit takes, the
|
|
20
|
+
* next tick is always the fresh world's first. A game that registers no probe gets the old
|
|
21
|
+
* behavior exactly (every wait resolves immediately).
|
|
22
|
+
*
|
|
23
|
+
* The wait is BOUNDED and loud: a remount that never settles is a real defect, and
|
|
24
|
+
* `WORLD_UNSETTLED_TIMEOUT` names it rather than letting the driver hang.
|
|
25
|
+
*/
|
|
26
|
+
import { DebugError } from './debug-registry';
|
|
27
|
+
/** A remount is a couple of React commits on an idle main thread; polling faster buys nothing
|
|
28
|
+
* and slower delays every settled check by the poll period. */
|
|
29
|
+
const SETTLED_POLL_MS = 4;
|
|
30
|
+
/** A commit that hasn't landed after this long is not "in flight", it is stuck. */
|
|
31
|
+
const SETTLED_TIMEOUT_MS = 10_000;
|
|
32
|
+
export async function runTicksWhenSettled(registry, n, opts,
|
|
33
|
+
/** Test-only overrides — real callers leave this unset (the same seam
|
|
34
|
+
* convention as fast-forward's `batchTicks`). */
|
|
35
|
+
waits) {
|
|
36
|
+
const target = registry.getRunTicksTarget();
|
|
37
|
+
if (target === null) {
|
|
38
|
+
throw new DebugError('RUN_TICKS_UNAVAILABLE', 'runTicksWhenSettled: no run-ticks target is wired — no Game has mounted yet');
|
|
39
|
+
}
|
|
40
|
+
const timeoutMs = waits?.timeoutMs ?? SETTLED_TIMEOUT_MS;
|
|
41
|
+
const pollMs = waits?.pollMs ?? SETTLED_POLL_MS;
|
|
42
|
+
const render = opts?.render ?? 'last';
|
|
43
|
+
for (let i = 0; i < n; i++) {
|
|
44
|
+
if (!registry.worldSettled()) {
|
|
45
|
+
const deadline = Date.now() + timeoutMs;
|
|
46
|
+
while (!registry.worldSettled()) {
|
|
47
|
+
if (Date.now() > deadline) {
|
|
48
|
+
throw new DebugError('WORLD_UNSETTLED_TIMEOUT', `runTicksWhenSettled: a world-settled probe still answers false after ${timeoutMs}ms — ` +
|
|
49
|
+
'a scene remount (or a broken probe) is stuck, and driving ticks into it would race it');
|
|
50
|
+
}
|
|
51
|
+
await new Promise((resolve) => setTimeout(resolve, pollMs));
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
const isFinalTick = i === n - 1;
|
|
55
|
+
// Same per-tick render policy `Game.runTicks` applies across its own loop.
|
|
56
|
+
const tickRender = render === 'all' ? 'all' : render === 'none' ? 'none' : isFinalTick ? 'last' : 'none';
|
|
57
|
+
target.runTicks(1, { render: tickRender });
|
|
58
|
+
}
|
|
59
|
+
}
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@vgai/engine",
|
|
3
3
|
"author": "Volter AI, Inc.",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
|
-
"version": "0.5.
|
|
5
|
+
"version": "0.5.25",
|
|
6
6
|
"description": "Readable TypeScript game engine and universal host for Three.js, PixiJS, and React games.",
|
|
7
7
|
"keywords": [
|
|
8
8
|
"game-engine",
|
|
@@ -31,6 +31,7 @@ export const GAME_LIFECYCLE_SHAPE = defineSeamShape<VgaiGameLifecycle>()({
|
|
|
31
31
|
start: { optional: true, kind: 'function', required: 'effect' },
|
|
32
32
|
pause: { optional: true, kind: 'function', required: 'effect' },
|
|
33
33
|
resume: { optional: true, kind: 'function', required: 'effect' },
|
|
34
|
+
dispose: { optional: true, kind: 'function', required: 'effect' },
|
|
34
35
|
});
|
|
35
36
|
|
|
36
37
|
export const GAME_SCENES_SHAPE = defineSeamShape<VgaiGameScenes>()({
|
|
@@ -42,6 +42,28 @@ export interface VgaiGameLifecycle {
|
|
|
42
42
|
start?(): void;
|
|
43
43
|
pause?(): void;
|
|
44
44
|
resume?(): void;
|
|
45
|
+
/**
|
|
46
|
+
* END this session: unmount the game's root, stop its frame loop, release
|
|
47
|
+
* what its boot created. The host calls it FIRST at ingest teardown, before
|
|
48
|
+
* its own reclamation — the game's own way out always outranks the host's.
|
|
49
|
+
*
|
|
50
|
+
* Why this slot exists (measured on racing-game): a self-booting R3F game's
|
|
51
|
+
* fiber loop is not the host's to stop — the game never calls
|
|
52
|
+
* `renderer.setAnimationLoop` (the loop-gate's own warning says it cannot
|
|
53
|
+
* hold it) and fiber is a shared bare dependency the realm scheduler does
|
|
54
|
+
* not wrap — so after teardown the DEAD mount's `useFrame` kept ticking
|
|
55
|
+
* against React-nulled refs, one `TypeError` per frame (~490 per walk)
|
|
56
|
+
* until the page reloaded. Only the code that created the root can end it,
|
|
57
|
+
* and for a vendored game that code is the host-added entry shim, which
|
|
58
|
+
* publishes the unmount for the contract shim to declare here.
|
|
59
|
+
*
|
|
60
|
+
* A game that declares nothing keeps today's behavior — host-side
|
|
61
|
+
* reclamation only, with its loop's ungovernability remaining the
|
|
62
|
+
* loop-gate's named standing warning. A CANVAS ingest whose module-scope
|
|
63
|
+
* `Application` survives teardown BY DESIGN (the warm-remount contract —
|
|
64
|
+
* see `resolve-three.ts`'s `remountEpochs` doc) simply does not declare it.
|
|
65
|
+
*/
|
|
66
|
+
dispose?(): void;
|
|
45
67
|
}
|
|
46
68
|
|
|
47
69
|
/** One of the game's own scenes, as {@link VgaiGameScenes} lists it. `id` is the
|
|
@@ -77,6 +77,15 @@ export interface NativeDebugModule {
|
|
|
77
77
|
readonly events?: {
|
|
78
78
|
readonly subscribe: (listener: (event: string, detail?: unknown) => void) => () => void;
|
|
79
79
|
};
|
|
80
|
+
/**
|
|
81
|
+
* `false` while the app is intentionally BETWEEN worlds — a scene remount in flight (a
|
|
82
|
+
* `reload_current_scene`-style restart unmounts the running scene and the fresh one arrives
|
|
83
|
+
* on an ASYNC React commit). Session tick drivers (`runTicksWhenSettled`, behind both
|
|
84
|
+
* run-ticks doors) wait for `true` before each tick, so which tick first runs the fresh
|
|
85
|
+
* world is a function of the sim, never of wall timing between driver calls. Omitted =
|
|
86
|
+
* always settled.
|
|
87
|
+
*/
|
|
88
|
+
readonly settled?: () => boolean;
|
|
80
89
|
}
|
|
81
90
|
|
|
82
91
|
type NativeInputBinding = NonNullable<NativeDebugModule['input']>;
|
|
@@ -177,7 +186,11 @@ export function nativeDebugBindingFromEntryModule(
|
|
|
177
186
|
throw new Error(`Root "${rootId}" exports \`debug\`, but it is not an object.`);
|
|
178
187
|
}
|
|
179
188
|
const raw = entryModule['debug'];
|
|
180
|
-
rejectUnknownKeys(
|
|
189
|
+
rejectUnknownKeys(
|
|
190
|
+
raw,
|
|
191
|
+
['commands', 'state', 'input', 'events', 'settled'],
|
|
192
|
+
`Root "${rootId}" debug export`,
|
|
193
|
+
);
|
|
181
194
|
|
|
182
195
|
// A thunk table defers to install time (see {@link NativeTable}); a plain
|
|
183
196
|
// record validates here, where the error can still name the export.
|
|
@@ -198,7 +211,11 @@ export function nativeDebugBindingFromEntryModule(
|
|
|
198
211
|
const state = parseTable(raw['state'], 'debug.state');
|
|
199
212
|
const input = raw['input'] === undefined ? undefined : parseInput(raw['input']);
|
|
200
213
|
const events = raw['events'] === undefined ? undefined : parseEvents(raw['events']);
|
|
201
|
-
|
|
214
|
+
const settled = raw['settled'];
|
|
215
|
+
if (settled !== undefined && typeof settled !== 'function') {
|
|
216
|
+
throw new Error('debug.settled must be a function returning a boolean.');
|
|
217
|
+
}
|
|
218
|
+
if (!commands && !state && !input && !events && !settled) {
|
|
202
219
|
throw new Error(`Root "${rootId}" exports an empty \`debug\` object.`);
|
|
203
220
|
}
|
|
204
221
|
return {
|
|
@@ -208,6 +225,7 @@ export function nativeDebugBindingFromEntryModule(
|
|
|
208
225
|
...(state ? { state } : {}),
|
|
209
226
|
...(input ? { input } : {}),
|
|
210
227
|
...(events ? { events } : {}),
|
|
228
|
+
...(settled ? { settled: settled as () => boolean } : {}),
|
|
211
229
|
},
|
|
212
230
|
};
|
|
213
231
|
}
|
|
@@ -418,6 +436,9 @@ export function installNativeDebugBindings(
|
|
|
418
436
|
// subscription's disposer is deliberately dropped: it lives exactly as
|
|
419
437
|
// long as this Game's registry does.
|
|
420
438
|
binding.debug.events?.subscribe((event, detail) => root.emit(event, detail));
|
|
439
|
+
// The app's own between-worlds truth → the session's tick gate
|
|
440
|
+
// (`runTicksWhenSettled`). Same lifetime rule as the event subscription.
|
|
441
|
+
if (binding.debug.settled) registry.registerWorldSettledProbe(binding.debug.settled);
|
|
421
442
|
}
|
|
422
443
|
}
|
|
423
444
|
|
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
import type { DebugAdapter, TickStampedEvent } from '../adapter/system-adapter';
|
|
19
19
|
import type { GameLoopLiveness } from '../core/types';
|
|
20
20
|
import { DebugError, type DebugRegistry, type RunTicksOptions } from './debug-registry';
|
|
21
|
+
import { runTicksWhenSettled } from './run-ticks-settled';
|
|
21
22
|
|
|
22
23
|
/** Query-param name that opts a standalone page into the debug bridge (D18) —
|
|
23
24
|
* mirrors `render-seed.ts`'s `RENDER_MODE_QUERY_PARAM` naming/shape, own
|
|
@@ -143,6 +144,18 @@ export interface VgaiDebugHandle {
|
|
|
143
144
|
* silent no-op.
|
|
144
145
|
*/
|
|
145
146
|
runTicks(n: number, opts?: RunTicksOptions): void;
|
|
147
|
+
/**
|
|
148
|
+
* The SETTLED-AWARE variant of {@link runTicks} (`runtime/run-ticks-settled.ts` — one
|
|
149
|
+
* implementation with the editor relay's `run-ticks` case, D17): drives the budget one tick
|
|
150
|
+
* at a time and, before each tick, waits for every registered world-settled probe
|
|
151
|
+
* (`DebugRegistry.registerWorldSettledProbe`, declared by the game's `debug.settled` entry
|
|
152
|
+
* export) — so a tick never races a scene remount's async commit, and WHICH tick first runs
|
|
153
|
+
* a freshly reloaded world is a function of the sim rather than wall timing. Session tick
|
|
154
|
+
* drivers (`@vgai/live`'s fastForward) prefer this door; with no probe registered it behaves
|
|
155
|
+
* exactly like {@link runTicks}. Bounded: throws `WORLD_UNSETTLED_TIMEOUT` if a probe never
|
|
156
|
+
* settles.
|
|
157
|
+
*/
|
|
158
|
+
runTicksSettled(n: number, opts?: RunTicksOptions): Promise<void>;
|
|
146
159
|
/**
|
|
147
160
|
* Collapses `input.setVirtualAction(action, true)` → wait `simSeconds` of
|
|
148
161
|
* REAL sim time (real ticks — deliberately NOT `runTicks`/fast-forward;
|
|
@@ -468,6 +481,9 @@ function buildDebugHandle(opts: {
|
|
|
468
481
|
}
|
|
469
482
|
target.runTicks(n, runTicksOpts);
|
|
470
483
|
},
|
|
484
|
+
runTicksSettled(n, runTicksOpts) {
|
|
485
|
+
return runTicksWhenSettled(registry, n, runTicksOpts);
|
|
486
|
+
},
|
|
471
487
|
async holdFor(action, simSeconds, worldId) {
|
|
472
488
|
const target = requireInputTarget('holdFor', worldId);
|
|
473
489
|
const setResult = target.setVirtualAction(action, true);
|
|
@@ -370,6 +370,24 @@ export interface DebugRegistry {
|
|
|
370
370
|
* error in that case rather than silently no-op-ing — see
|
|
371
371
|
* `debug-bridge.ts`'s `runTicks` method. */
|
|
372
372
|
getRunTicksTarget(): RunTicksTarget | null;
|
|
373
|
+
/**
|
|
374
|
+
* Register a WORLD-SETTLED probe: `false` while this game is intentionally
|
|
375
|
+
* between worlds — a scene remount in flight (`reload_current_scene`'s
|
|
376
|
+
* React remount commits asynchronously). The game declares it through the
|
|
377
|
+
* `settled` key of its `debug` entry export (`native-debug-module.ts`);
|
|
378
|
+
* session tick drivers ({@link runTicksWhenSettled} behind BOTH run-ticks
|
|
379
|
+
* doors) wait for every probe to answer `true` before each tick, so WHICH
|
|
380
|
+
* tick first runs a freshly remounted scene is a function of the sim, not
|
|
381
|
+
* of wall timing between driver calls — measured before this seam: the
|
|
382
|
+
* same drive script produced 7 or 8 post-respawn walked ticks depending on
|
|
383
|
+
* how long the driver idled between ticks. Returns the deregistration.
|
|
384
|
+
*/
|
|
385
|
+
registerWorldSettledProbe(probe: () => boolean): () => void;
|
|
386
|
+
/** `true` when every registered probe answers `true` (and vacuously with
|
|
387
|
+
* none registered). A probe that THROWS counts as settled=false — a
|
|
388
|
+
* broken probe must stall the driver loudly (its bounded wait names the
|
|
389
|
+
* timeout), never silently un-gate it. */
|
|
390
|
+
worldSettled(): boolean;
|
|
373
391
|
/** D15/T-D15.3/.5 — the CURRENT shared game tick (the same counter the
|
|
374
392
|
* built-in `time` provider's `tick` field reads), for a per-world
|
|
375
393
|
* `InputManager.poll(tick)` call to key its `scheduleActionAtTick`
|
|
@@ -458,6 +476,7 @@ export function createDebugRegistry(opts: {
|
|
|
458
476
|
const inputTraceSources = new Map<string, () => InputTraceSnapshot>();
|
|
459
477
|
const virtualInputTargets = new Map<string, DebugVirtualInputTarget>();
|
|
460
478
|
let runTicksTarget: RunTicksTarget | null = null;
|
|
479
|
+
const worldSettledProbes = new Set<() => boolean>();
|
|
461
480
|
let attachedRoom: DebugRoomHandle | null = null;
|
|
462
481
|
const pendingServerCommands = new Map<string, PendingServerCommand>();
|
|
463
482
|
let requestCounter = 0;
|
|
@@ -907,6 +926,24 @@ export function createDebugRegistry(opts: {
|
|
|
907
926
|
getRunTicksTarget() {
|
|
908
927
|
return runTicksTarget;
|
|
909
928
|
},
|
|
929
|
+
registerWorldSettledProbe(probe: () => boolean) {
|
|
930
|
+
worldSettledProbes.add(probe);
|
|
931
|
+
return () => {
|
|
932
|
+
worldSettledProbes.delete(probe);
|
|
933
|
+
};
|
|
934
|
+
},
|
|
935
|
+
worldSettled() {
|
|
936
|
+
for (const probe of worldSettledProbes) {
|
|
937
|
+
try {
|
|
938
|
+
if (!probe()) return false;
|
|
939
|
+
} catch {
|
|
940
|
+
// A throwing probe stalls the driver LOUDLY (the bounded wait's
|
|
941
|
+
// timeout names it) rather than silently un-gating the tick.
|
|
942
|
+
return false;
|
|
943
|
+
}
|
|
944
|
+
}
|
|
945
|
+
return true;
|
|
946
|
+
},
|
|
910
947
|
getGameTick() {
|
|
911
948
|
return opts.getTick();
|
|
912
949
|
},
|
package/src/runtime/game.ts
CHANGED
|
@@ -777,6 +777,18 @@ export interface GameInternal extends Game {
|
|
|
777
777
|
* absorbs it exactly as it would absorb any other slow-frame gap (up to
|
|
778
778
|
* 8 substeps, additional time dropped) — `runTicks` does not need to
|
|
779
779
|
* (and does not) touch the accumulator itself to make this safe.
|
|
780
|
+
* One consequence worth its own sentence: because the burst is one
|
|
781
|
+
* synchronous JS turn, no React commit can interleave it — a scene
|
|
782
|
+
* RELOAD triggered inside the burst (a translated
|
|
783
|
+
* `reload_current_scene`, a `SceneManager.LoadScene`) leaves the
|
|
784
|
+
* incoming world unmounted for the burst's remaining ticks, which the
|
|
785
|
+
* outgoing world's replacement therefore never simulates. Measured on
|
|
786
|
+
* the starter-kit port: a 20-tick burst spanning a reload left the
|
|
787
|
+
* fresh scene with zero ticks (its census had no player), while the
|
|
788
|
+
* same 20 ticks driven as 1-tick calls interleaved the commit and
|
|
789
|
+
* matched the source engine, whose reloads happen between frames. A
|
|
790
|
+
* caller that can trigger remounts mid-window drives 1-tick bursts
|
|
791
|
+
* (the fidelity driver's `advanceTicks` is the worked example).
|
|
780
792
|
* - **`opts.render`** (default `'last'`): `'last'` skips the `preRender`/
|
|
781
793
|
* `render` phases for ticks `0..n-2` and runs the full phase list
|
|
782
794
|
* (including `preRender`/`render`) on the final tick only — the GGPO
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `runTicksWhenSettled` — the settled-aware tick driver behind BOTH session run-ticks doors
|
|
3
|
+
* (the bridge's `window.__vgai.runTicksSettled`, the editor relay's `run-ticks` case), one
|
|
4
|
+
* implementation with byte-identical semantics across doors, exactly as `runTicks` itself is
|
|
5
|
+
* shared (D17).
|
|
6
|
+
*
|
|
7
|
+
* Why it exists: `Game.runTicks` is deliberately SYNCHRONOUS, but a game may be intentionally
|
|
8
|
+
* BETWEEN worlds when a tick arrives — `reload_current_scene` unmounts the running scene and
|
|
9
|
+
* the fresh one arrives on an ASYNC React commit. A tick driven into that gap runs against
|
|
10
|
+
* nothing, and WHICH tick first runs the fresh world then depends on wall timing between
|
|
11
|
+
* driver calls — measured on the starter-kit fidelity drive: the same script produced 7 or 8
|
|
12
|
+
* post-respawn walked ticks depending on how long the driver idled between ticks. The fidelity
|
|
13
|
+
* contract (docs/MIGRATE-FIDELITY.md) treats a nondeterministic channel as a MECHANISM defect,
|
|
14
|
+
* and this is the mechanism: ticks must not race remounts.
|
|
15
|
+
*
|
|
16
|
+
* So this driver runs the budget ONE tick at a time and, before each tick, waits for every
|
|
17
|
+
* registered world-settled probe ({@link DebugRegistry.registerWorldSettledProbe} — declared by
|
|
18
|
+
* the game through its `debug.settled` entry export) to answer `true`. The wall-clock poll is
|
|
19
|
+
* sound because the OUTCOME no longer depends on timing: however long the commit takes, the
|
|
20
|
+
* next tick is always the fresh world's first. A game that registers no probe gets the old
|
|
21
|
+
* behavior exactly (every wait resolves immediately).
|
|
22
|
+
*
|
|
23
|
+
* The wait is BOUNDED and loud: a remount that never settles is a real defect, and
|
|
24
|
+
* `WORLD_UNSETTLED_TIMEOUT` names it rather than letting the driver hang.
|
|
25
|
+
*/
|
|
26
|
+
import { DebugError, type DebugRegistry, type RunTicksOptions } from './debug-registry';
|
|
27
|
+
|
|
28
|
+
/** A remount is a couple of React commits on an idle main thread; polling faster buys nothing
|
|
29
|
+
* and slower delays every settled check by the poll period. */
|
|
30
|
+
const SETTLED_POLL_MS = 4;
|
|
31
|
+
/** A commit that hasn't landed after this long is not "in flight", it is stuck. */
|
|
32
|
+
const SETTLED_TIMEOUT_MS = 10_000;
|
|
33
|
+
|
|
34
|
+
export async function runTicksWhenSettled(
|
|
35
|
+
registry: Pick<DebugRegistry, 'worldSettled' | 'getRunTicksTarget'>,
|
|
36
|
+
n: number,
|
|
37
|
+
opts?: RunTicksOptions,
|
|
38
|
+
/** Test-only overrides — real callers leave this unset (the same seam
|
|
39
|
+
* convention as fast-forward's `batchTicks`). */
|
|
40
|
+
waits?: { timeoutMs?: number; pollMs?: number },
|
|
41
|
+
): Promise<void> {
|
|
42
|
+
const target = registry.getRunTicksTarget();
|
|
43
|
+
if (target === null) {
|
|
44
|
+
throw new DebugError(
|
|
45
|
+
'RUN_TICKS_UNAVAILABLE',
|
|
46
|
+
'runTicksWhenSettled: no run-ticks target is wired — no Game has mounted yet',
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
const timeoutMs = waits?.timeoutMs ?? SETTLED_TIMEOUT_MS;
|
|
50
|
+
const pollMs = waits?.pollMs ?? SETTLED_POLL_MS;
|
|
51
|
+
const render = opts?.render ?? 'last';
|
|
52
|
+
for (let i = 0; i < n; i++) {
|
|
53
|
+
if (!registry.worldSettled()) {
|
|
54
|
+
const deadline = Date.now() + timeoutMs;
|
|
55
|
+
while (!registry.worldSettled()) {
|
|
56
|
+
if (Date.now() > deadline) {
|
|
57
|
+
throw new DebugError(
|
|
58
|
+
'WORLD_UNSETTLED_TIMEOUT',
|
|
59
|
+
`runTicksWhenSettled: a world-settled probe still answers false after ${timeoutMs}ms — ` +
|
|
60
|
+
'a scene remount (or a broken probe) is stuck, and driving ticks into it would race it',
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
await new Promise((resolve) => setTimeout(resolve, pollMs));
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
const isFinalTick = i === n - 1;
|
|
67
|
+
// Same per-tick render policy `Game.runTicks` applies across its own loop.
|
|
68
|
+
const tickRender =
|
|
69
|
+
render === 'all' ? 'all' : render === 'none' ? 'none' : isFinalTick ? 'last' : 'none';
|
|
70
|
+
target.runTicks(1, { render: tickRender });
|
|
71
|
+
}
|
|
72
|
+
}
|