@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
@@ -22,8 +22,8 @@
22
22
 
23
23
  import { measureAdapterReach } from '../host/adapter-reach';
24
24
  import { nextPaint } from '../host/after-paint';
25
- import { setActiveAuthoring } from '@volter/editor-core/authoring/active-adapter';
26
- import { setActiveSystems } from '@volter/editor-core/authoring/active-systems';
25
+ import { setActiveAuthoring } from '@volter/editor-sdk/kit/authoring/active-adapter';
26
+ import { setActiveSystems } from '@volter/editor-sdk/kit/authoring/active-systems';
27
27
  import { BabylonAuthoringAdapter } from '../host/authoring/babylon-authoring-adapter';
28
28
  import {
29
29
  type BabylonRealmLike,
@@ -43,9 +43,9 @@ import { resolveCanvasPixiForEditor } from '../host/canvas-entry-runtime';
43
43
  import {
44
44
  capturePixiDisplayObjectThumbnail,
45
45
  registerPresentedPixiApps,
46
- } from '@volter/editor-core/canvas-preview-frames';
46
+ } from '../host/canvas-preview-frames';
47
47
  import { editorConsole } from '@volter/editor-sdk/kit/editor-console';
48
- import type { EditorShellStore } from '@volter/editor-core/editor-shell-store';
48
+ import type { EditorShellStore } from '@volter/editor-threejs/kit/editor-shell-store';
49
49
  import { GAME_SURFACE_CONTAINMENT_CSS } from '../host/game-realm-page';
50
50
  import {
51
51
  clearGameSurface,
@@ -55,20 +55,20 @@ import {
55
55
  } from '../host/gated-globals';
56
56
  import { authoringJournal } from '../host/history/json-history-resource';
57
57
  import { acquireLiveDocument, liveDocumentContainer } from '@volter/editor-sdk/kit/live-document';
58
- import { getCurrentProject } from '@volter/editor-core/project-manager';
58
+ import { getCurrentProject } from '@volter/editor-sdk/kit/active-project';
59
59
  import { recordRootReadiness } from '@volter/editor-sdk/kit/readiness';
60
60
  import type { MeasuredLoop } from '../host/same-realm-loop-gate';
61
- import { projectContractSystemAdapters } from '@volter/game-runtime/adapter/ingest/contract-system-adapters';
62
- import type { RenderDebugWiring } from '@volter/game-runtime/dev/render-debug-adapter';
63
- import type { IngestGame2D } from '@volter/game-runtime/pixi/ingest';
64
- import { INGEST_GAME_2D_LOAD_ERROR_NAME, mountIngestGame2D } from '@volter/game-runtime/pixi/ingest';
65
- import { createPhysics2DRegistry } from '@volter/game-runtime/pixi/physics-registry';
66
- import { installPixiRenderPassBracket } from '@volter/game-runtime/pixi/render-pass-bracket';
61
+ import { projectContractSystemAdapters } from '../runtime/adapter/ingest/contract-system-adapters';
62
+ import type { RenderDebugWiring } from '../runtime/dev/render-debug-adapter';
63
+ import type { IngestGame2D } from '../runtime/pixi/ingest';
64
+ import { INGEST_GAME_2D_LOAD_ERROR_NAME, mountIngestGame2D } from '../runtime/pixi/ingest';
65
+ import { createPhysics2DRegistry } from '../runtime/pixi/physics-registry';
66
+ import { installPixiRenderPassBracket } from '../runtime/pixi/render-pass-bracket';
67
67
  import {
68
68
  composePhysicsAdapters2D,
69
69
  createPhysicsAdapter2D,
70
70
  type PhysicsAdapter2D,
71
- } from '@volter/game-runtime/pixi/system-adapters';
71
+ } from '../runtime/pixi/system-adapters';
72
72
  import type { AuthoringAdapter } from '@volter/editor-project/adapter/authoring';
73
73
  import { readGameReady } from '@volter/editor-project/adapter/ingest/game-contract';
74
74
  import { displayKeyedPhysics } from '@volter/editor-project/adapter/system-adapter';
@@ -214,7 +214,7 @@ function rendererCanvasBelongsToHost(renderer: unknown, hostEl: HTMLElement): bo
214
214
  * The projection is the ONE validator: presence + typeof for the four members,
215
215
  * plus the keying check that makes a node-id-keyed declaration on this surface
216
216
  * `malformed` by name instead of a bound shape nothing here can call
217
- * (`@volter/game-runtime/adapter/ingest/contract-system-adapters`). Both verdicts reach
217
+ * (`@volter/editor-game/runtime/adapter/ingest/contract-system-adapters`). Both verdicts reach
218
218
  * the reader through the coverage row for `system.physics`, so a refusal here
219
219
  * is never silent.
220
220
  */
@@ -339,7 +339,7 @@ function publishStructuralCanvasRuntime(
339
339
  });
340
340
  disposeScene = installIngestCanvasScene(store);
341
341
 
342
- setGameInputGate(() => store.playState === 'playing' && store.activeViewportTab === 'play');
342
+ setGameInputGate(() => store.shell.playState === 'playing' && store.shell.activeViewportTab === 'play');
343
343
  setActiveAuthoring(adapter);
344
344
  // No captured Pixi renderer on this branch — the host's pixi drew nothing, so
345
345
  // there is no context to instrument, no runner pair to bracket, and no
@@ -347,7 +347,7 @@ function publishStructuralCanvasRuntime(
347
347
  // declared is the only physics this route can have.
348
348
  publishCanvasIngestSystems(game.name, undefined, declaredCanvasPhysics());
349
349
  landIngestBootInEdit();
350
- store.notifyIngestEdit();
350
+ store.shell.notifyIngestEdit();
351
351
  clearMountFailureReports();
352
352
 
353
353
  recordMountCoverage({
@@ -395,7 +395,7 @@ async function mountCanvasIngestRootInner(
395
395
  return;
396
396
  }
397
397
 
398
- store.setPlayState('playing');
398
+ store.shell.setPlayState('playing');
399
399
  editorConsole.log(`Ingesting unmodified PixiJS game: ${game.name}`, 'ingest');
400
400
 
401
401
  // PD-3: READINESS, RECORDED. The three lane's self-booting mount has always
@@ -473,7 +473,7 @@ async function mountCanvasIngestRootInner(
473
473
  markGameCssScope(hostEl);
474
474
  const scopedCssProject = getCurrentProject();
475
475
  if (scopedCssProject) {
476
- const { ensureScopedGameStyles } = await import('@volter/editor-core/scoped-game-css');
476
+ const { ensureScopedGameStyles } = await import('@volter/editor-sdk/kit/scoped-game-css');
477
477
  await ensureScopedGameStyles(scopedCssProject.rootPath);
478
478
  }
479
479
  }
@@ -587,7 +587,7 @@ async function mountCanvasIngestRootInner(
587
587
  }
588
588
 
589
589
  // The captured `Application` — the game's own, trapped on its first render
590
- // (`@volter/game-runtime/pixi/scene-capture`). Two things hang off it, and neither is
590
+ // (`@volter/editor-game/runtime/pixi/scene-capture`). Two things hang off it, and neither is
591
591
  // available anywhere else.
592
592
  const app = mount.capture.captured?.app as Application | undefined;
593
593
 
@@ -685,7 +685,7 @@ async function mountCanvasIngestRootInner(
685
685
  journal: authoringJournal(sessionId),
686
686
  target: createCreationSiteCanvasWriteTarget({
687
687
  physics: physicsAdapter,
688
- history: store.projectHistory,
688
+ history: store.shell.projectHistory,
689
689
  }),
690
690
  ...(stories ? { stories } : {}),
691
691
  // The captured game canvas is the screen↔stage mapping `pickable`/`rects`
@@ -755,7 +755,7 @@ async function mountCanvasIngestRootInner(
755
755
  // R2c: PixiJS ingest fixtures (`ingest/games/**`) are just as
756
756
  // unshadowed-by-default as the three.js ones — drive the same gate as
757
757
  // {@link mountThreeIngestRoot} (see that function's doc comment).
758
- setGameInputGate(() => store.playState === 'playing' && store.activeViewportTab === 'play');
758
+ setGameInputGate(() => store.shell.playState === 'playing' && store.shell.activeViewportTab === 'play');
759
759
 
760
760
  setActiveAuthoring(adapter);
761
761
  // The captured game's OWN renderer — the one object that carries both halves
@@ -771,7 +771,7 @@ async function mountCanvasIngestRootInner(
771
771
  declaredPhysics ? physicsAdapter : null,
772
772
  );
773
773
  landIngestBootInEdit();
774
- store.notifyIngestEdit();
774
+ store.shell.notifyIngestEdit();
775
775
  clearMountFailureReports(); // D-W3: mount succeeded
776
776
  // PD-3: the mount stood — but `contract-ready` may only be recorded when the
777
777
  // declared promise actually ANSWERED. The three lane's `awaitWorldReady`
@@ -13,7 +13,7 @@
13
13
  */
14
14
 
15
15
  import type { AdapterReach } from '../host/adapter-reach';
16
- import { getActiveSystems } from '@volter/editor-core/authoring/active-systems';
16
+ import { getActiveSystems } from '@volter/editor-sdk/kit/authoring/active-systems';
17
17
  import { ingestDataWriterNow } from '../host/authoring/ingest-data-writer';
18
18
  import { ingestOwnershipNow } from '../host/authoring/ingest-source-persistence';
19
19
  import {
@@ -36,7 +36,7 @@ import {
36
36
  import {
37
37
  type ContractSurface,
38
38
  projectContractSystemAdapters,
39
- } from '@volter/game-runtime/adapter/ingest/contract-system-adapters';
39
+ } from '../runtime/adapter/ingest/contract-system-adapters';
40
40
  import type { VgaiGameContract } from '@volter/editor-project/adapter/ingest/game-contract';
41
41
  import type { SystemAdapters } from '@volter/editor-project/adapter/system-adapter';
42
42
  import { activeIngest } from './active-ingest';
@@ -6,12 +6,12 @@
6
6
  */
7
7
 
8
8
  import { measureAdapterReach } from '../host/adapter-reach';
9
- import { setActiveAuthoring } from '@volter/editor-core/authoring/active-adapter';
10
- import { setActiveSystems } from '@volter/editor-core/authoring/active-systems';
9
+ import { setActiveAuthoring } from '@volter/editor-sdk/kit/authoring/active-adapter';
10
+ import { setActiveSystems } from '@volter/editor-sdk/kit/authoring/active-systems';
11
11
  import { clearMountFailureReports } from '@volter/editor-sdk/kit/mount-failure-report';
12
12
  import { resolveAllRoots } from '../host/binding-resolver';
13
13
  import { editorConsole } from '@volter/editor-sdk/kit/editor-console';
14
- import type { EditorShellStore } from '@volter/editor-core/editor-shell-store';
14
+ import type { EditorShellStore } from '@volter/editor-threejs/kit/editor-shell-store';
15
15
  import { setGameInputGate } from '../host/gated-globals';
16
16
  import { authoringJournal } from '../host/history/json-history-resource';
17
17
  import { acquireLiveDocument, liveDocumentContainer } from '@volter/editor-sdk/kit/live-document';
@@ -89,14 +89,14 @@ async function mountDomIngestRootInner(store: EditorShellStore, folderId: string
89
89
  // react session — closes the cross-kind leak (F26 residual).
90
90
  exitActiveIngest();
91
91
 
92
- store.setPlayState('playing');
92
+ store.shell.setPlayState('playing');
93
93
  editorConsole.log(`Ingesting unmodified native-React game: ${game.manifest.name}`, 'ingest');
94
94
 
95
95
  // F26: same cold-mount announcement as the other ingest routes — the react
96
96
  // world's entry executes in the editor realm and may declare the game
97
97
  // contract to defer its session until ▶. Opt-in, never demanded.
98
98
  (window as unknown as { __vgaiMountCold?: boolean }).__vgaiMountCold = true;
99
- const { createGameRuntime } = await import('@volter/game-runtime/runtime/create-runtime');
99
+ const { createGameRuntime } = await import('../runtime/create-runtime');
100
100
  const specs = await resolveAllRoots(game.manifest, projectRoot);
101
101
  const w = gameContainer.clientWidth;
102
102
  const h = gameContainer.clientHeight;
@@ -144,12 +144,12 @@ async function mountDomIngestRootInner(store: EditorShellStore, folderId: string
144
144
  // `game-globals-shadow.ts` roots its shadow at — so a native-React fixture's
145
145
  // own listeners are shadowed on the same terms as every other surface's now
146
146
  // (this comment used to record the opposite, from the R-N6 residual).
147
- setGameInputGate(() => store.playState === 'playing' && store.activeViewportTab === 'play');
147
+ setGameInputGate(() => store.shell.playState === 'playing' && store.shell.activeViewportTab === 'play');
148
148
 
149
149
  setActiveAuthoring(adapter);
150
150
  setActiveSystems({});
151
151
  landIngestBootInEdit();
152
- store.notifyIngestEdit();
152
+ store.shell.notifyIngestEdit();
153
153
  clearMountFailureReports(); // D-W3: mount succeeded
154
154
 
155
155
  const coverage = domMountCoverage(adapter);
@@ -207,7 +207,7 @@ export async function mountDomIngestRootFromManifest(
207
207
  // react session — closes the cross-kind leak (F26 residual).
208
208
  exitActiveIngest();
209
209
 
210
- store.setPlayState('playing');
210
+ store.shell.setPlayState('playing');
211
211
  editorConsole.log(
212
212
  `Ingesting unmodified native-React game (external folder): ${world.id}`,
213
213
  'ingest',
@@ -216,7 +216,7 @@ export async function mountDomIngestRootFromManifest(
216
216
  // F26: same cold-mount announcement the vendored route makes — an
217
217
  // external-folder game may declare the game contract too.
218
218
  (window as unknown as { __vgaiMountCold?: boolean }).__vgaiMountCold = true;
219
- const { createGameRuntime } = await import('@volter/game-runtime/runtime/create-runtime');
219
+ const { createGameRuntime } = await import('../runtime/create-runtime');
220
220
  const specs = await resolveAllRoots({ ...manifest, roots: [world] }, projectRoot);
221
221
  const w = gameContainer.clientWidth;
222
222
  const h = gameContainer.clientHeight;
@@ -249,12 +249,12 @@ export async function mountDomIngestRootFromManifest(
249
249
  siblings: [],
250
250
  worldId: world.id,
251
251
  });
252
- setGameInputGate(() => store.playState === 'playing' && store.activeViewportTab === 'play');
252
+ setGameInputGate(() => store.shell.playState === 'playing' && store.shell.activeViewportTab === 'play');
253
253
 
254
254
  setActiveAuthoring(adapter);
255
255
  setActiveSystems({});
256
256
  landIngestBootInEdit();
257
- store.notifyIngestEdit();
257
+ store.shell.notifyIngestEdit();
258
258
  clearMountFailureReports(); // D-W3: mount succeeded
259
259
 
260
260
  const coverage = domMountCoverage(adapter);
@@ -23,11 +23,11 @@
23
23
  * path is therefore its catch block.
24
24
  */
25
25
 
26
- import { getAuthoringOverride, setActiveAuthoring } from '@volter/editor-core/authoring/active-adapter';
26
+ import { getAuthoringOverride, setActiveAuthoring } from '@volter/editor-sdk/kit/authoring/active-adapter';
27
27
  import {
28
28
  CompositeAuthoringAdapter,
29
29
  type CompositeChild,
30
- } from '@volter/editor-core/authoring/composite-authoring-adapter';
30
+ } from '@volter/editor-sdk/kit/authoring/composite-authoring-adapter';
31
31
  import {
32
32
  addMountFailureReport,
33
33
  clearMountFailureReports,
@@ -36,12 +36,11 @@ import {
36
36
  type MountFailureReport,
37
37
  } from '@volter/editor-sdk/kit/mount-failure-report';
38
38
  import { editorConsole } from '@volter/editor-sdk/kit/editor-console';
39
- import type { EditorShellStore } from '@volter/editor-core/editor-shell-store';
39
+ import type { EditorShellStore } from '@volter/editor-threejs/kit/editor-shell-store';
40
40
  import { registerEditorStateFacet } from '@volter/editor-sdk/kit/editor-state-facets';
41
41
  import { liveDocumentContainer } from '@volter/editor-sdk/kit/live-document';
42
- import { fetchGameManifest, isManifestAbsence } from '@volter/editor-core/manifest-project';
43
- import { getCurrentProject } from '@volter/editor-core/project-manager';
44
- import { onThreeStore } from '@volter/editor-core/shell-store-door';
42
+ import { fetchGameManifest, isManifestAbsence } from '@volter/editor-sdk/kit/manifest-project';
43
+ import { getCurrentProject } from '@volter/editor-sdk/kit/active-project';
45
44
  import { ingestRoots, rootById } from '@volter/editor-project/adapter/manifest-interpreter';
46
45
  import { MANIFEST_FILENAME } from '@volter/editor-project/manifest/filename';
47
46
  import type { ResolvedAdapterRoot, ResolvedGameManifest } from '@volter/editor-project/manifest/load';
@@ -76,6 +75,7 @@ export {
76
75
  unmountDomIngestRoot,
77
76
  unmountThreeIngestRoot,
78
77
  } from './unmount-ingest-root';
78
+ import { onThreeStore } from '@volter/editor-threejs/kit/three-state';
79
79
 
80
80
  type CanvasMounts = typeof import('./mount-canvas-ingest-root');
81
81
  type DomMounts = typeof import('./mount-dom-ingest-root');
@@ -197,13 +197,13 @@ function reportFailedIngestMount(store: EditorShellStore, report: MountFailureRe
197
197
  resetIngestPlaySurface();
198
198
  // The prologue's `setPlayState('playing')` must never outlive a failed mount
199
199
  // — that flag is what `collectState` reported as a live game (S-1).
200
- store.setPlayState('stopped');
200
+ store.shell.setPlayState('stopped');
201
201
  addMountFailureReport(report);
202
202
  // `addMountFailureReport` notifies the status item through the slot's own
203
203
  // subscribe; this broadcast is for the STORE-subscribed panels (hierarchy,
204
204
  // play controls) that must re-render off the teardown above — a failed
205
205
  // mount never reaches the success path's `notifyIngestEdit()`.
206
- store.notifyIngestEdit();
206
+ store.shell.notifyIngestEdit();
207
207
  }
208
208
 
209
209
  /**
@@ -19,15 +19,15 @@
19
19
  */
20
20
 
21
21
  import { measureAdapterReach } from '../host/adapter-reach';
22
- import { setActiveAuthoring } from '@volter/editor-core/authoring/active-adapter';
23
- import { setActiveSystems } from '@volter/editor-core/authoring/active-systems';
22
+ import { setActiveAuthoring } from '@volter/editor-sdk/kit/authoring/active-adapter';
23
+ import { setActiveSystems } from '@volter/editor-sdk/kit/authoring/active-systems';
24
24
  import { withContractHierarchy } from '../host/authoring/contract-hierarchy-authoring';
25
25
  import { clearMountFailureReports } from '@volter/editor-sdk/kit/mount-failure-report';
26
26
  import { editorConsole } from '@volter/editor-sdk/kit/editor-console';
27
- import type { EditorShellStore } from '@volter/editor-core/editor-shell-store';
27
+ import type { EditorShellStore } from '@volter/editor-threejs/kit/editor-shell-store';
28
28
  import { gameLoopGate, setGameInputGate } from '../host/gated-globals';
29
29
  import { acquireLiveDocument, liveDocumentContainer } from '@volter/editor-sdk/kit/live-document';
30
- import { pickGameCamera } from '@volter/editor-core/scene-framing';
30
+ import { pickGameCamera } from '@volter/editor-threejs/kit/scene-framing';
31
31
  import type { ResolvedAdapterRoot } from '@volter/editor-project/manifest/load';
32
32
  import type { CaptureMechanism } from '@volter/threejs-runtime/adapter/ingest/scene-capture';
33
33
  import { type IngestSession, serializeEntry, setActiveIngest } from './active-ingest';
@@ -165,7 +165,7 @@ function activateCapturedThreeIngest(args: {
165
165
  // world in for several seconds afterwards.
166
166
  store.focusOnScene(() => pickGameCamera(mount.capture.captured?.camera, liveScene));
167
167
  landIngestBootInEdit();
168
- store.notifyIngestEdit(); // ensure panels re-render against the override
168
+ store.shell.notifyIngestEdit(); // ensure panels re-render against the override
169
169
  clearMountFailureReports(); // D-W3: mount succeeded
170
170
 
171
171
  // What this editor CANNOT do with this game, said out loud once, right where
@@ -241,7 +241,7 @@ async function mountThreeIngestRootInner(
241
241
  // own persistence provider, which is what EditorShellStore's autosave/saveNow
242
242
  // now consult (design). Still switch into the guarded "playing" state so the
243
243
  // viewport swaps onto the live scene.
244
- store.setPlayState('playing');
244
+ store.shell.setPlayState('playing');
245
245
  editorConsole.log(`Ingesting unmodified game: ${game.name}`, 'ingest');
246
246
 
247
247
  // Drive the SAME input gate play-mode uses (play-mode.ts's
@@ -252,7 +252,7 @@ async function mountThreeIngestRootInner(
252
252
  // tab is the active viewport surface, exactly like a first-party play
253
253
  // session.
254
254
  const ingestInputActive = () =>
255
- store.playState === 'playing' && store.activeViewportTab === 'play';
255
+ store.shell.playState === 'playing' && store.shell.activeViewportTab === 'play';
256
256
 
257
257
  try {
258
258
  const mountOpts: MountIngestOptions = { captureTimeoutMs: game.captureTimeoutMs };
@@ -285,7 +285,7 @@ async function mountThreeIngestRootInner(
285
285
  // holds when the gate CLOSES — leaving play, or switching to the Edit tab
286
286
  // mid-flight — must be released, or the editor is left with a captured,
287
287
  // invisible cursor over a game that is no longer receiving input.
288
- session.inputGateUnsubscribe = store.subscribe(() => {
288
+ session.inputGateUnsubscribe = store.shell.subscribe(() => {
289
289
  if (!ingestInputActive()) releaseGamePointerLock();
290
290
  });
291
291
  // The realm gate only just became reachable, so push the play state we
@@ -4,7 +4,7 @@
4
4
  * is a per-PROJECT property, not a per-realm one.
5
5
  */
6
6
 
7
- import type { IngestGame2D } from '@volter/game-runtime/pixi/ingest';
7
+ import type { IngestGame2D } from '../runtime/pixi/ingest';
8
8
  import type { ResolvedAdapterRoot } from '@volter/editor-project/manifest/load';
9
9
  import { composeIngestLoad } from './entry-load';
10
10
  import { ingestModuleLoaders } from './resolve-three';
@@ -27,7 +27,7 @@
27
27
  * `document.body` (`setGameSurface`), absolutely positioned and full-size,
28
28
  * so the transplanted body lands in a real box.
29
29
  * - STYLE it. The root's `styles` manifest field serves the bundle's own
30
- * stylesheet rewritten into `@scope` (`server/scoped-game-css.ts`), which is
30
+ * stylesheet rewritten into `@scope` (`@volter/editor-sdk/session/scoped-game-css`), which is
31
31
  * what turns `#root,body,html{width:100%;height:100%}` into a sized root
32
32
  * without the editor seeing one of those rules. A `<link rel=stylesheet>` in
33
33
  * the document is NOT auto-loaded here: an unscoped page sheet restyles the
@@ -19,7 +19,7 @@ import {
19
19
  type IngestEntry,
20
20
  ingestEntriesOnSurface,
21
21
  } from '../host/ingest/registry';
22
- import type { IngestGame2D } from '@volter/game-runtime/pixi/ingest';
22
+ import type { IngestGame2D } from '../runtime/pixi/ingest';
23
23
  import { composeIngestLoad } from './entry-load';
24
24
 
25
25
  type BaseFields2D = Pick<IngestGame2D, 'id' | 'name' | 'description' | 'captureTimeoutMs'>;
@@ -16,8 +16,8 @@
16
16
  * resetting the gate is no longer a separate step.
17
17
  */
18
18
 
19
- import { setActiveAuthoring } from '@volter/editor-core/authoring/active-adapter';
20
- import { setActiveSystems } from '@volter/editor-core/authoring/active-systems';
19
+ import { setActiveAuthoring } from '@volter/editor-sdk/kit/authoring/active-adapter';
20
+ import { setActiveSystems } from '@volter/editor-sdk/kit/authoring/active-systems';
21
21
  import { clearMountFailureReports } from '@volter/editor-sdk/kit/mount-failure-report';
22
22
  import { editorConsole } from '@volter/editor-sdk/kit/editor-console';
23
23
  import { reclaimGameRealm } from '../host/game-realm-reclaim';
@@ -121,7 +121,7 @@ function disposeThreejsSession(s: IngestSession): void {
121
121
  /* scene may not have been swapped if capture failed */
122
122
  }
123
123
  }
124
- s.store.setPlayState('stopped');
124
+ s.store.shell.setPlayState('stopped');
125
125
 
126
126
  // Tear down the mounted game (stops its loop, frees renderer, uninstalls trap).
127
127
  try {
@@ -153,7 +153,7 @@ function disposePixiSession(s: IngestSession2D): void {
153
153
  setActiveAuthoring(null);
154
154
  setActiveSystems(null);
155
155
  clearMountFailureReports(); // D-W3: no session -> nothing left to report
156
- s.store.setPlayState('stopped');
156
+ s.store.shell.setPlayState('stopped');
157
157
  try {
158
158
  s.dispose();
159
159
  } catch {
@@ -177,7 +177,7 @@ function disposeReactSession(s: IngestSessionReact): void {
177
177
  setActiveAuthoring(null);
178
178
  setActiveSystems(null);
179
179
  clearMountFailureReports(); // D-W3: no session -> nothing left to report (mirrors disposeThreejsSession's identical call)
180
- s.store.setPlayState('stopped');
180
+ s.store.shell.setPlayState('stopped');
181
181
  try {
182
182
  s.stop();
183
183
  } catch {
@@ -1,4 +1,4 @@
1
- import { getActiveSystems } from '@volter/editor-core/authoring/active-systems';
1
+ import { getActiveSystems } from '@volter/editor-sdk/kit/authoring/active-systems';
2
2
  import { editorHost } from '@volter/editor-sdk/host';
3
3
  import type { NavigationAdapter } from '@volter/editor-project/adapter';
4
4
  import { getUserData } from '@volter/threejs-runtime/ecs/user-data';
@@ -11,18 +11,21 @@ import {
11
11
  navBakeBusy,
12
12
  resetNavMeshBaked,
13
13
  } from './navmesh-workflow-store';
14
+ import { threeNavigation } from '@volter/editor-threejs/adapter/three-contract';
15
+ import { hostHierarchyObjects } from '@volter/editor-threejs/host-hierarchy-objects';
16
+ import { setViewportHelper, viewportRig } from '@volter/editor-threejs/viewport-door';
14
17
 
15
18
  /**
16
19
  * The game skew's side of the Navigation verbs: bake/clear and the walkable
17
- * overlay tint, shown through the viewport door (`host.viewport.setHelper`,
20
+ * overlay tint, shown through the viewport door (`viewport-door`'s `setViewportHelper`,
18
21
  * kind `navmesh` — the Helpers menu's own toggle).
19
22
  *
20
23
  * Started by `contributions/navmesh.service.ts`, so its lifetime is the
21
24
  * contribution pass; it used to be a mount effect in the editor's scene panel,
22
25
  * which made a host panel the owner of a game-skew tool.
23
26
  *
24
- * It reads the authoring scene through `host.hierarchy.objects()` and the
25
- * viewport through `host.viewport.setHelper` / `.rig()`, but keeps the
27
+ * It reads the authoring scene through `host-hierarchy-objects` and the
28
+ * viewport through `viewport-door`'s `setViewportHelper` / `.rig()`, but keeps the
26
29
  * `@editor/authoring/active-systems` import for the adapter itself: the bake
27
30
  * collects the PRIMARY AUTHORING mount's walkable meshes, so the adapter it
28
31
  * bakes into must be that same mount's — `getActiveSystems()`. The door's
@@ -63,20 +66,21 @@ export function setupNavMeshHandlers(): () => void {
63
66
  */
64
67
  function collectNavigationIds(role: 'walkable' | 'obstacle'): Set<string> {
65
68
  const ids = new Set<string>();
66
- for (const [id, obj] of editorHost().hierarchy.objects()) {
69
+ for (const [id, obj] of (hostHierarchyObjects()?.objects() ?? new Map<string, THREE.Object3D>())) {
67
70
  if (getUserData(obj, 'navRole') === role) ids.add(id);
68
71
  }
69
72
  return ids;
70
73
  }
71
74
 
72
75
  function clearPresentation(): void {
73
- editorHost().viewport.setHelper('navmesh', null);
76
+ setViewportHelper('navmesh', null);
74
77
  }
75
78
 
76
79
  /** Follow late registration/replacement of the primary mounted adapter. A
77
80
  * root may register navigation only after its async WASM setup completes. */
78
81
  function syncMountedNavigation(): void {
79
- const nav = getActiveSystems().navigation ?? null;
82
+ const active = getActiveSystems().navigation;
83
+ const nav = active ? threeNavigation(active) : null;
80
84
  if (nav !== boundNavigation) {
81
85
  boundNavigation = nav;
82
86
  clearPresentation();
@@ -101,7 +105,7 @@ export function setupNavMeshHandlers(): () => void {
101
105
  markNavMeshBaked();
102
106
  // The adapter builds its debug mesh against the editor's scene; without
103
107
  // a mounted viewport there is nothing to show it in.
104
- const scene = editorHost().viewport.rig()?.scene;
108
+ const scene = viewportRig()?.scene;
105
109
  if (!scene) return;
106
110
  let debugMesh: THREE.Object3D | null = null;
107
111
  try {
@@ -114,7 +118,7 @@ export function setupNavMeshHandlers(): () => void {
114
118
  }
115
119
  if (debugMesh) {
116
120
  applyWalkableTint(debugMesh);
117
- editorHost().viewport.setHelper('navmesh', debugMesh);
121
+ setViewportHelper('navmesh', debugMesh);
118
122
  }
119
123
  }
120
124
 
@@ -124,7 +128,8 @@ export function setupNavMeshHandlers(): () => void {
124
128
  // Recast's solo bake is synchronous WASM — yield a frame so the Bake
125
129
  // button visibly paints its busy state before the build blocks the thread.
126
130
  await new Promise((r) => requestAnimationFrame(() => r(null)));
127
- const nav = getActiveSystems().navigation;
131
+ const active = getActiveSystems().navigation;
132
+ const nav = active ? threeNavigation(active) : undefined;
128
133
  if (!nav) {
129
134
  const reason = 'The mounted game has no NavigationAdapter';
130
135
  editorHost().console.warn(`${reason} — nothing can be baked`, 'navigation');
@@ -141,7 +146,9 @@ export function setupNavMeshHandlers(): () => void {
141
146
  const walkableIds = collectNavigationIds('walkable');
142
147
  if (walkableIds.size === 0) {
143
148
  editorHost().console.warn(
144
- 'No walkable entities found — tag meshes as "walkable" in the Navigation section',
149
+ // The role is the object's own `userData.navRole` (see `collectNavigationIds`); a source
150
+ // world tags it where the mesh is written.
151
+ 'No walkable meshes found — give the floors `userData={{ navRole: \'walkable\' }}` (and blockers `\'obstacle\'`) where they are written',
145
152
  'navigation',
146
153
  );
147
154
  endNavBake('No walkable-tagged entities in the scene');
@@ -155,7 +162,7 @@ export function setupNavMeshHandlers(): () => void {
155
162
  // the bake; obstacles alone can't produce a mesh.
156
163
  const meshes: THREE.Mesh[] = [];
157
164
  for (const id of [...walkableIds, ...collectNavigationIds('obstacle')]) {
158
- const obj = editorHost().hierarchy.objects().get(id);
165
+ const obj = (hostHierarchyObjects()?.objects() ?? new Map<string, THREE.Object3D>()).get(id);
159
166
  if (!obj) continue;
160
167
  obj.traverse((child) => {
161
168
  if ((child as THREE.Mesh).isMesh) meshes.push(child as THREE.Mesh);
@@ -186,11 +193,11 @@ export function setupNavMeshHandlers(): () => void {
186
193
  }
187
194
 
188
195
  boundNavigation = nav;
189
- const scene = editorHost().viewport.rig()?.scene;
196
+ const scene = viewportRig()?.scene;
190
197
  const debugMesh = scene ? nav.debugMesh(scene) : null;
191
198
  if (debugMesh) {
192
199
  applyWalkableTint(debugMesh);
193
- editorHost().viewport.setHelper('navmesh', debugMesh);
200
+ setViewportHelper('navmesh', debugMesh);
194
201
  }
195
202
 
196
203
  endNavBake(null);
@@ -200,7 +207,8 @@ export function setupNavMeshHandlers(): () => void {
200
207
  };
201
208
 
202
209
  const onClear = () => {
203
- const nav = getActiveSystems().navigation;
210
+ const active = getActiveSystems().navigation;
211
+ const nav = active ? threeNavigation(active) : undefined;
204
212
  if (!nav) {
205
213
  editorHost().console.warn('The mounted game has no NavigationAdapter to clear', 'navigation');
206
214
  return;
@@ -213,7 +221,7 @@ export function setupNavMeshHandlers(): () => void {
213
221
  return;
214
222
  }
215
223
  try {
216
- nav.clear(editorHost().viewport.rig()?.scene ?? new THREE.Scene());
224
+ nav.clear(viewportRig()?.scene ?? new THREE.Scene());
217
225
  } catch (error) {
218
226
  editorHost().console.error(`NavMesh clear failed: ${error}`, 'navigation');
219
227
  return;