@volter/editor-game 0.5.67 → 0.5.69

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 (173) hide show
  1. package/NOTICE +7 -7
  2. package/contributions/autoplay.service.ts +1 -1
  3. package/contributions/build-player.document.tsx +95 -0
  4. package/contributions/build-profiles.document.tsx +1 -1
  5. package/contributions/build-progress.status.tsx +2 -2
  6. package/contributions/build.header.tsx +1 -1
  7. package/contributions/connection.status.tsx +1 -1
  8. package/contributions/coverage.service.ts +2 -2
  9. package/contributions/game-eval.command.ts +6 -6
  10. package/contributions/gameplay.command.ts +2 -2
  11. package/contributions/generations.status.tsx +1 -1
  12. package/contributions/ingest.service.ts +2 -2
  13. package/contributions/play.command.ts +6 -6
  14. package/contributions/react/react-inspector.service.ts +1 -1
  15. package/package.json +9 -8
  16. package/serving/index.ts +1 -1
  17. package/src/asset-budget/AssetBudgetPanel.tsx +1 -1
  18. package/src/asset-budget/asset-budget-model.ts +14 -14
  19. package/src/asset-budget/optimize-apply.ts +8 -8
  20. package/src/bridge/call.ts +3 -3
  21. package/src/bridge/dispatch.ts +12 -12
  22. package/src/bridge/screenshot.ts +6 -6
  23. package/src/build/BuildProfilesPanel.tsx +19 -8
  24. package/src/build/build-session.ts +35 -0
  25. package/src/canvas/canvas-board/CanvasBoardDocument.tsx +78 -5
  26. package/src/canvas/canvas-board/canvas-component-board.ts +1 -1
  27. package/src/canvas/canvas-design-mount.ts +1 -1
  28. package/src/coverage/live-project-verbs.ts +3 -3
  29. package/src/coverage/native-system-coverage.ts +3 -3
  30. package/src/coverage/root-coverage.ts +2 -2
  31. package/src/coverage/session-coverage.ts +2 -2
  32. package/src/design-system-stories/InspectorNarrowBodies.stories.tsx +2 -2
  33. package/src/game-document/DevicePresetPicker.tsx +6 -6
  34. package/src/game-document/GameCaptureFrameButton.tsx +1 -1
  35. package/src/game-document/GameDocument.tsx +2 -2
  36. package/src/game-document/GamePanel.tsx +9 -9
  37. package/src/game-document/InstanceInspectorPicker.tsx +1 -1
  38. package/src/game-document/device-preview.ts +4 -4
  39. package/src/game-document/physics-debug.ts +2 -2
  40. package/src/generation/GenerationActivity.tsx +22 -22
  41. package/src/generation/GenerationGallery.css +79 -79
  42. package/src/generation/generation-documents.tsx +25 -25
  43. package/src/generation/generation-presentation.ts +1 -1
  44. package/src/host/adapter-reach.ts +1 -1
  45. package/src/host/adapter-runtime-bindings.ts +5 -5
  46. package/src/host/after-paint.ts +3 -3
  47. package/src/host/api/configurations.ts +1 -1
  48. package/src/host/authoring/canvas-runtime-recognition.ts +2 -2
  49. package/src/host/authoring/contract-hierarchy-authoring.ts +6 -6
  50. package/src/host/authoring/contract-scenes-stories.ts +5 -5
  51. package/src/host/authoring/ingest-data-writer.ts +1 -1
  52. package/src/host/authoring/ingest-source-persistence.ts +2 -2
  53. package/src/host/authoring/mount-isolated-pixi-screen.ts +1 -1
  54. package/src/host/authoring/pixi-authoring-adapter.ts +206 -28
  55. package/src/host/authoring/pixi-creatable-kinds.ts +80 -0
  56. package/src/host/authoring/pixi-live-write-target.ts +6 -5
  57. package/src/host/authoring/pixi-source-write-target.ts +118 -20
  58. package/src/host/authoring/pixi-structure-history.ts +3 -3
  59. package/src/host/binding-resolver.ts +6 -6
  60. package/src/host/browser-transpile.ts +10 -10
  61. package/src/host/canvas-preview-frames.ts +1 -1
  62. package/src/host/components/CameraAuthoringOverlay.tsx +14 -14
  63. package/src/host/components/HeaderTelemetry.tsx +11 -11
  64. package/src/host/components/PixiIsolationSceneContent.tsx +3 -3
  65. package/src/host/components/ResolutionPicker.tsx +4 -4
  66. package/src/host/components/scene-document.tsx +3 -3
  67. package/src/host/components/world-root-stage-binding.tsx +1 -1
  68. package/src/host/components/world-root-stage.ts +1 -1
  69. package/src/host/coverage/authoring-read-probe.ts +1 -1
  70. package/src/host/coverage/capability-coverage.ts +22 -22
  71. package/src/host/coverage/game-contract-seam-evidence.ts +8 -8
  72. package/src/host/coverage/project-verb-coverage.ts +1 -1
  73. package/src/host/coverage/system-adapter-coverage.ts +19 -6
  74. package/src/host/game-location-guard.ts +3 -3
  75. package/src/host/game-module-access.ts +6 -6
  76. package/src/host/game-realm-page.ts +3 -3
  77. package/src/host/game-realm-reclaim.ts +1 -1
  78. package/src/host/gameplay-recording.ts +5 -5
  79. package/src/host/gated-globals.ts +13 -13
  80. package/src/host/ingest/registry.ts +14 -14
  81. package/src/host/play-control-hook.ts +1 -1
  82. package/src/host/playwright-shim.ts +2 -2
  83. package/src/host/projection/pixi.ts +2 -2
  84. package/src/host/react-mount-runtime.ts +1 -1
  85. package/src/host/roots/canvas-root.tsx +13 -1
  86. package/src/host/roots/r3f-root.tsx +1 -1
  87. package/src/host/scene-view-drawability.ts +1 -1
  88. package/src/host/sdk/tools.ts +1 -1
  89. package/src/host/served-bundle-runtime-modules.ts +2 -0
  90. package/src/host/staged-projects.ts +1 -1
  91. package/src/host/stories/story-pixi-preview.ts +1 -1
  92. package/src/host/stories/story-three-preview.ts +1 -1
  93. package/src/host/three-ingest-runtime.ts +1 -1
  94. package/src/ingest/active-ingest.ts +1 -1
  95. package/src/ingest/authoring/ingest-dom-surface-authoring.ts +4 -4
  96. package/src/ingest/authoring/ingest-root-adapter.ts +11 -11
  97. package/src/ingest/capture-wait-report.ts +4 -4
  98. package/src/ingest/discovery-public-ingest.ts +4 -4
  99. package/src/ingest/dom-stub-mark.ts +1 -1
  100. package/src/ingest/entry-load.ts +1 -1
  101. package/src/ingest/game-contract-realm.ts +3 -3
  102. package/src/ingest/game-pointer-lock.ts +1 -1
  103. package/src/ingest/ingest-canvas-scene-document.tsx +3 -3
  104. package/src/ingest/ingest-evidence-hook.ts +6 -6
  105. package/src/ingest/ingest-frame-snapshot.ts +2 -2
  106. package/src/ingest/ingest-play-commands.ts +1 -1
  107. package/src/ingest/ingest-play-control.ts +11 -11
  108. package/src/ingest/ingest-render-debug.ts +5 -5
  109. package/src/ingest/ingest-siblings.ts +3 -3
  110. package/src/ingest/module-mode.ts +2 -2
  111. package/src/ingest/mount-canvas-ingest-root.ts +10 -10
  112. package/src/ingest/mount-coverage.ts +3 -3
  113. package/src/ingest/mount-dom-ingest-root.ts +7 -7
  114. package/src/ingest/mount-ingest-root.ts +10 -10
  115. package/src/ingest/mount-three-ingest-root.ts +5 -5
  116. package/src/ingest/resolve-three.ts +2 -2
  117. package/src/ingest/served-bundle.ts +6 -6
  118. package/src/ingest/served-html-boot.ts +8 -8
  119. package/src/ingest/surface-dom.ts +9 -9
  120. package/src/ingest/surface-three.ts +1 -1
  121. package/src/ingest/types.ts +1 -1
  122. package/src/ingest/unmount-ingest-root.ts +3 -3
  123. package/src/network/NetworkInspectorPanel.tsx +521 -54
  124. package/src/network/network-inspector-model.ts +6 -0
  125. package/src/play/play-boot-stall.ts +1 -1
  126. package/src/play/play-mode.ts +31 -30
  127. package/src/play/play-recording.ts +12 -12
  128. package/src/play-bar/PlayBar.tsx +8 -8
  129. package/src/play-bar/PlayerCountPicker.tsx +3 -3
  130. package/src/profiler/FrameDebuggerPanel.tsx +2 -2
  131. package/src/profiler/PerformancePanel.tsx +4 -4
  132. package/src/react/design-time-react-mount.ts +5 -5
  133. package/src/react/dom-authoring-adapter.ts +3 -3
  134. package/src/react/react-inspector-section.tsx +2 -2
  135. package/src/react/react-world-authoring-adapter.ts +20 -20
  136. package/src/react/story-documents/story-documents.tsx +4 -4
  137. package/src/react/ui-component-board.ts +1 -1
  138. package/src/runtime/adapter/audio-meter.ts +1 -1
  139. package/src/runtime/adapter/ingest/contract-debug-adapter.ts +4 -4
  140. package/src/runtime/adapter/ingest/contract-system-adapters.ts +9 -9
  141. package/src/runtime/adapter/ingest/merge-debug-adapters.ts +2 -2
  142. package/src/runtime/adapter/ingest/observation-debug-adapter.ts +1 -1
  143. package/src/runtime/adapter/native-debug-module.ts +5 -5
  144. package/src/runtime/audio/pose-guard.ts +1 -1
  145. package/src/runtime/core/game-scoped-slot.ts +1 -1
  146. package/src/runtime/create-runtime.ts +15 -15
  147. package/src/runtime/debug-bridge.ts +25 -25
  148. package/src/runtime/debug-registry.ts +17 -17
  149. package/src/runtime/dev/instruments.ts +1 -1
  150. package/src/runtime/dev/performance-profiler.ts +2 -2
  151. package/src/runtime/dev/register-render-vitals.ts +2 -2
  152. package/src/runtime/dev/static-batch-advisor.ts +3 -3
  153. package/src/runtime/dev-build.ts +3 -3
  154. package/src/runtime/game.ts +5 -5
  155. package/src/runtime/input-router.ts +24 -11
  156. package/src/runtime/mount-manifest.ts +9 -9
  157. package/src/runtime/pixi/authoring.ts +1 -1
  158. package/src/runtime/pixi/ingest.ts +1 -1
  159. package/src/runtime/presentation.ts +1 -1
  160. package/src/runtime/render-control.ts +21 -21
  161. package/src/runtime/render-seed.ts +3 -3
  162. package/src/runtime/run-ticks-settled.ts +1 -1
  163. package/src/services/game-audio.ts +3 -3
  164. package/src/services/game-network.ts +125 -15
  165. package/src/three/authoring/model-asset-inspector-section.css +15 -15
  166. package/src/three/authoring/model-asset-inspector-section.tsx +7 -7
  167. package/src/three/authoring/r3f-design-session.ts +10 -10
  168. package/src/three/authoring/r3f-source-authoring-adapter.ts +5 -5
  169. package/src/three/authoring/three-authoring-adapter.ts +5 -4
  170. package/src/three/authoring/typed-three-inspector.ts +1 -1
  171. package/src/three/story-documents/three-story-documents.tsx +3 -3
  172. package/src/three/three-board/board-scene.ts +9 -9
  173. package/src/three/three-board/three-component-board.ts +1 -1
package/NOTICE CHANGED
@@ -1,15 +1,15 @@
1
1
  Copyright 2026 Volter AI, Inc.
2
2
 
3
- The files in this package were imported from volter-ai/vgai-engine at commit
3
+ The files in this package were imported from volter-ai/volter-engine at commit
4
4
  09c2749ce. LICENSE contains the AGPL-3.0-only license they retain.
5
5
 
6
- packages/game/src, packages/game/contributions (@vgai/game)
6
+ packages/game/src, packages/game/contributions
7
7
  -> src, contributions
8
- packages/dom/src, packages/dom/contributions (@vgai/dom)
8
+ packages/dom/src, packages/dom/contributions
9
9
  -> src/react, contributions/react
10
10
  packages/threejs/src except viewport/ and capture/, packages/threejs/contributions
11
- (@vgai/threejs) -> src/three, contributions/three
12
- host modules of packages/editor/src (@vgai/editor) -> src/host, including
11
+ -> src/three, contributions/three
12
+ host modules of packages/editor/src -> src/host, including
13
13
  gameplay-export.ts and document-preview-three.ts, and the world-root stage
14
14
  (components/world-root-stage.ts and the modules it draws with)
15
15
  src/host/components/world-root-stage-binding.tsx is transcribed from the
@@ -18,6 +18,6 @@ The files in this package were imported from volter-ai/vgai-engine at commit
18
18
  contributions/scene-document.service.ts from the Scene document half of
19
19
  packages/editor/src/components/CenterDocuments.tsx
20
20
 
21
- src/host/sdk/tools.ts was imported from packages/vgai-sdk/src/tools.ts, part of
22
- the Apache-2.0 @vgai/sdk package, and retains that license. It re-exports the
21
+ src/host/sdk/tools.ts was imported from src/tools.ts of the Apache-2.0 SDK
22
+ package of volter-ai/volter-engine, and retains that license. It re-exports the
23
23
  Apache-2.0 tool contract of @volter/editor-sdk.
@@ -12,7 +12,7 @@
12
12
  * which fires at once when one is already registered) rather than for a React
13
13
  * mount.
14
14
  *
15
- * It reports its failure to the editor console — `vgai console` is what reads
15
+ * It reports its failure to the editor console — `volter-game-editor console` is what reads
16
16
  * it — rather than leaving a stopped surface with no reason on it.
17
17
  */
18
18
  import { onShellStore } from '@volter/editor-sdk/kit/shell-store-door';
@@ -0,0 +1,95 @@
1
+ /**
2
+ * BUILD PLAYER (`workspace.document`) — the project's last build, run as a
3
+ * player runs it: its own `dist/`, served by the editor server, in a frame
4
+ * with nothing of the editor inside it. Build Profiles' Build And Run opens
5
+ * it, as Unity's Build And Run launches the player and Godot's Web export
6
+ * runs in a browser; each run reloads the frame.
7
+ *
8
+ * What the build prints reaches the editor's console, prefixed
9
+ * `[Build Player]`, as a Godot export run with remote debug reports into the
10
+ * editor's debugger: its console calls, and its uncaught errors. The capture
11
+ * door photographs the build itself (`framed-document-capture.ts`).
12
+ */
13
+
14
+ import type { ToolContributionProps } from '@volter/editor-sdk/contributions';
15
+ import { registerFramedCapture } from '@volter/editor-sdk/kit/framed-document-capture';
16
+ import { useSyncExternalStore } from 'react';
17
+ import { BUILD_PLAYER_URL, buildRunCount, subscribeBuildRuns } from '../src/build/build-session';
18
+
19
+ export const point = 'workspace.document';
20
+ export const title = 'Build Player';
21
+
22
+ const FORWARDED = ['log', 'info', 'warn', 'error'] as const;
23
+
24
+ const HOOKED = Symbol('build-player-output');
25
+
26
+ /** Hook the player's document once it exists: the build's module scripts run
27
+ * before `load`, after its HTML is parsed and while their bundle is fetched,
28
+ * so the frame is watched from insertion until its document is the build's. */
29
+ function watchFrame(frame: HTMLIFrameElement | null): void {
30
+ if (!frame) return;
31
+ const tick = () => {
32
+ if (!frame.isConnected) return;
33
+ const player = frame.contentWindow as (Window & typeof globalThis & { [HOOKED]?: true }) | null;
34
+ if (player?.location.pathname === new URL(BUILD_PLAYER_URL, location.href).pathname) {
35
+ if (!player[HOOKED]) {
36
+ forwardOutput(player);
37
+ registerFramedCapture(frame, {
38
+ container: () => player.document.getElementById('game-canvas') ?? player.document.body,
39
+ canvasFrame: (canvas) => copyAfterRender(player, canvas),
40
+ });
41
+ }
42
+ if (player.document.readyState === 'complete') return;
43
+ }
44
+ setTimeout(tick, 0);
45
+ };
46
+ tick();
47
+ }
48
+
49
+ /** A copy of `canvas` taken in the player's next frame, after the game's own
50
+ * frame callbacks (registered a frame earlier) have drawn it. */
51
+ function copyAfterRender(player: Window & typeof globalThis, canvas: HTMLCanvasElement): Promise<CanvasImageSource | null> {
52
+ return new Promise((resolve) => {
53
+ player.requestAnimationFrame(() => {
54
+ const copy = player.document.createElement('canvas');
55
+ copy.width = canvas.width;
56
+ copy.height = canvas.height;
57
+ const context = copy.getContext('2d');
58
+ if (!context) return resolve(null);
59
+ context.drawImage(canvas, 0, 0);
60
+ resolve(copy);
61
+ });
62
+ });
63
+ }
64
+
65
+ function forwardOutput(player: Window & typeof globalThis & { [HOOKED]?: true }): void {
66
+ player[HOOKED] = true;
67
+ for (const level of FORWARDED) {
68
+ const own = player.console[level].bind(player.console);
69
+ player.console[level] = (...args: unknown[]) => {
70
+ own(...args);
71
+ console[level]('[Build Player]', ...args);
72
+ };
73
+ }
74
+ player.addEventListener('error', (event) => {
75
+ console.error('[Build Player] Uncaught', event.error ?? event.message);
76
+ });
77
+ player.addEventListener('unhandledrejection', (event) => {
78
+ console.error('[Build Player] Unhandled rejection', event.reason);
79
+ });
80
+ console.info(`[Build Player] Running ${player.document.title || 'the build'}`);
81
+ }
82
+
83
+ export default function BuildPlayerDocument(_props: ToolContributionProps) {
84
+ const run = useSyncExternalStore(subscribeBuildRuns, buildRunCount);
85
+ return (
86
+ <iframe
87
+ key={run}
88
+ title="Build Player"
89
+ data-build-player={run}
90
+ src={`${BUILD_PLAYER_URL}?run=${run}`}
91
+ ref={watchFrame}
92
+ style={{ width: '100%', height: '100%', border: 0, display: 'block', background: '#000' }}
93
+ />
94
+ );
95
+ }
@@ -3,7 +3,7 @@
3
3
  * as a center document: the build-role targets, the manifest fields a build
4
4
  * reads, and the Build trigger. A document rather than a dialog because the
5
5
  * configuration is a persistent authored surface (it writes
6
- * `vgai.project.json` through the history service) someone tunes and re-runs,
6
+ * `volter.project.json` through the history service) someone tunes and re-runs,
7
7
  * and because a modal would block the viewport while a build streams.
8
8
  *
9
9
  * It ships with `@volter/editor-game`, so a folder of models has no Build Profiles tab
@@ -23,7 +23,7 @@ export default function BuildProgressStatus() {
23
23
  if (session.phase === 'building') {
24
24
  return (
25
25
  <span
26
- className="vgai-status-copy"
26
+ className="volter-status-copy"
27
27
  data-testid="status-build-progress"
28
28
  data-build-phase="building"
29
29
  data-status-tone="accent"
@@ -34,7 +34,7 @@ export default function BuildProgressStatus() {
34
34
  }
35
35
  return (
36
36
  <span
37
- className="vgai-status-copy"
37
+ className="volter-status-copy"
38
38
  data-testid="status-build-progress"
39
39
  data-build-phase={session.result?.ok ? 'complete' : 'failed'}
40
40
  data-status-tone={session.result?.ok ? 'success' : 'danger'}
@@ -25,7 +25,7 @@ export default function BuildHeader() {
25
25
  aria-label="Export project"
26
26
  disabled={playing}
27
27
  title={playing ? 'Stop Play mode before exporting the project' : 'Export project'}
28
- className="vgai-chrome-island vgai-glass-island"
28
+ className="volter-chrome-island volter-glass-island"
29
29
  onClick={() => {
30
30
  openBuildProfilesDocument();
31
31
  }}
@@ -31,7 +31,7 @@ export default function ConnectionStatus() {
31
31
  type="button"
32
32
  variant="ghost"
33
33
  size="compact"
34
- className="vgai-status-action"
34
+ className="volter-status-action"
35
35
  data-testid="status-connection"
36
36
  data-connection-state={state}
37
37
  onClick={() => editorHost().workspace.showUtility(NETWORK_UTILITY_ID)}
@@ -15,7 +15,7 @@
15
15
  *
16
16
  * ## The two doors, both the host's own, neither of them new vocabulary
17
17
  *
18
- * - `session.reportFacet(collect, { reusableKeys })` — the four `vgai status`
18
+ * - `session.reportFacet(collect, { reusableKeys })` — the four `volter-game-editor status`
19
19
  * facets. The keys are declared REUSABLE because grading a root re-walks
20
20
  * its tree (76ms–1.3s, measured), which is exactly the cost
21
21
  * `command-listener.ts`'s `REUSABLE_DERIVED_FACETS` exists to keep off the
@@ -86,7 +86,7 @@ function coverageFacets(reuse: Record<string, unknown> | null): Record<string, u
86
86
  : null,
87
87
  // The THIRD derived family, and the one that lives outside both adapter
88
88
  // contracts: the native verbs whose subject is the PROJECT rather than a
89
- // mounted root — its committed proof route, whether `vgai add` can land a
89
+ // mounted root — its committed proof route, whether `volter-game-editor add` can land a
90
90
  // capability here, and whether it can produce a standalone build at all
91
91
  // (`@editor/coverage/project-verb-coverage`). Without it a project could
92
92
  // be green in the other two families and silently have none of the three.
@@ -1,13 +1,13 @@
1
1
  /**
2
2
  * The STEP verbs of the session wire (`@volter/editor-sdk/commands`, a
3
3
  * `workspace.command` contribution): `game-eval`, the module lane behind
4
- * `vgai eval`'s `game.run(...)`, and `page-script`, the in-page Playwright
4
+ * `volter-game-editor eval`'s `game.run(...)`, and `page-script`, the in-page Playwright
5
5
  * shim behind `page(...)`. Both carry a step function's own SOURCE over the
6
6
  * wire and reconstruct it here — closures do not survive the trip — so both
7
7
  * are gated on a live game surface (a play session or an ingest mount) and
8
8
  * rooted at the game container, never editor chrome.
9
9
  *
10
- * The module lane's page-side door (`window.__vgaiGameEval`) and the two
10
+ * The module lane's page-side door (`window.__volterGameEval`) and the two
11
11
  * providers it needs are installed when this module loads, which is when the
12
12
  * verbs themselves become available: one handler, two doors, registered
13
13
  * together.
@@ -37,7 +37,7 @@ export const point = 'workspace.command';
37
37
  * source in the editor page (same wire contract as `page-script`: closures do
38
38
  * not survive) and runs it against a scope of { page, modules, instanceId } —
39
39
  * `modules(path)` importing the RUNNING mount's own module instances
40
- * (`game-module-access.ts`). This is what makes `vgai eval` able to touch the
40
+ * (`game-module-access.ts`). This is what makes `volter-game-editor eval` able to touch the
41
41
  * game's exported modules directly, in the browser, with no registry: the
42
42
  * step is literal JS against the game's real functions.
43
43
  *
@@ -51,12 +51,12 @@ export const point = 'workspace.command';
51
51
  */
52
52
  declare global {
53
53
  interface Window {
54
- __vgaiGameEval?: (src: string, instance?: string) => Promise<unknown>;
54
+ __volterGameEval?: (src: string, instance?: string) => Promise<unknown>;
55
55
  }
56
56
  }
57
57
  if (typeof window !== 'undefined') {
58
58
  setFocusedInstanceProvider(focusedInstanceId);
59
- window.__vgaiGameEval = async (src: string, instance?: string) => {
59
+ window.__volterGameEval = async (src: string, instance?: string) => {
60
60
  const result = await handleGameEval({
61
61
  type: 'game-eval',
62
62
  src,
@@ -151,7 +151,7 @@ async function handlePageScript(cmd: EditorCommandMessage): Promise<EditorComman
151
151
  // first-party `play-mode.ts` session. Keep the Playwright-style page door on
152
152
  // the same reachability rule as bridge calls/screenshots: a real ingest
153
153
  // container is sufficient, while the genuinely-unmounted case still
154
- // refuses below. Without this, `vgai play` could start an ingested game and
154
+ // refuses below. Without this, `volter-game-editor play` could start an ingested game and
155
155
  // `game.commands()` would work, yet `page(...)` answered "not in play mode"
156
156
  // against that very same visible game.
157
157
  if (!isPlayModeActive() && !isIngestActive()) return notPlayingResult();
@@ -96,7 +96,7 @@ export const commands: CommandContribution['commands'] = {
96
96
  }
97
97
  // D15/T-D15.5 (review objection 2's fix) — resolved through the SAME
98
98
  // per-world `DebugRegistry.getVirtualInputTarget(worldId?)` the debug
99
- // bridge's `window.__vgai.input.*` calls, instead of the old
99
+ // bridge's `window.__volter.input.*` calls, instead of the old
100
100
  // `Game.input` (always the DEFAULT world only) — an explicit
101
101
  // `cmd['worldId']` reaches that world specifically; omitted resolves
102
102
  // to the same default both doors now share. Throws
@@ -217,7 +217,7 @@ export const commands: CommandContribution['commands'] = {
217
217
  // session's `GameInternal.runTicks` through `getPlayRuntimeAccess()`'s
218
218
  // `runTicks` accessor (itself backed by the SAME
219
219
  // `DebugRegistry.getRunTicksTarget()` the bridge's
220
- // `window.__vgai.runTicks` calls — one implementation, byte-identical
220
+ // `window.__volter.runTicks` calls — one implementation, byte-identical
221
221
  // behavior across doors, D17). `runTicks` itself throws a structured
222
222
  // `DebugError` (`RUN_TICKS_PAUSED`) while paused — never a silent no-op —
223
223
  // which `structuredErrorResult` below carries through as `data.code`.
@@ -38,7 +38,7 @@ export default function GenerationsStatus() {
38
38
  type="button"
39
39
  variant="ghost"
40
40
  size="compact"
41
- className="vgai-status-action"
41
+ className="volter-status-action"
42
42
  data-testid="status-generations"
43
43
  aria-label={`Generations, ${unseen} unseen, ${running} running`}
44
44
  title={`${unseen} unseen generation results, ${running} running — open Generations`}
@@ -9,7 +9,7 @@
9
9
  * registration, its `ingest`/`ingestCaptureWait` state facets and its
10
10
  * `onShellStore` binding are module-load side effects of
11
11
  * `mount-ingest-root.ts`. The static import below is therefore load-bearing
12
- * — `vgai status` carries `ingest: null` / `ingestCaptureWait: null` before
12
+ * — `volter-game-editor status` carries `ingest: null` / `ingestCaptureWait: null` before
13
13
  * contribution pass. A product that composes no `@volter/editor-game` reports
14
14
  * neither key, which is the honest state: no lane claims to mount
15
15
  * unmodified games.
@@ -24,7 +24,7 @@
24
24
  * `isIngestActive()` is answered by a mount this hook already made.
25
25
  *
26
26
  * 3. REGISTERING THIS LANE'S ADAPTER DECLARATIONS. A repo-vendored game does
27
- * not ship its own `vgai.adapter.ts` — by the REALM rule its host-realm
27
+ * not ship its own `volter.adapter.ts` — by the REALM rule its host-realm
28
28
  * declaration lives in the in-tree registry (`@editor/ingest/registry`),
29
29
  * which the host used to import directly and therefore carried in every
30
30
  * editor boot, a `models` build that mounts no unmodified game included.
@@ -116,7 +116,7 @@ export const commands: CommandContribution['commands'] = {
116
116
  // guard here: `play` on an already-playing (or still-booting) session
117
117
  // is a RESTART, not a no-op, matching the SDK's own documented contract
118
118
  // (`play.start`'s summary: "Start (or restart) play mode" —
119
- // `packages/vgai-sdk/src/play/lifecycle-operations.ts`). What used to
119
+ // `packages/volter-sdk/src/play/lifecycle-operations.ts`). What used to
120
120
  // make a restart unsafe was `enterPlayMode()` having no reentrancy
121
121
  // guard for the async-boot window before it assigns `_session` — two
122
122
  // overlapping calls ran their entire prologues concurrently and
@@ -127,11 +127,11 @@ export const commands: CommandContribution['commands'] = {
127
127
  // SDK, a UI Play-button click racing a relayed command — gets a safe,
128
128
  // clean restart for free without needing a guard here too.
129
129
  try {
130
- // D15/T-D15.6 (objection-4 fix) — `vgai play --seed <n>` relays as
130
+ // D15/T-D15.6 (objection-4 fix) — `volter-game-editor play --seed <n>` relays as
131
131
  // `cmd['seed']`; `enterPlayMode`'s explicit-config seed leg (beats
132
- // manifest.determinism.defaultSeed/?vgai-seed=).
132
+ // manifest.determinism.defaultSeed/?volter-seed=).
133
133
  const seed = cmd['seed'];
134
- // `vgai play --name <text>` rides the same wire as `--seed`: a plain
134
+ // `volter-game-editor play --name <text>` rides the same wire as `--seed`: a plain
135
135
  // field on the relayed command, slugified server-side into this run's
136
136
  // log filename and journal line. Absent, everything is unchanged.
137
137
  const runName = cmd['name'];
@@ -173,11 +173,11 @@ export const commands: CommandContribution['commands'] = {
173
173
  // EVERY PLAY RECORDS. There is no flag and no opt-in — see
174
174
  // `play-recording.ts` for why the capability had to stop being one an
175
175
  // agent must remember to switch on. `cmd['record']` only NAMES the file
176
- // (`vgai play --record <name>`); its absence names the clip after the
176
+ // (`volter-game-editor play --record <name>`); its absence names the clip after the
177
177
  // durable Gameplay Session.
178
178
  //
179
179
  // Started here rather than inside `enterPlayMode` on purpose: this
180
- // handler is the RELAYED play (`vgai play`, the SDK's `play.start`),
180
+ // handler is the RELAYED play (`volter-game-editor play`, the SDK's `play.start`),
181
181
  // which is exactly the population the recording exists for. A human
182
182
  // clicking the editor's own Play button is their own witness and gets
183
183
  // play unchanged.
@@ -62,7 +62,7 @@
62
62
  * the DOM projection and the CSS inspection estate
63
63
  * (`components/RootSelectionOverlay.tsx`); the surgical JSX writer and the
64
64
  * structural write pipe (`authoring/r3f-source-authoring-adapter.ts`,
65
- * `@vgai/canvas/pixi-source-write-target.ts`); the breakpoint state
65
+ * `@volter/canvas/pixi-source-write-target.ts`); the breakpoint state
66
66
  * (`components/BoardRulers.tsx`); `authoring/react-story-board.ts`, the
67
67
  * board's geometry, which three host surfaces read
68
68
  * (`components/RootSelectionOverlay.tsx:98`,
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@volter/editor-game",
3
3
  "author": "Volter AI, Inc.",
4
4
  "license": "AGPL-3.0-only",
5
- "version": "0.5.67",
5
+ "version": "0.5.69",
6
6
  "publishConfig": {
7
7
  "access": "public"
8
8
  },
@@ -30,7 +30,7 @@
30
30
  "./host/stories/story-pixi-preview": "./src/host/stories/story-pixi-preview.ts",
31
31
  "./host/stories/story-media-captures": "./src/host/stories/story-media-captures.ts"
32
32
  },
33
- "vgai": {
33
+ "volter": {
34
34
  "contributions": [
35
35
  "./contributions/asset-budget-asset.menu.ts",
36
36
  "./contributions/asset-budget.action.ts",
@@ -42,6 +42,7 @@
42
42
  "./contributions/autoplay.service.ts",
43
43
  "./contributions/bridge.command.ts",
44
44
  "./contributions/build-profiles.document.tsx",
45
+ "./contributions/build-player.document.tsx",
45
46
  "./contributions/build-progress.status.tsx",
46
47
  "./contributions/build.action.ts",
47
48
  "./contributions/build.command.ts",
@@ -100,11 +101,11 @@
100
101
  "serving": "./dist-node/serving.mjs"
101
102
  },
102
103
  "dependencies": {
103
- "@volter/editor-sdk": "0.5.67",
104
- "@volter/editor-project": "0.5.67",
105
- "@volter/editor-threejs": "0.5.67",
106
- "@volter/threejs-runtime": "0.5.67",
107
- "@volter/game-runtime": "0.5.67",
104
+ "@volter/editor-sdk": "0.5.69",
105
+ "@volter/editor-project": "0.5.69",
106
+ "@volter/editor-threejs": "0.5.69",
107
+ "@volter/threejs-runtime": "0.5.69",
108
+ "@volter/game-runtime": "0.5.69",
108
109
  "@colyseus/msgpackr": "^1.11.3",
109
110
  "@colyseus/schema": "^4.0.14",
110
111
  "@colyseus/sdk": "^0.17.34",
@@ -137,7 +138,7 @@
137
138
  "xstate": "^5.32.4",
138
139
  "zod": "^4.3.6",
139
140
  "@fortawesome/fontawesome-svg-core": "^7.2.0",
140
- "@volter/editor-react": "0.5.67"
141
+ "@volter/editor-react": "0.5.69"
141
142
  },
142
143
  "peerDependencies": {
143
144
  "@sparkjsdev/spark": "^2.1.0",
package/serving/index.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * `@volter/editor-game`'s server half (`package.json#vgai.serving`): the one deep specifier a
2
+ * `@volter/editor-game`'s server half (`package.json#volter.serving`): the one deep specifier a
3
3
  * game's own contributions name, `@editor/game-module-access` (the template's
4
4
  * `src/contributions/use-game-modules.ts`), resolved to this package's module. The page
5
5
  * bundle maps the same specifier for its own copy (`src/host/served-bundle-runtime-modules.ts`);
@@ -882,7 +882,7 @@ function OptimizeActions({ entry, onApplied }: { entry: AssetBudgetEntry; onAppl
882
882
  {lodCandidates.length > 0 ? (
883
883
  <div style={{ display: 'flex', gap: spaceVar[2], marginTop: spaceVar[3] }}>
884
884
  <Select
885
- className="vgai-select"
885
+ className="volter-select"
886
886
  aria-label="LOD base node"
887
887
  data-testid="asset-budget-op-lod-node"
888
888
  value={chosenLodNode}
@@ -12,7 +12,7 @@
12
12
  * - the project REFERENCE GRAPH: which manifest entries, code files, or
13
13
  * sibling assets mention each asset ("what uses this", critique P5),
14
14
  * the unused list derived from it, and duplicate groups by sha256
15
- * - provenance stamps projected from `.vgai/provenance.json`
15
+ * - provenance stamps projected from `.volter/provenance.json`
16
16
  *
17
17
  * Anti-shim: anything unmeasurable is reported as absent/unknown with a
18
18
  * reason (`inspectError`, `gpuBytes: null`, `unknownTextureCount`) — never a
@@ -190,7 +190,7 @@ export interface AssetBudgetSource {
190
190
  * Reference-owner documents living OUTSIDE the walked snapshot, scanned for
191
191
  * references but never budget rows. Server mode uses this for the project
192
192
  * manifest: `HttpStorage` is hard-rooted at `public/` (its own doc comment;
193
- * the T3.3 "two-`.vgai`-dirs" finding), so `vgai.project.json` is unreachable
193
+ * the T3.3 "two-`.volter`-dirs" finding), so `volter.project.json` is unreachable
194
194
  * through the seam and is fetched over the dev server instead — without it,
195
195
  * every manifest-referenced asset (input maps, scenes) would be reported
196
196
  * unused, a fabricated finding.
@@ -213,7 +213,7 @@ export interface AssetBudgetSource {
213
213
  readonly codeReferencesScannable?: boolean;
214
214
  readBytes(path: string): Promise<Uint8Array>;
215
215
  readText(path: string): Promise<string>;
216
- /** Parsed `.vgai/provenance.json` (or null/undefined when absent). */
216
+ /** Parsed `.volter/provenance.json` (or null/undefined when absent). */
217
217
  readonly provenance?: unknown;
218
218
  }
219
219
 
@@ -282,7 +282,7 @@ export function isEngineVendoredRuntimePath(path: string): boolean {
282
282
  // --- Reference scanning ------------------------------------------------------
283
283
 
284
284
  const CODE_OWNER_PATTERN = /\.(?:tsx?|jsx?|mjs|cjs)$/i;
285
- const MANIFEST_NAME = 'vgai.project.json';
285
+ const MANIFEST_NAME = 'volter.project.json';
286
286
 
287
287
  /**
288
288
  * The manifest is the ONLY JSON document that owns asset references. An
@@ -450,7 +450,7 @@ const IGNORED_DIRS = new Set([
450
450
  '.git',
451
451
  'dist',
452
452
  'build',
453
- '.vgai',
453
+ '.volter',
454
454
  '.ci-scaffold',
455
455
  'coverage',
456
456
  'test-results',
@@ -476,21 +476,21 @@ export async function collectProjectBudgetSource(
476
476
  await walk('');
477
477
 
478
478
  // Server mode: `HttpStorage` is hard-rooted at the project's `public/`
479
- // folder (its doc comment; the T3.3 "two-`.vgai`-dirs" finding), so BOTH
479
+ // folder (its doc comment; the T3.3 "two-`.volter`-dirs" finding), so BOTH
480
480
  // project-root documents the budget needs live outside the seam. Use the
481
481
  // dev server's own idioms for each: the raw manifest served at
482
- // `/vgai.project.json` (`manifest-project.ts`) and the `.vgai/`-scoped
483
- // `/__editor/vgai-file` route (`project-provenance.ts`). Anything
482
+ // `/volter.project.json` (`manifest-project.ts`) and the `.volter/`-scoped
483
+ // `/__editor/volter-file` route (`project-provenance.ts`). Anything
484
484
  // unavailable stays honestly absent — no fabricated owners or stamps.
485
485
  if (isPublicRootedBackend(backend)) {
486
486
  const ownerFiles: AssetBudgetFile[] = [];
487
487
  const virtualTexts = new Map<string, string>();
488
488
  try {
489
- const manifestRes = await fetch('/vgai.project.json');
489
+ const manifestRes = await fetch('/volter.project.json');
490
490
  if (manifestRes.ok) {
491
491
  const text = await manifestRes.text();
492
- virtualTexts.set('vgai.project.json', text);
493
- ownerFiles.push({ path: 'vgai.project.json', size: text.length });
492
+ virtualTexts.set('volter.project.json', text);
493
+ ownerFiles.push({ path: 'volter.project.json', size: text.length });
494
494
  }
495
495
  } catch {
496
496
  // No reachable manifest → no manifest-owned references.
@@ -501,7 +501,7 @@ export async function collectProjectBudgetSource(
501
501
  // answers `text/plain` raw file bytes, which that JSON-only reader would
502
502
  // reject as a non-answer. See `optimize-apply.ts`'s `readLedgerText`.
503
503
  const provenanceRes = await fetch(
504
- `/__editor/vgai-file?${new URLSearchParams({ path: '.vgai/provenance.json' })}`,
504
+ `/__editor/volter-file?${new URLSearchParams({ path: '.volter/provenance.json' })}`,
505
505
  );
506
506
  if (provenanceRes.ok) provenance = JSON.parse(await provenanceRes.text());
507
507
  } catch {
@@ -525,8 +525,8 @@ export async function collectProjectBudgetSource(
525
525
 
526
526
  let provenance: unknown = null;
527
527
  try {
528
- if (await backend.exists('.vgai/provenance.json')) {
529
- provenance = JSON.parse(await backend.read('.vgai/provenance.json'));
528
+ if (await backend.exists('.volter/provenance.json')) {
529
+ provenance = JSON.parse(await backend.read('.volter/provenance.json'));
530
530
  }
531
531
  } catch {
532
532
  provenance = null; // unreadable provenance = no stamps, never a crash
@@ -2,7 +2,7 @@
2
2
  * Storage-side APPLY flow for Asset Budget optimizations (W4a M3).
3
3
  *
4
4
  * One place owns "optimized bytes land in the project": write through the
5
- * storage seam, stamp central provenance (`.vgai/provenance.json`, the SAME
5
+ * storage seam, stamp central provenance (`.volter/provenance.json`, the SAME
6
6
  * document/idiom the generative-assets pipeline stamps and
7
7
  * `project-provenance.ts` projects — one operation with an `outputs` entry
8
8
  * carrying path/bytes/sha256), invalidate the engine's URL-keyed asset cache
@@ -27,7 +27,7 @@ import { handleProjectMutationFailure } from '@volter/editor-sdk/kit/source-conf
27
27
  import { isPublicRootedBackend, type StorageBackend } from '@volter/editor-sdk/kit/storage-types';
28
28
  import { invalidateCachedAsset } from '@volter/threejs-runtime/asset-loaders';
29
29
 
30
- const PROVENANCE_PATH = '.vgai/provenance.json';
30
+ const PROVENANCE_PATH = '.volter/provenance.json';
31
31
 
32
32
  /** Serving path (`/models/x.glb`) or bare path → storage path under public/. */
33
33
  export function assetStoragePath(path: string): string {
@@ -74,10 +74,10 @@ function ledgerAssetPath(storagePath: string): string {
74
74
 
75
75
  /**
76
76
  * Ledger IO honoring the backend's reach: server-mode `HttpStorage` is
77
- * hard-rooted at `public/`, so writing `.vgai/provenance.json` through it
78
- * would land at `public/.vgai/provenance.json` — a divergent second ledger
79
- * (the exact T3.3 "two-`.vgai`-dirs" bug class). The dev server's
80
- * `.vgai/`-scoped `/__editor/vgai-file` GET/POST route pair is the recorded
77
+ * hard-rooted at `public/`, so writing `.volter/provenance.json` through it
78
+ * would land at `public/.volter/provenance.json` — a divergent second ledger
79
+ * (the exact T3.3 "two-`.volter`-dirs" bug class). The dev server's
80
+ * `.volter/`-scoped `/__editor/volter-file` GET/POST route pair is the recorded
81
81
  * fix for that class; every other
82
82
  * backend reaches the project root directly.
83
83
  */
@@ -88,7 +88,7 @@ async function readLedgerText(backend: StorageBackend): Promise<string | null> {
88
88
  // file bytes, and that reader's whole rule is "the editor server answers
89
89
  // JSON" — it would reject this route's successes.
90
90
  const res = await fetch(
91
- `/__editor/vgai-file?${new URLSearchParams({ path: PROVENANCE_PATH })}`,
91
+ `/__editor/volter-file?${new URLSearchParams({ path: PROVENANCE_PATH })}`,
92
92
  );
93
93
  if (res.status === 404) return null;
94
94
  if (!res.ok) throw new Error(`read ${PROVENANCE_PATH}: HTTP ${res.status}`);
@@ -101,7 +101,7 @@ async function readLedgerText(backend: StorageBackend): Promise<string | null> {
101
101
  async function writeLedgerText(backend: StorageBackend, content: string): Promise<void> {
102
102
  if (isPublicRootedBackend(backend)) {
103
103
  const write = async () => {
104
- const res = await fetch('/__editor/vgai-file', {
104
+ const res = await fetch('/__editor/volter-file', {
105
105
  method: 'POST',
106
106
  headers: { 'Content-Type': 'application/json' },
107
107
  body: JSON.stringify({ path: PROVENANCE_PATH, content, ...sourceMutationAttribution() }),
@@ -17,7 +17,7 @@ import { dispatchBridgeMethod, hasLiveDebugPlane } from './dispatch';
17
17
  * this package); everything else is `dispatchBridgeMethod`'s own structured
18
18
  * failure, caught here and shipped back via `structuredErrorResult` so
19
19
  * `code`/`data` survive the relay round trip byte-equivalent to the
20
- * page-transport's `unwrap()` path (`packages/vgai-live/src/game-client/client.ts`). */
20
+ * page-transport's `unwrap()` path (`packages/volter-live/src/game-client/client.ts`). */
21
21
  export async function handleBridgeCall(cmd: EditorCommandMessage): Promise<EditorCommandResult> {
22
22
  // The precondition is "no plane at all", not "not playing" — see
23
23
  // `hasLiveDebugPlane`. The per-method preconditions inside
@@ -28,7 +28,7 @@ export async function handleBridgeCall(cmd: EditorCommandMessage): Promise<Edito
28
28
  // the still edit world can be driven.
29
29
  if (!isPlayModeActive() && !hasLiveDebugPlane()) {
30
30
  // A LIVE INGEST that publishes no plane is a third state, and answering it
31
- // with "not in play mode" sends the reader to `vgai play` over a game that
31
+ // with "not in play mode" sends the reader to `volter-game-editor play` over a game that
32
32
  // is already running and visible. MEASURED on the `flappy` canvas ingest:
33
33
  // `game.waitSimTime(...)` refused with the play sentence while the mount's
34
34
  // own play state read `playing`. The mount is what is missing a plane, so
@@ -43,7 +43,7 @@ export async function handleBridgeCall(cmd: EditorCommandMessage): Promise<Edito
43
43
  'this ingest mount is live, but it publishes no debug plane — the mount installs no ' +
44
44
  'SystemAdapters.debug, so there is nothing to enumerate, read or drive through the ' +
45
45
  'game seam. Starting play will not change that; the game itself must declare the ' +
46
- 'vgai game contract (or carry a contract shim beside it) for these calls to have an ' +
46
+ 'volter game contract (or carry a contract shim beside it) for these calls to have an ' +
47
47
  'answer.',
48
48
  }
49
49
  : notPlayingResult();