@volter/editor-game 0.5.66 → 0.5.68

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 (239) hide show
  1. package/contributions/audio-unlock.service.ts +2 -2
  2. package/contributions/autoplay.service.ts +1 -1
  3. package/contributions/bridge.command.ts +3 -3
  4. package/contributions/build-player.document.tsx +95 -0
  5. package/contributions/canvas/component-board.service.ts +16 -0
  6. package/contributions/canvas/design-time-mount.service.ts +45 -0
  7. package/contributions/canvas-story-capture.service.ts +12 -0
  8. package/contributions/edit-mode-audio.service.ts +2 -2
  9. package/contributions/edit-mode-networking.service.ts +1 -1
  10. package/contributions/gameplay.command.ts +4 -4
  11. package/contributions/generation.service.ts +1 -1
  12. package/contributions/godot.style.ts +26 -6
  13. package/contributions/godot.view.ts +6 -0
  14. package/contributions/ingest.service.ts +2 -2
  15. package/contributions/instances.command.ts +1 -1
  16. package/contributions/navmesh.menu.ts +1 -1
  17. package/contributions/network-observer.service.ts +14 -0
  18. package/contributions/play.command.ts +10 -4
  19. package/contributions/react/component-board.service.ts +1 -1
  20. package/contributions/react/design-time-mount.service.ts +1 -1
  21. package/contributions/scene-document.service.ts +3 -3
  22. package/contributions/state-watch.menu.ts +1 -1
  23. package/contributions/state-watch.utility.tsx +1 -1
  24. package/contributions/team-playtest.service.ts +4 -4
  25. package/contributions/three/component-board.service.ts +1 -1
  26. package/contributions/three/component-verbs.command.ts +6 -6
  27. package/contributions/three/three-authoring.service.ts +8 -5
  28. package/contributions/three-story-capture.service.ts +12 -0
  29. package/contributions/unity.style.ts +17 -7
  30. package/contributions/unity.view.ts +6 -0
  31. package/contributions/unreal.style.ts +10 -2
  32. package/contributions/unreal.view.ts +5 -0
  33. package/package.json +21 -10
  34. package/src/asset-budget/AssetBudgetPanel.tsx +1 -1
  35. package/src/asset-budget/asset-budget-model.ts +1 -1
  36. package/src/audio/AudioDebuggerPanel.tsx +1 -1
  37. package/src/bridge/dispatch.ts +14 -14
  38. package/src/bridge/live-frames.ts +1 -1
  39. package/src/bridge/screenshot.ts +3 -3
  40. package/src/build/BuildProfilesPanel.tsx +14 -3
  41. package/src/build/build-session.ts +35 -0
  42. package/src/canvas/canvas-board/CanvasBoardDocument.tsx +749 -0
  43. package/src/canvas/canvas-board/canvas-board-model.ts +407 -0
  44. package/src/canvas/canvas-board/canvas-component-board.ts +56 -0
  45. package/src/canvas/canvas-design-mount.ts +524 -0
  46. package/src/canvas/design-time-canvas-mount.ts +79 -0
  47. package/src/coverage/live-authoring-surface.ts +5 -5
  48. package/src/coverage/live-project-verbs.ts +1 -1
  49. package/src/coverage/native-system-coverage.ts +5 -5
  50. package/src/coverage/root-coverage.ts +1 -1
  51. package/src/coverage/session-coverage.ts +3 -3
  52. package/src/design-system-stories/ApplicationChrome.stories.tsx +5 -5
  53. package/src/design-system-stories/InspectorNarrowBodies.stories.tsx +7 -7
  54. package/src/edit-mode/edit-mode-audio.ts +4 -4
  55. package/src/edit-mode/edit-mode-networking.ts +2 -2
  56. package/src/game-document/GameCaptureFrameButton.tsx +1 -1
  57. package/src/game-document/GameDocument.tsx +2 -2
  58. package/src/game-document/GamePanel.tsx +4 -4
  59. package/src/game-document/InstanceInspectorPicker.tsx +2 -2
  60. package/src/game-document/crowd-debug.ts +1 -1
  61. package/src/game-document/device-preview.ts +10 -11
  62. package/src/game-document/physics-debug.ts +1 -1
  63. package/src/generation/GenerationActivity.tsx +3 -3
  64. package/src/generation/generation-documents.tsx +5 -5
  65. package/src/generation/generation-jobs.ts +1 -1
  66. package/src/host/adapter-runtime-bindings.ts +96 -5
  67. package/src/host/authoring/babylon-authoring-adapter.ts +6 -6
  68. package/src/host/authoring/gesture-persist.ts +1 -1
  69. package/src/host/authoring/ingest-data-writer.ts +1 -1
  70. package/src/host/authoring/ingest-source-persistence.ts +4 -4
  71. package/src/host/authoring/mounted-authoring.ts +4 -4
  72. package/src/host/authoring/phaser-live-authoring-adapter.ts +4 -4
  73. package/src/host/authoring/pixi-authoring-adapter.ts +178 -31
  74. package/src/host/authoring/pixi-creatable-kinds.ts +62 -0
  75. package/src/host/authoring/pixi-creation-site-write-target.ts +2 -2
  76. package/src/host/authoring/pixi-live-write-target.ts +4 -4
  77. package/src/host/authoring/pixi-source-identity.ts +3 -3
  78. package/src/host/authoring/pixi-source-write-target.ts +1709 -0
  79. package/src/host/authoring/pixi-still-presentation.ts +1 -1
  80. package/src/host/authoring/pixi-structure-history.ts +2 -2
  81. package/src/host/authoring/pixi-transform-channels.ts +16 -14
  82. package/src/host/authoring/source-persistence-backend.ts +3 -3
  83. package/src/host/authoring/struct-write-pipe.ts +1 -1
  84. package/src/host/binding-resolver.ts +8 -9
  85. package/src/host/browser-transpile.ts +1 -1
  86. package/src/host/canvas-entry-runtime.ts +58 -47
  87. package/src/host/canvas-preview-frames.ts +482 -0
  88. package/src/host/components/CameraAuthoringOverlay.tsx +1 -1
  89. package/src/host/components/HeaderTelemetry.tsx +4 -4
  90. package/src/host/components/PixiIsolationSceneContent.tsx +11 -11
  91. package/src/host/components/ThreeIsolationSceneContent.tsx +3 -3
  92. package/src/host/components/frame-debugger-model.ts +2 -2
  93. package/src/host/components/header-telemetry-model.ts +2 -2
  94. package/src/host/components/scene-document.tsx +14 -14
  95. package/src/host/components/utility-view-state.ts +1 -1
  96. package/src/host/components/world-root-stage-binding.tsx +12 -12
  97. package/src/host/components/world-root-stage.ts +70 -49
  98. package/src/host/coverage/system-adapter-coverage.ts +3 -4
  99. package/src/host/design-system-stories/fixtures/editor-runtime.tsx +9 -11
  100. package/src/host/document-preview-three.ts +1 -1
  101. package/src/host/entry-adjudication.ts +6 -6
  102. package/src/host/game-css-scope-transform.ts +4 -0
  103. package/src/host/game-realm-page.ts +1 -1
  104. package/src/host/gameplay-export.ts +25 -14
  105. package/src/host/gameplay-recording.ts +5 -5
  106. package/src/host/gated-globals.ts +2 -2
  107. package/src/host/history/json-history-resource.ts +1 -1
  108. package/src/host/projection/pixi.ts +24 -2
  109. package/src/host/r3f-entry-runtime.ts +65 -34
  110. package/src/host/react-mount-runtime.ts +7 -48
  111. package/src/host/realm-services.ts +1 -1
  112. package/src/host/roots/canvas-root.tsx +373 -0
  113. package/src/host/roots/r3f-root.tsx +473 -0
  114. package/src/host/roots/react-root.ts +9 -43
  115. package/src/host/served-bundle-runtime-modules.ts +3 -19
  116. package/src/host/server-log-bridge.ts +2 -2
  117. package/src/host/stories/mounted-story-viewport-source.ts +1 -1
  118. package/src/host/stories/pixi-story-model.ts +30 -0
  119. package/src/host/stories/story-media-captures.ts +46 -0
  120. package/src/host/stories/story-media-presence.ts +3 -3
  121. package/src/host/stories/story-pixi-preview.ts +408 -0
  122. package/src/host/stories/story-three-preview.ts +806 -0
  123. package/src/host/stories/three-story-captures.ts +35 -0
  124. package/src/host/story-three-preview-runtime.ts +56 -0
  125. package/src/host/use-active-performance-source.ts +2 -2
  126. package/src/host/viewport-pose-memory.ts +1 -1
  127. package/src/host/viewport-root-presentation.ts +6 -5
  128. package/src/ingest/active-ingest.ts +1 -1
  129. package/src/ingest/authoring/ingest-dom-surface-authoring.ts +4 -4
  130. package/src/ingest/authoring/ingest-root-adapter.ts +8 -8
  131. package/src/ingest/deferred-ingest-play.ts +6 -6
  132. package/src/ingest/discovery-public-ingest.ts +2 -2
  133. package/src/ingest/ingest-boot-viewport.ts +2 -2
  134. package/src/ingest/ingest-canvas-scene-document.tsx +9 -9
  135. package/src/ingest/ingest-canvas-scene.ts +3 -3
  136. package/src/ingest/ingest-evidence-hook.ts +1 -1
  137. package/src/ingest/ingest-frame-snapshot.ts +1 -1
  138. package/src/ingest/ingest-play-control.ts +1 -1
  139. package/src/ingest/ingest-render-debug.ts +10 -10
  140. package/src/ingest/ingest-siblings.ts +13 -25
  141. package/src/ingest/module-mode.ts +14 -14
  142. package/src/ingest/mount-canvas-ingest-root.ts +21 -21
  143. package/src/ingest/mount-coverage.ts +2 -2
  144. package/src/ingest/mount-dom-ingest-root.ts +11 -11
  145. package/src/ingest/mount-ingest-root.ts +8 -8
  146. package/src/ingest/mount-three-ingest-root.ts +8 -8
  147. package/src/ingest/resolve-canvas.ts +1 -1
  148. package/src/ingest/served-html-boot.ts +1 -1
  149. package/src/ingest/surface-canvas.ts +1 -1
  150. package/src/ingest/unmount-ingest-root.ts +5 -5
  151. package/src/navmesh/navmesh-handler.ts +24 -16
  152. package/src/network/NetworkInspectorPanel.tsx +939 -37
  153. package/src/network/network-inspector-model.ts +20 -2
  154. package/src/play/play-log-events.ts +1 -1
  155. package/src/play/play-mode.ts +76 -133
  156. package/src/play/play-recording.ts +1 -1
  157. package/src/play/react-play-live-authoring.ts +3 -3
  158. package/src/play/run-selection.ts +93 -0
  159. package/src/play-bar/PlayBar.tsx +20 -39
  160. package/src/profiler/FrameDebuggerPanel.tsx +1 -1
  161. package/src/profiler/PerformancePanel.tsx +3 -3
  162. package/src/react/design-time-react-mount.ts +23 -65
  163. package/src/react/dom-authoring-adapter.ts +9 -9
  164. package/src/react/react-inspector-section.tsx +5 -5
  165. package/src/react/react-world-authoring-adapter.ts +11 -11
  166. package/src/react/story-documents/story-documents.tsx +9 -9
  167. package/src/react/ui-board-document.tsx +7 -7
  168. package/src/react/ui-component-board.ts +2 -2
  169. package/src/runtime/adapter/audio-meter.ts +21 -0
  170. package/src/runtime/adapter/first-party-audio-system.ts +230 -0
  171. package/src/runtime/adapter/ingest/contract-debug-adapter.ts +114 -0
  172. package/src/runtime/adapter/ingest/contract-system-adapters.ts +256 -0
  173. package/src/runtime/adapter/ingest/merge-debug-adapters.ts +197 -0
  174. package/src/runtime/adapter/ingest/observation-debug-adapter.ts +162 -0
  175. package/src/runtime/adapter/ingest/upstream-pin.ts +51 -0
  176. package/src/runtime/adapter/native-debug-module.ts +498 -0
  177. package/src/runtime/audio/bus-mixer.ts +161 -0
  178. package/src/runtime/audio/pose-guard.ts +80 -0
  179. package/src/runtime/core/frame-pacing.ts +126 -0
  180. package/src/runtime/core/game-loop.ts +225 -0
  181. package/src/runtime/core/game-scoped-slot.ts +28 -0
  182. package/src/runtime/core/seeded-random.ts +162 -0
  183. package/src/runtime/core/sim-clock.ts +391 -0
  184. package/src/runtime/core/system-runner.ts +269 -0
  185. package/src/runtime/core/types.ts +104 -0
  186. package/src/runtime/create-runtime.ts +1128 -0
  187. package/src/runtime/debug-bridge.ts +570 -0
  188. package/src/runtime/debug-registry.ts +899 -0
  189. package/src/runtime/dev/chrome-trace.ts +153 -0
  190. package/src/runtime/dev/instruments.ts +403 -0
  191. package/src/runtime/dev/logger.ts +119 -0
  192. package/src/runtime/dev/performance-profiler.ts +367 -0
  193. package/src/runtime/dev/register-render-vitals.ts +276 -0
  194. package/src/runtime/dev/render-census.ts +354 -0
  195. package/src/runtime/dev/render-debug-adapter.ts +218 -0
  196. package/src/runtime/dev/render-memory.ts +226 -0
  197. package/src/runtime/dev/render-vitals.ts +338 -0
  198. package/src/runtime/dev/static-batch-advisor.ts +188 -0
  199. package/src/runtime/dev/webgl-frame-capture.ts +366 -0
  200. package/src/runtime/dev/webgl-gpu-timer.ts +53 -0
  201. package/src/runtime/dev-build.ts +47 -0
  202. package/src/runtime/game.ts +1636 -0
  203. package/src/runtime/gameplay-rng-trap.ts +135 -0
  204. package/src/runtime/host-context.ts +64 -0
  205. package/src/runtime/input-router.ts +182 -0
  206. package/src/runtime/mount-manifest.ts +480 -0
  207. package/src/runtime/pixi/authoring.ts +706 -0
  208. package/src/runtime/pixi/ingest.ts +116 -0
  209. package/src/runtime/pixi/physics-registry.ts +49 -0
  210. package/src/runtime/pixi/render-pass-bracket.ts +117 -0
  211. package/src/runtime/pixi/scene-capture.ts +179 -0
  212. package/src/runtime/pixi/system-adapters.ts +69 -0
  213. package/src/runtime/playtest.ts +22 -0
  214. package/src/runtime/presentation.ts +141 -0
  215. package/src/runtime/render-control.ts +642 -0
  216. package/src/runtime/render-seed.ts +77 -0
  217. package/src/runtime/run-ticks-settled.ts +73 -0
  218. package/src/runtime/setup/setup-audio.ts +72 -0
  219. package/src/services/audio-pose-guard.ts +2 -2
  220. package/src/services/game-audio.ts +152 -0
  221. package/src/services/game-network.ts +767 -0
  222. package/src/services/game-physics.ts +334 -0
  223. package/src/state-watch/StateWatchPanel.tsx +1 -1
  224. package/src/three/authoring/camera-runtime-inspector-section.tsx +3 -2
  225. package/src/three/authoring/constraint-inspector-section.tsx +6 -5
  226. package/src/three/authoring/model-asset-inspector-section.tsx +7 -6
  227. package/src/three/authoring/oid-source-persistence.ts +7 -7
  228. package/src/three/authoring/r3f-design-session.ts +58 -54
  229. package/src/three/authoring/r3f-source-authoring-adapter.ts +95 -91
  230. package/src/three/authoring/reflection-probe-inspector-section.tsx +3 -2
  231. package/src/three/authoring/three-authoring-adapter.ts +29 -29
  232. package/src/three/component-verbs/extract-menu.ts +7 -6
  233. package/src/three/component-verbs/fork-menu.ts +7 -6
  234. package/src/three/component-verbs/internals-menu.ts +2 -2
  235. package/src/three/story-documents/three-story-documents.tsx +13 -13
  236. package/src/three/three-board/ThreeBoardDocument.tsx +13 -12
  237. package/src/three/three-board/board-scene.ts +6 -6
  238. package/src/three/three-board/three-component-board.ts +2 -2
  239. package/src/services/game-audio-unlock.ts +0 -48
@@ -20,18 +20,18 @@ import {
20
20
  activeDocumentSourcePath,
21
21
  activeSaveDestination,
22
22
  activeSaveState,
23
- } from '@volter/editor-core/authoring/shell-document-ops';
24
- import { Object3DDocumentViewport } from '@volter/editor-core/components/Object3DDocumentViewport';
23
+ } from '@volter/editor-sdk/kit/authoring/shell-document-ops';
24
+ import { Object3DDocumentViewport } from '@volter/editor-threejs/kit/components/Object3DDocumentViewport';
25
25
  import type { DocumentPreviewSource } from '@volter/editor-sdk/kit/document-preview-source';
26
26
  import { editorConsole } from '@volter/editor-sdk/kit/editor-console';
27
- import type { EditorShellStore, ViewportTab } from '@volter/editor-core/editor-shell-store';
28
- import { projectAdapterFacet, subscribeProjectAdapter } from '@volter/editor-core/project-adapter';
29
- import { getCurrentProject } from '@volter/editor-core/project-manager';
30
- import { isolationTabsReplaceGenericScene, sceneTabRow } from '@volter/editor-core/scene-document-plan';
27
+ import type { EditorShellStore, ViewportTab } from '@volter/editor-threejs/kit/editor-shell-store';
28
+ import { projectAdapterFacet, subscribeProjectAdapter } from '@volter/editor-sdk/kit/project-adapter';
29
+ import { getCurrentProject } from '@volter/editor-sdk/kit/active-project';
30
+ import { isolationTabsReplaceGenericScene, sceneTabRow } from '@volter/editor-sdk/kit/scene-document-plan';
31
31
  import {
32
32
  registerAvailableWorkspaceDocument,
33
33
  unregisterAvailableWorkspaceDocument,
34
- } from '@volter/editor-core/workspace-available-documents';
34
+ } from '@volter/editor-sdk/kit/workspace-available-documents';
35
35
  import { SCENE_DOCUMENT_ID } from '@volter/editor-sdk/kit/workspace-document-ids';
36
36
  import {
37
37
  activateWorkspaceDocument,
@@ -378,23 +378,23 @@ export function bindSceneDocument(store: EditorShellStore): () => void {
378
378
  // tab still represents the same authored TSX document.
379
379
  let lastSourcePath: string | null = null;
380
380
  const view: CenterDocumentsStore = {
381
- subscribe: (listener) => store.subscribe(listener),
381
+ subscribe: (listener) => store.shell.subscribe(listener),
382
382
  get playState() {
383
- return store.playState;
383
+ return store.shell.playState;
384
384
  },
385
385
  get activeViewportTab() {
386
- return store.activeViewportTab;
386
+ return store.shell.activeViewportTab;
387
387
  },
388
388
  get savePath() {
389
- return activeSaveDestination(store);
389
+ return activeSaveDestination(store.shell);
390
390
  },
391
391
  get sourcePath() {
392
- const current = activeDocumentSourcePath(store);
392
+ const current = activeDocumentSourcePath(store.shell);
393
393
  if (current) lastSourcePath = current;
394
394
  return lastSourcePath;
395
395
  },
396
396
  get isDirty() {
397
- return activeSaveState(store) === 'unsaved';
397
+ return activeSaveState(store.shell) === 'unsaved';
398
398
  },
399
399
  };
400
400
  const docs = createCenterDocumentDescriptors(view);
@@ -403,7 +403,7 @@ export function bindSceneDocument(store: EditorShellStore): () => void {
403
403
  const run = () =>
404
404
  syncCenterDocuments(view, docs, getCurrentProject()?.config.hasThreeRoot !== false);
405
405
  run();
406
- const unsubscribe = store.subscribe(run);
406
+ const unsubscribe = store.shell.subscribe(run);
407
407
  const unsubscribeAdapter = subscribeProjectAdapter(run);
408
408
  // Unbinding follows the session's store and leaves the document registered:
409
409
  // a store arriving again at boot must not close a restored Scene tab. The
@@ -16,7 +16,7 @@
16
16
  * button both select a view of a bench that now ships in `@volter/editor-game`.
17
17
  */
18
18
 
19
- import { showWorkspaceUtility } from '@volter/editor-core/workspace-host-commands';
19
+ import { showWorkspaceUtility } from '@volter/editor-sdk/kit/workspace-host-commands';
20
20
 
21
21
  export type ProfilerViewId = 'profiler' | 'frame';
22
22
 
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * THE GAME'S WORLD-ROOT BINDING for the kit's stage host
3
- * (`@volter/editor-core/components/world-root-binding`): the world's surface,
3
+ * (`@volter/editor-threejs/kit/components/world-root-binding`): the world's surface,
4
4
  * its stage, and the overlays the stage shows only over a world.
5
5
  *
6
6
  * `Overlays` is the world-root half of vgai's `stage-overlay-set.tsx` — every
@@ -10,7 +10,7 @@
10
10
  * `StageOverlays`, which the host renders beside this.
11
11
  */
12
12
  import { EDITOR_LAYER } from '@volter/editor-threejs/viewport/editor-layers';
13
- import { activeAuthoringVersion, subscribeActiveAuthoring } from '@volter/editor-core/authoring/active-adapter';
13
+ import { activeAuthoringVersion, subscribeActiveAuthoring } from '@volter/editor-sdk/kit/authoring/active-adapter';
14
14
  import {
15
15
  getMountFailureReports,
16
16
  subscribeToMountFailures,
@@ -18,16 +18,16 @@ import {
18
18
  import {
19
19
  object3DDocumentSessionsVersion,
20
20
  subscribeObject3DDocumentSessions,
21
- } from '@volter/editor-core/authoring/object3d-document-session-registry';
22
- import { RootSelectionOverlay } from '@volter/editor-core/components/RootSelectionOverlay';
23
- import { SurfaceStateOverlay } from '@volter/editor-core/components/SurfaceStateOverlay';
21
+ } from '@volter/editor-threejs/kit/authoring/object3d-document-session-registry';
22
+ import { RootSelectionOverlay } from '@volter/editor-sdk/kit/components/RootSelectionOverlay';
23
+ import { SurfaceStateOverlay } from '@volter/editor-sdk/kit/components/SurfaceStateOverlay';
24
24
  import type {
25
25
  WorldRootOverlayProps,
26
26
  WorldRootStageBinding,
27
- } from '@volter/editor-core/components/world-root-binding';
28
- import type { EditorShellStore } from '@volter/editor-core/editor-shell-store';
27
+ } from '@volter/editor-threejs/kit/components/world-root-binding';
28
+ import type { EditorShellStore } from '@volter/editor-threejs/kit/editor-shell-store';
29
29
  import { readinessFacet, subscribeRootReadiness } from '@volter/editor-sdk/kit/readiness';
30
- import { documentStageContext } from '@volter/editor-core/stage-context';
30
+ import { documentStageContext } from '@volter/editor-sdk/kit/stage-context';
31
31
  import { explainSurface } from '@volter/editor-sdk/kit/surface-state';
32
32
  import {
33
33
  subscribeWorkspaceDocuments,
@@ -54,7 +54,7 @@ function SceneViewportStateOverlay({
54
54
  rootIds: readonly string[];
55
55
  mountStatus: 'mounting' | 'ready';
56
56
  }) {
57
- useSyncExternalStore(store.subscribe, store.getSnapshot);
57
+ useSyncExternalStore(store.shell.subscribe, store.shell.getSnapshot);
58
58
  const rootReadiness = useSyncExternalStore(subscribeRootReadiness, readinessFacet);
59
59
  const mountFailures = useSyncExternalStore(subscribeToMountFailures, getMountFailureReports);
60
60
  const sceneBackground = store.scene?.background as THREE.Color | null | undefined;
@@ -70,7 +70,7 @@ function SceneViewportStateOverlay({
70
70
  ignoredLayer: EDITOR_LAYER,
71
71
  }),
72
72
  ),
73
- [store.scene, store.contentVersion],
73
+ [store.scene, store.shell.contentVersion],
74
74
  );
75
75
  const sceneHasContent = Boolean(
76
76
  store.scene && (sceneBackgroundIsAuthored || sceneHasRenderableObjects),
@@ -93,13 +93,13 @@ function WorldRootOverlays({
93
93
  mountStatus,
94
94
  rootIds,
95
95
  }: WorldRootOverlayProps) {
96
- useSyncExternalStore(store.subscribe, store.getShellSnapshot ?? store.getSnapshot);
96
+ useSyncExternalStore(store.shell.subscribe, store.shell.getShellSnapshot ?? store.shell.getSnapshot);
97
97
  useSyncExternalStore(subscribeActiveAuthoring, activeAuthoringVersion);
98
98
  useSyncExternalStore(subscribeObject3DDocumentSessions, object3DDocumentSessionsVersion);
99
99
  useSyncExternalStore(subscribeWorkspaceDocuments, workspaceDocumentRegistryVersion);
100
100
  // The world root's stage is the Scene document's: the kit's overlay props
101
101
  // carry no document id, and the Scene document is the one world-root stage.
102
- const ctx = documentStageContext(store, documentId, 'document');
102
+ const ctx = documentStageContext(store.shell, documentId, 'document');
103
103
  return (
104
104
  <>
105
105
  {/* Three-scene selection overlay. React/Pixi documents mount their own
@@ -26,10 +26,9 @@ import {
26
26
  registerStudioPreset,
27
27
  type StudioPreset,
28
28
  } from '@volter/editor-sdk/kit/viewport-presentation';
29
- import type { ViewportPresentation, ViewportRoot } from '@volter/editor-sdk/host';
30
29
  import { themeVars } from '@volter/editor-sdk/widgets';
31
- import { createPerformanceProfiler } from '@volter/game-runtime/dev/performance-profiler';
32
- import { createWebGLGpuTimer } from '@volter/game-runtime/dev/webgl-gpu-timer';
30
+ import { createPerformanceProfiler } from '../../runtime/dev/performance-profiler';
31
+ import { createWebGLGpuTimer } from '../../runtime/dev/webgl-gpu-timer';
33
32
  import type { AuthoringAdapter, Transform } from '@volter/editor-project/adapter';
34
33
  import { markHostRenderer } from '@volter/editor-threejs/viewport/renderer-ownership';
35
34
  import { applyWorldRendererConfig } from '@volter/threejs-runtime/adapter/renderer-config';
@@ -51,62 +50,75 @@ import {
51
50
  type Pass,
52
51
  } from 'postprocessing';
53
52
  import * as THREE from 'three';
54
- import { getActiveAuthoring } from '@volter/editor-core/authoring/active-adapter';
55
- import type { CompositeAuthoringAdapter } from '@volter/editor-core/authoring/composite-authoring-adapter';
53
+ import { getActiveAuthoring } from '@volter/editor-sdk/kit/authoring/active-adapter';
54
+ import type { CompositeAuthoringAdapter } from '@volter/editor-sdk/kit/authoring/composite-authoring-adapter';
56
55
  import {
57
56
  applyAuthoringTransform,
58
57
  beginAuthoringTransformEdit,
59
58
  endAuthoringTransformEdit,
60
- } from '@volter/editor-core/authoring/consumer-actions';
61
- import { designTimeMountFor } from '@volter/editor-core/authoring/design-time-mount-registry';
62
- import { attachProjectAuthoringStage } from '@volter/editor-core/authoring/project-authoring-session';
59
+ } from '@volter/editor-sdk/kit/authoring/consumer-actions';
60
+ import { designTimeMountFor } from '@volter/editor-sdk/kit/authoring/design-time-mount-registry';
61
+ import { attachProjectAuthoringStage } from '@volter/editor-sdk/kit/authoring/project-authoring-session';
63
62
  import {
64
63
  isThreejsSurfaceVisible,
65
64
  resolveThreeViewportRootId,
66
- } from '@volter/editor-core/authoring/world-hidden-viewport';
65
+ } from '@volter/editor-threejs/kit/authoring/world-hidden-viewport';
67
66
  import { AutoFrameWindow } from '../auto-frame-window';
68
67
  import {
69
68
  type CameraAuthoringSubject,
70
69
  type CameraViewMode,
71
70
  cameraAuthoringPresentation,
72
71
  installCameraAuthoringHost,
73
- } from '@volter/editor-core/camera-authoring';
74
- import { registerPresentedCanvasFrame } from '@volter/editor-core/canvas-preview-frames';
75
- import { collectState } from '@volter/editor-core/command-listener';
76
- import { getDownloadedAssetPath, getOnlineAssetFiles, reportEditorState } from '@volter/editor-core/editor-api';
72
+ } from '@volter/editor-threejs/kit/camera-authoring';
73
+ import { registerPresentedCanvasFrame } from '../canvas-preview-frames';
74
+ import { collectState } from '@volter/editor-sdk/kit/command-listener';
75
+ import { getDownloadedAssetPath, getOnlineAssetFiles, reportEditorState } from '@volter/editor-sdk/kit/editor-api';
77
76
  import { editorConsole } from '@volter/editor-sdk/kit/editor-console';
78
77
  import { isEditorPresentationActive } from '@volter/editor-sdk/kit/editor-presentation-activity';
79
- import type { EditorStats } from '@volter/editor-core/editor-runtime';
80
- import type { EditorShellStore } from '@volter/editor-core/editor-shell-store';
81
- import { EditorViewport, type OnlineAssetDrop } from '@volter/editor-core/editor-viewport';
82
- import { entityObject3D } from '@volter/editor-core/entity-object';
78
+ import type { EditorStats } from '@volter/editor-sdk/kit/editor-runtime';
79
+ import type { EditorShellStore } from '@volter/editor-threejs/kit/editor-shell-store';
80
+ import { EditorViewport, type OnlineAssetDrop } from '@volter/editor-threejs/kit/editor-viewport';
81
+ import { entityObject3D } from '@volter/editor-threejs/kit/entity-object';
83
82
  import {
84
83
  nativeSelectionColors,
85
84
  nativeViewportLook,
86
85
  subscribeNativeSelectionTheme,
87
86
  } from '@volter/editor-sdk/kit/native-selection-style';
88
- import { registerPerformanceSource } from '@volter/editor-core/performance-sources';
87
+ import { registerPerformanceSource } from '@volter/editor-sdk/kit/performance-sources';
89
88
  import { drawSceneUnlessRefused } from '../scene-view-drawability';
90
- import { withSceneFogNeutralized } from '@volter/editor-core/scene-view-fog';
89
+ import { withSceneFogNeutralized } from '@volter/editor-threejs/kit/scene-view-fog';
91
90
  import { connectServerLogs } from '../server-log-bridge';
92
- import { focusedStageStore } from '@volter/editor-core/stage-context';
91
+ import { focusedStageStore } from '@volter/editor-sdk/kit/stage-context';
93
92
  import {
94
93
  acquireThreeSelectionOutline,
95
94
  releaseThreeSelectionOutline,
96
95
  setThreeSelectionOutlineColors,
97
96
  syncThreeSelectionOutline,
98
- } from '@volter/editor-core/three-viewport/selection-outline';
97
+ } from '@volter/editor-threejs/kit/three-viewport/selection-outline';
99
98
  import {
100
99
  setThreeViewportProjection,
101
100
  subscribeThreeViewportPresentation,
102
101
  threeViewportPresentation,
103
- } from '@volter/editor-core/three-viewport-presentation';
102
+ } from '@volter/editor-sdk/kit/three-viewport-presentation';
104
103
  import { recordViewportFirstFrame } from '@volter/editor-sdk/kit/viewport-activation-timings';
105
104
  import { savedViewportPose, saveViewportPose } from '../viewport-pose-memory';
106
105
  import { presentThreeRoots } from '../viewport-root-presentation';
107
- import { isEditorViewportShadingTarget } from '@volter/editor-core/viewport-shading-boundary';
108
- import { downloadOnlineAssetWithHistory } from '@volter/editor-core/components/asset-editor-persistence';
109
- import { bindStagePresenceMarkers } from '@volter/editor-core/components/stage-presence-markers';
106
+ import { isEditorViewportShadingTarget } from '@volter/editor-threejs/kit/viewport-shading-boundary';
107
+ import { downloadOnlineAssetWithHistory } from '@volter/editor-sdk/kit/components/asset-editor-persistence';
108
+ import { bindStagePresenceMarkers } from '@volter/editor-threejs/kit/components/stage-presence-markers';
109
+ import type { ViewportPresentation, ViewportRoot } from '@volter/editor-threejs/viewport-api';
110
+
111
+ /** Everything the world root's stage hands its medium's design session: the stage's own three
112
+ * handles. The stage and the medium that registered for `three` agree on it; the kit's mount
113
+ * registry types it `unknown`. */
114
+ export interface WorldRootSessionContext {
115
+ /** The shell store the session's adapter is built over. */
116
+ readonly store: EditorShellStore;
117
+ /** The edit-mode composite the session swaps its own child adapter into. */
118
+ readonly composite: CompositeAuthoringAdapter;
119
+ /** The stage's renderer — the session adopts it rather than building one. */
120
+ readonly renderer: THREE.WebGLRenderer;
121
+ }
110
122
 
111
123
  /**
112
124
  * THE WORLD STAGE'S STARTING PRESENTATION. Its studio is the light the world has always been
@@ -468,8 +480,8 @@ export function installWorldRootStage(options: WorldRootStageOptions): WorldRoot
468
480
  );
469
481
  const syncSelectionOutline = (): void => {
470
482
  if (!selectionOutline) return;
471
- const adapter = getActiveAuthoring(store);
472
- const roots = [...store.selectedEntityIds]
483
+ const adapter = getActiveAuthoring(store.shell);
484
+ const roots = [...store.shell.selectedEntityIds]
473
485
  // Edit↔Play swaps the active child before its native graph is rebuilt.
474
486
  // Do not route a stale outgoing id through the composite during that
475
487
  // handoff: it is temporarily absent, not an ownership error.
@@ -495,7 +507,7 @@ export function installWorldRootStage(options: WorldRootStageOptions): WorldRoot
495
507
  // postprocessing). `editor-viewport.ts` bumps `composerVersion` (via
496
508
  // `store.reapplyEnvironment()`) on the world hide/show edges, which is
497
509
  // what re-runs this rebuild.
498
- const hiddenRootId = resolveThreeViewportRootId(store);
510
+ const hiddenRootId = resolveThreeViewportRootId(store.shell);
499
511
  void hiddenRootId;
500
512
  // Unwind the previous adoption's config BEFORE re-deriving, so the
501
513
  // re-derive below and the (possibly absent) re-apply at the end both
@@ -568,24 +580,24 @@ export function installWorldRootStage(options: WorldRootStageOptions): WorldRoot
568
580
  applyViewportPresentation();
569
581
 
570
582
  const resolveCameraSubject = (id: string): CameraAuthoringSubject | null =>
571
- cameraSubjectFor(getActiveAuthoring(store), store.objectMap, id);
583
+ cameraSubjectFor(getActiveAuthoring(store.shell), store.objectMap, id);
572
584
 
573
585
  let pilotGestureId: string | null = null;
574
586
  const finishPilotGesture = (): void => {
575
587
  if (!pilotGestureId) return;
576
- endAuthoringTransformEdit(getActiveAuthoring(store), pilotGestureId);
588
+ endAuthoringTransformEdit(getActiveAuthoring(store.shell), pilotGestureId);
577
589
  pilotGestureId = null;
578
590
  };
579
591
  const beginPilotGesture = (): void => {
580
592
  const view = cameraAuthoringPresentation().view;
581
593
  if (view?.mode !== 'pilot' || !view.subject.canAuthorPose) return;
582
594
  pilotGestureId = view.subject.id;
583
- beginAuthoringTransformEdit(getActiveAuthoring(store), pilotGestureId);
595
+ beginAuthoringTransformEdit(getActiveAuthoring(store.shell), pilotGestureId);
584
596
  };
585
597
  const applyPilotGesture = (): void => {
586
598
  if (!pilotGestureId || viewport.cameraViewMode !== 'pilot') return;
587
599
  const subject = resolveCameraSubject(pilotGestureId);
588
- const adapter = getActiveAuthoring(store);
600
+ const adapter = getActiveAuthoring(store.shell);
589
601
  const transforms = adapter.transforms;
590
602
  if (!subject || !transforms) return;
591
603
  // `transforms.get` REFUSES BY THROWING for a node with no transform truth
@@ -610,16 +622,16 @@ export function installWorldRootStage(options: WorldRootStageOptions): WorldRoot
610
622
  rotation: subject.camera.quaternion.toArray() as [number, number, number, number],
611
623
  scale: previous.scale,
612
624
  });
613
- store.notifyIngestEdit();
625
+ store.shell.notifyIngestEdit();
614
626
  };
615
627
  viewport.orbitControls.addEventListener('start', beginPilotGesture);
616
628
  viewport.orbitControls.addEventListener('change', applyPilotGesture);
617
629
  viewport.orbitControls.addEventListener('end', finishPilotGesture);
618
630
 
619
631
  const disposeCameraAuthoring = installCameraAuthoringHost({
620
- active: () => store.playState === 'stopped' && store.activeViewportTab === 'edit',
632
+ active: () => store.shell.playState === 'stopped' && store.shell.activeViewportTab === 'edit',
621
633
  selected: () => {
622
- const id = store.selectedEntityId;
634
+ const id = store.shell.selectedEntityId;
623
635
  return id ? resolveCameraSubject(id) : null;
624
636
  },
625
637
  resolve: resolveCameraSubject,
@@ -636,7 +648,7 @@ export function installWorldRootStage(options: WorldRootStageOptions): WorldRoot
636
648
  presence.reportCamera();
637
649
  },
638
650
  alignToViewport: (subject: CameraAuthoringSubject) => {
639
- const adapter = getActiveAuthoring(store);
651
+ const adapter = getActiveAuthoring(store.shell);
640
652
  const transforms = adapter.transforms;
641
653
  if (!transforms || !subject.canAuthorPose) return;
642
654
  const targetObject = store.objectMap.get(subject.id) ?? null;
@@ -671,10 +683,10 @@ export function installWorldRootStage(options: WorldRootStageOptions): WorldRoot
671
683
  rotation: localQuaternion.toArray() as [number, number, number, number],
672
684
  scale: previous.scale,
673
685
  });
674
- store.notifyIngestEdit();
686
+ store.shell.notifyIngestEdit();
675
687
  endAuthoringTransformEdit(adapter, subject.id);
676
688
  },
677
- subscribe: store.subscribe,
689
+ subscribe: store.shell.subscribe,
678
690
  });
679
691
 
680
692
  // --- Store subscription → sync viewport ---
@@ -694,7 +706,7 @@ export function installWorldRootStage(options: WorldRootStageOptions): WorldRoot
694
706
  // React never owns it.
695
707
  let lastThreejsSurface: boolean | null = null;
696
708
  const syncSurfaceVisibility = (): void => {
697
- const visible = isThreejsSurfaceVisible(store);
709
+ const visible = isThreejsSurfaceVisible(store.shell);
698
710
  if (visible === lastThreejsSurface) return;
699
711
  lastThreejsSurface = visible;
700
712
  canvas.style.opacity = visible ? '1' : '0';
@@ -715,7 +727,7 @@ export function installWorldRootStage(options: WorldRootStageOptions): WorldRoot
715
727
  syncSurfaceVisibility();
716
728
 
717
729
  let lastComposerVersion = store.composerVersion;
718
- const unsubStore = store.subscribe(() => {
730
+ const unsubStore = store.shell.subscribe(() => {
719
731
  syncSurfaceVisibility();
720
732
  // Swap viewport scene if the store's scene changed (play mode enter/exit)
721
733
  const storeScene = store.scene;
@@ -755,14 +767,14 @@ export function installWorldRootStage(options: WorldRootStageOptions): WorldRoot
755
767
  viewport.orbitControls.addEventListener('end', rememberPose);
756
768
 
757
769
  // --- Viewport action subscription ---
758
- const unsubActions = store.onViewportAction((action) => {
770
+ const unsubActions = store.shell.onViewportAction((action) => {
759
771
  switch (action.type) {
760
772
  // Resolved through the ACTIVE ADAPTER first, same as selection and the
761
773
  // gizmo — an adopted play scene's nodes live in the adapter's walk and
762
774
  // never reach `objectMap`, so a store-only lookup silently framed
763
775
  // nothing for every entity in a running game (`entity-object.ts`).
764
776
  case 'focus-entity': {
765
- const obj = entityObject3D(getActiveAuthoring(store), store.objectMap, action.id);
777
+ const obj = entityObject3D(getActiveAuthoring(store.shell), store.objectMap, action.id);
766
778
  if (obj) viewport.focusOn(obj);
767
779
  break;
768
780
  }
@@ -786,13 +798,13 @@ export function installWorldRootStage(options: WorldRootStageOptions): WorldRoot
786
798
  break;
787
799
  }
788
800
  }
789
- gameCameraLookup = action.gameCamera ?? null;
801
+ gameCameraLookup = store.sceneCameraLookup;
790
802
  autoFrame.begin(performance.now(), gameCameraLookup !== null);
791
803
  break;
792
804
  }
793
805
  case 'focus-selection': {
794
- const adapter = getActiveAuthoring(store);
795
- const objects = [...store.selectedEntityIds]
806
+ const adapter = getActiveAuthoring(store.shell);
807
+ const objects = [...store.shell.selectedEntityIds]
796
808
  .map((id) => entityObject3D(adapter, store.objectMap, id))
797
809
  .filter((o): o is THREE.Object3D => o !== null);
798
810
  viewport.focusOnMultiple(objects);
@@ -804,6 +816,15 @@ export function installWorldRootStage(options: WorldRootStageOptions): WorldRoot
804
816
  case 'set-view-preset':
805
817
  viewport.setViewPreset(action.preset);
806
818
  break;
819
+ case 'step-view':
820
+ viewport.stepView(action.step);
821
+ break;
822
+ case 'frame-all':
823
+ viewport.focusOnScene();
824
+ break;
825
+ case 'zoom-view':
826
+ viewport.zoomStep(action.direction);
827
+ break;
807
828
  case 'set-camera-pose':
808
829
  viewport.setPose(action.position, action.target, action.fov);
809
830
  break;
@@ -899,7 +920,7 @@ export function installWorldRootStage(options: WorldRootStageOptions): WorldRoot
899
920
 
900
921
  /** Whether this stage is the one the shared panels are following, and so the
901
922
  * one that fills the shell's frame/camera readout — see its use below. */
902
- const ownsShellReadout = (): boolean => focusedStageStore(store) === store;
923
+ const ownsShellReadout = (): boolean => focusedStageStore(store.shell) === store.shell;
903
924
 
904
925
  function frame(now: number, resumed: boolean): void {
905
926
  if (disposed) return;
@@ -1024,7 +1045,7 @@ export function installWorldRootStage(options: WorldRootStageOptions): WorldRoot
1024
1045
  const stageMount = designTimeMountFor('three');
1025
1046
  if (disposed || editModeComposite !== composite) return;
1026
1047
  const disposeSession = stageMount
1027
- ? await stageMount.mountWorldRootSession({ store, composite, renderer })
1048
+ ? await stageMount.mountWorldRootSession({ store, composite, renderer } satisfies WorldRootSessionContext)
1028
1049
  : () => {};
1029
1050
  if (disposed || editModeComposite !== composite) {
1030
1051
  disposeSession();
@@ -1034,9 +1055,9 @@ export function installWorldRootStage(options: WorldRootStageOptions): WorldRoot
1034
1055
  if (!disposed) options.onMountStatus('ready');
1035
1056
  }
1036
1057
 
1037
- const authoringStage = attachProjectAuthoringStage(store, installStage);
1058
+ const authoringStage = attachProjectAuthoringStage(store.shell, installStage);
1038
1059
  authoringStage.ready
1039
- .then(() => reportEditorState(collectState(store)))
1060
+ .then(() => reportEditorState(collectState(store.shell)))
1040
1061
  .catch((err) => {
1041
1062
  editorConsole.error(
1042
1063
  `Editor boot failed: ${err instanceof Error ? err.message : String(err)}`,
@@ -46,7 +46,7 @@
46
46
  * no live session.
47
47
  */
48
48
 
49
- import type { DeclaredSystemAbsence } from '@volter/game-runtime/runtime/game';
49
+ import type { DeclaredSystemAbsence } from '../../runtime/game';
50
50
  import type { SystemAdapters } from '@volter/editor-project/adapter/system-adapter';
51
51
  import {
52
52
  SYSTEM_ADAPTER_SLOTS,
@@ -139,9 +139,8 @@ function shippedLibraries(slot: SystemAdapterSlot, facts: NativeProjectFacts): r
139
139
  function contradictionFix(slot: SystemAdapterSlot, libraries: readonly string[]): string {
140
140
  return (
141
141
  `this project depends on ${libraries.join(' + ')}, so "nothing built a ${slot} world" is not ` +
142
- `a settled answer. Reach a terminal state either way: BIND it — declare a ${slot} adapter in ` +
143
- `the root entry's \`systems\` table (the engine ships \`rapierPhysicsSystem()\` for the R3F ` +
144
- `Rapier bridge; other slots take the game's own adapter) — or DECLARE the absence with ` +
142
+ `a settled answer. Reach a terminal state either way: BIND it — declare the game's own ${slot} ` +
143
+ `adapter in the root entry's \`systems\` table — or DECLARE the absence with ` +
145
144
  `\`absent(reason)\` in that same table. The reason must NAME the dependency and say why it ` +
146
145
  `is there while the subsystem is not (a transitive pull, a leftover, a build-only use); a ` +
147
146
  `declared absence blind to the shipped dependency grades malformed, not terminal.`
@@ -1,16 +1,17 @@
1
1
  import { type ReactNode, useEffect, useLayoutEffect, useState } from 'react';
2
- import { resetProjectThumbnailManifestCache } from '@volter/editor-core/asset-workflow/thumbnail-system';
3
- import { type EditorRuntime, EditorRuntimeProvider, type EditorStats } from '@volter/editor-core/editor-runtime';
4
- import { EditorShellStore } from '@volter/editor-core/editor-shell-store';
5
- import { EditorSession } from '@volter/editor-core/history/editor-session';
6
- import { getStorageBackend, MemStorage, setStorageBackend } from '@volter/editor-core/storage/index';
2
+ import { resetProjectThumbnailManifestCache } from '@volter/editor-sdk/kit/asset-workflow/thumbnail-system';
3
+ import { type EditorRuntime, EditorRuntimeProvider, type EditorStats } from '@volter/editor-sdk/kit/editor-runtime';
4
+ import { type EditorShellStore, threeStateOf } from '@volter/editor-threejs/kit/editor-shell-store';
5
+ import { ShellStore } from '@volter/editor-sdk/kit/shell-store';
6
+ import { EditorSession } from '@volter/editor-sdk/kit/history/editor-session';
7
+ import { getStorageBackend, MemStorage, setStorageBackend } from '@volter/editor-sdk/kit/storage/index';
7
8
  import {
8
9
  activeWorkspaceUtility,
9
10
  installWorkspaceHostCommands,
10
11
  setActiveWorkspaceUtility,
11
12
  setWorkspaceUtilityTabs,
12
13
  workspaceUtilityTabs,
13
- } from '@volter/editor-core/workspace-host-commands';
14
+ } from '@volter/editor-sdk/kit/workspace-host-commands';
14
15
  import { availableWorkspaceUtilities } from '@volter/editor-sdk/kit/workspace-utility-registry';
15
16
 
16
17
  const ZERO_STATS: EditorStats = {
@@ -24,15 +25,12 @@ const ZERO_STATS: EditorStats = {
24
25
 
25
26
  /** A story runtime's Three half, for a production component that reads the scene. */
26
27
  export function storyThreeStore(runtime: EditorRuntime): EditorShellStore {
27
- if (!(runtime.store instanceof EditorShellStore)) {
28
- throw new Error('This runtime was not made by createStoryEditorRuntime: it has no Three store.');
29
- }
30
- return runtime.store;
28
+ return threeStateOf(runtime.store);
31
29
  }
32
30
 
33
31
  /** A real, bounded editor runtime for production component stories. */
34
32
  export function createStoryEditorRuntime(): EditorRuntime {
35
- const store = new EditorShellStore();
33
+ const store = new ShellStore();
36
34
  const session = new EditorSession('storybook-fixture');
37
35
  store.attachHistory(session.history);
38
36
  return {
@@ -3,7 +3,7 @@ import { isEditorOwnedObject } from '@volter/editor-threejs/viewport/editor-laye
3
3
  import { markHostRenderer } from '@volter/editor-threejs/viewport/renderer-ownership';
4
4
  import * as THREE from 'three';
5
5
  import type { DocumentPreviewCaptureRequest } from '@volter/editor-sdk/kit/document-preview-source';
6
- import { frameableContentBounds } from '@volter/editor-core/scene-framing';
6
+ import { frameableContentBounds } from '@volter/editor-threejs/kit/scene-framing';
7
7
 
8
8
  function authoredCameras(root: THREE.Object3D): THREE.Camera[] {
9
9
  const cameras: THREE.Camera[] = [];
@@ -1,9 +1,9 @@
1
1
  /**
2
2
  * WHAT DOES THIS ENTRY MODULE MEAN? — the ONE editor-side answer.
3
3
  *
4
- * The engine owns the answer itself (`resolveR3FEntryAdapter`, and the
5
- * packaged-aware `resolveR3FEntryAdapterForEditor` delegate that routes it
6
- * through the project's own module graph). The editor's job is to ASK, once.
4
+ * `roots/r3f-root.tsx` owns the answer itself (`resolveR3FEntryAdapter`), and
5
+ * `resolveR3FEntryAdapterForEditor` hands it the React and Fiber of the
6
+ * project's own module graph. The rest of the editor's job is to ASK, once.
7
7
  * Before this module there were three askers, and they had already drifted:
8
8
  *
9
9
  * - the dev-server lane called the packaged-aware `…ForEditor`;
@@ -20,9 +20,9 @@
20
20
  * told which lane and which file, and that is the caller's knowledge, not
21
21
  * this function's.
22
22
  *
23
- * `entry-adjudication-single-owner.test.ts` is the tripwire; the canvas lane
24
- * has its own single owner in the engine (`resolveCanvasEntryAdapter`, reached
25
- * through `canvas-entry-runtime.ts`) and is not adjudicated here.
23
+ * The canvas lane has its own single owner (`roots/canvas-root.tsx`'s
24
+ * `resolveCanvasEntryAdapter`, reached through `canvas-entry-runtime.ts`) and
25
+ * is not adjudicated here.
26
26
  */
27
27
 
28
28
  import type { RootAdapter } from '@volter/editor-project/adapter';
@@ -0,0 +1,4 @@
1
+ /** The `@scope` transform the session applies to a game's stylesheets, for a
2
+ * page that must scope CSS a game creates at runtime. Its own module so the
3
+ * transform's parser loads only where a game's page asks for it. */
4
+ export { scopeGameCss } from '@volter/editor-sdk/session/scoped-game-css';
@@ -90,7 +90,7 @@ export const SCOPED_STYLE_MARK = 'vgaiScopedCss';
90
90
  let gameCssScoper: Promise<(css: string) => string> | null = null;
91
91
  export function loadGameCssScoper(): Promise<(css: string) => string> {
92
92
  gameCssScoper ??= Promise.all([
93
- import('@volter/editor-core/game-css-scope-transform'),
93
+ import('./game-css-scope-transform'),
94
94
  import('@volter/editor-sdk/session/game-css-scope'),
95
95
  ]).then(
96
96
  ([{ scopeGameCss }, { GAME_CSS_SCOPE_SELECTOR }]) =>
@@ -1,4 +1,3 @@
1
- import { pcmStats } from '@volter/game-runtime/audio/wav-encode';
2
1
  import type { OfflineAudioRenderer } from '@volter/editor-project/adapter';
3
2
  import {
4
3
  AudioBufferSource,
@@ -10,8 +9,25 @@ import {
10
9
  Quality,
11
10
  WebMOutputFormat,
12
11
  } from 'mediabunny';
13
- import type { CaptureOptions } from '@volter/editor-core/composite-screenshot';
14
- import { createImageSnapshotCache, drawPlayCompositeFrame } from '@volter/editor-core/composite-screenshot';
12
+ import type { CaptureOptions } from '@volter/editor-sdk/kit/composite-screenshot';
13
+ import { createImageSnapshotCache, drawPlayCompositeFrame } from '@volter/editor-sdk/kit/composite-screenshot';
14
+
15
+ /** RMS and peak over all channels and samples: evidence the track is sound, not an all-zero
16
+ * buffer. */
17
+ function pcmStats(channelData: readonly Float32Array[]): { rms: number; peak: number } {
18
+ let sumSquares = 0;
19
+ let peak = 0;
20
+ let count = 0;
21
+ for (const data of channelData) {
22
+ for (let i = 0; i < data.length; i++) {
23
+ const v = data[i] ?? 0;
24
+ sumSquares += v * v;
25
+ peak = Math.max(peak, Math.abs(v));
26
+ count++;
27
+ }
28
+ }
29
+ return { rms: count > 0 ? Math.sqrt(sumSquares / count) : 0, peak };
30
+ }
15
31
 
16
32
  /**
17
33
  * Opus in the SAME WebM `Output` the video track already uses — the whole
@@ -25,14 +41,10 @@ import { createImageSnapshotCache, drawPlayCompositeFrame } from '@volter/editor
25
41
  * second container pipeline beside the first is how one export's timing,
26
42
  * metadata and codec support drift away from the other's.
27
43
  *
28
- * Consequently `audio/wav-encode.ts` is NOT used to make the track.
29
- * `encodeWav16` exists for the one place that genuinely needs a file on a
30
- * wire — `runtime/render-audio-control.ts` base64s a complete WAV across
31
- * `page.evaluate` to a Node capture driver. Here the `AudioBuffer` and the
32
- * muxer are in the same JS heap, so encoding to 16-bit WAV and handing the
33
- * bytes back to an encoder would quantize the samples for no reason at all.
34
- * `pcmStats` from that module IS used, for the non-silence evidence in the
35
- * result.
44
+ * The `AudioBuffer` and the muxer are in the same JS heap, so the samples go
45
+ * to the encoder as they are; encoding to 16-bit WAV on the way would quantize
46
+ * them for no reason at all. {@link pcmStats} gives the non-silence evidence in
47
+ * the result.
36
48
  *
37
49
  * Opus rather than a PCM track (Matroska can carry `A_PCM/INT/LIT`) because
38
50
  * WebM's normal audio codec is what every player and every `ffprobe` build
@@ -105,9 +117,8 @@ export interface GameplayExportResult {
105
117
  /** How the export gets sound: the world's own audio for the ABSOLUTE sim
106
118
  * window the frame walk covers, rendered offline.
107
119
  *
108
- * THE OFFSET TRAP, restated at the call site because it is the correctness
109
- * argument of this whole path (`runtime/render-audio-control.ts` states it
110
- * first): an offline render of `[10, 10.72)` schedules its first event at
120
+ * THE OFFSET TRAP, stated at the call site because it is the correctness
121
+ * argument of this whole path: an offline render of `[10, 10.72)` schedules its first event at
111
122
  * LOCAL time 0, not absolute 10. `startSeconds` is where the paused run
112
123
  * stands on its own canonical clock when frame 0 is captured; `render` is
113
124
  * asked for `[startSeconds, startSeconds + frames / fps)` and must subtract