@vgai/engine 0.5.21 → 0.5.22
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/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 +45 -3
- package/dist/adapter/native-debug-module.d.ts.map +1 -1
- package/dist/adapter/native-debug-module.js +128 -10
- package/dist/adapter/renderer-config.d.ts +1 -1
- package/dist/adapter/renderer-config.js +1 -1
- 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/sim-clock.d.ts +14 -2
- package/dist/core/sim-clock.d.ts.map +1 -1
- package/dist/core/sim-clock.js +14 -2
- 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/input/input-manager.d.ts +15 -0
- package/dist/input/input-manager.d.ts.map +1 -1
- package/dist/input/input-manager.js +15 -0
- 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/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 +15 -0
- package/dist/runtime/game.d.ts.map +1 -1
- package/dist/runtime/game.js +40 -8
- package/dist/runtime/mount-game.d.ts.map +1 -1
- package/dist/runtime/mount-game.js +18 -2
- package/dist/runtime/mount-manifest.d.ts.map +1 -1
- package/dist/runtime/mount-manifest.js +4 -2
- package/dist/runtime/types.d.ts +1 -1
- 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 +19 -25
- package/dist/world3d-react/r3f-root-factory.d.ts.map +1 -1
- package/dist/world3d-react/r3f-root-factory.js +396 -50
- package/dist/world3d-react/rapier-physics-bridge.d.ts +24 -12
- package/dist/world3d-react/rapier-physics-bridge.d.ts.map +1 -1
- package/dist/world3d-react/rapier-physics-bridge.js +82 -49
- package/package.json +1 -1
- package/schemas/engine-capabilities.json +3 -3
- package/src/adapter/manifest-interpreter.ts +64 -0
- package/src/adapter/native-debug-module.ts +212 -15
- package/src/adapter/renderer-config.ts +1 -1
- 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/sim-clock.ts +14 -2
- package/src/dev/instruments.ts +108 -11
- package/src/input/input-manager.ts +15 -0
- 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/runtime/game-input-seams.ts +108 -0
- package/src/runtime/game.ts +65 -7
- package/src/runtime/mount-game.ts +23 -1
- package/src/runtime/mount-manifest.ts +4 -2
- package/src/runtime/types.ts +1 -1
- package/src/world3d-react/index.ts +15 -31
- package/src/world3d-react/r3f-root-factory.tsx +444 -53
- package/src/world3d-react/rapier-physics-bridge.tsx +88 -49
- 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/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
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The manifest's SOLE INTERPRETER (owner ruling, 2026-08-20 — see
|
|
3
|
+
* docs/ARCHITECTURE-CORE.md §adapter). `vgai.project.json` is static
|
|
4
|
+
* inventory; the adapter seam is the ONE layer that turns it into execution
|
|
5
|
+
* bindings, and host code consumes the manifest through THESE derivations —
|
|
6
|
+
* never by reading `manifest.roots` directly (the guard is
|
|
7
|
+
* `packages/engine/test/manifest-sole-interpreter.test.ts`).
|
|
8
|
+
*
|
|
9
|
+
* Why a doorway and not a convention: one deriver means one direction of
|
|
10
|
+
* truth (manifest → adapter → host). When the project's own `vgai.adapter.ts`
|
|
11
|
+
* later interposes on a derivation, every host path that asked the
|
|
12
|
+
* interpreter gets the project's answer for free; a path that read the raw
|
|
13
|
+
* field would silently keep the mechanical one.
|
|
14
|
+
*
|
|
15
|
+
* The module-free audiences named by the ruling (a bundled CLI's raw
|
|
16
|
+
* discovery over unvalidated files, Vite config time, synchronous
|
|
17
|
+
* dep-optimization, and the loader that CONSTRUCTS the resolution) remain
|
|
18
|
+
* direct readers by design; everything else asks here.
|
|
19
|
+
*
|
|
20
|
+
* These functions are pure and synchronous over an already-loaded manifest —
|
|
21
|
+
* interpreting inventory never evaluates project modules, so any host realm
|
|
22
|
+
* may import this. They are structurally generic so both the loader's
|
|
23
|
+
* `ResolvedGameManifest` and the editor's lenient `EditModeManifest` view
|
|
24
|
+
* flow through the same doorway.
|
|
25
|
+
*/
|
|
26
|
+
/**
|
|
27
|
+
* The declared adapter roots, in mount order (the loader already sorted by
|
|
28
|
+
* `zOrder`, ties by declaration order). This is the mount plan, the readiness
|
|
29
|
+
* roster, and the enumeration every other derivation composes from.
|
|
30
|
+
*/
|
|
31
|
+
export declare function declaredRoots<Root>(manifest: {
|
|
32
|
+
readonly roots: readonly Root[];
|
|
33
|
+
}): readonly Root[];
|
|
34
|
+
/** The root declaring `id`, or undefined — never a silent first-wins pick. */
|
|
35
|
+
export declare function rootById<Root extends {
|
|
36
|
+
readonly id: string;
|
|
37
|
+
}>(manifest: {
|
|
38
|
+
readonly roots: readonly Root[];
|
|
39
|
+
}, id: string): Root | undefined;
|
|
40
|
+
/** Whether any declared root mounts on `surface` (e.g. the editor's
|
|
41
|
+
* "does this project have a Three world" gates). The parameter is the closed
|
|
42
|
+
* surface union, not `string` — a typo'd literal must stay a compile error,
|
|
43
|
+
* not a silent forever-false. */
|
|
44
|
+
export declare function hasRootOnSurface(manifest: {
|
|
45
|
+
readonly roots: readonly {
|
|
46
|
+
readonly surface: string;
|
|
47
|
+
}[];
|
|
48
|
+
}, surface: 'three' | 'canvas' | 'dom'): boolean;
|
|
49
|
+
/** The declared ingest roots (`adapter.type === 'ingest'`), in mount order.
|
|
50
|
+
* Composite-manifest rules (exactly one, ≥2 is a loud named error) belong to
|
|
51
|
+
* the call sites that state them. */
|
|
52
|
+
export declare function ingestRoots<Root extends {
|
|
53
|
+
readonly adapter: {
|
|
54
|
+
readonly type: string;
|
|
55
|
+
};
|
|
56
|
+
}>(manifest: {
|
|
57
|
+
readonly roots: readonly Root[];
|
|
58
|
+
}): Root[];
|
|
59
|
+
//# sourceMappingURL=manifest-interpreter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manifest-interpreter.d.ts","sourceRoot":"","sources":["../../src/adapter/manifest-interpreter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,QAAQ,EAAE;IAC5C,QAAQ,CAAC,KAAK,EAAE,SAAS,IAAI,EAAE,CAAC;CACjC,GAAG,SAAS,IAAI,EAAE,CAElB;AAED,8EAA8E;AAC9E,wBAAgB,QAAQ,CAAC,IAAI,SAAS;IAAE,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;CAAE,EAC3D,QAAQ,EAAE;IAAE,QAAQ,CAAC,KAAK,EAAE,SAAS,IAAI,EAAE,CAAA;CAAE,EAC7C,EAAE,EAAE,MAAM,GACT,IAAI,GAAG,SAAS,CAElB;AAED;;;kCAGkC;AAClC,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE;IAAE,QAAQ,CAAC,KAAK,EAAE,SAAS;QAAE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;KAAE,EAAE,CAAA;CAAE,EACrE,OAAO,EAAE,OAAO,GAAG,QAAQ,GAAG,KAAK,GAClC,OAAO,CAET;AAED;;sCAEsC;AACtC,wBAAgB,WAAW,CACzB,IAAI,SAAS;IAAE,QAAQ,CAAC,OAAO,EAAE;QAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,EAC5D,QAAQ,EAAE;IAAE,QAAQ,CAAC,KAAK,EAAE,SAAS,IAAI,EAAE,CAAA;CAAE,GAAG,IAAI,EAAE,CAEvD"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The manifest's SOLE INTERPRETER (owner ruling, 2026-08-20 — see
|
|
3
|
+
* docs/ARCHITECTURE-CORE.md §adapter). `vgai.project.json` is static
|
|
4
|
+
* inventory; the adapter seam is the ONE layer that turns it into execution
|
|
5
|
+
* bindings, and host code consumes the manifest through THESE derivations —
|
|
6
|
+
* never by reading `manifest.roots` directly (the guard is
|
|
7
|
+
* `packages/engine/test/manifest-sole-interpreter.test.ts`).
|
|
8
|
+
*
|
|
9
|
+
* Why a doorway and not a convention: one deriver means one direction of
|
|
10
|
+
* truth (manifest → adapter → host). When the project's own `vgai.adapter.ts`
|
|
11
|
+
* later interposes on a derivation, every host path that asked the
|
|
12
|
+
* interpreter gets the project's answer for free; a path that read the raw
|
|
13
|
+
* field would silently keep the mechanical one.
|
|
14
|
+
*
|
|
15
|
+
* The module-free audiences named by the ruling (a bundled CLI's raw
|
|
16
|
+
* discovery over unvalidated files, Vite config time, synchronous
|
|
17
|
+
* dep-optimization, and the loader that CONSTRUCTS the resolution) remain
|
|
18
|
+
* direct readers by design; everything else asks here.
|
|
19
|
+
*
|
|
20
|
+
* These functions are pure and synchronous over an already-loaded manifest —
|
|
21
|
+
* interpreting inventory never evaluates project modules, so any host realm
|
|
22
|
+
* may import this. They are structurally generic so both the loader's
|
|
23
|
+
* `ResolvedGameManifest` and the editor's lenient `EditModeManifest` view
|
|
24
|
+
* flow through the same doorway.
|
|
25
|
+
*/
|
|
26
|
+
/**
|
|
27
|
+
* The declared adapter roots, in mount order (the loader already sorted by
|
|
28
|
+
* `zOrder`, ties by declaration order). This is the mount plan, the readiness
|
|
29
|
+
* roster, and the enumeration every other derivation composes from.
|
|
30
|
+
*/
|
|
31
|
+
export function declaredRoots(manifest) {
|
|
32
|
+
return manifest.roots;
|
|
33
|
+
}
|
|
34
|
+
/** The root declaring `id`, or undefined — never a silent first-wins pick. */
|
|
35
|
+
export function rootById(manifest, id) {
|
|
36
|
+
return manifest.roots.find((root) => root.id === id);
|
|
37
|
+
}
|
|
38
|
+
/** Whether any declared root mounts on `surface` (e.g. the editor's
|
|
39
|
+
* "does this project have a Three world" gates). The parameter is the closed
|
|
40
|
+
* surface union, not `string` — a typo'd literal must stay a compile error,
|
|
41
|
+
* not a silent forever-false. */
|
|
42
|
+
export function hasRootOnSurface(manifest, surface) {
|
|
43
|
+
return manifest.roots.some((root) => root.surface === surface);
|
|
44
|
+
}
|
|
45
|
+
/** The declared ingest roots (`adapter.type === 'ingest'`), in mount order.
|
|
46
|
+
* Composite-manifest rules (exactly one, ≥2 is a loud named error) belong to
|
|
47
|
+
* the call sites that state them. */
|
|
48
|
+
export function ingestRoots(manifest) {
|
|
49
|
+
return manifest.roots.filter((root) => root.adapter.type === 'ingest');
|
|
50
|
+
}
|
|
@@ -13,17 +13,36 @@
|
|
|
13
13
|
* copy of its stores.
|
|
14
14
|
*/
|
|
15
15
|
import type { Game } from '../runtime/game';
|
|
16
|
+
import { type ContractSurface } from './ingest/contract-system-adapters';
|
|
17
|
+
import type { SystemAdapters } from './system-adapter';
|
|
16
18
|
export declare const NATIVE_INPUT_VALUE_TYPES: readonly ["digital", "scalar", "vector2", "pointerDelta", "pointerPosition"];
|
|
17
19
|
export type NativeInputValueType = (typeof NATIVE_INPUT_VALUE_TYPES)[number];
|
|
18
20
|
export type NativeInputValue = boolean | number | {
|
|
19
21
|
readonly x: number;
|
|
20
22
|
readonly y: number;
|
|
21
23
|
};
|
|
24
|
+
/** A table may be a THUNK, evaluated once at install (after every project
|
|
25
|
+
* module has run), so a game whose declarations accrete during module
|
|
26
|
+
* evaluation — the dev-tools registry's `stat()`/`cheat()` lines beside each
|
|
27
|
+
* mechanic — hands a complete snapshot without ordering its own imports
|
|
28
|
+
* around the debugger. */
|
|
29
|
+
type NativeTable<T> = Readonly<Record<string, T>> | (() => Readonly<Record<string, T>>);
|
|
30
|
+
/** A command is a plain function, or `{ description, run }` when it wants the
|
|
31
|
+
* session's `game.commands()` listing to say what it does. Argument
|
|
32
|
+
* validation stays inside the function — the game's words at the game's
|
|
33
|
+
* door. */
|
|
34
|
+
export type NativeCommandEntry = ((...args: unknown[]) => unknown) | {
|
|
35
|
+
readonly description?: string;
|
|
36
|
+
readonly run: (...args: unknown[]) => unknown;
|
|
37
|
+
};
|
|
22
38
|
export interface NativeDebugModule {
|
|
23
|
-
readonly commands?:
|
|
24
|
-
readonly state?:
|
|
39
|
+
readonly commands?: NativeTable<NativeCommandEntry>;
|
|
40
|
+
readonly state?: NativeTable<() => unknown>;
|
|
25
41
|
readonly input?: {
|
|
26
|
-
|
|
42
|
+
/** May be a thunk, read LIVE on every use — an app whose action set loads
|
|
43
|
+
* asynchronously (an input map fetched at boot) answers with what it has
|
|
44
|
+
* NOW rather than freezing the empty pre-load set at install. */
|
|
45
|
+
readonly actions: Readonly<Record<string, NativeInputValueType>> | (() => Readonly<Record<string, NativeInputValueType>>);
|
|
27
46
|
readonly set: (action: string, value: NativeInputValue) => void;
|
|
28
47
|
readonly clear: () => void;
|
|
29
48
|
/** Optional native-scheduler operation. The adapter never synthesizes one. */
|
|
@@ -31,6 +50,12 @@ export interface NativeDebugModule {
|
|
|
31
50
|
/** Optional native-scheduler operation. The adapter never adds a host phase. */
|
|
32
51
|
readonly scheduleAtTick?: (tick: number, action: string, value: NativeInputValue) => void;
|
|
33
52
|
};
|
|
53
|
+
/** The app's own EVENT STREAM, bridged into the session's tick-stamped
|
|
54
|
+
* event log at install — the entry-export replacement for the react
|
|
55
|
+
* emit hook. The app owns the emitter; the host only forwards. */
|
|
56
|
+
readonly events?: {
|
|
57
|
+
readonly subscribe: (listener: (event: string, detail?: unknown) => void) => () => void;
|
|
58
|
+
};
|
|
34
59
|
}
|
|
35
60
|
export interface NativeDebugBinding {
|
|
36
61
|
readonly rootId: string;
|
|
@@ -40,4 +65,21 @@ export interface NativeDebugBinding {
|
|
|
40
65
|
export declare function nativeDebugBindingFromEntryModule(rootId: string, entryModule: unknown): NativeDebugBinding | null;
|
|
41
66
|
/** Project native registries onto the existing session debugger after mount. */
|
|
42
67
|
export declare function installNativeDebugBindings(game: Game, bindings: readonly NativeDebugBinding[]): void;
|
|
68
|
+
/** One root's statically declared, already-validated system-adapter slots. */
|
|
69
|
+
export interface NativeSystemsBinding {
|
|
70
|
+
readonly rootId: string;
|
|
71
|
+
readonly slots: Readonly<Partial<SystemAdapters>>;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Read the single native `systems` export from an already-loaded root module.
|
|
75
|
+
* `surface` is the root's own mount surface when the caller knows it — it
|
|
76
|
+
* feeds the physics keying check (`PHYSICS_KEYING_BY_SURFACE`).
|
|
77
|
+
*/
|
|
78
|
+
export declare function nativeSystemsBindingFromEntryModule(rootId: string, entryModule: unknown, surface?: ContractSurface | undefined): NativeSystemsBinding | null;
|
|
79
|
+
/** Install every declared binding onto the mounted Game's game-scoped slot
|
|
80
|
+
* table (`Game.installDeclaredSystemAdapters`), where the ordinary
|
|
81
|
+
* `game.systemAdapters` merge picks them up ahead of any lingering component
|
|
82
|
+
* registration for the same root. */
|
|
83
|
+
export declare function installNativeSystemsBindings(game: Game, bindings: readonly NativeSystemsBinding[]): void;
|
|
84
|
+
export {};
|
|
43
85
|
//# sourceMappingURL=native-debug-module.d.ts.map
|
|
@@ -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;
|
|
1
|
+
{"version":3,"file":"native-debug-module.d.ts","sourceRoot":"","sources":["../../src/adapter/native-debug-module.ts"],"names":[],"mappings":"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"}
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
* copy of its stores.
|
|
14
14
|
*/
|
|
15
15
|
import { DebugError, getDebugRegistry, } from '../runtime/debug-registry';
|
|
16
|
+
import { CONTRACT_SYSTEM_SLOTS, projectContractSystemAdapters, } from './ingest/contract-system-adapters';
|
|
16
17
|
export const NATIVE_INPUT_VALUE_TYPES = [
|
|
17
18
|
'digital',
|
|
18
19
|
'scalar',
|
|
@@ -61,6 +62,17 @@ function parseInput(value) {
|
|
|
61
62
|
if (!isRecord(value))
|
|
62
63
|
throw new Error('debug.input must be an object.');
|
|
63
64
|
rejectUnknownKeys(value, ['actions', 'set', 'clear', 'tap', 'scheduleAtTick'], 'debug.input');
|
|
65
|
+
if (typeof value['actions'] === 'function') {
|
|
66
|
+
// A live table: validated per read (requireAction/the actions source), not
|
|
67
|
+
// here — the whole point is that its content changes after install.
|
|
68
|
+
const set = value['set'];
|
|
69
|
+
const clear = value['clear'];
|
|
70
|
+
if (typeof set !== 'function')
|
|
71
|
+
throw new Error('debug.input.set must be a function.');
|
|
72
|
+
if (typeof clear !== 'function')
|
|
73
|
+
throw new Error('debug.input.clear must be a function.');
|
|
74
|
+
return value;
|
|
75
|
+
}
|
|
64
76
|
const set = value['set'];
|
|
65
77
|
const clear = value['clear'];
|
|
66
78
|
const tap = value['tap'];
|
|
@@ -95,11 +107,32 @@ export function nativeDebugBindingFromEntryModule(rootId, entryModule) {
|
|
|
95
107
|
throw new Error(`Root "${rootId}" exports \`debug\`, but it is not an object.`);
|
|
96
108
|
}
|
|
97
109
|
const raw = entryModule['debug'];
|
|
98
|
-
rejectUnknownKeys(raw, ['commands', 'state', 'input'], `Root "${rootId}" debug export`);
|
|
99
|
-
|
|
100
|
-
|
|
110
|
+
rejectUnknownKeys(raw, ['commands', 'state', 'input', 'events'], `Root "${rootId}" debug export`);
|
|
111
|
+
// A thunk table defers to install time (see {@link NativeTable}); a plain
|
|
112
|
+
// record validates here, where the error can still name the export.
|
|
113
|
+
const parseTable = (value, at) => {
|
|
114
|
+
if (value === undefined)
|
|
115
|
+
return undefined;
|
|
116
|
+
if (typeof value === 'function')
|
|
117
|
+
return value;
|
|
118
|
+
return functionRecord(value, at);
|
|
119
|
+
};
|
|
120
|
+
// Commands allow the `{ description?, run }` entry shape; full validation
|
|
121
|
+
// happens at install (`resolveCommandTable`), where thunks resolve too.
|
|
122
|
+
const parseCommands = (value, at) => {
|
|
123
|
+
if (value === undefined)
|
|
124
|
+
return undefined;
|
|
125
|
+
if (typeof value === 'function')
|
|
126
|
+
return value;
|
|
127
|
+
if (!isRecord(value))
|
|
128
|
+
throw new Error(`${at} must be an object of named commands.`);
|
|
129
|
+
return value;
|
|
130
|
+
};
|
|
131
|
+
const commands = parseCommands(raw['commands'], 'debug.commands');
|
|
132
|
+
const state = parseTable(raw['state'], 'debug.state');
|
|
101
133
|
const input = raw['input'] === undefined ? undefined : parseInput(raw['input']);
|
|
102
|
-
|
|
134
|
+
const events = raw['events'] === undefined ? undefined : parseEvents(raw['events']);
|
|
135
|
+
if (!commands && !state && !input && !events) {
|
|
103
136
|
throw new Error(`Root "${rootId}" exports an empty \`debug\` object.`);
|
|
104
137
|
}
|
|
105
138
|
return {
|
|
@@ -108,9 +141,42 @@ export function nativeDebugBindingFromEntryModule(rootId, entryModule) {
|
|
|
108
141
|
...(commands ? { commands } : {}),
|
|
109
142
|
...(state ? { state } : {}),
|
|
110
143
|
...(input ? { input } : {}),
|
|
144
|
+
...(events ? { events } : {}),
|
|
111
145
|
},
|
|
112
146
|
};
|
|
113
147
|
}
|
|
148
|
+
function parseEvents(value) {
|
|
149
|
+
if (!isRecord(value) || typeof value['subscribe'] !== 'function') {
|
|
150
|
+
throw new Error('debug.events must be an object with a subscribe(listener) function.');
|
|
151
|
+
}
|
|
152
|
+
return value;
|
|
153
|
+
}
|
|
154
|
+
/** Resolve a possibly-thunk COMMAND table, validating each entry's shape. */
|
|
155
|
+
function resolveCommandTable(table, at) {
|
|
156
|
+
if (table === undefined)
|
|
157
|
+
return {};
|
|
158
|
+
const raw = typeof table === 'function' ? table() : table;
|
|
159
|
+
if (!isRecord(raw))
|
|
160
|
+
throw new Error(`${at} must be an object of named commands.`);
|
|
161
|
+
for (const [name, entry] of Object.entries(raw)) {
|
|
162
|
+
if (!name)
|
|
163
|
+
throw new Error(`${at} contains an empty name.`);
|
|
164
|
+
const ok = typeof entry === 'function' ||
|
|
165
|
+
(isRecord(entry) && typeof entry.run === 'function');
|
|
166
|
+
if (!ok)
|
|
167
|
+
throw new Error(`${at}.${name} must be a function or { description?, run }.`);
|
|
168
|
+
}
|
|
169
|
+
return raw;
|
|
170
|
+
}
|
|
171
|
+
/** Resolve a possibly-thunk table at install time, validating the result. */
|
|
172
|
+
function resolveTable(table, at) {
|
|
173
|
+
if (table === undefined)
|
|
174
|
+
return {};
|
|
175
|
+
if (typeof table === 'function') {
|
|
176
|
+
return functionRecord(table(), at);
|
|
177
|
+
}
|
|
178
|
+
return table;
|
|
179
|
+
}
|
|
114
180
|
function valueMatches(type, value) {
|
|
115
181
|
if (type === 'digital')
|
|
116
182
|
return typeof value === 'boolean';
|
|
@@ -126,11 +192,14 @@ function valueMatches(type, value) {
|
|
|
126
192
|
function installInput(game, registry, binding, input) {
|
|
127
193
|
const trace = [];
|
|
128
194
|
let recording = false;
|
|
195
|
+
// LIVE read on every use — see the `actions` field's own comment.
|
|
196
|
+
const liveActions = () => typeof input.actions === 'function' ? input.actions() : input.actions;
|
|
129
197
|
const requireAction = (action, value) => {
|
|
130
|
-
const
|
|
198
|
+
const actions = liveActions();
|
|
199
|
+
const type = actions[action];
|
|
131
200
|
if (!type) {
|
|
132
201
|
throw new DebugError('INPUT_ACTION_NOT_FOUND', `Native input has no action named "${action}".`, {
|
|
133
|
-
registered: Object.keys(
|
|
202
|
+
registered: Object.keys(actions),
|
|
134
203
|
});
|
|
135
204
|
}
|
|
136
205
|
if (!valueMatches(type, value)) {
|
|
@@ -197,7 +266,7 @@ function installInput(game, registry, binding, input) {
|
|
|
197
266
|
unsupportedSource('injectPointerPosition');
|
|
198
267
|
},
|
|
199
268
|
};
|
|
200
|
-
registry.setInputActionsSource(binding.rootId, () => Object.entries(
|
|
269
|
+
registry.setInputActionsSource(binding.rootId, () => Object.entries(liveActions()).map(([name, valueType]) => ({ name, valueType })));
|
|
201
270
|
registry.setInputTraceSource(binding.rootId, () => ({
|
|
202
271
|
version: 1,
|
|
203
272
|
seed: null,
|
|
@@ -218,13 +287,62 @@ export function installNativeDebugBindings(game, bindings) {
|
|
|
218
287
|
throw new Error(`Native debug binding names unmounted root "${binding.rootId}".`);
|
|
219
288
|
}
|
|
220
289
|
const root = registry.forRoot(binding.rootId);
|
|
221
|
-
|
|
290
|
+
const state = resolveTable(binding.debug.state, `Root "${binding.rootId}" debug.state`);
|
|
291
|
+
for (const [name, read] of Object.entries(state)) {
|
|
222
292
|
root.registerStateProvider(name, read, { tier: 'assisted' });
|
|
223
293
|
}
|
|
224
|
-
|
|
225
|
-
|
|
294
|
+
const commands = resolveCommandTable(binding.debug.commands, `Root "${binding.rootId}" debug.commands`);
|
|
295
|
+
for (const [name, entry] of Object.entries(commands)) {
|
|
296
|
+
const run = typeof entry === 'function' ? entry : entry.run;
|
|
297
|
+
const description = typeof entry === 'function' ? undefined : entry.description;
|
|
298
|
+
root.registerCommand(name, { locus: 'client', ...(description === undefined ? {} : { description }) }, run);
|
|
226
299
|
}
|
|
227
300
|
if (binding.debug.input)
|
|
228
301
|
installInput(game, registry, binding, binding.debug.input);
|
|
302
|
+
// The app's emitter → the session's tick-stamped event log. The
|
|
303
|
+
// subscription's disposer is deliberately dropped: it lives exactly as
|
|
304
|
+
// long as this Game's registry does.
|
|
305
|
+
binding.debug.events?.subscribe((event, detail) => root.emit(event, detail));
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
/**
|
|
309
|
+
* Read the single native `systems` export from an already-loaded root module.
|
|
310
|
+
* `surface` is the root's own mount surface when the caller knows it — it
|
|
311
|
+
* feeds the physics keying check (`PHYSICS_KEYING_BY_SURFACE`).
|
|
312
|
+
*/
|
|
313
|
+
export function nativeSystemsBindingFromEntryModule(rootId, entryModule, surface) {
|
|
314
|
+
if (!isRecord(entryModule) || entryModule['systems'] === undefined)
|
|
315
|
+
return null;
|
|
316
|
+
const raw = entryModule['systems'];
|
|
317
|
+
if (!isRecord(raw)) {
|
|
318
|
+
throw new Error(`Root "${rootId}" exports \`systems\`, but it is not an object.`);
|
|
319
|
+
}
|
|
320
|
+
rejectUnknownKeys(raw, CONTRACT_SYSTEM_SLOTS, `Root "${rootId}" systems export`);
|
|
321
|
+
const projection = projectContractSystemAdapters({ systemAdapters: raw }, surface);
|
|
322
|
+
if (projection.malformed.length > 0) {
|
|
323
|
+
throw new Error(`Root "${rootId}" systems export is malformed: ` +
|
|
324
|
+
projection.malformed.map((slot) => `${slot.slot} — ${slot.reason}`).join('; '));
|
|
325
|
+
}
|
|
326
|
+
if (Object.keys(projection.bound).length === 0 && projection.empty.length === 0) {
|
|
327
|
+
throw new Error(`Root "${rootId}" exports an empty \`systems\` object.`);
|
|
328
|
+
}
|
|
329
|
+
return { rootId, slots: projection.bound };
|
|
330
|
+
}
|
|
331
|
+
/** Install every declared binding onto the mounted Game's game-scoped slot
|
|
332
|
+
* table (`Game.installDeclaredSystemAdapters`), where the ordinary
|
|
333
|
+
* `game.systemAdapters` merge picks them up ahead of any lingering component
|
|
334
|
+
* registration for the same root. */
|
|
335
|
+
export function installNativeSystemsBindings(game, bindings) {
|
|
336
|
+
if (bindings.length === 0)
|
|
337
|
+
return;
|
|
338
|
+
const install = game.installDeclaredSystemAdapters;
|
|
339
|
+
if (!install) {
|
|
340
|
+
throw new Error('Cannot install native systems bindings: this Game does not implement ' +
|
|
341
|
+
'installDeclaredSystemAdapters.');
|
|
342
|
+
}
|
|
343
|
+
for (const binding of bindings) {
|
|
344
|
+
if (Object.keys(binding.slots).length === 0)
|
|
345
|
+
continue;
|
|
346
|
+
install.call(game, binding.rootId, binding.slots);
|
|
229
347
|
}
|
|
230
348
|
}
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
* engine's pipeline — an imported Godot 3 GLES2 game does gamma-space lighting with no tonemapper
|
|
18
18
|
* at all, so ACES quietly desaturates and darkens every colour its author picked.
|
|
19
19
|
*
|
|
20
|
-
* So a
|
|
20
|
+
* So a mount may DECLARE the pipeline its world was authored for, and the mounting adapter applies it to the
|
|
21
21
|
* host's renderer for the life of the mount, restoring what it found on dispose. Three properties
|
|
22
22
|
* of that shape are load-bearing:
|
|
23
23
|
*
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
* engine's pipeline — an imported Godot 3 GLES2 game does gamma-space lighting with no tonemapper
|
|
18
18
|
* at all, so ACES quietly desaturates and darkens every colour its author picked.
|
|
19
19
|
*
|
|
20
|
-
* So a
|
|
20
|
+
* So a mount may DECLARE the pipeline its world was authored for, and the mounting adapter applies it to the
|
|
21
21
|
* host's renderer for the life of the mount, restoring what it found on dispose. Three properties
|
|
22
22
|
* of that shape are load-bearing:
|
|
23
23
|
*
|
|
@@ -15,28 +15,21 @@
|
|
|
15
15
|
* or the Pixi reconciler.
|
|
16
16
|
*
|
|
17
17
|
* Surface:
|
|
18
|
-
* - `createPixiReactAdapter({ id, content })` — mount a `@pixi/react` tree as
|
|
19
|
-
* a first-party `surface: "canvas"` root under the host's gated loop.
|
|
20
18
|
* - `pixiReactRootFactory` / `resolveCanvasEntryAdapter` — what a canvas entry
|
|
21
|
-
* module MEANS: a default-exported component
|
|
19
|
+
* module MEANS: a default-exported component, mounted as a first-party
|
|
20
|
+
* `surface: "canvas"` root under the host's gated loop. The world's vgai
|
|
21
|
+
* surface is its entry module's static exports
|
|
22
|
+
* (`export { debug, systems } from './commands'`), connected by the host at
|
|
23
|
+
* mount.
|
|
22
24
|
* - `PixiPrimitive` / `adoptNow` — the canvas surface's `<primitive object={…}>`:
|
|
23
25
|
* render a container the game already owns, and place a spawn in the
|
|
24
26
|
* display tree ahead of the commit that renders it.
|
|
25
|
-
* - `useGameContext()` — this root's `CanvasGameContext` (`input`, `debug`,
|
|
26
|
-
* `random`, `clock`, `game`, `roots`) from inside any component in the tree.
|
|
27
|
-
* Behavior in a canvas world is components + hooks, never a class under a
|
|
28
|
-
* string key.
|
|
29
|
-
* - `EngineBridge` / `EngineBridgeValue` — the context contract, exported for
|
|
30
|
-
* adopters building their own bridge.
|
|
31
27
|
*
|
|
32
28
|
* The Pixi runtime itself is NOT re-exported here. A component reaches the live
|
|
33
29
|
* `Application` (and therefore `stage`, `renderer`, `ticker`) with
|
|
34
30
|
* `@pixi/react`'s own `useApplication()`, ticks with its `useTick()`, and loads
|
|
35
31
|
* assets with Pixi's own `Assets` — the library's API, not a second one.
|
|
36
32
|
*/
|
|
37
|
-
export { EngineBridge, type EngineBridgeValue, useGameContext } from './engine-bridge';
|
|
38
33
|
export { adoptNow, PixiPrimitive, type PixiPrimitiveProps } from './pixi-primitive';
|
|
39
|
-
export { type CreatePixiReactAdapterOptions, createPixiReactAdapter, } from './pixi-react-adapter';
|
|
40
34
|
export { pixiReactRootFactory, resolveCanvasEntryAdapter } from './pixi-react-root-factory';
|
|
41
|
-
export { type CanvasGameContext, type CanvasRootContextOptions, type CanvasRootRuntime, createCanvasRootContext, DEFAULT_INPUT_MAP_PATH, } from './world-context';
|
|
42
35
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/canvas-react/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/canvas-react/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAEH,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,KAAK,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACpF,OAAO,EAAE,oBAAoB,EAAE,yBAAyB,EAAE,MAAM,2BAA2B,CAAC"}
|
|
@@ -15,27 +15,20 @@
|
|
|
15
15
|
* or the Pixi reconciler.
|
|
16
16
|
*
|
|
17
17
|
* Surface:
|
|
18
|
-
* - `createPixiReactAdapter({ id, content })` — mount a `@pixi/react` tree as
|
|
19
|
-
* a first-party `surface: "canvas"` root under the host's gated loop.
|
|
20
18
|
* - `pixiReactRootFactory` / `resolveCanvasEntryAdapter` — what a canvas entry
|
|
21
|
-
* module MEANS: a default-exported component
|
|
19
|
+
* module MEANS: a default-exported component, mounted as a first-party
|
|
20
|
+
* `surface: "canvas"` root under the host's gated loop. The world's vgai
|
|
21
|
+
* surface is its entry module's static exports
|
|
22
|
+
* (`export { debug, systems } from './commands'`), connected by the host at
|
|
23
|
+
* mount.
|
|
22
24
|
* - `PixiPrimitive` / `adoptNow` — the canvas surface's `<primitive object={…}>`:
|
|
23
25
|
* render a container the game already owns, and place a spawn in the
|
|
24
26
|
* display tree ahead of the commit that renders it.
|
|
25
|
-
* - `useGameContext()` — this root's `CanvasGameContext` (`input`, `debug`,
|
|
26
|
-
* `random`, `clock`, `game`, `roots`) from inside any component in the tree.
|
|
27
|
-
* Behavior in a canvas world is components + hooks, never a class under a
|
|
28
|
-
* string key.
|
|
29
|
-
* - `EngineBridge` / `EngineBridgeValue` — the context contract, exported for
|
|
30
|
-
* adopters building their own bridge.
|
|
31
27
|
*
|
|
32
28
|
* The Pixi runtime itself is NOT re-exported here. A component reaches the live
|
|
33
29
|
* `Application` (and therefore `stage`, `renderer`, `ticker`) with
|
|
34
30
|
* `@pixi/react`'s own `useApplication()`, ticks with its `useTick()`, and loads
|
|
35
31
|
* assets with Pixi's own `Assets` — the library's API, not a second one.
|
|
36
32
|
*/
|
|
37
|
-
export { EngineBridge, useGameContext } from './engine-bridge';
|
|
38
33
|
export { adoptNow, PixiPrimitive } from './pixi-primitive';
|
|
39
|
-
export { createPixiReactAdapter, } from './pixi-react-adapter';
|
|
40
34
|
export { pixiReactRootFactory, resolveCanvasEntryAdapter } from './pixi-react-root-factory';
|
|
41
|
-
export { createCanvasRootContext, DEFAULT_INPUT_MAP_PATH, } from './world-context';
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* `pixiReactRootFactory` — mount a `canvas` root whose entry module
|
|
3
|
-
* DEFAULT-EXPORTS a React component.
|
|
4
|
-
*
|
|
5
|
-
* A model asked for a 2D world writes:
|
|
3
|
+
* DEFAULT-EXPORTS a React component. This is the ONE first-party canvas mount:
|
|
6
4
|
*
|
|
7
5
|
* ```tsx
|
|
8
6
|
* export default function World() {
|
|
@@ -10,11 +8,13 @@
|
|
|
10
8
|
* }
|
|
11
9
|
* ```
|
|
12
10
|
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
11
|
+
* The world is an ordinary `@pixi/react` app. Everything vgai-shaped stays at
|
|
12
|
+
* the entry module's STATIC surface (`export { debug, systems } from
|
|
13
|
+
* './commands'`) and on the host's side of the seam; no vgai runtime context
|
|
14
|
+
* ever enters the React tree. The host advances Pixi's real (never-started)
|
|
15
|
+
* ticker on GAME time, wires the game-scoped input seams from outside
|
|
16
|
+
* (`../runtime/game-input-seams.ts`), and installs `WorldProvider` off the
|
|
17
|
+
* Game handle so the lib-legal react doors resolve.
|
|
18
18
|
*
|
|
19
19
|
* ## Why this is NOT in `mount-game.ts`
|
|
20
20
|
*
|
|
@@ -24,12 +24,28 @@
|
|
|
24
24
|
* the opt-in module that owns those dependencies, so the factory lives here and
|
|
25
25
|
* a project opts in with `registerAdapter('canvas', pixiReactRootFactory)`.
|
|
26
26
|
*
|
|
27
|
-
* ##
|
|
27
|
+
* ## The loop contract
|
|
28
|
+
*
|
|
29
|
+
* `Application` is initialized with `autoStart: false` and `sharedTicker:
|
|
30
|
+
* false`, so it owns a native Pixi ticker that is NEVER started and therefore
|
|
31
|
+
* never requests an animation frame. `mounted.update(dt)` is the only thing
|
|
32
|
+
* that advances that ticker, and it feeds GAME time, not wall time — which is
|
|
33
|
+
* what makes the world freeze exactly when the host freezes it, and what makes
|
|
34
|
+
* `game.waitSimTime` work in a hidden tab (a hidden tab has no rAF; the engine
|
|
35
|
+
* loop's own catch-up still calls `update`, and Pixi has no independent clock
|
|
36
|
+
* to disagree with it).
|
|
28
37
|
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
38
|
+
* ## Component catalogue
|
|
39
|
+
*
|
|
40
|
+
* `@pixi/react` resolves `<pixiSprite>` etc. through a module-global catalogue
|
|
41
|
+
* that starts EMPTY — the first intrinsic in an un-extended tree throws
|
|
42
|
+
* "X is not part of the PIXI namespace! Did you forget to extend?". This
|
|
43
|
+
* module extends it with the whole `pixi.js` namespace once per mount
|
|
44
|
+
* (idempotent `Object.assign`). A world that adds its own classes
|
|
45
|
+
* (`@pixi/tilemap`, a custom `Container` subclass) calls `extend`/`useExtend`
|
|
46
|
+
* itself.
|
|
31
47
|
*/
|
|
32
|
-
import type { RootAdapter } from '../adapter
|
|
48
|
+
import type { RootAdapter } from '../adapter';
|
|
33
49
|
import type { AdapterSurfaceFactory } from '../runtime/mount-game';
|
|
34
50
|
/**
|
|
35
51
|
* What a canvas entry module MEANS, in one place.
|
|
@@ -37,20 +53,17 @@ import type { AdapterSurfaceFactory } from '../runtime/mount-game';
|
|
|
37
53
|
* Two callers need this answer and must never disagree about it: the runtime
|
|
38
54
|
* mount ({@link pixiReactRootFactory}, below) and the EDITOR, which resolves
|
|
39
55
|
* the same entry for play mode and for the design-time layer. When only one
|
|
40
|
-
* side knows
|
|
41
|
-
*
|
|
42
|
-
* paid for.
|
|
56
|
+
* side knows the shape, a world plays fine and shows "(no scene loaded)" in
|
|
57
|
+
* edit mode.
|
|
43
58
|
*
|
|
44
|
-
* Returns `null` when the module
|
|
45
|
-
* to do about that (the factory throws; the editor
|
|
46
|
-
* that root's boundary node and leaves every
|
|
59
|
+
* Returns `null` when the module has no default-exported component — the
|
|
60
|
+
* callers differ on what to do about that (the factory throws; the editor
|
|
61
|
+
* reports a mount failure on that root's boundary node and leaves every
|
|
62
|
+
* sibling working).
|
|
47
63
|
*/
|
|
48
64
|
export declare function resolveCanvasEntryAdapter(entryModule: unknown, rootId: string): RootAdapter<'canvas'> | null;
|
|
49
65
|
/**
|
|
50
66
|
* Register with `registerAdapter('canvas', pixiReactRootFactory)`.
|
|
51
|
-
*
|
|
52
|
-
* Resolution order mirrors the three lane's (explicit adapter wins) and then
|
|
53
|
-
* accepts the default-exported component.
|
|
54
67
|
*/
|
|
55
68
|
export declare const pixiReactRootFactory: AdapterSurfaceFactory;
|
|
56
69
|
//# sourceMappingURL=pixi-react-root-factory.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pixi-react-root-factory.d.ts","sourceRoot":"","sources":["../../src/canvas-react/pixi-react-root-factory.tsx"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"pixi-react-root-factory.d.ts","sourceRoot":"","sources":["../../src/canvas-react/pixi-react-root-factory.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8CG;AAMH,OAAO,KAAK,EAAsC,WAAW,EAAE,MAAM,YAAY,CAAC;AAKlF,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAuQnE;;;;;;;;;;;;;GAaG;AACH,wBAAgB,yBAAyB,CACvC,WAAW,EAAE,OAAO,EACpB,MAAM,EAAE,MAAM,GACb,WAAW,CAAC,QAAQ,CAAC,GAAG,IAAI,CAI9B;AAED;;GAEG;AACH,eAAO,MAAM,oBAAoB,EAAE,qBAOlC,CAAC"}
|