@volter/editor-game 0.5.68 → 0.5.70

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 (169) hide show
  1. package/NOTICE +7 -7
  2. package/contributions/autoplay.service.ts +1 -1
  3. package/contributions/build-profiles.document.tsx +1 -1
  4. package/contributions/build-progress.status.tsx +2 -2
  5. package/contributions/build.header.tsx +1 -1
  6. package/contributions/connection.status.tsx +1 -1
  7. package/contributions/coverage.service.ts +2 -2
  8. package/contributions/game-eval.command.ts +6 -6
  9. package/contributions/gameplay.command.ts +2 -2
  10. package/contributions/generations.status.tsx +1 -1
  11. package/contributions/ingest.service.ts +2 -2
  12. package/contributions/play.command.ts +6 -6
  13. package/contributions/react/react-inspector.service.ts +2 -2
  14. package/package.json +8 -8
  15. package/serving/index.ts +1 -1
  16. package/src/asset-budget/AssetBudgetPanel.tsx +1 -1
  17. package/src/asset-budget/asset-budget-model.ts +14 -14
  18. package/src/asset-budget/optimize-apply.ts +8 -8
  19. package/src/bridge/call.ts +3 -3
  20. package/src/bridge/dispatch.ts +12 -12
  21. package/src/bridge/screenshot.ts +6 -6
  22. package/src/build/BuildProfilesPanel.tsx +8 -8
  23. package/src/canvas/canvas-board/CanvasBoardDocument.tsx +2 -2
  24. package/src/canvas/canvas-board/canvas-component-board.ts +1 -1
  25. package/src/canvas/canvas-design-mount.ts +1 -1
  26. package/src/coverage/live-project-verbs.ts +3 -3
  27. package/src/coverage/native-system-coverage.ts +3 -3
  28. package/src/coverage/root-coverage.ts +2 -2
  29. package/src/coverage/session-coverage.ts +2 -2
  30. package/src/design-system-stories/InspectorNarrowBodies.stories.tsx +2 -2
  31. package/src/game-document/DevicePresetPicker.tsx +6 -6
  32. package/src/game-document/GameCaptureFrameButton.tsx +1 -1
  33. package/src/game-document/GameDocument.tsx +2 -2
  34. package/src/game-document/GamePanel.tsx +9 -9
  35. package/src/game-document/InstanceInspectorPicker.tsx +1 -1
  36. package/src/game-document/device-preview.ts +4 -4
  37. package/src/game-document/physics-debug.ts +2 -2
  38. package/src/generation/GenerationActivity.tsx +22 -22
  39. package/src/generation/GenerationGallery.css +79 -79
  40. package/src/generation/generation-documents.tsx +25 -25
  41. package/src/generation/generation-presentation.ts +1 -1
  42. package/src/host/adapter-reach.ts +1 -1
  43. package/src/host/adapter-runtime-bindings.ts +5 -5
  44. package/src/host/after-paint.ts +3 -3
  45. package/src/host/api/configurations.ts +1 -1
  46. package/src/host/authoring/canvas-runtime-recognition.ts +2 -2
  47. package/src/host/authoring/contract-hierarchy-authoring.ts +6 -6
  48. package/src/host/authoring/contract-scenes-stories.ts +5 -5
  49. package/src/host/authoring/ingest-data-writer.ts +1 -1
  50. package/src/host/authoring/ingest-source-persistence.ts +2 -2
  51. package/src/host/authoring/mount-isolated-pixi-screen.ts +1 -1
  52. package/src/host/authoring/pixi-authoring-adapter.ts +60 -4
  53. package/src/host/authoring/pixi-creatable-kinds.ts +18 -0
  54. package/src/host/authoring/pixi-live-write-target.ts +6 -5
  55. package/src/host/authoring/pixi-source-write-target.ts +5 -2
  56. package/src/host/authoring/pixi-structure-history.ts +3 -3
  57. package/src/host/binding-resolver.ts +6 -6
  58. package/src/host/browser-transpile.ts +11 -11
  59. package/src/host/canvas-preview-frames.ts +1 -1
  60. package/src/host/components/CameraAuthoringOverlay.tsx +14 -14
  61. package/src/host/components/HeaderTelemetry.tsx +11 -11
  62. package/src/host/components/PixiIsolationSceneContent.tsx +2 -2
  63. package/src/host/components/ResolutionPicker.tsx +4 -4
  64. package/src/host/components/scene-document.tsx +3 -3
  65. package/src/host/components/world-root-stage-binding.tsx +1 -1
  66. package/src/host/components/world-root-stage.ts +1 -1
  67. package/src/host/coverage/authoring-read-probe.ts +1 -1
  68. package/src/host/coverage/capability-coverage.ts +22 -22
  69. package/src/host/coverage/game-contract-seam-evidence.ts +8 -8
  70. package/src/host/coverage/project-verb-coverage.ts +1 -1
  71. package/src/host/coverage/system-adapter-coverage.ts +19 -6
  72. package/src/host/game-location-guard.ts +4 -4
  73. package/src/host/game-module-access.ts +6 -6
  74. package/src/host/game-realm-page.ts +3 -3
  75. package/src/host/game-realm-reclaim.ts +1 -1
  76. package/src/host/gameplay-recording.ts +5 -5
  77. package/src/host/gated-globals.ts +13 -13
  78. package/src/host/ingest/registry.ts +14 -14
  79. package/src/host/play-control-hook.ts +1 -1
  80. package/src/host/playwright-shim.ts +3 -3
  81. package/src/host/projection/pixi.ts +2 -2
  82. package/src/host/react-mount-runtime.ts +1 -1
  83. package/src/host/roots/canvas-root.tsx +2 -2
  84. package/src/host/roots/r3f-root.tsx +1 -1
  85. package/src/host/scene-view-drawability.ts +1 -1
  86. package/src/host/sdk/tools.ts +1 -1
  87. package/src/host/staged-projects.ts +1 -1
  88. package/src/host/stories/story-pixi-preview.ts +1 -1
  89. package/src/host/stories/story-three-preview.ts +1 -1
  90. package/src/host/three-ingest-runtime.ts +1 -1
  91. package/src/ingest/active-ingest.ts +1 -1
  92. package/src/ingest/authoring/ingest-dom-surface-authoring.ts +4 -4
  93. package/src/ingest/authoring/ingest-root-adapter.ts +11 -11
  94. package/src/ingest/capture-wait-report.ts +4 -4
  95. package/src/ingest/discovery-public-ingest.ts +4 -4
  96. package/src/ingest/dom-stub-mark.ts +1 -1
  97. package/src/ingest/entry-load.ts +1 -1
  98. package/src/ingest/game-contract-realm.ts +3 -3
  99. package/src/ingest/game-pointer-lock.ts +1 -1
  100. package/src/ingest/ingest-canvas-scene-document.tsx +2 -2
  101. package/src/ingest/ingest-evidence-hook.ts +6 -6
  102. package/src/ingest/ingest-frame-snapshot.ts +2 -2
  103. package/src/ingest/ingest-play-commands.ts +1 -1
  104. package/src/ingest/ingest-play-control.ts +11 -11
  105. package/src/ingest/ingest-render-debug.ts +5 -5
  106. package/src/ingest/ingest-siblings.ts +3 -3
  107. package/src/ingest/module-mode.ts +2 -2
  108. package/src/ingest/mount-canvas-ingest-root.ts +10 -10
  109. package/src/ingest/mount-coverage.ts +3 -3
  110. package/src/ingest/mount-dom-ingest-root.ts +7 -7
  111. package/src/ingest/mount-ingest-root.ts +11 -11
  112. package/src/ingest/mount-three-ingest-root.ts +5 -5
  113. package/src/ingest/resolve-three.ts +2 -2
  114. package/src/ingest/served-bundle.ts +6 -6
  115. package/src/ingest/served-html-boot.ts +8 -8
  116. package/src/ingest/surface-dom.ts +9 -9
  117. package/src/ingest/surface-three.ts +1 -1
  118. package/src/ingest/types.ts +1 -1
  119. package/src/ingest/unmount-ingest-root.ts +3 -3
  120. package/src/network/NetworkInspectorPanel.tsx +2 -2
  121. package/src/play/play-boot-stall.ts +1 -1
  122. package/src/play/play-mode.ts +31 -30
  123. package/src/play/play-recording.ts +12 -12
  124. package/src/play-bar/PlayBar.tsx +8 -8
  125. package/src/play-bar/PlayerCountPicker.tsx +3 -3
  126. package/src/profiler/FrameDebuggerPanel.tsx +2 -2
  127. package/src/profiler/PerformancePanel.tsx +4 -4
  128. package/src/react/design-time-react-mount.ts +5 -5
  129. package/src/react/dom-authoring-adapter.ts +3 -3
  130. package/src/react/react-inspector-section.tsx +2 -2
  131. package/src/react/react-world-authoring-adapter.ts +20 -20
  132. package/src/react/story-documents/story-documents.tsx +4 -4
  133. package/src/react/ui-component-board.ts +1 -1
  134. package/src/runtime/adapter/audio-meter.ts +1 -1
  135. package/src/runtime/adapter/ingest/contract-debug-adapter.ts +4 -4
  136. package/src/runtime/adapter/ingest/contract-system-adapters.ts +9 -9
  137. package/src/runtime/adapter/ingest/merge-debug-adapters.ts +2 -2
  138. package/src/runtime/adapter/ingest/observation-debug-adapter.ts +1 -1
  139. package/src/runtime/adapter/native-debug-module.ts +5 -5
  140. package/src/runtime/audio/pose-guard.ts +1 -1
  141. package/src/runtime/core/game-scoped-slot.ts +1 -1
  142. package/src/runtime/create-runtime.ts +15 -15
  143. package/src/runtime/debug-bridge.ts +25 -25
  144. package/src/runtime/debug-registry.ts +17 -17
  145. package/src/runtime/dev/instruments.ts +1 -1
  146. package/src/runtime/dev/performance-profiler.ts +2 -2
  147. package/src/runtime/dev/register-render-vitals.ts +2 -2
  148. package/src/runtime/dev/static-batch-advisor.ts +3 -3
  149. package/src/runtime/dev-build.ts +3 -3
  150. package/src/runtime/game.ts +5 -5
  151. package/src/runtime/input-router.ts +1 -1
  152. package/src/runtime/mount-manifest.ts +10 -10
  153. package/src/runtime/pixi/authoring.ts +1 -1
  154. package/src/runtime/pixi/ingest.ts +1 -1
  155. package/src/runtime/presentation.ts +1 -1
  156. package/src/runtime/render-control.ts +21 -21
  157. package/src/runtime/render-seed.ts +3 -3
  158. package/src/runtime/run-ticks-settled.ts +1 -1
  159. package/src/services/game-audio.ts +3 -3
  160. package/src/services/game-network.ts +4 -4
  161. package/src/three/authoring/model-asset-inspector-section.css +15 -15
  162. package/src/three/authoring/model-asset-inspector-section.tsx +7 -7
  163. package/src/three/authoring/r3f-design-session.ts +10 -10
  164. package/src/three/authoring/r3f-source-authoring-adapter.ts +5 -5
  165. package/src/three/authoring/three-authoring-adapter.ts +5 -4
  166. package/src/three/authoring/typed-three-inspector.ts +1 -1
  167. package/src/three/story-documents/three-story-documents.tsx +3 -3
  168. package/src/three/three-board/board-scene.ts +9 -9
  169. package/src/three/three-board/three-component-board.ts +1 -1
@@ -47,7 +47,7 @@ import type { ResolvedAdapter, ResolvedAdapterRoot } from '@volter/editor-projec
47
47
  import { loadGameManifest, type ResolvedGameManifest } from '@volter/editor-project/manifest/load';
48
48
 
49
49
  /** The one manifest glob. Every in-tree ingest fixture, whatever its surface. */
50
- const manifestModules = import.meta.glob('./games/*/vgai.project.json', {
50
+ const manifestModules = import.meta.glob('./games/*/volter.project.json', {
51
51
  eager: true,
52
52
  import: 'default',
53
53
  }) as Record<string, unknown>;
@@ -58,7 +58,7 @@ const manifestModules = import.meta.glob('./games/*/vgai.project.json', {
58
58
  * the editor's realm. `.d.ts` is excluded: an ambient declaration file
59
59
  * is not a module and must never become a dynamic-import chunk.
60
60
  *
61
- * `vgai.adapter.ts` is excluded too, and for a different reason: it is not a
61
+ * `volter.adapter.ts` is excluded too, and for a different reason: it is not a
62
62
  * GAME module at all. It is host-realm DECLARATION (see {@link adapterModules}),
63
63
  * read without booting anything, and a manifest that named it as an `entry` or
64
64
  * a `contractShim` would be nonsense — so it is not in the set those fields
@@ -68,15 +68,15 @@ export const entryModules = import.meta.glob([
68
68
  './games/*/*.js',
69
69
  './games/*/*.ts',
70
70
  '!./games/*/*.d.ts',
71
- '!./games/*/vgai.adapter.ts',
71
+ '!./games/*/volter.adapter.ts',
72
72
  ]) as Record<string, () => Promise<unknown>>;
73
73
 
74
74
  /**
75
- * THE ADAPTER GLOB — one `vgai.adapter.ts` per ingest game, keyed by game id.
75
+ * THE ADAPTER GLOB — one `volter.adapter.ts` per ingest game, keyed by game id.
76
76
  *
77
77
  * ARCHITECTURE-CORE §The editor protocol: "Placement follows REALM: game-realm
78
78
  * code (a shim that runs inside the game) lives with the game's bundle;
79
- * host-realm declaration (`vgai.adapter.ts`) lives where the host can import it
79
+ * host-realm declaration (`volter.adapter.ts`) lives where the host can import it
80
80
  * as a real module — a repo-vendored bundle's adapter file lives in the host's
81
81
  * in-tree registry, never inside the verbatim-served bundle." This directory IS
82
82
  * that registry, so it holds BOTH populations:
@@ -86,7 +86,7 @@ export const entryModules = import.meta.glob([
86
86
  * its bytes are served verbatim from `public/ingest/<id>/` and hashed by
87
87
  * `vendor/games/verify-unaltered.mjs`, so nothing host-owned may go there.
88
88
  *
89
- * A folder with no `vgai.project.json` is invisible to {@link manifestModules}
89
+ * A folder with no `volter.project.json` is invisible to {@link manifestModules}
90
90
  * and therefore to {@link discoverIngestEntries} — the second population adds no
91
91
  * fixtures, only declarations.
92
92
  *
@@ -98,18 +98,18 @@ export const entryModules = import.meta.glob([
98
98
  * be used to fix that file"). Vite resolves the glob statically in dev and in
99
99
  * a production build alike, so no generated dispatch table is needed.
100
100
  */
101
- const adapterModules = import.meta.glob('./games/*/vgai.adapter.ts') as Record<
101
+ const adapterModules = import.meta.glob('./games/*/volter.adapter.ts') as Record<
102
102
  string,
103
103
  () => Promise<unknown>
104
104
  >;
105
105
 
106
106
  /** The adapter module's filename — the contract's ONE spelling, host side. */
107
- const ADAPTER_FILENAME = 'vgai.adapter.ts';
107
+ const ADAPTER_FILENAME = 'volter.adapter.ts';
108
108
 
109
109
  /** This directory's repo path, so a published `modulePath` names a real file. */
110
110
  const REGISTRY_REPO_DIR = 'packages/editor/src/ingest/games';
111
111
 
112
- const ADAPTER_KEY_RE = /^\.\/games\/([^/]+)\/vgai\.adapter\.ts$/;
112
+ const ADAPTER_KEY_RE = /^\.\/games\/([^/]+)\/volter\.adapter\.ts$/;
113
113
 
114
114
  /**
115
115
  * THE LOOKUP KEY IS THE GAME ID; THE STORAGE KEY IS THE FOLDER NAME. What makes
@@ -124,8 +124,8 @@ const ADAPTER_KEY_RE = /^\.\/games\/([^/]+)\/vgai\.adapter\.ts$/;
124
124
  *
125
125
  * The invariant is therefore `folder id === the id that game's manifest
126
126
  * declares`, for BOTH populations this registry serves — in-tree fixtures
127
- * (`./games/<id>/vgai.project.json`) and public bundles
128
- * (`public/ingest/<id>/vgai.project.json`, whose registry folder holds only the
127
+ * (`./games/<id>/volter.project.json`) and public bundles
128
+ * (`public/ingest/<id>/volter.project.json`, whose registry folder holds only the
129
129
  * adapter file). It is guarded ONCE, statically, in
130
130
  * `packages/editor/test/ingest-adapter-modules.test.ts`, which reads both id
131
131
  * spaces off disk — the only realm that can, since `public/` is outside the
@@ -167,7 +167,7 @@ export const assetUrls = import.meta.glob('./games/*/assets/**', {
167
167
  import: 'default',
168
168
  }) as Record<string, string>;
169
169
 
170
- const MANIFEST_KEY_RE = /^\.\/games\/([^/]+)\/vgai\.project\.json$/;
170
+ const MANIFEST_KEY_RE = /^\.\/games\/([^/]+)\/volter\.project\.json$/;
171
171
 
172
172
  /** Folder-relative glob key for a file inside a discovered game's folder. */
173
173
  export function gameFileKey(folderId: string, relPath: string): string {
@@ -206,14 +206,14 @@ function buildEntry(folderId: string, raw: unknown): IngestEntry {
206
206
  const roots = declaredRoots(manifest);
207
207
  if (roots.length !== 1) {
208
208
  throw new Error(
209
- `ingest registry: "${folderId}/vgai.project.json" must declare exactly one root ` +
209
+ `ingest registry: "${folderId}/volter.project.json" must declare exactly one root ` +
210
210
  `(found ${roots.length}).`,
211
211
  );
212
212
  }
213
213
  const root = roots[0]!;
214
214
  if (root.adapter.type !== 'ingest') {
215
215
  throw new Error(
216
- `ingest registry: "${folderId}/vgai.project.json"'s root must be an { ingest } root ` +
216
+ `ingest registry: "${folderId}/volter.project.json"'s root must be an { ingest } root ` +
217
217
  `(found adapter identity "${root.adapter.identity}").`,
218
218
  );
219
219
  }
@@ -4,7 +4,7 @@
4
4
  * `PlayBar` renders two different transports — the native one (title "Play
5
5
  * (run game)") and the ingest one (label "Run ingested game") — and anything
6
6
  * outside the component that needs to find "the play control" was matching a
7
- * LABEL. `vgai doctor` polled for the native string as its editor-readiness
7
+ * LABEL. A probe polled for the native string as its editor-readiness
8
8
  * boundary and therefore waited out its whole timeout budget on every ingest
9
9
  * project, which renders the other one (SimCity ingest dogfood, S-6).
10
10
  *
@@ -8,7 +8,7 @@
8
8
  * `page-script` relay op constructs one per call and hands it to a
9
9
  * reconstructed step function; a real `@playwright/test` `Page` drives the SAME
10
10
  * step file when the spec runs under `PageTransport`
11
- * (`packages/vgai-live/src/game-client/client.ts`) in CI. That duality is why
11
+ * (`packages/volter-live/src/game-client/client.ts`) in CI. That duality is why
12
12
  * `createPageShim`'s return value is typed `as Page` — every implemented member
13
13
  * matches Playwright's own shape closely enough that a step written against it
14
14
  * compiles against the real type too.
@@ -41,7 +41,7 @@
41
41
  * under both `PageTransport` (real Playwright, real closures) and
42
42
  * `RelayTransport` (this shim, serialized) must be written as though ALWAYS
43
43
  * serialized — inline every value the step needs; see
44
- * `packages/vgai-live/src/game-client/client.ts`'s `GameClient.page()` doc comment for
44
+ * `packages/volter-live/src/game-client/client.ts`'s `GameClient.page()` doc comment for
45
45
  * the client-facing half of this contract.
46
46
  */
47
47
 
@@ -61,7 +61,7 @@ export class PageShimUnsupportedError extends Error {
61
61
  `playwright-shim: ${objectName}.${member} is not supported by the in-page shim. ` +
62
62
  `Supported ${objectName} members: ${supported.join(', ')}. ` +
63
63
  'This shim is DOM-only — canvas gameplay input must use game.input.*, while React-only ' +
64
- 'DOM games may use Page keyboard/locator input. See packages/editor/src/playwright-shim.ts for ' +
64
+ 'DOM games may use Page keyboard/locator input. See packages/editor-game/src/host/playwright-shim.ts for ' +
65
65
  "the full supported subset and the wire's closure-capture limitation.",
66
66
  );
67
67
  this.name = 'PageShimUnsupportedError';
@@ -179,8 +179,8 @@ export class PixiProjector {
179
179
  if (rect.width <= 0 || rect.height <= 0) return null;
180
180
  const mapped = this.mapping?.pointFromClient?.(clientX, clientY, rect) ?? null;
181
181
  if (this.mapping?.pointFromClient) return mapped;
182
- const logicalWidth = Number(surface.dataset?.['vgaiStageWidth'] ?? rect.width);
183
- const logicalHeight = Number(surface.dataset?.['vgaiStageHeight'] ?? rect.height);
182
+ const logicalWidth = Number(surface.dataset?.['volterStageWidth'] ?? rect.width);
183
+ const logicalHeight = Number(surface.dataset?.['volterStageHeight'] ?? rect.height);
184
184
  if (!(logicalWidth > 0) || !(logicalHeight > 0)) return null;
185
185
  return {
186
186
  x: (clientX - rect.left) * (logicalWidth / rect.width),
@@ -54,7 +54,7 @@ function staticReactRootMountRuntime(): ReactRootMountRuntime {
54
54
 
55
55
  /**
56
56
  * Import + shape-check the packaged runtime's synthetic
57
- * `/__vgai-react-world-runtime` module (`vite-plugin-module-doorways.ts`,
57
+ * `/__volter-react-world-runtime` module (`vite-plugin-module-doorways.ts`,
58
58
  * registered only by `packaged.ts`'s project-rooted Vite instance and by
59
59
  * `vitest.config.ts` for test coverage — never by `dev.ts`/the root
60
60
  * `vite.config.ts`). A loud, named failure if the module resolves but is
@@ -134,7 +134,7 @@ function canvasWorldAdapter(
134
134
  throw new Error(
135
135
  `canvas world "${id}": this lane has already mounted this canvas. @pixi/react keys ` +
136
136
  'its reconciler roots off the canvas element, so re-using one would resurrect a ' +
137
- 'root whose Application is destroyed. Hand each mount a fresh canvas (every vgai ' +
137
+ 'root whose Application is destroyed. Hand each mount a fresh canvas (every volter ' +
138
138
  'host already does).',
139
139
  );
140
140
  }
@@ -308,7 +308,7 @@ function canvasWorldAdapter(
308
308
  mountedApp.ticker.update(elapsedMs);
309
309
  },
310
310
  // Pixi's own hit test finds only interactive objects (`eventMode` static or dynamic), so a
311
- // HUD claims its buttons and lets every other point fall through to the world beneath.
311
+ // 2D layer claims its tappable objects and lets every other point fall through to the world beneath.
312
312
  hitTest(x: number, y: number): boolean {
313
313
  if (disposed) return false;
314
314
  // Pixi points its boundary at the last rendered scene inside each of its own pointer
@@ -208,7 +208,7 @@ function threeWorldAdapter(id: string, component: ComponentType, runtime: R3FRun
208
208
  Fragment,
209
209
  null,
210
210
  content,
211
- createElement(MountEffectsReady, { key: 'vgai-mount-effects-ready' }),
211
+ createElement(MountEffectsReady, { key: 'volter-mount-effects-ready' }),
212
212
  );
213
213
  // A reconcile-time crash (e.g. a missing `extend` catalogue entry)
214
214
  // surfaces as an uncaught window error and `onCreated` never fires —
@@ -21,7 +21,7 @@
21
21
  * throw, attributes it to that scene, and stops re-throwing it forever.
22
22
  *
23
23
  * The game is NOT lost when this fires: its own renderer keeps drawing into its
24
- * own canvas, which the host adopted, so the Game tab and `vgai screenshot`
24
+ * own canvas, which the host adopted, so the Game tab and `volter-game-editor screenshot`
25
25
  * show the real thing. What is lost is the editor-camera Scene view of it,
26
26
  * which is exactly what the message says.
27
27
  */
@@ -5,7 +5,7 @@
5
5
  * input/result schemas, structured error codes, and the metadata a caller reads
6
6
  * before invoking (`permission`, `host`, `mutates`, `supportsDryRun`). The
7
7
  * contract exists because a tool is called across a process boundary — CLI to
8
- * editor to node host, and `vgai mcp` to an external agent over stdio — where
8
+ * editor to node host, and `volter mcp` to an external agent over stdio — where
9
9
  * you cannot throw. `ToolRegistry.dispatch` turns every expected failure
10
10
  * (unknown name, bad input, an `impl` throw, a bad return) into a typed outcome
11
11
  * instead.
@@ -20,5 +20,5 @@ export function isSafeIngestId(id: string): boolean {
20
20
  }
21
21
 
22
22
  export function publicIngestManifestUrl(id: string): string {
23
- return `${PUBLIC_INGEST_BASE}${id}/vgai.project.json`;
23
+ return `${PUBLIC_INGEST_BASE}${id}/volter.project.json`;
24
24
  }
@@ -350,7 +350,7 @@ const FIRST_FRAME_TIMEOUT_MS = PIXI_MOUNT_TIMEOUT_MS;
350
350
  * Wait until every collected `Application` has PRESENTED a frame with content
351
351
  * in it — the readiness test a capture of a canvas story owes itself.
352
352
  *
353
- * MEASURED DEFECT (this is why the function exists): `vgai screenshot
353
+ * MEASURED DEFECT (this is why the function exists): `volter-game-editor screenshot
354
354
  * <file>.stories.tsx` photographed a `@pixi/react` story blank. The capture
355
355
  * lane's own readiness test is "the container has committed child nodes", and
356
356
  * `<Application>` commits its `<canvas>` on the FIRST commit — before
@@ -150,7 +150,7 @@ export interface MountedStoryObject3D {
150
150
 
151
151
  /** The name of the wrapper `<group>` every story is rendered into, so its root
152
152
  * `Object3D` can be extracted unambiguously from fiber's scene. */
153
- export const PREVIEW_ROOT_NAME = 'vgai:story-preview-root';
153
+ export const PREVIEW_ROOT_NAME = 'volter:story-preview-root';
154
154
 
155
155
  /** How long to wait for fiber's first commit before giving up. The LAST-RESORT
156
156
  * ceiling only: a reconcile-time crash is now caught by
@@ -4,7 +4,7 @@
4
4
  * `canvas-entry-runtime.ts`'s `resolveCanvasPixiForEditor`.
5
5
  *
6
6
  * See `../vite-plugin-module-doorways.ts` for the measured failure this
7
- * closes and for why the ingest lane does not borrow `/__vgai-r3f-runtime`.
7
+ * closes and for why the ingest lane does not borrow `/__volter-r3f-runtime`.
8
8
  *
9
9
  * A mount site resolves this ONCE and hands what it gets to everything it
10
10
  * builds for that game. Nothing further down reaches for a static import: a
@@ -108,7 +108,7 @@ export type ActiveIngest = (
108
108
  ) & {
109
109
  siblings: SiblingMount[];
110
110
  /** The mounted world's id — the SAME id every log line and the
111
- * `__vgaiIngest` hook's `gameId` names. Carried on the slot (rather than
111
+ * `__volterIngest` hook's `gameId` names. Carried on the slot (rather than
112
112
  * re-derived) so the status facet can report WHICH world is live
113
113
  * without a second source of truth (S-1). */
114
114
  worldId: string;
@@ -20,7 +20,7 @@ import {
20
20
  walkOidTree,
21
21
  } from '../../react/react-world-authoring-adapter';
22
22
  import type { AuthoringAdapter } from '@volter/editor-project/adapter';
23
- import type { VgaiGameContract } from '@volter/editor-project/adapter/ingest/game-contract';
23
+ import type { VolterGameContract } from '@volter/editor-project/adapter/ingest/game-contract';
24
24
 
25
25
  type ReadableDomRoot = OverlayElement & DomElementLike & { readonly ownerDocument?: Document };
26
26
 
@@ -50,7 +50,7 @@ function iframeDocumentRoot(hostEl: HTMLElement): ReadableDomRoot | null {
50
50
 
51
51
  function resolveGameDomRoot(
52
52
  hostEl: HTMLElement,
53
- declaredRoot: VgaiGameContract['root'] | undefined,
53
+ declaredRoot: VolterGameContract['root'] | undefined,
54
54
  ): ReadableDomRoot | null {
55
55
  if (isReadableDomRoot(declaredRoot)) return declaredRoot;
56
56
  return iframeDocumentRoot(hostEl) ?? (isReadableDomRoot(hostEl) ? hostEl : null);
@@ -143,7 +143,7 @@ export function withDetectedDomSurface(args: {
143
143
  primary: AuthoringAdapter;
144
144
  worldId: string;
145
145
  hostEl: HTMLElement;
146
- declaredRoot?: VgaiGameContract['root'];
146
+ declaredRoot?: VolterGameContract['root'];
147
147
  store: EditorShellStore;
148
148
  }): AuthoringAdapter {
149
149
  const gameRoot = resolveGameDomRoot(args.hostEl, args.declaredRoot);
@@ -158,7 +158,7 @@ export function withDetectedDomSurface(args: {
158
158
  // refuse every detected DOM sibling before the ingest could mount.
159
159
  const domUiJournalId = `${args.worldId}/dom-ui`;
160
160
  const liveUiRoot: DomElementLike & OidElementLike = {
161
- tagName: 'vgai-dom-surface',
161
+ tagName: 'volter-dom-surface',
162
162
  id: '',
163
163
  className: '',
164
164
  get children() {
@@ -385,7 +385,7 @@ function bootWindowPageErrors(startedAt: number): string[] {
385
385
  /**
386
386
  * Wait for the game's world to be BUILT, declaration first.
387
387
  *
388
- * A game that declares `window.vgaiGame.ready` is awaited exactly once and the
388
+ * A game that declares `window.volterGame.ready` is awaited exactly once and the
389
389
  * measured poll never runs — the game states when it is done, so the host has
390
390
  * nothing to estimate. Everything else keeps {@link waitForSceneToSettle},
391
391
  * which is the MEASURED fallback and is labelled as such wherever readiness is
@@ -408,7 +408,7 @@ async function awaitWorldReady(
408
408
  return 'declared';
409
409
  } catch (err) {
410
410
  editorConsole.error(
411
- `Ingest game "${gameId}" declared \`window.vgaiGame.ready\` and it REJECTED (${String(err)}) ` +
411
+ `Ingest game "${gameId}" declared \`window.volterGame.ready\` and it REJECTED (${String(err)}) ` +
412
412
  '— the world was already captured, so the host fell back to the measured settle wait. ' +
413
413
  'This root now reports readiness as measured.',
414
414
  'ingest',
@@ -442,8 +442,8 @@ async function waitForSceneToSettle(scene: THREE.Scene, maxMs = 5000): Promise<v
442
442
  * Some games append their canvas to `document.body` — reparent it into the
443
443
  * host. A DOM-hybrid game (React/R3F with HTML UI: HUDs, overlay panels, drei
444
444
  * `<Html>` portals) can declare the element that OWNS its canvas via
445
- * `window.vgaiGame.root` (the declared game→host contract, game-contract.ts;
446
- * `__vgaiGameRoot` is the pre-contract alias). Adopting only the bare canvas
445
+ * `window.volterGame.root` (the declared game→host contract, game-contract.ts;
446
+ * `__volterGameRoot` is the pre-contract alias). Adopting only the bare canvas
447
447
  * would strand that UI at page level over the editor chrome, and following the
448
448
  * canvas would require the game to know host layout internals — an arcane
449
449
  * demand. Adopt the declared root wholesale so the game's own DOM structure
@@ -472,7 +472,7 @@ function adoptGameDomRoot(hostEl: HTMLElement, surface: HTMLElement): HTMLElemen
472
472
  const realmWindow = ingestGameRealmWindow();
473
473
  const declaredRoot =
474
474
  readIngestGameContract()?.root ??
475
- (realmWindow as unknown as { __vgaiGameRoot?: unknown }).__vgaiGameRoot;
475
+ (realmWindow as unknown as { __volterGameRoot?: unknown }).__volterGameRoot;
476
476
  const declared =
477
477
  declaredRoot instanceof HTMLElement && declaredRoot.contains(surface) ? declaredRoot : surface;
478
478
  if (declared.contains(hostEl)) return hostEl;
@@ -516,7 +516,7 @@ export async function mountIngestGame(
516
516
  // Host policy, not per-game CSS — see `game-realm-page.ts` for the four
517
517
  // page-shaped assumptions this covers and why each one breaks an in-realm
518
518
  // mount. Registered on the DEFAULT realm because an ingest descriptor's
519
- // module urls carry no `?vgai-mount=` (binding-resolver.ts's
519
+ // module urls carry no `?volter-mount=` (binding-resolver.ts's
520
520
  // `resolveIngestDescriptor` builds bare `fsImportPath` urls).
521
521
  const realmPage = setGameSurface(hostEl);
522
522
 
@@ -614,10 +614,10 @@ export async function mountIngestGame(
614
614
  // Signal COLD MOUNT before the entry executes: editor mounts are for
615
615
  // inspection first, so a session-driven game MAY defer its side-effects
616
616
  // (backend connection, narrative, audio) until the editor's play control
617
- // dispatches 'vgai:ingest-play' (getIngestPlayControl, ingest/mount-ingest-root.ts).
617
+ // dispatches 'volter:ingest-play' (getIngestPlayControl, ingest/mount-ingest-root.ts).
618
618
  // Rendering must continue regardless — capture needs a frame — and games
619
619
  // that ignore the flag behave exactly as before (opt-in, never demanded).
620
- (window as unknown as { __vgaiMountCold?: boolean }).__vgaiMountCold = true;
620
+ (window as unknown as { __volterMountCold?: boolean }).__volterMountCold = true;
621
621
  // THE BOOT WINDOW OPENS HERE (M29). Everything the page throws from this
622
622
  // instant until the mount resolves belongs to this game's boot, and it is the
623
623
  // fact that separates "crashed before ready" from "never became ready" — the
@@ -650,7 +650,7 @@ export async function mountIngestGame(
650
650
  // boots in the background parks here instead of dying, with the trap still
651
651
  // installed, so the first frame after the human foregrounds the tab is the
652
652
  // captured one. `setCaptureWait` is what keeps that park from reading as a
653
- // hung mount — `vgai status` names it.
653
+ // hung mount — `volter-game-editor status` names it.
654
654
  rt = await capture.waitForCapture({
655
655
  timeoutMs,
656
656
  onWait: (wait) => setCaptureWait(game.id, wait),
@@ -797,10 +797,10 @@ export async function mountIngestGame(
797
797
  // well after `setPaused` returned. Nothing else would notify the store, and
798
798
  // `collectState` is push-based — the control API would keep serving a
799
799
  // snapshot taken before the measurement existed, reporting `loop: null`
800
- // forever. Broadcast so `vgai status` sees the verdict it just produced.
800
+ // forever. Broadcast so `volter-game-editor status` sees the verdict it just produced.
801
801
  onVerdict: () => store.shell.notifyIngestEdit(),
802
802
  });
803
- // The game's DECLARED system surface (`window.vgaiGame.systems`), projected
803
+ // The game's DECLARED system surface (`window.volterGame.systems`), projected
804
804
  // onto the host's ordinary `SystemAdapters.debug`. `activateCapturedThreeIngest`
805
805
  // hands `mounted.systems` straight to `setActiveSystems`, so a shim that
806
806
  // declares verbs makes `game.commands()`/`game.state()` work through the same
@@ -7,13 +7,13 @@
7
7
  * background — the normal human path — no longer burns its window unable to
8
8
  * draw. What it does instead is WAIT, potentially for as long as the human
9
9
  * takes to come back to the tab, and a wait is exactly the state every door
10
- * used to report as silence: nothing mounted, nothing failed, `vgai status`
10
+ * used to report as silence: nothing mounted, nothing failed, `volter-game-editor status`
11
11
  * counting down a clock that was not running. So the wait is published:
12
- * `collectState`'s `ingestCaptureWait` carries it, and `vgai status` prints
12
+ * `collectState`'s `ingestCaptureWait` carries it, and `volter-game-editor status` prints
13
13
  * "waiting for first visible frame — tab is hidden" instead of a countdown.
14
14
  *
15
15
  * A LIVE VIEW, never a snapshot — same rule as `IngestMount.realmLoopVerdict`
16
- * and the `__vgaiIngest` hook's `reflected`/`sceneChildren`: the elapsed
16
+ * and the `__volterIngest` hook's `reflected`/`sceneChildren`: the elapsed
17
17
  * numbers move on their own, so a frozen copy starts lying the instant it is
18
18
  * taken. The slot holds the window itself and derives the report at read time.
19
19
  *
@@ -27,7 +27,7 @@
27
27
  import { notifyLiveSessionsChanged } from '@volter/editor-sdk/kit/live-session-registry';
28
28
  import type { VisibleCaptureWindow } from '@volter/threejs-runtime/adapter/ingest/visible-capture-window';
29
29
 
30
- /** The wait as `vgai status` reports it. */
30
+ /** The wait as `volter-game-editor status` reports it. */
31
31
  export interface CaptureWaitStatus {
32
32
  /** The world whose first frame is being waited for. */
33
33
  readonly worldId: string;
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * The three sibling of `surface-canvas.ts` (the pixi lane, which is the idiom
5
5
  * benchmark this file is modelled on): a game vendored under
6
- * `public/ingest/<id>/` carries its own declarative `vgai.project.json`, and
6
+ * `public/ingest/<id>/` carries its own declarative `volter.project.json`, and
7
7
  * its id resolves it into the SAME `IngestGame` descriptor every other three
8
8
  * ingest route produces. Adding a fourth vendored game is a folder plus a
9
9
  * manifest — no edit to this file, no per-game page, no branch anywhere.
@@ -81,7 +81,7 @@ function readVendoredIngestRoot(
81
81
  const roots = declaredRoots(manifest);
82
82
  if (roots.length !== 1) {
83
83
  throw new Error(
84
- `vendored ingest discovery: "${folderId}/vgai.project.json" must declare exactly one root ` +
84
+ `vendored ingest discovery: "${folderId}/volter.project.json" must declare exactly one root ` +
85
85
  `(found ${roots.length}).`,
86
86
  );
87
87
  }
@@ -92,7 +92,7 @@ function readVendoredIngestRoot(
92
92
  root.adapter.identity !== expect.identity
93
93
  ) {
94
94
  throw new Error(
95
- `vendored ingest discovery: "${folderId}/vgai.project.json" must declare one ` +
95
+ `vendored ingest discovery: "${folderId}/volter.project.json" must declare one ` +
96
96
  `${expect.surface} { ingest } root (found surface "${root.surface}", adapter identity ` +
97
97
  `"${root.adapter.identity}").`,
98
98
  );
@@ -161,7 +161,7 @@ export function buildPublicCanvasIngestGame(
161
161
  }
162
162
 
163
163
  /**
164
- * Resolve a vendored game id against `public/ingest/<id>/vgai.project.json`.
164
+ * Resolve a vendored game id against `public/ingest/<id>/volter.project.json`.
165
165
  *
166
166
  * `null` means "no such vendored three ingest" (no manifest served at that
167
167
  * path) — the caller falls through to its own unknown-id report. A manifest
@@ -4,4 +4,4 @@
4
4
  * page can retire the stub whose id it supplies itself (`served-html-boot.ts`).
5
5
  * Shared here because the two sides must agree on one mark.
6
6
  */
7
- export const DOM_STUB_MARK = 'vgaiDomStub';
7
+ export const DOM_STUB_MARK = 'volterDomStub';
@@ -3,7 +3,7 @@
3
3
  * editor's realm, preceded by the host-added contract module the manifest names
4
4
  * in `ingest.contractShim` when it declares one.
5
5
  *
6
- * ORDER IS THE WHOLE CONTRACT. The shim assigns `window.vgaiGame` synchronously
6
+ * ORDER IS THE WHOLE CONTRACT. The shim assigns `window.volterGame` synchronously
7
7
  * at top level (see the field's schema description), so it must be evaluated
8
8
  * BEFORE the game's entry — a game that reads the declaration during its own
9
9
  * module evaluation would otherwise see nothing, and a shim that lazily
@@ -1,13 +1,13 @@
1
1
  import { gameRealmForMountId } from '../host/gated-globals';
2
2
  import {
3
3
  readGameContract,
4
- type VgaiGameContract,
4
+ type VolterGameContract,
5
5
  } from '@volter/editor-project/adapter/ingest/game-contract';
6
6
 
7
7
  /**
8
8
  * The browser realm used by the singleton ingest routes.
9
9
  *
10
- * Vendored ingest entry graphs deliberately carry no `?vgai-mount=` query:
10
+ * Vendored ingest entry graphs deliberately carry no `?volter-mount=` query:
11
11
  * they share the editor's Pixi/Three packages and run in the default gated
12
12
  * realm. Realm hardening keeps game-owned expandos on that realm's window
13
13
  * proxy, so host code must read the contract from the same proxy rather than
@@ -28,7 +28,7 @@ export function ingestGameRealmWindow(): Window {
28
28
  * reached by every `bridge-call`) degrading instead of throwing
29
29
  * `window is not defined` at them.
30
30
  */
31
- export function readIngestGameContract(): VgaiGameContract | null {
31
+ export function readIngestGameContract(): VolterGameContract | null {
32
32
  if (typeof window === 'undefined') return null;
33
33
  return readGameContract(ingestGameRealmWindow());
34
34
  }
@@ -59,7 +59,7 @@ export function installGamePointerLockGate(): void {
59
59
  if (entry && !entry.gate()) {
60
60
  // A NEW native console.error site, suppressed to keep this task's diff at
61
61
  // zero new lint warnings — and native on purpose: this fires from a game's
62
- // own click handler in the page, and the page console is what `vgai
62
+ // own click handler in the page, and the page console is what `volter-game-editor
63
63
  // status` reads.
64
64
  // biome-ignore lint/suspicious/noConsole: see comment above
65
65
  console.error(
@@ -136,8 +136,8 @@ export function IngestCanvasSceneContent({
136
136
  <div
137
137
  ref={containerRef}
138
138
  data-testid="world-document:ingest-canvas-scene"
139
- data-vgai-backdrop-color={active ? CANVAS_SCENE_BACKGROUND : undefined}
140
- data-vgai-backdrop-policy={active ? 'dark-frost' : undefined}
139
+ data-volter-backdrop-color={active ? CANVAS_SCENE_BACKGROUND : undefined}
140
+ data-volter-backdrop-policy={active ? 'dark-frost' : undefined}
141
141
  style={{
142
142
  position: 'absolute',
143
143
  inset: 0,
@@ -1,7 +1,7 @@
1
1
  /**
2
- * The `__vgaiIngest` / `__vgaiIngest2D` / `__vgaiIngestReact` dev hooks: the
2
+ * The `__volterIngest` / `__volterIngest2D` / `__volterIngestReact` dev hooks: the
3
3
  * headless-readable evidence a live ingest mount publishes for automation,
4
- * screenshots and `vgai doctor`.
4
+ * screenshots and probes.
5
5
  *
6
6
  * Everything here is EVIDENCE, not control: names read off the live adapter,
7
7
  * counters read off the live gate, the coverage report re-derived on demand.
@@ -18,7 +18,7 @@ import type { IngestMount } from './authoring/ingest-root-adapter';
18
18
  import { ingestCoverageReport } from './mount-coverage';
19
19
 
20
20
  /** The window key each surface's mount publishes its evidence under. */
21
- export type IngestHookKey = '__vgaiIngest' | '__vgaiIngest2D' | '__vgaiIngestReact';
21
+ export type IngestHookKey = '__volterIngest' | '__volterIngest2D' | '__volterIngestReact';
22
22
 
23
23
  const AUTHORING_PROVIDER_KEYS = [
24
24
  'hierarchy',
@@ -57,7 +57,7 @@ export function ingestHookEvidence(adapter: AuthoringAdapter): Record<string, un
57
57
  }
58
58
 
59
59
  /**
60
- * The loop fields the `__vgaiIngest` dev hook publishes — the measured verdict
60
+ * The loop fields the `__volterIngest` dev hook publishes — the measured verdict
61
61
  * plus the gate's own counters, so automation can drive Play/Pause/Step through
62
62
  * exactly the seam the editor's own buttons use rather than a parallel one.
63
63
  */
@@ -85,10 +85,10 @@ export function defineLoopHookFields(target: Record<string, unknown>, mount: Ing
85
85
 
86
86
  /**
87
87
  * D-L1 — the LIVE value behind
88
- * `__vgaiIngestReact.domEvidence()`, shared by both react ingest routes.
88
+ * `__volterIngestReact.domEvidence()`, shared by both react ingest routes.
89
89
  * Evaluated at scrape time (a function result, never memoized),
90
90
  * same "read the live state fresh on every call" discipline as
91
- * `__vgaiSiblingMounts` (D-H1).
91
+ * `__volterSiblingMounts` (D-H1).
92
92
  *
93
93
  * `elementCount` prefers the DOM's real `querySelectorAll('*').length` — a
94
94
  * real browser `HTMLElement` (what `reactRoot()` actually returns in
@@ -1,12 +1,12 @@
1
1
  /**
2
- * SAME-FRAME PIXELS for an ingested game's canvas — the reason `vgai
2
+ * SAME-FRAME PIXELS for an ingested game's canvas — the reason `volter-game-editor
3
3
  * screenshot` no longer returns black over a running ingest.
4
4
  *
5
5
  * ## The failure
6
6
  *
7
7
  * `composite-screenshot.ts` reads a game's canvas with `drawImage`, and that
8
8
  * only works on a WebGL canvas whose context was created with
9
- * `preserveDrawingBuffer: true`. Every canvas the vgai RUNTIME mounts sets it
9
+ * `preserveDrawingBuffer: true`. Every canvas the volter RUNTIME mounts sets it
10
10
  * (`@volter/editor-game/runtime/create-runtime`), which is why the composite leg has always
11
11
  * worked for first-party play. An INGESTED game creates its own canvas: the
12
12
  * racing-game's `<Canvas>` passes no `gl` prop, so fiber's default
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Relay play-control dispatch for an INGEST session — the SimCity ledger's S-2
3
- * ("`vgai play` destroys a working source-mount").
3
+ * ("`volter-game-editor play` destroys a working source-mount").
4
4
  *
5
5
  * ## The defect
6
6
  *