@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
@@ -7,11 +7,11 @@
7
7
  * neither matters to a project that plays nothing.
8
8
  */
9
9
  import { installAudioPoseGuard } from '../src/services/audio-pose-guard';
10
- import { installGameAudioUnlock } from '../src/services/game-audio-unlock';
10
+ import { installGameAudio } from '../src/services/game-audio';
11
11
 
12
12
  export const point = 'workspace.service';
13
13
 
14
14
  export function start(): void {
15
- installGameAudioUnlock();
15
+ installGameAudio();
16
16
  installAudioPoseGuard();
17
17
  }
@@ -15,7 +15,7 @@
15
15
  * It reports its failure to the editor console — `vgai console` is what reads
16
16
  * it — rather than leaving a stopped surface with no reason on it.
17
17
  */
18
- import { onShellStore } from '@volter/editor-core/shell-store-door';
18
+ import { onShellStore } from '@volter/editor-sdk/kit/shell-store-door';
19
19
  import { editorHost } from '@volter/editor-sdk/host';
20
20
  import { enterPlayMode } from '../src/play/play-mode';
21
21
 
@@ -21,13 +21,13 @@
21
21
  * imports when they move. Nothing here is host API.
22
22
  */
23
23
 
24
- import { getActiveSystems } from '@volter/editor-core/authoring/active-systems';
24
+ import { getActiveSystems } from '@volter/editor-sdk/kit/authoring/active-systems';
25
25
  import {
26
26
  activeGameplayRecordingTimeline,
27
27
  startGameplayRecording,
28
28
  stopGameplayRecording,
29
29
  } from '../src/host/gameplay-recording';
30
- import { captureGameplayReplay, exportGameplayReplay } from '@volter/editor-core/gameplay-replay';
30
+ import { captureGameplayReplay, exportGameplayReplay } from '@volter/editor-sdk/kit/gameplay-replay';
31
31
  import type { CommandContribution } from '@volter/editor-sdk/commands';
32
32
  import { handleBridgeCall } from '../src/bridge/call';
33
33
  import { hasLiveDebugPlane } from '../src/bridge/dispatch';
@@ -140,7 +140,7 @@ export const commands: CommandContribution['commands'] = {
140
140
  appendGameplayRecordingChunk,
141
141
  finishGameplayRecordingSink,
142
142
  abortGameplayRecordingSink,
143
- } = await import('@volter/editor-core/editor-api');
143
+ } = await import('@volter/editor-sdk/kit/editor-api');
144
144
  const sink = await beginGameplayRecordingSink({
145
145
  startedAt: new Date().toISOString(),
146
146
  mimeType: 'video/webm',
@@ -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
+ }
@@ -0,0 +1,16 @@
1
+ /**
2
+ * THE CANVAS MEDIUM'S COMPONENT BOARD (`@volter/editor-sdk/services`, a
3
+ * `workspace.service` contribution): `@volter/editor-game`'s canvas medium tells the host's component
4
+ * board registry that this project's `canvas` stories have a `2D` board.
5
+ *
6
+ * The same shape as `contributions/react/component-board.service.ts`.
7
+ */
8
+
9
+ import { registerComponentBoard } from '@volter/editor-sdk/kit/component-board-registry';
10
+ import { canvasComponentBoard } from '../../src/canvas/canvas-board/canvas-component-board';
11
+
12
+ export const point = 'workspace.service';
13
+
14
+ export function start(): () => void {
15
+ return registerComponentBoard(canvasComponentBoard);
16
+ }
@@ -0,0 +1,45 @@
1
+ /**
2
+ * THE CANVAS MEDIUM'S DESIGN-TIME MOUNT (a `workspace.service` contribution):
3
+ * tells the SDK's design-time mount registry how a `canvas` world mounts in
4
+ * Edit. The same shape as `contributions/react/design-time-mount.service.ts`;
5
+ * the mount itself stays behind a dynamic `import()` so `pixi.js` and
6
+ * `@pixi/react` load only for a project that declares a canvas root.
7
+ */
8
+
9
+ import { registerDesignTimeMount } from '@volter/editor-sdk/kit/authoring/design-time-mount-registry';
10
+
11
+ export const point = 'workspace.service';
12
+
13
+ export function start(): () => void {
14
+ return registerDesignTimeMount({
15
+ kind: 'canvas',
16
+ owner: '@volter/editor-game/canvas/design-time-mount',
17
+ // The `ResolvedAdapter['identity']` a mount failure is reported under —
18
+ // the literal the host's own catch block used to spell.
19
+ identity: 'default-pixi',
20
+ // A canvas layer is always interactive: its content IS the document's
21
+ // whole subject (the game's 2D scene), and a click on it is how you
22
+ // select in it. The dom medium declares the opposite, because its
23
+ // design-time hover/press testing competes with authoring gestures.
24
+ alwaysInteractive: true,
25
+ mount: async (candidate, layer, context) => {
26
+ const { mountCanvasDesignTimeLayer } = await import('../../src/canvas/design-time-canvas-mount');
27
+ return mountCanvasDesignTimeLayer(candidate, layer, context);
28
+ },
29
+ remountWhen: (invalidate) => {
30
+ let stopped = false;
31
+ let stop: (() => void) | null = null;
32
+ // Loaded here for the same reason the mount is: the host calls this only when a canvas
33
+ // candidate exists.
34
+ void import('../../src/canvas/design-time-canvas-mount').then((module) => {
35
+ if (stopped) return;
36
+ stop = module.remountWhenSourceIsWritten(invalidate);
37
+ });
38
+ return () => {
39
+ stopped = true;
40
+ stop?.();
41
+ stop = null;
42
+ };
43
+ },
44
+ });
45
+ }
@@ -0,0 +1,12 @@
1
+ /**
2
+ * The canvas medium's captures, installed at boot (`workspace.service`): story thumbnails for a
3
+ * canvas story in an offscreen Pixi application, and Pixi's same-frame canvas pixels
4
+ * (`src/host/stories/story-media-captures.ts`). They are the game's, because Pixi is.
5
+ */
6
+ import { registerStoryMediaCaptures } from '../src/host/stories/story-media-captures';
7
+
8
+ export const point = 'workspace.service';
9
+
10
+ export function start(): () => void {
11
+ return registerStoryMediaCaptures();
12
+ }
@@ -10,8 +10,8 @@
10
10
  *
11
11
  * It was `components/EditModeAudioBootstrap.tsx`, a component that rendered
12
12
  * `null` so the shell's layout could run an effect, and through it the host
13
- * imported `@volter/game-runtime/setup/setup-audio`, `@volter/game-runtime/audio/bus-mixer` and
14
- * `@volter/game-runtime/audio/pose-guard` — the engine's audio RUNTIME — into every editor
13
+ * imported `@volter/editor-game/runtime/setup/setup-audio`, `@volter/editor-game/runtime/audio/bus-mixer` and
14
+ * `@volter/editor-game/runtime/audio/pose-guard` — the engine's audio RUNTIME — into every editor
15
15
  * boot (WORK.md §The open-source launch, phase 1 unit 7).
16
16
  */
17
17
  import { installEditModeAudio } from '../src/edit-mode/edit-mode-audio';
@@ -12,7 +12,7 @@
12
12
  * that always was, and the shell no longer names it (WORK.md §The workbench,
13
13
  * P3b).
14
14
  */
15
- import { onProjectChange } from '@volter/editor-core/project-manager';
15
+ import { onProjectChange } from '@volter/editor-sdk/kit/active-project';
16
16
  import { installEditModeNetworking } from '../src/edit-mode/edit-mode-networking';
17
17
 
18
18
  export const point = 'workspace.service';
@@ -5,7 +5,7 @@
5
5
  *
6
6
  * All eight read/actuate the LIVE play session's game-scoped debug registry
7
7
  * (`SystemAdapters.debug`, installed by `setActiveSystems` on play enter) or
8
- * its InputManager/GameLoop (via `getPlayRuntimeAccess`). A stopped session
8
+ * its input door/GameLoop (via `getPlayRuntimeAccess`). A stopped session
9
9
  * answers with a structured failure, never a fabricated success; a running
10
10
  * game that exposes NO debug adapter (a non-first-party mount) degrades to
11
11
  * the honest empty/null shape.
@@ -17,7 +17,7 @@
17
17
  * when they move. Nothing here is host API.
18
18
  */
19
19
 
20
- import { getActiveSystems } from '@volter/editor-core/authoring/active-systems';
20
+ import { getActiveSystems } from '@volter/editor-sdk/kit/authoring/active-systems';
21
21
  import type { CommandContribution } from '@volter/editor-sdk/commands';
22
22
  import { notPlayingResult, structuredErrorResult } from '../src/command-results';
23
23
  import { getPlayRuntimeAccess, isPlayModeActive } from '../src/play/play-mode';
@@ -111,7 +111,7 @@ export const commands: CommandContribution['commands'] = {
111
111
  if (!input) {
112
112
  return {
113
113
  ok: false,
114
- error: 'this play session has no first-party InputManager to inject into',
114
+ error: 'this play session has no input door: no root entry exports `debug.input`',
115
115
  };
116
116
  }
117
117
  try {
@@ -122,7 +122,7 @@ export const commands: CommandContribution['commands'] = {
122
122
  // bindings, so `delivered` here means "the source was written").
123
123
  if (cmd['kind'] === 'action') {
124
124
  const atTick = cmd['atTick'];
125
- // D15/T-D15.5 — `atTick` defers to InputManager.scheduleActionAtTick
125
+ // D15/T-D15.5 — `atTick` defers to the target's scheduleActionAtTick
126
126
  // instead of an immediate setVirtualAction. scheduleActionAtTick
127
127
  // throws InputActionError/a valueType mismatch (same as
128
128
  // setVirtualAction) or InputTickError ('TICK_ALREADY_PASSED',
@@ -30,7 +30,7 @@
30
30
  * routes over HTTP exactly as it did when it lived in the host.
31
31
  */
32
32
 
33
- import { registerDocumentOpener } from '@volter/editor-core/document-open-registry';
33
+ import { registerDocumentOpener } from '@volter/editor-sdk/kit/document-open-registry';
34
34
  import { CONTRIBUTED_WORKSPACE_UTILITIES } from '@volter/editor-sdk/kit/workspace-core-utilities';
35
35
  import { registerWorkspaceUtility } from '@volter/editor-sdk/kit/workspace-utility-registry';
36
36
  import { GenerationActivity } from '../src/generation/GenerationActivity';
@@ -31,12 +31,29 @@ export const style: StyleContribution = {
31
31
  large: '0 6px 18px rgba(0,0,0,0.5)',
32
32
  },
33
33
  stage: {
34
- // Godot's `manipulator_gizmo_size` is 80, but its unit is not ours: the stage's px per
35
- // gizmo unit is fitted, not transcribed. At 128 the rotation rings measure ~80 px in
36
- // radius on a 1x capture, against ~85 px in `engine-reference/godot/tuto_3d5.png`.
37
- gizmoSize: 128,
38
- // The move arrows reach 1.6 ring radii with a head about half again three's
39
- // (`tuto_3d5.png`: a 142 px tip against a 90 px ring, a 25 px head).
34
+ // THE VIEWPORT'S OWN CHROME (`tuto_3d3.png`): the 3D editor's toolbar is a flush band
35
+ // over the view, the tools at its start and the view's controls after them; inside the
36
+ // view only the "⋮ Perspective" pill at the top-left, which opens the view menu.
37
+ // The transform controls (local space, snap) follow the tools on the band, as Godot's do.
38
+ chrome: { bar: 'strip', viewName: 'menu', tools: 'bar-start', display: 'bar-end', transformControls: 'bar' },
39
+ // Godot's display modes and its View menu, where the gizmos are switched.
40
+ words: {
41
+ shading: {
42
+ solid: 'Display Normal',
43
+ wireframe: 'Display Wireframe',
44
+ overdraw: 'Display Overdraw',
45
+ unlit: 'Display Unshaded',
46
+ },
47
+ helpers: 'View',
48
+ },
49
+ // The stage's ring radius in CSS px. Godot's gizmo unit is `manipulator_gizmo_size` (80)
50
+ // px on screen (`gizmo_scale = gizmo_size / dd`, `node_3d_editor_plugin.cpp`, at EDSCALE 1
51
+ // in a viewport at least 400 px tall) and its ring stands at `GIZMO_CIRCLE_SIZE` 1.1 of
52
+ // it: 88 px, as `engine-reference/godot/tuto_3d5.png`'s ~90 px ring.
53
+ gizmoSize: 88,
54
+ // The move arrows' tips stand at `GIZMO_ARROW_OFFSET` + `GIZMO_ARROW_SIZE` (1.4 + 0.35)
55
+ // units, 1.6 ring radii, with a head about half again three's (`tuto_3d5.png`: a 142 px
56
+ // tip against a 90 px ring, a 25 px head).
40
57
  gizmoArrowLength: 1.6,
41
58
  gizmoArrowHead: 1.5,
42
59
  // Its rotation rings are about twice three's thickness (`tuto_3d5.png`).
@@ -44,6 +61,9 @@ export const style: StyleContribution = {
44
61
  // `manipulator_gizmo_opacity` 0.9; the highlight is the axis colour at a quarter of its
45
62
  // saturation and full value (`node_3d_editor_plugin.cpp`).
46
63
  gizmoOpacity: 0.9,
64
+ // Its orientation gizmo is its own (`ViewportRotationControl::_draw_axis`): opacity by
65
+ // depth, darkened negatives, no mix toward the viewport (the editor's `godot` form).
66
+ navigationGizmo: 'godot',
47
67
  gizmoHighlightSaturation: 0.25,
48
68
  gizmoHighlightValue: 1,
49
69
  // Godot's grid lines are hairlines at both levels.
@@ -13,6 +13,9 @@ export const view: ViewPreset = {
13
13
  id: 'godot',
14
14
  title: 'Godot',
15
15
  layer: {
16
+ // Godot's editor camera: `editors/3d/default_fov` 70 (`editor_settings.cpp`), vertical — the
17
+ // editor's Camera3D keeps its height.
18
+ camera: { fov: { degrees: 70, axis: 'vertical' } },
16
19
  all: {
17
20
  lighting: {
18
21
  source: 'preview',
@@ -43,6 +46,9 @@ export const view: ViewPreset = {
43
46
  },
44
47
  },
45
48
  overlays: {
49
+ // No zoom and pan buttons under the gizmo and no camera readout: the engine draws neither.
50
+ navigationControls: false,
51
+ cameraReadout: false,
46
52
  grid: {
47
53
  visible: true,
48
54
  majorEvery: 8,
@@ -42,10 +42,10 @@
42
42
  */
43
43
  import { editorConsole } from '@volter/editor-sdk/kit/editor-console';
44
44
  import { importIngestAdapterModule, ingestAdapterModulePath } from '../src/host/ingest/registry';
45
- import { registerAdapterDefinitionSource } from '@volter/editor-core/project-adapter';
46
- import { threeStoreForHost } from '@volter/editor-core/shell-store-door';
45
+ import { registerAdapterDefinitionSource } from '@volter/editor-sdk/kit/project-adapter';
47
46
  import { editorHost } from '@volter/editor-sdk/host';
48
47
  import { autoLaunchIngest } from '../src/ingest/mount-ingest-root';
48
+ import { threeStoreForHost } from '@volter/editor-threejs/kit/three-state';
49
49
 
50
50
  export const point = 'workspace.service';
51
51
 
@@ -10,7 +10,7 @@
10
10
  * when they move. Nothing here is host API.
11
11
  */
12
12
 
13
- import { liveInstanceIds } from '@volter/editor-core/authoring/active-systems';
13
+ import { liveInstanceIds } from '@volter/editor-sdk/kit/authoring/active-systems';
14
14
  import type { CommandContribution } from '@volter/editor-sdk/commands';
15
15
  import {
16
16
  instanceEntries,
@@ -11,7 +11,7 @@
11
11
  * on its availability tick while a menu is open, so they follow the mounted
12
12
  * game's `NavigationAdapter` and a bake in flight.
13
13
  */
14
- import { getActiveSystems } from '@volter/editor-core/authoring/active-systems';
14
+ import { getActiveSystems } from '@volter/editor-sdk/kit/authoring/active-systems';
15
15
  import type { MenuContribution } from '@volter/editor-sdk/chrome';
16
16
  import { dispatchNavMeshBake, dispatchNavMeshClear } from '../src/navmesh/navmesh-actions';
17
17
  import { navBakeBusy, navMeshBaked } from '../src/navmesh/navmesh-workflow-store';
@@ -0,0 +1,14 @@
1
+ /**
2
+ * The page-level observer of a RUNNING game's Colyseus rooms (`@volter/editor-sdk/services`, a
3
+ * `workspace.service` contribution): wraps the page's WebSocket and fetch once, before any game
4
+ * joins a room, so the Network inspector reads a game that declares no networking adapter
5
+ * (`src/services/game-network.ts`). Page-wide and idempotent; a game that joins nothing is not
6
+ * affected.
7
+ */
8
+ import { installGameNetwork } from '../src/services/game-network';
9
+
10
+ export const point = 'workspace.service';
11
+
12
+ export function start(): void {
13
+ installGameNetwork();
14
+ }
@@ -28,8 +28,8 @@
28
28
  * it, and no contribution point injects a panel's header component.
29
29
  */
30
30
 
31
- import { getActiveSystems } from '@volter/editor-core/authoring/active-systems';
32
- import { setGameplayExportActive } from '@volter/editor-core/gameplay-export-state';
31
+ import { getActiveSystems } from '@volter/editor-sdk/kit/authoring/active-systems';
32
+ import { setGameplayExportActive } from '@volter/editor-sdk/kit/gameplay-export-state';
33
33
  import { stopGameplayRecording } from '../src/host/gameplay-recording';
34
34
  import { liveInstanceContainer } from '@volter/editor-sdk/kit/live-session-registry';
35
35
  import type { CommandContribution } from '@volter/editor-sdk/commands';
@@ -46,6 +46,7 @@ import {
46
46
  stepPlayMode,
47
47
  } from '../src/play/play-mode';
48
48
  import { beginPlayRecording, endPlayRecording, notePlayActivity } from '../src/play/play-recording';
49
+ import { startSelectedRunConfiguration, stopStartedRunConfiguration } from '../src/play/run-selection';
49
50
 
50
51
  export const point = 'workspace.command';
51
52
 
@@ -55,7 +56,7 @@ export const point = 'workspace.command';
55
56
  async function captureLiveCanvasFrame(
56
57
  canvas: HTMLCanvasElement,
57
58
  ): Promise<CanvasImageSource | null> {
58
- const { liveCanvasFrame } = await import('@volter/editor-core/live-canvas-frame');
59
+ const { liveCanvasFrame } = await import('@volter/editor-sdk/kit/live-canvas-frame');
59
60
  return liveCanvasFrame(canvas);
60
61
  }
61
62
 
@@ -134,6 +135,10 @@ export const commands: CommandContribution['commands'] = {
134
135
  // field on the relayed command, slugified server-side into this run's
135
136
  // log filename and journal line. Absent, everything is unchanged.
136
137
  const runName = cmd['name'];
138
+ // What Play runs beside the host starts first, exactly as the Play button starts it: a
139
+ // `play + server` project's room server is up before its game joins.
140
+ const start = await startSelectedRunConfiguration();
141
+ if (!start.ok) return { ok: false, error: `${start.title}: ${start.detail}` };
137
142
  await enterPlayMode(
138
143
  typeof seed === 'number' ? seed : undefined,
139
144
  undefined,
@@ -208,6 +213,7 @@ export const commands: CommandContribution['commands'] = {
208
213
  // someone stopping the run wanted to look at.
209
214
  const capture = await endPlayRecording('stop');
210
215
  exitPlayMode();
216
+ await stopStartedRunConfiguration();
211
217
  return { ok: true, ...(capture ? { data: { recording: capture } } : {}) };
212
218
  },
213
219
  },
@@ -303,7 +309,7 @@ export const commands: CommandContribution['commands'] = {
303
309
  appendGameplayRecordingChunk,
304
310
  finishGameplayRecordingSink,
305
311
  abortGameplayRecordingSink,
306
- } = await import('@volter/editor-core/editor-api');
312
+ } = await import('@volter/editor-sdk/kit/editor-api');
307
313
  controller.signal.throwIfAborted();
308
314
  const sink = await beginGameplayRecordingSink(
309
315
  {
@@ -11,7 +11,7 @@
11
11
  * candidate appears: a promise cannot answer a verdict thunk.
12
12
  */
13
13
 
14
- import { registerComponentBoard } from '@volter/editor-core/component-board-registry';
14
+ import { registerComponentBoard } from '@volter/editor-sdk/kit/component-board-registry';
15
15
  import { uiComponentBoard } from '../../src/react/ui-component-board';
16
16
 
17
17
  export const point = 'workspace.service';
@@ -21,7 +21,7 @@
21
21
  * the build's eager graph.
22
22
  */
23
23
 
24
- import { registerDesignTimeMount } from '@volter/editor-core/authoring/design-time-mount-registry';
24
+ import { registerDesignTimeMount } from '@volter/editor-sdk/kit/authoring/design-time-mount-registry';
25
25
 
26
26
  export const point = 'workspace.service';
27
27
 
@@ -7,13 +7,13 @@
7
7
  *
8
8
  * The session store arrives after the contribution pass, and a project switch
9
9
  * brings a new one, so the document binds on each store's ARRIVAL
10
- * (`@volter/editor-core/shell-store-door`'s `onShellStore`, as Play's
10
+ * (`@volter/editor-sdk/kit/shell-store-door`'s `onShellStore`, as Play's
11
11
  * autoplay entry does) and unbinds the previous store's binding first.
12
12
  */
13
- import { onThreeStore } from '@volter/editor-core/shell-store-door';
14
- import { unregisterAvailableWorkspaceDocument } from '@volter/editor-core/workspace-available-documents';
13
+ import { unregisterAvailableWorkspaceDocument } from '@volter/editor-sdk/kit/workspace-available-documents';
15
14
  import { SCENE_DOCUMENT_ID } from '@volter/editor-sdk/kit/workspace-document-ids';
16
15
  import { bindSceneDocument } from '../src/host/components/scene-document';
16
+ import { onThreeStore } from '@volter/editor-threejs/kit/three-state';
17
17
 
18
18
  export const point = 'workspace.service';
19
19
 
@@ -3,7 +3,7 @@
3
3
  * same predicate the drawer tab's own `available` gate reads. `disabled` is
4
4
  * asked at render, so it follows the session.
5
5
  */
6
- import { getActiveDebug } from '@volter/editor-core/authoring/active-systems';
6
+ import { getActiveDebug } from '@volter/editor-sdk/kit/authoring/active-systems';
7
7
  import type { MenuContribution } from '@volter/editor-sdk/chrome';
8
8
  import { editorHost } from '@volter/editor-sdk/host';
9
9
 
@@ -7,7 +7,7 @@
7
7
  * `available` reads the PRIMARY authoring mount's debug adapter, exactly what
8
8
  * the panel itself reads, so the gate and the content can never disagree.
9
9
  */
10
- import { getActiveDebug } from '@volter/editor-core/authoring/active-systems';
10
+ import { getActiveDebug } from '@volter/editor-sdk/kit/authoring/active-systems';
11
11
  import { StateWatchPanel } from '../src/state-watch/StateWatchPanel';
12
12
 
13
13
  export const point = 'workspace.utility';
@@ -11,10 +11,10 @@
11
11
  * through the `@editor/*` alias.
12
12
  */
13
13
 
14
- import { getActiveNetworking, subscribeActiveNetworking } from '@volter/editor-core/authoring/active-systems';
15
- import { connectCollaboration } from '@volter/editor-core/collaboration-client';
16
- import { reportCollaborationPresence } from '@volter/editor-core/collaboration-presence';
17
- import { EDITOR_PARTICIPANT_ID } from '@volter/editor-core/editor-presence';
14
+ import { getActiveNetworking, subscribeActiveNetworking } from '@volter/editor-sdk/kit/authoring/active-systems';
15
+ import { connectCollaboration } from '@volter/editor-sdk/kit/collaboration-client';
16
+ import { reportCollaborationPresence } from '@volter/editor-sdk/kit/collaboration-presence';
17
+ import { EDITOR_PARTICIPANT_ID } from '@volter/editor-sdk/kit/editor-presence';
18
18
  import { activePlaytest, enterPlayMode, exitPlayMode } from '../src/play/play-mode';
19
19
 
20
20
  export const point = 'workspace.service';
@@ -14,7 +14,7 @@
14
14
  * the same question as "do you want three?".
15
15
  */
16
16
 
17
- import { registerComponentBoard } from '@volter/editor-core/component-board-registry';
17
+ import { registerComponentBoard } from '@volter/editor-sdk/kit/component-board-registry';
18
18
  import { threeComponentBoard } from '../../src/three/three-board/three-component-board';
19
19
 
20
20
  export const point = 'workspace.service';
@@ -24,14 +24,14 @@
24
24
  * the two cannot drift.
25
25
  */
26
26
 
27
- import { getActiveAuthoring } from '@volter/editor-core/authoring/active-adapter';
28
- import type { EditorShellStore } from '@volter/editor-core/editor-shell-store';
27
+ import { getActiveAuthoring } from '@volter/editor-sdk/kit/authoring/active-adapter';
28
+ import type { EditorShellStore } from '@volter/editor-threejs/kit/editor-shell-store';
29
29
  import { canExtractNode, isExtractedHint } from '../../src/host/instance-extract-actions';
30
30
  import { canForkInstance, isForkedHint } from '../../src/host/instance-fork-actions';
31
- import { threeStoreForHost } from '@volter/editor-core/shell-store-door';
32
31
  import type { CommandContribution } from '@volter/editor-sdk/commands';
33
32
  import { instanceExtractSourceFor } from '../../src/three/component-verbs/extract-menu';
34
33
  import { instanceForkSourceFor } from '../../src/three/component-verbs/fork-menu';
34
+ import { threeStoreForHost } from '@volter/editor-threejs/kit/three-state';
35
35
 
36
36
  /** The shell store, or the refusal that says the page has not installed one —
37
37
  * the same shape `bridge.command.ts` takes it in, made explicit because both
@@ -42,7 +42,7 @@ const NO_STORE = { ok: false as const, error: 'the editor shell has not started
42
42
  function subjectId(cmd: Record<string, unknown>, store: EditorShellStore): string | undefined {
43
43
  const given = cmd['id'];
44
44
  if (typeof given === 'string' && given.trim() !== '') return given;
45
- return [...store.selectedEntityIds][0];
45
+ return [...store.shell.selectedEntityIds][0];
46
46
  }
47
47
 
48
48
  export const commands: CommandContribution['commands'] = {
@@ -55,7 +55,7 @@ export const commands: CommandContribution['commands'] = {
55
55
  if (!store) return NO_STORE;
56
56
  const id = subjectId(cmd, store);
57
57
  if (!id) return { ok: false, error: 'extract-component needs an id or a selected row.' };
58
- const adapter = getActiveAuthoring(store);
58
+ const adapter = getActiveAuthoring(store.shell);
59
59
  const source = instanceExtractSourceFor(adapter, id);
60
60
  if (!canExtractNode(adapter.hierarchy.node(id), source, id)) {
61
61
  return {
@@ -86,7 +86,7 @@ export const commands: CommandContribution['commands'] = {
86
86
  if (!store) return NO_STORE;
87
87
  const id = subjectId(cmd, store);
88
88
  if (!id) return { ok: false, error: 'fork-component needs an id or a selected row.' };
89
- const adapter = getActiveAuthoring(store);
89
+ const adapter = getActiveAuthoring(store.shell);
90
90
  const source = instanceForkSourceFor(adapter, id);
91
91
  if (!canForkInstance(adapter.hierarchy.node(id), source, id)) {
92
92
  return {
@@ -25,11 +25,13 @@
25
25
  * product that composes this package pays for it.
26
26
  */
27
27
 
28
- import { setBaseAuthoringFactory } from '@volter/editor-core/authoring/active-adapter';
29
- import { registerDesignTimeMount } from '@volter/editor-core/authoring/design-time-mount-registry';
30
- import { queueEditModeRebuild } from '@volter/editor-core/authoring/edit-mode-authoring';
28
+ import { setBaseAuthoringFactory } from '@volter/editor-sdk/kit/authoring/active-adapter';
29
+ import { registerDesignTimeMount } from '@volter/editor-sdk/kit/authoring/design-time-mount-registry';
30
+ import { queueEditModeRebuild } from '@volter/editor-sdk/kit/authoring/edit-mode-authoring';
31
31
  import { authoringJournal } from '../../src/host/history/json-history-resource';
32
32
  import { oidThree } from '../../src/three/authoring/three-authoring-adapter';
33
+ import type { WorldRootSessionContext } from '../../src/host/components/world-root-stage';
34
+ import { threeStateOf } from '@volter/editor-threejs/kit/three-state';
33
35
 
34
36
  export const point = 'workspace.service';
35
37
 
@@ -45,12 +47,13 @@ export function start(): () => void {
45
47
  // R3F design session's fiber scene, once it adopts) is what the hierarchy
46
48
  // shows, and an unmounted world honestly shows nothing rather than a
47
49
  // fabricated document.
48
- oidThree(store, () => store.scene, worldId, authoringJournal(worldId)),
50
+ oidThree(threeStateOf(store), () => threeStateOf(store).scene, worldId, authoringJournal(worldId)),
49
51
  );
50
52
  const stopMount = registerDesignTimeMount({
51
53
  kind: 'three',
52
54
  owner: '@volter/editor-game/three/three-authoring',
53
- mountWorldRootSession: async (context) => {
55
+ async mountWorldRootSession(stage) {
56
+ const context = stage as WorldRootSessionContext;
54
57
  const { mountR3FDesignSession } = await session;
55
58
  return mountR3FDesignSession(context.store, context.composite, context.renderer);
56
59
  },