@vgai/engine 0.5.16 → 0.5.17

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.
Files changed (99) hide show
  1. package/dist/adapter/adapter-module.d.ts +1 -16
  2. package/dist/adapter/adapter-module.d.ts.map +1 -1
  3. package/dist/adapter/adapter-module.js +1 -11
  4. package/dist/adapter/finders/scenes-from-entrypoint-selection.d.ts +0 -2
  5. package/dist/adapter/finders/scenes-from-entrypoint-selection.d.ts.map +1 -1
  6. package/dist/adapter/finders/scenes-from-entrypoint-selection.js +3 -6
  7. package/dist/adapter/root-adapter.d.ts +4 -0
  8. package/dist/adapter/root-adapter.d.ts.map +1 -1
  9. package/dist/adapter/root-seam-contract.d.ts +5 -0
  10. package/dist/adapter/root-seam-contract.d.ts.map +1 -1
  11. package/dist/adapter/root-seam-contract.js +1 -0
  12. package/dist/adapter/setup-three-root-adapter.js +9 -9
  13. package/dist/canvas-react/pixi-react-adapter.d.ts.map +1 -1
  14. package/dist/canvas-react/pixi-react-adapter.js +92 -41
  15. package/dist/data/curve.d.ts +1 -1
  16. package/dist/data/curve.js +2 -2
  17. package/dist/dev/instruments.d.ts +4 -4
  18. package/dist/dev/instruments.js +4 -4
  19. package/dist/dev/register-render-vitals.d.ts +2 -2
  20. package/dist/dev/register-render-vitals.js +2 -2
  21. package/dist/dev/static-batch-advisor.d.ts +1 -1
  22. package/dist/dev/static-batch-advisor.js +2 -2
  23. package/dist/input/input-manager.d.ts +15 -0
  24. package/dist/input/input-manager.d.ts.map +1 -1
  25. package/dist/input/input-manager.js +22 -0
  26. package/dist/manifest/load.d.ts +0 -3
  27. package/dist/manifest/load.d.ts.map +1 -1
  28. package/dist/manifest/load.js +0 -4
  29. package/dist/manifest/schema.d.ts +0 -2
  30. package/dist/manifest/schema.d.ts.map +1 -1
  31. package/dist/manifest/schema.js +2 -23
  32. package/dist/pixi/authoring.d.ts +33 -0
  33. package/dist/pixi/authoring.d.ts.map +1 -1
  34. package/dist/pixi/authoring.js +86 -6
  35. package/dist/react/world-state.d.ts +12 -0
  36. package/dist/react/world-state.d.ts.map +1 -1
  37. package/dist/react/world-state.js +14 -0
  38. package/dist/render/soft-particle-depth.d.ts +3 -3
  39. package/dist/render/soft-particle-depth.d.ts.map +1 -1
  40. package/dist/render/soft-particle-depth.js +8 -13
  41. package/dist/runtime/create-runtime.d.ts +2 -16
  42. package/dist/runtime/create-runtime.d.ts.map +1 -1
  43. package/dist/runtime/create-runtime.js +36 -38
  44. package/dist/runtime/dev-build.d.ts +37 -0
  45. package/dist/runtime/dev-build.d.ts.map +1 -0
  46. package/dist/runtime/dev-build.js +49 -0
  47. package/dist/runtime/game.d.ts +9 -1
  48. package/dist/runtime/game.d.ts.map +1 -1
  49. package/dist/runtime/game.js +25 -1
  50. package/dist/runtime/mount-manifest.d.ts +0 -13
  51. package/dist/runtime/mount-manifest.d.ts.map +1 -1
  52. package/dist/runtime/mount-manifest.js +1 -20
  53. package/dist/world3d-react/engine-bridge.d.ts.map +1 -1
  54. package/dist/world3d-react/engine-bridge.js +28 -3
  55. package/dist/world3d-react/index.d.ts +1 -1
  56. package/dist/world3d-react/index.js +1 -1
  57. package/dist/world3d-react/r3f-adapter.d.ts.map +1 -1
  58. package/dist/world3d-react/r3f-adapter.js +89 -14
  59. package/dist/world3d-react/r3f-root-factory.d.ts.map +1 -1
  60. package/dist/world3d-react/r3f-root-factory.js +12 -2
  61. package/dist/world3d-react/rapier-physics-bridge.d.ts +4 -4
  62. package/dist/world3d-react/rapier-physics-bridge.js +3 -3
  63. package/dist/world3d-react/world-context.d.ts +43 -0
  64. package/dist/world3d-react/world-context.d.ts.map +1 -1
  65. package/dist/world3d-react/world-context.js +89 -46
  66. package/dist-config/config.js.map +1 -1
  67. package/package.json +1 -1
  68. package/schemas/engine-capabilities.json +3 -3
  69. package/schemas/vgai-project.schema.json +1 -6
  70. package/src/adapter/adapter-module.ts +1 -25
  71. package/src/adapter/finders/scenes-from-entrypoint-selection.ts +3 -8
  72. package/src/adapter/root-adapter.ts +4 -0
  73. package/src/adapter/root-seam-contract.ts +1 -0
  74. package/src/adapter/setup-three-root-adapter.ts +9 -9
  75. package/src/canvas-react/pixi-react-adapter.tsx +98 -53
  76. package/src/data/curve.ts +2 -2
  77. package/src/dev/instruments.ts +4 -4
  78. package/src/dev/register-render-vitals.ts +2 -2
  79. package/src/dev/static-batch-advisor.ts +2 -2
  80. package/src/input/input-manager.ts +23 -0
  81. package/src/manifest/load.ts +0 -7
  82. package/src/manifest/schema.ts +2 -25
  83. package/src/pixi/authoring.ts +98 -6
  84. package/src/react/world-state.tsx +15 -0
  85. package/src/render/soft-particle-depth.ts +8 -13
  86. package/src/runtime/create-runtime.ts +38 -52
  87. package/src/runtime/dev-build.ts +49 -0
  88. package/src/runtime/game.ts +31 -2
  89. package/src/runtime/mount-manifest.ts +1 -32
  90. package/src/world3d-react/engine-bridge.ts +28 -3
  91. package/src/world3d-react/index.ts +1 -1
  92. package/src/world3d-react/r3f-adapter.tsx +87 -18
  93. package/src/world3d-react/r3f-root-factory.tsx +12 -2
  94. package/src/world3d-react/rapier-physics-bridge.tsx +4 -4
  95. package/src/world3d-react/world-context.ts +100 -51
  96. package/dist/runtime/dev-layers.d.ts +0 -34
  97. package/dist/runtime/dev-layers.d.ts.map +0 -1
  98. package/dist/runtime/dev-layers.js +0 -46
  99. package/src/runtime/dev-layers.ts +0 -46
@@ -443,22 +443,12 @@ async function createRootsGameRuntime(config) {
443
443
  // DOM-root layer shares this SAME stacking pass even though it is a `<div>`, not a
444
444
  // canvas, and carries no `hitTest` (the router never sees react entries at
445
445
  // all — see the dispatch loop below). ---
446
- // Dev layers sit TOPMOST, above every non-dev root, whatever zOrder either
447
- // declares: a dev GUI the game can paint over is not a dev GUI. Expressed as
448
- // two independent `stackOrder` passes concatenated rather than a magic
449
- // zOrder value, so `stackOrder`'s one rule (ascending zOrder, ties -> array
450
- // order) still governs WITHIN each band and nothing has to reason about what
451
- // number is "high enough".
452
446
  const claimEntries = mountSpecs.map((spec) => ({
453
447
  id: spec.id,
454
448
  zOrder: spec.zOrder ?? 0,
455
449
  hitTest: spec.hitTest,
456
- dev: spec.dev === true,
457
450
  }));
458
- const stacked = [
459
- ...stackOrder(claimEntries.filter((e) => !e.dev)),
460
- ...stackOrder(claimEntries.filter((e) => e.dev)),
461
- ];
451
+ const stacked = stackOrder(claimEntries);
462
452
  const bottomId = stacked[0]?.id;
463
453
  const kindById = new Map(mountSpecs.map((spec) => [spec.id, spec.kind]));
464
454
  const surfacesById = new Map();
@@ -473,12 +463,6 @@ async function createRootsGameRuntime(config) {
473
463
  // surface.ts`, which is the one door the capture/staleness/screenshot
474
464
  // sites now ask (ARCHITECTURE-CORE §The editor protocol, zero inference).
475
465
  surface.dataset['vgaiRootId'] = entry.id;
476
- // The capture's marker (`composite-screenshot.ts` reads exactly this
477
- // attribute): a dev layer is excluded from a play capture unless the
478
- // capture asks for it, because a contaminated "does the game look right"
479
- // frame is worthless.
480
- if (entry.dev)
481
- surface.dataset['vgaiDevLayer'] = 'true';
482
466
  if (!isReact) {
483
467
  const canvas = surface;
484
468
  canvas.width = w;
@@ -577,33 +561,47 @@ async function createRootsGameRuntime(config) {
577
561
  const retractRenderHarness = renderMode && renderModeLocation !== undefined
578
562
  ? installSessionRenderHarness(game, renderModeLocation, config.renderControl?.target)
579
563
  : undefined;
564
+ let resolveStopComplete;
565
+ const stopComplete = new Promise((resolve) => {
566
+ resolveStopComplete = resolve;
567
+ });
568
+ let stopping = false;
580
569
  function fullCleanup() {
581
- loop.stop();
582
- router.dispose();
583
- for (const entry of mountedEntries) {
584
- entry.mounted.dispose();
585
- entry.renderer?.dispose();
586
- entry.renderer?.forceContextLoss();
587
- // Remove from the element's CURRENT parent, not the mount-time
588
- // `container`: the editor's Game panel re-parents the live surfaces
589
- // when its mount element swaps (fill <-> device preset, W2c), and
590
- // `container.removeChild` would throw NotFoundError after such a move.
591
- // `container` remains the fallback for hosts whose element stand-ins
592
- // never wire `parentNode` (headless unit fixtures); an element already
593
- // detached by such a host is a no-op via the catch.
594
- try {
595
- (entry.element.parentNode ?? container).removeChild(entry.element);
596
- }
597
- catch {
598
- /* already detached — nothing to remove */
570
+ if (stopping)
571
+ return;
572
+ stopping = true;
573
+ try {
574
+ loop.stop();
575
+ router.dispose();
576
+ for (const entry of mountedEntries) {
577
+ entry.mounted.dispose();
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
+ }
599
593
  }
594
+ game.dispose();
595
+ retractDevGlobals();
596
+ retractRenderHarness?.();
597
+ }
598
+ finally {
599
+ void Promise.allSettled(mountedEntries.map((entry) => entry.mounted.disposeComplete ?? Promise.resolve())).then(() => resolveStopComplete());
600
600
  }
601
- game.dispose();
602
- retractDevGlobals();
603
- retractRenderHarness?.();
604
601
  }
605
602
  return {
606
603
  stop: fullCleanup,
604
+ stopComplete,
607
605
  // `Game.play` owns per-world pause, loop-gate, and audio-gate semantics.
608
606
  pause() {
609
607
  game.play.pause();
@@ -0,0 +1,37 @@
1
+ /**
2
+ * THE one owner of "is this a development context". Every reader that has to
3
+ * answer that question calls {@link devBuildEnabled}; there is deliberately NO
4
+ * second source of truth — not a module-level cached boolean, not a
5
+ * `globalThis` flag, not a per-host copy of the `import.meta.env` read below.
6
+ * Instrumentation that ships to players because two places disagreed about
7
+ * what "dev" means is exactly the failure this single owner exists to make
8
+ * impossible.
9
+ *
10
+ * Ownership, stated in one place (the build rule):
11
+ * - OWNER: this function. It resolves the answer; nothing else derives it.
12
+ * - SHARERS: the two three-root adapters (`adapter/setup-three-root-adapter.ts`
13
+ * and `world3d-react/r3f-adapter.tsx`), which seed live render vitals only
14
+ * under it, and the `static-batch` capability's mutation watch and `Frozen`
15
+ * warning. Any future dev-only instrument calls this too, with its own
16
+ * `override`.
17
+ * - TEARDOWN: none. This is a pure predicate over build config and one
18
+ * caller-supplied argument — it owns no resource, allocates nothing, and
19
+ * has no lifecycle to end.
20
+ *
21
+ * The three inputs, highest precedence first:
22
+ * 1. `override` — the explicit per-call answer. A headless test, a capture
23
+ * harness, or a host that knows better passes `true`/`false` and gets
24
+ * exactly that. Passing `undefined` (or omitting it) means "decide for
25
+ * me" and falls through. The editor's own preview mount is the worked
26
+ * case: it is a dev session by definition even when the editor SPA it
27
+ * runs inside is a production build.
28
+ * 2. A dev build — `import.meta.env.DEV`. The ordinary local/editor case.
29
+ * 3. A production build's EXPLICIT opt-in — `VITE_VGAI_DEV_BUILD=true`.
30
+ * Instrumenting a production bundle is a real, legitimate choice (an
31
+ * internal playtest build, a QA build), and it must be an opt-in someone
32
+ * had to type, never something a default drifts into.
33
+ *
34
+ * Anything else — a production build with no opt-in — is `false`.
35
+ */
36
+ export declare function devBuildEnabled(override?: boolean | undefined): boolean;
37
+ //# sourceMappingURL=dev-build.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dev-build.d.ts","sourceRoot":"","sources":["../../src/runtime/dev-build.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,wBAAgB,eAAe,CAAC,QAAQ,CAAC,EAAE,OAAO,GAAG,SAAS,GAAG,OAAO,CAavE"}
@@ -0,0 +1,49 @@
1
+ /**
2
+ * THE one owner of "is this a development context". Every reader that has to
3
+ * answer that question calls {@link devBuildEnabled}; there is deliberately NO
4
+ * second source of truth — not a module-level cached boolean, not a
5
+ * `globalThis` flag, not a per-host copy of the `import.meta.env` read below.
6
+ * Instrumentation that ships to players because two places disagreed about
7
+ * what "dev" means is exactly the failure this single owner exists to make
8
+ * impossible.
9
+ *
10
+ * Ownership, stated in one place (the build rule):
11
+ * - OWNER: this function. It resolves the answer; nothing else derives it.
12
+ * - SHARERS: the two three-root adapters (`adapter/setup-three-root-adapter.ts`
13
+ * and `world3d-react/r3f-adapter.tsx`), which seed live render vitals only
14
+ * under it, and the `static-batch` capability's mutation watch and `Frozen`
15
+ * warning. Any future dev-only instrument calls this too, with its own
16
+ * `override`.
17
+ * - TEARDOWN: none. This is a pure predicate over build config and one
18
+ * caller-supplied argument — it owns no resource, allocates nothing, and
19
+ * has no lifecycle to end.
20
+ *
21
+ * The three inputs, highest precedence first:
22
+ * 1. `override` — the explicit per-call answer. A headless test, a capture
23
+ * harness, or a host that knows better passes `true`/`false` and gets
24
+ * exactly that. Passing `undefined` (or omitting it) means "decide for
25
+ * me" and falls through. The editor's own preview mount is the worked
26
+ * case: it is a dev session by definition even when the editor SPA it
27
+ * runs inside is a production build.
28
+ * 2. A dev build — `import.meta.env.DEV`. The ordinary local/editor case.
29
+ * 3. A production build's EXPLICIT opt-in — `VITE_VGAI_DEV_BUILD=true`.
30
+ * Instrumenting a production bundle is a real, legitimate choice (an
31
+ * internal playtest build, a QA build), and it must be an opt-in someone
32
+ * had to type, never something a default drifts into.
33
+ *
34
+ * Anything else — a production build with no opt-in — is `false`.
35
+ */
36
+ export function devBuildEnabled(override) {
37
+ if (override !== undefined)
38
+ return override;
39
+ // `import.meta` is cast whole, not just its `.env`: this module is reachable
40
+ // from programs whose tsconfig does not pull in `vite/client` (the session
41
+ // client's, for one, which reaches the three adapter transitively), and there
42
+ // `ImportMeta` has no declared `env` at all. The cast keeps the single owner
43
+ // of the dev answer importable from ANY program rather than forcing every
44
+ // downstream tsconfig to adopt Vite's ambient types.
45
+ const env = import.meta.env;
46
+ if (env?.DEV === true)
47
+ return true;
48
+ return env?.VITE_VGAI_DEV_BUILD === 'true';
49
+ }
@@ -504,8 +504,16 @@ export interface GameInternal extends Game {
504
504
  * the conventional `/inputmaps/default.inputmap.json` (or the adapter's
505
505
  * configured `inputMapPath`); runtime additions go through
506
506
  * `ctx.input.registerAction` instead.
507
+ *
508
+ * `{ optional: true }` is the CONVENTIONAL-PATH probe a root uses when the
509
+ * project never named a map: an absent file resolves quietly (a brand-new
510
+ * scaffold declares no actions yet), pins nothing — so a sibling root may
511
+ * still declare its own map — and yields to a map another root already
512
+ * owns. A map that exists but fails to parse is as loud either way.
507
513
  */
508
- loadInputMap(path: string): Promise<void>;
514
+ loadInputMap(path: string, options?: {
515
+ optional?: boolean;
516
+ }): Promise<void>;
509
517
  /** Release game-owned resources after every mounted root has disposed. */
510
518
  dispose(): void;
511
519
  }
@@ -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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"}
@@ -318,6 +318,10 @@ export function createGame(opts) {
318
318
  input.setDebugEmit((event, detail) => debugRegistry.forRoot('(game)').emit(event, detail));
319
319
  let inputMapPath = null;
320
320
  let inputMapLoad = null;
321
+ /** In-flight/settled conventional-path probes (`loadInputMap(path, {optional})`),
322
+ * so two roots probing the same path share one fetch. Separate from
323
+ * `inputMapLoad` because a probe that found nothing declares nothing. */
324
+ const inputMapProbes = new Map();
321
325
  function requireDefaultRoot() {
322
326
  if (roots.length === 0) {
323
327
  throw new Error('Game.defaultRoot: no roots registered yet');
@@ -913,7 +917,27 @@ export function createGame(opts) {
913
917
  runFrameImpl(fixedDt, { skipRenderPhases });
914
918
  }
915
919
  },
916
- loadInputMap(path) {
920
+ loadInputMap(path, options) {
921
+ if (options?.optional === true) {
922
+ // The conventional-path probe. It never becomes the game's declared
923
+ // map unless a file was actually there, so a root that DOES name a
924
+ // map (a sibling canvas root, a later mount) is never pre-empted by a
925
+ // probe that found nothing — the competing-path throw below would
926
+ // otherwise fire on a project that declared exactly one map.
927
+ if (inputMapPath)
928
+ return inputMapLoad ?? Promise.resolve();
929
+ let probe = inputMapProbes.get(path);
930
+ if (!probe) {
931
+ probe = input.loadMapIfPresent(path).then((loaded) => {
932
+ if (loaded && !inputMapPath) {
933
+ inputMapPath = path;
934
+ inputMapLoad = Promise.resolve();
935
+ }
936
+ });
937
+ inputMapProbes.set(path, probe);
938
+ }
939
+ return probe;
940
+ }
917
941
  if (inputMapPath && inputMapPath !== path) {
918
942
  throw new Error(`Game.loadInputMap: input map is already "${inputMapPath}"; root requested "${path}". ` +
919
943
  'Input is game-owned, so roots cannot load competing maps.');
@@ -106,15 +106,6 @@ export interface MountManifestOptions {
106
106
  readonly seed?: number | undefined;
107
107
  /** Host identity for a private play run or coordinated Team Test. */
108
108
  readonly playtest?: PlaytestContext | null | undefined;
109
- /**
110
- * The explicit per-mount answer to "are dev layers enabled" — forwarded
111
- * verbatim to `devLayersEnabled` (`runtime/dev-layers.ts`), the ONE owner of
112
- * that question. Omit it and the build decides (dev build ⇒ on; production
113
- * build ⇒ off unless `VITE_VGAI_DEV_LAYERS=true`). A root declaring
114
- * `dev: true` is simply not mounted when the answer is `false`, so a shipped
115
- * build carries no dev GUI at all.
116
- */
117
- readonly devLayers?: boolean | undefined;
118
109
  /** Where to read `?vgai-seed=` from for the boot-time seed reader. Same
119
110
  * override precedent as `debugBridge.url` (defaults to `window.location`
120
111
  * when a real `window` exists; a headless caller with no override gets no
@@ -165,10 +156,6 @@ export declare function resolveManifest(raw: unknown): ResolvedGameManifest;
165
156
  * ingest }` adapter with no caller-supplied adapter, or an empty manifest all
166
157
  * throw a named `Error` identifying the world id, its kind, and what was
167
158
  * expected — never a silent skip or a partially-mounted session.
168
- *
169
- * The ONE root that IS skipped silently is a `dev: true` dev layer when dev
170
- * layers are disabled (`devLayersEnabled`) — that skip is the feature: it is
171
- * what makes a dev GUI safe to leave in the game.
172
159
  */
173
160
  export declare function mountManifestRoots(opts: MountManifestOptions): Promise<GameSession>;
174
161
  //# sourceMappingURL=mount-manifest.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"mount-manifest.d.ts","sourceRoot":"","sources":["../../src/runtime/mount-manifest.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"mount-manifest.d.ts","sourceRoot":"","sources":["../../src/runtime/mount-manifest.ts"],"names":[],"mappings":"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"}
@@ -30,7 +30,6 @@ import { loadGameManifest, } from '../manifest/load';
30
30
  import { createGameRuntime } from './create-runtime';
31
31
  import { maybeInstallDebugBridge } from './debug-bridge';
32
32
  import { getDebugRegistry } from './debug-registry';
33
- import { devLayersEnabled } from './dev-layers';
34
33
  import { getGameplayRngTrapControl } from './gameplay-rng-trap';
35
34
  import { RENDER_SEED_QUERY_PARAM } from './render-seed';
36
35
  /**
@@ -167,7 +166,6 @@ function buildRootMountSpec(world, entry) {
167
166
  id: world.id,
168
167
  zOrder: world.zOrder,
169
168
  pausable: world.pausable,
170
- dev: world.dev,
171
169
  };
172
170
  // `entry`'s `kind` is guaranteed to agree with `world.kind` past the guard
173
171
  // above (or `entry` is `undefined`) — TS can't narrow a `Record` lookup
@@ -208,10 +206,6 @@ function buildRootMountSpec(world, entry) {
208
206
  * ingest }` adapter with no caller-supplied adapter, or an empty manifest all
209
207
  * throw a named `Error` identifying the world id, its kind, and what was
210
208
  * expected — never a silent skip or a partially-mounted session.
211
- *
212
- * The ONE root that IS skipped silently is a `dev: true` dev layer when dev
213
- * layers are disabled (`devLayersEnabled`) — that skip is the feature: it is
214
- * what makes a dev GUI safe to leave in the game.
215
209
  */
216
210
  export async function mountManifestRoots(opts) {
217
211
  const manifest = resolveManifest(opts.manifest);
@@ -219,20 +213,7 @@ export async function mountManifestRoots(opts) {
219
213
  throw new Error('mountManifestRoots: manifest declares no roots — nothing to mount.');
220
214
  }
221
215
  const entries = opts.entries ?? {};
222
- // The SHIP GATE. A `dev: true` root is the game's own dev GUI; it mounts
223
- // only when dev layers are enabled, so a production build carries no dev
224
- // GUI. The answer comes from `devLayersEnabled` and nowhere else — see that
225
- // function's header for why there is exactly one owner. Dropping the root
226
- // here (rather than mounting it hidden) is deliberate: nothing of the dev
227
- // layer is constructed, so its entry module's cost and its DOM never exist
228
- // in a shipped build.
229
- const devEnabled = devLayersEnabled(opts.devLayers);
230
- const mountable = devEnabled ? manifest.roots : manifest.roots.filter((world) => !world.dev);
231
- if (mountable.length === 0) {
232
- throw new Error('mountManifestRoots: every root in this manifest is a dev layer (`dev: true`) and dev ' +
233
- 'layers are disabled for this build — there is no game to mount.');
234
- }
235
- const roots = mountable.map((world) => buildRootMountSpec(world, entries[world.id]));
216
+ const roots = manifest.roots.map((world) => buildRootMountSpec(world, entries[world.id]));
236
217
  // D15 (T-D15.1) — resolved BEFORE `createGameRuntime` (which constructs the
237
218
  // Game, and therefore `ctx.random`, before any world's `mount()`/`setup()`
238
219
  // runs — see `createGame`'s own doc comment): the seed must be baked in at
@@ -1 +1 @@
1
- {"version":3,"file":"engine-bridge.d.ts","sourceRoot":"","sources":["../../src/world3d-react/engine-bridge.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAGH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAEtD,MAAM,WAAW,iBAAiB;IAChC;;wCAEoC;IACpC,QAAQ,CAAC,GAAG,CAAC,EAAE,cAAc,GAAG,SAAS,CAAC;CAC3C;AAED,eAAO,MAAM,YAAY,mDAAgD,CAAC;AAE1E;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,cAAc,IAAI,cAAc,CAU/C"}
1
+ {"version":3,"file":"engine-bridge.d.ts","sourceRoot":"","sources":["../../src/world3d-react/engine-bridge.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAIH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAEtD,MAAM,WAAW,iBAAiB;IAChC;;wCAEoC;IACpC,QAAQ,CAAC,GAAG,CAAC,EAAE,cAAc,GAAG,SAAS,CAAC;CAC3C;AAED,eAAO,MAAM,YAAY,mDAAgD,CAAC;AAE1E;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,cAAc,IAAI,cAAc,CAkC/C"}
@@ -14,6 +14,7 @@
14
14
  * component reaches engine services.
15
15
  */
16
16
  import { createContext, useContext } from 'react';
17
+ import { useOptionalGame } from '../react/world-state';
17
18
  export const EngineBridge = createContext(null);
18
19
  /**
19
20
  * This R3F root's context, for use inside any component in the tree — an
@@ -39,10 +40,34 @@ export const EngineBridge = createContext(null);
39
40
  */
40
41
  export function useGameContext() {
41
42
  const bridge = useContext(EngineBridge);
43
+ // Read unconditionally (rules of hooks) — used only to shape the throw below.
44
+ const hostedByGame = useOptionalGame() !== null;
42
45
  if (!bridge?.ctx) {
43
- throw new Error('useGameContext(): no engine root context. This hook only works inside an R3F ' +
44
- 'root mounted by createR3FAdapter (@engine/world3d-react)check that the ' +
45
- 'component is rendered inside your world entry, not in a standalone <Canvas>.');
46
+ // NAME THE REAL CAUSE. This throw used to say "check that the component is
47
+ // rendered inside your world entry" advice a scaffolded game has already
48
+ // followed, because the shape `vgai create` produces (`export default
49
+ // function World()`) mounts as a COMPONENT ROOT and receives no vgai
50
+ // runtime context at all: `r3f-root-factory.tsx` passes
51
+ // `engineRuntime: false` deliberately, so this hook can never resolve
52
+ // there however the component is nested. A world whose first render calls
53
+ // it dies with "fiber crashed before its first commit" and a fix
54
+ // instruction that cannot work. The `Game` in scope tells the two cases
55
+ // apart: present means a vgai-mounted world, absent means no root at all.
56
+ throw new Error(hostedByGame
57
+ ? 'useGameContext(): this world mounts as a COMPONENT ROOT (the default-exported ' +
58
+ 'shape `vgai create` scaffolds) and receives no vgai runtime context — by design, ' +
59
+ 'so nesting cannot fix it. Game-scoped services are on the Game handle instead: ' +
60
+ '`useGame().input` (from @vgai/engine/react/world-state) is the game-owned ' +
61
+ "InputManager the host already loaded this project's input map into and the same " +
62
+ 'one `game.input.hold/tap` drives; `useDebugProvider`/`useDebugCommand`/' +
63
+ '`useWorldState` are the state/command doors. If this world genuinely needs the ' +
64
+ 'imperative runtime (`ctx.systems`, adapter options like `inputMapPath`), export ' +
65
+ '`adapter = createR3FAdapter({ id, content: <World/> })` from the entry instead of ' +
66
+ 'default-exporting the component.'
67
+ : 'useGameContext(): no engine root context and no Game in scope — this component is ' +
68
+ 'rendering outside any mounted vgai root (a standalone <Canvas>, a story, or a ' +
69
+ "bare test render). Mount it through your project's three root, or read services " +
70
+ 'the component root way (native hooks and project-owned state).');
46
71
  }
47
72
  return bridge.ctx;
48
73
  }
@@ -33,7 +33,7 @@
33
33
  * Deliberately NOT re-exported here: `<RapierPhysicsBridge>`
34
34
  * (`@engine/world3d-react/rapier-physics-bridge`), which registers an R3F
35
35
  * world's `@react-three/rapier` physics as the game's
36
- * `SystemAdapters.physics` — so the dev menu's colliders instrument and the
36
+ * `SystemAdapters.physics` — so the colliders instrument and the
37
37
  * editor's transform coordination can see it. It imports
38
38
  * `@react-three/rapier`, and only a world that already depends on that library
39
39
  * should pull it into its graph; a deep import keeps this barrel's peer
@@ -33,7 +33,7 @@
33
33
  * Deliberately NOT re-exported here: `<RapierPhysicsBridge>`
34
34
  * (`@engine/world3d-react/rapier-physics-bridge`), which registers an R3F
35
35
  * world's `@react-three/rapier` physics as the game's
36
- * `SystemAdapters.physics` — so the dev menu's colliders instrument and the
36
+ * `SystemAdapters.physics` — so the colliders instrument and the
37
37
  * editor's transform coordination can see it. It imports
38
38
  * `@react-three/rapier`, and only a world that already depends on that library
39
39
  * should pull it into its graph; a deep import keeps this barrel's peer
@@ -1 +1 @@
1
- {"version":3,"file":"r3f-adapter.d.ts","sourceRoot":"","sources":["../../src/world3d-react/r3f-adapter.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAWH,OAAO,EAA2B,KAAK,SAAS,EAAsB,MAAM,OAAO,CAAC;AACpF,OAAO,KAAK,EAAoB,WAAW,EAAoB,MAAM,YAAY,CAAC;AAgBlF,OAAO,EAA4B,KAAK,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AA2CvF,sEAAsE;AACtE,MAAM,WAAW,uBAAuB;IACtC,qEAAqE;IACrE,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB;;uBAEmB;IACnB,QAAQ,CAAC,OAAO,EAAE,SAAS,CAAC;IAC5B;;;;0CAIsC;IACtC,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IAClD;;;;;OAKG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC7C;;;iDAG6C;IAC7C,QAAQ,CAAC,QAAQ,CAAC,EAAE,mBAAmB,GAAG,SAAS,CAAC;CACrD;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,uBAAuB,GAAG,WAAW,CA2gB9E"}
1
+ {"version":3,"file":"r3f-adapter.d.ts","sourceRoot":"","sources":["../../src/world3d-react/r3f-adapter.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAWH,OAAO,EAA2B,KAAK,SAAS,EAAsB,MAAM,OAAO,CAAC;AACpF,OAAO,KAAK,EAAoB,WAAW,EAAoB,MAAM,YAAY,CAAC;AAgBlF,OAAO,EAA4B,KAAK,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAgDvF,sEAAsE;AACtE,MAAM,WAAW,uBAAuB;IACtC,qEAAqE;IACrE,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB;;uBAEmB;IACnB,QAAQ,CAAC,OAAO,EAAE,SAAS,CAAC;IAC5B;;;;0CAIsC;IACtC,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IAClD;;;;;OAKG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC7C;;;iDAG6C;IAC7C,QAAQ,CAAC,QAAQ,CAAC,EAAE,mBAAmB,GAAG,SAAS,CAAC;CACrD;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,uBAAuB,GAAG,WAAW,CA2kB9E"}