@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.
- package/contributions/audio-unlock.service.ts +2 -2
- package/contributions/autoplay.service.ts +1 -1
- package/contributions/bridge.command.ts +3 -3
- package/contributions/build-player.document.tsx +95 -0
- package/contributions/canvas/component-board.service.ts +16 -0
- package/contributions/canvas/design-time-mount.service.ts +45 -0
- package/contributions/canvas-story-capture.service.ts +12 -0
- package/contributions/edit-mode-audio.service.ts +2 -2
- package/contributions/edit-mode-networking.service.ts +1 -1
- package/contributions/gameplay.command.ts +4 -4
- package/contributions/generation.service.ts +1 -1
- package/contributions/godot.style.ts +26 -6
- package/contributions/godot.view.ts +6 -0
- package/contributions/ingest.service.ts +2 -2
- package/contributions/instances.command.ts +1 -1
- package/contributions/navmesh.menu.ts +1 -1
- package/contributions/network-observer.service.ts +14 -0
- package/contributions/play.command.ts +10 -4
- package/contributions/react/component-board.service.ts +1 -1
- package/contributions/react/design-time-mount.service.ts +1 -1
- package/contributions/scene-document.service.ts +3 -3
- package/contributions/state-watch.menu.ts +1 -1
- package/contributions/state-watch.utility.tsx +1 -1
- package/contributions/team-playtest.service.ts +4 -4
- package/contributions/three/component-board.service.ts +1 -1
- package/contributions/three/component-verbs.command.ts +6 -6
- package/contributions/three/three-authoring.service.ts +8 -5
- package/contributions/three-story-capture.service.ts +12 -0
- package/contributions/unity.style.ts +17 -7
- package/contributions/unity.view.ts +6 -0
- package/contributions/unreal.style.ts +10 -2
- package/contributions/unreal.view.ts +5 -0
- package/package.json +21 -10
- package/src/asset-budget/AssetBudgetPanel.tsx +1 -1
- package/src/asset-budget/asset-budget-model.ts +1 -1
- package/src/audio/AudioDebuggerPanel.tsx +1 -1
- package/src/bridge/dispatch.ts +14 -14
- package/src/bridge/live-frames.ts +1 -1
- package/src/bridge/screenshot.ts +3 -3
- package/src/build/BuildProfilesPanel.tsx +14 -3
- package/src/build/build-session.ts +35 -0
- package/src/canvas/canvas-board/CanvasBoardDocument.tsx +749 -0
- package/src/canvas/canvas-board/canvas-board-model.ts +407 -0
- package/src/canvas/canvas-board/canvas-component-board.ts +56 -0
- package/src/canvas/canvas-design-mount.ts +524 -0
- package/src/canvas/design-time-canvas-mount.ts +79 -0
- package/src/coverage/live-authoring-surface.ts +5 -5
- package/src/coverage/live-project-verbs.ts +1 -1
- package/src/coverage/native-system-coverage.ts +5 -5
- package/src/coverage/root-coverage.ts +1 -1
- package/src/coverage/session-coverage.ts +3 -3
- package/src/design-system-stories/ApplicationChrome.stories.tsx +5 -5
- package/src/design-system-stories/InspectorNarrowBodies.stories.tsx +7 -7
- package/src/edit-mode/edit-mode-audio.ts +4 -4
- package/src/edit-mode/edit-mode-networking.ts +2 -2
- package/src/game-document/GameCaptureFrameButton.tsx +1 -1
- package/src/game-document/GameDocument.tsx +2 -2
- package/src/game-document/GamePanel.tsx +4 -4
- package/src/game-document/InstanceInspectorPicker.tsx +2 -2
- package/src/game-document/crowd-debug.ts +1 -1
- package/src/game-document/device-preview.ts +10 -11
- package/src/game-document/physics-debug.ts +1 -1
- package/src/generation/GenerationActivity.tsx +3 -3
- package/src/generation/generation-documents.tsx +5 -5
- package/src/generation/generation-jobs.ts +1 -1
- package/src/host/adapter-runtime-bindings.ts +96 -5
- package/src/host/authoring/babylon-authoring-adapter.ts +6 -6
- package/src/host/authoring/gesture-persist.ts +1 -1
- package/src/host/authoring/ingest-data-writer.ts +1 -1
- package/src/host/authoring/ingest-source-persistence.ts +4 -4
- package/src/host/authoring/mounted-authoring.ts +4 -4
- package/src/host/authoring/phaser-live-authoring-adapter.ts +4 -4
- package/src/host/authoring/pixi-authoring-adapter.ts +178 -31
- package/src/host/authoring/pixi-creatable-kinds.ts +62 -0
- package/src/host/authoring/pixi-creation-site-write-target.ts +2 -2
- package/src/host/authoring/pixi-live-write-target.ts +4 -4
- package/src/host/authoring/pixi-source-identity.ts +3 -3
- package/src/host/authoring/pixi-source-write-target.ts +1709 -0
- package/src/host/authoring/pixi-still-presentation.ts +1 -1
- package/src/host/authoring/pixi-structure-history.ts +2 -2
- package/src/host/authoring/pixi-transform-channels.ts +16 -14
- package/src/host/authoring/source-persistence-backend.ts +3 -3
- package/src/host/authoring/struct-write-pipe.ts +1 -1
- package/src/host/binding-resolver.ts +8 -9
- package/src/host/browser-transpile.ts +1 -1
- package/src/host/canvas-entry-runtime.ts +58 -47
- package/src/host/canvas-preview-frames.ts +482 -0
- package/src/host/components/CameraAuthoringOverlay.tsx +1 -1
- package/src/host/components/HeaderTelemetry.tsx +4 -4
- package/src/host/components/PixiIsolationSceneContent.tsx +11 -11
- package/src/host/components/ThreeIsolationSceneContent.tsx +3 -3
- package/src/host/components/frame-debugger-model.ts +2 -2
- package/src/host/components/header-telemetry-model.ts +2 -2
- package/src/host/components/scene-document.tsx +14 -14
- package/src/host/components/utility-view-state.ts +1 -1
- package/src/host/components/world-root-stage-binding.tsx +12 -12
- package/src/host/components/world-root-stage.ts +70 -49
- package/src/host/coverage/system-adapter-coverage.ts +3 -4
- package/src/host/design-system-stories/fixtures/editor-runtime.tsx +9 -11
- package/src/host/document-preview-three.ts +1 -1
- package/src/host/entry-adjudication.ts +6 -6
- package/src/host/game-css-scope-transform.ts +4 -0
- package/src/host/game-realm-page.ts +1 -1
- package/src/host/gameplay-export.ts +25 -14
- package/src/host/gameplay-recording.ts +5 -5
- package/src/host/gated-globals.ts +2 -2
- package/src/host/history/json-history-resource.ts +1 -1
- package/src/host/projection/pixi.ts +24 -2
- package/src/host/r3f-entry-runtime.ts +65 -34
- package/src/host/react-mount-runtime.ts +7 -48
- package/src/host/realm-services.ts +1 -1
- package/src/host/roots/canvas-root.tsx +373 -0
- package/src/host/roots/r3f-root.tsx +473 -0
- package/src/host/roots/react-root.ts +9 -43
- package/src/host/served-bundle-runtime-modules.ts +3 -19
- package/src/host/server-log-bridge.ts +2 -2
- package/src/host/stories/mounted-story-viewport-source.ts +1 -1
- package/src/host/stories/pixi-story-model.ts +30 -0
- package/src/host/stories/story-media-captures.ts +46 -0
- package/src/host/stories/story-media-presence.ts +3 -3
- package/src/host/stories/story-pixi-preview.ts +408 -0
- package/src/host/stories/story-three-preview.ts +806 -0
- package/src/host/stories/three-story-captures.ts +35 -0
- package/src/host/story-three-preview-runtime.ts +56 -0
- package/src/host/use-active-performance-source.ts +2 -2
- package/src/host/viewport-pose-memory.ts +1 -1
- package/src/host/viewport-root-presentation.ts +6 -5
- package/src/ingest/active-ingest.ts +1 -1
- package/src/ingest/authoring/ingest-dom-surface-authoring.ts +4 -4
- package/src/ingest/authoring/ingest-root-adapter.ts +8 -8
- package/src/ingest/deferred-ingest-play.ts +6 -6
- package/src/ingest/discovery-public-ingest.ts +2 -2
- package/src/ingest/ingest-boot-viewport.ts +2 -2
- package/src/ingest/ingest-canvas-scene-document.tsx +9 -9
- package/src/ingest/ingest-canvas-scene.ts +3 -3
- package/src/ingest/ingest-evidence-hook.ts +1 -1
- package/src/ingest/ingest-frame-snapshot.ts +1 -1
- package/src/ingest/ingest-play-control.ts +1 -1
- package/src/ingest/ingest-render-debug.ts +10 -10
- package/src/ingest/ingest-siblings.ts +13 -25
- package/src/ingest/module-mode.ts +14 -14
- package/src/ingest/mount-canvas-ingest-root.ts +21 -21
- package/src/ingest/mount-coverage.ts +2 -2
- package/src/ingest/mount-dom-ingest-root.ts +11 -11
- package/src/ingest/mount-ingest-root.ts +8 -8
- package/src/ingest/mount-three-ingest-root.ts +8 -8
- package/src/ingest/resolve-canvas.ts +1 -1
- package/src/ingest/served-html-boot.ts +1 -1
- package/src/ingest/surface-canvas.ts +1 -1
- package/src/ingest/unmount-ingest-root.ts +5 -5
- package/src/navmesh/navmesh-handler.ts +24 -16
- package/src/network/NetworkInspectorPanel.tsx +939 -37
- package/src/network/network-inspector-model.ts +20 -2
- package/src/play/play-log-events.ts +1 -1
- package/src/play/play-mode.ts +76 -133
- package/src/play/play-recording.ts +1 -1
- package/src/play/react-play-live-authoring.ts +3 -3
- package/src/play/run-selection.ts +93 -0
- package/src/play-bar/PlayBar.tsx +20 -39
- package/src/profiler/FrameDebuggerPanel.tsx +1 -1
- package/src/profiler/PerformancePanel.tsx +3 -3
- package/src/react/design-time-react-mount.ts +23 -65
- package/src/react/dom-authoring-adapter.ts +9 -9
- package/src/react/react-inspector-section.tsx +5 -5
- package/src/react/react-world-authoring-adapter.ts +11 -11
- package/src/react/story-documents/story-documents.tsx +9 -9
- package/src/react/ui-board-document.tsx +7 -7
- package/src/react/ui-component-board.ts +2 -2
- package/src/runtime/adapter/audio-meter.ts +21 -0
- package/src/runtime/adapter/first-party-audio-system.ts +230 -0
- package/src/runtime/adapter/ingest/contract-debug-adapter.ts +114 -0
- package/src/runtime/adapter/ingest/contract-system-adapters.ts +256 -0
- package/src/runtime/adapter/ingest/merge-debug-adapters.ts +197 -0
- package/src/runtime/adapter/ingest/observation-debug-adapter.ts +162 -0
- package/src/runtime/adapter/ingest/upstream-pin.ts +51 -0
- package/src/runtime/adapter/native-debug-module.ts +498 -0
- package/src/runtime/audio/bus-mixer.ts +161 -0
- package/src/runtime/audio/pose-guard.ts +80 -0
- package/src/runtime/core/frame-pacing.ts +126 -0
- package/src/runtime/core/game-loop.ts +225 -0
- package/src/runtime/core/game-scoped-slot.ts +28 -0
- package/src/runtime/core/seeded-random.ts +162 -0
- package/src/runtime/core/sim-clock.ts +391 -0
- package/src/runtime/core/system-runner.ts +269 -0
- package/src/runtime/core/types.ts +104 -0
- package/src/runtime/create-runtime.ts +1128 -0
- package/src/runtime/debug-bridge.ts +570 -0
- package/src/runtime/debug-registry.ts +899 -0
- package/src/runtime/dev/chrome-trace.ts +153 -0
- package/src/runtime/dev/instruments.ts +403 -0
- package/src/runtime/dev/logger.ts +119 -0
- package/src/runtime/dev/performance-profiler.ts +367 -0
- package/src/runtime/dev/register-render-vitals.ts +276 -0
- package/src/runtime/dev/render-census.ts +354 -0
- package/src/runtime/dev/render-debug-adapter.ts +218 -0
- package/src/runtime/dev/render-memory.ts +226 -0
- package/src/runtime/dev/render-vitals.ts +338 -0
- package/src/runtime/dev/static-batch-advisor.ts +188 -0
- package/src/runtime/dev/webgl-frame-capture.ts +366 -0
- package/src/runtime/dev/webgl-gpu-timer.ts +53 -0
- package/src/runtime/dev-build.ts +47 -0
- package/src/runtime/game.ts +1636 -0
- package/src/runtime/gameplay-rng-trap.ts +135 -0
- package/src/runtime/host-context.ts +64 -0
- package/src/runtime/input-router.ts +182 -0
- package/src/runtime/mount-manifest.ts +480 -0
- package/src/runtime/pixi/authoring.ts +706 -0
- package/src/runtime/pixi/ingest.ts +116 -0
- package/src/runtime/pixi/physics-registry.ts +49 -0
- package/src/runtime/pixi/render-pass-bracket.ts +117 -0
- package/src/runtime/pixi/scene-capture.ts +179 -0
- package/src/runtime/pixi/system-adapters.ts +69 -0
- package/src/runtime/playtest.ts +22 -0
- package/src/runtime/presentation.ts +141 -0
- package/src/runtime/render-control.ts +642 -0
- package/src/runtime/render-seed.ts +77 -0
- package/src/runtime/run-ticks-settled.ts +73 -0
- package/src/runtime/setup/setup-audio.ts +72 -0
- package/src/services/audio-pose-guard.ts +2 -2
- package/src/services/game-audio.ts +152 -0
- package/src/services/game-network.ts +767 -0
- package/src/services/game-physics.ts +334 -0
- package/src/state-watch/StateWatchPanel.tsx +1 -1
- package/src/three/authoring/camera-runtime-inspector-section.tsx +3 -2
- package/src/three/authoring/constraint-inspector-section.tsx +6 -5
- package/src/three/authoring/model-asset-inspector-section.tsx +7 -6
- package/src/three/authoring/oid-source-persistence.ts +7 -7
- package/src/three/authoring/r3f-design-session.ts +58 -54
- package/src/three/authoring/r3f-source-authoring-adapter.ts +95 -91
- package/src/three/authoring/reflection-probe-inspector-section.tsx +3 -2
- package/src/three/authoring/three-authoring-adapter.ts +29 -29
- package/src/three/component-verbs/extract-menu.ts +7 -6
- package/src/three/component-verbs/fork-menu.ts +7 -6
- package/src/three/component-verbs/internals-menu.ts +2 -2
- package/src/three/story-documents/three-story-documents.tsx +13 -13
- package/src/three/three-board/ThreeBoardDocument.tsx +13 -12
- package/src/three/three-board/board-scene.ts +6 -6
- package/src/three/three-board/three-component-board.ts +2 -2
- 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-
|
|
26
|
-
import { setActiveSystems } from '@volter/editor-
|
|
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 '
|
|
46
|
+
} from '../host/canvas-preview-frames';
|
|
47
47
|
import { editorConsole } from '@volter/editor-sdk/kit/editor-console';
|
|
48
|
-
import type { EditorShellStore } from '@volter/editor-
|
|
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-
|
|
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 '
|
|
62
|
-
import type { RenderDebugWiring } from '
|
|
63
|
-
import type { IngestGame2D } from '
|
|
64
|
-
import { INGEST_GAME_2D_LOAD_ERROR_NAME, mountIngestGame2D } from '
|
|
65
|
-
import { createPhysics2DRegistry } from '
|
|
66
|
-
import { installPixiRenderPassBracket } from '
|
|
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 '
|
|
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
|
|
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-
|
|
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
|
|
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-
|
|
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 '
|
|
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-
|
|
10
|
-
import { setActiveSystems } from '@volter/editor-
|
|
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-
|
|
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('
|
|
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('
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
43
|
-
import { getCurrentProject } from '@volter/editor-
|
|
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-
|
|
23
|
-
import { setActiveSystems } from '@volter/editor-
|
|
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-
|
|
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-
|
|
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 '
|
|
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` (
|
|
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 '
|
|
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-
|
|
20
|
-
import { setActiveSystems } from '@volter/editor-
|
|
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-
|
|
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 (`
|
|
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
|
|
25
|
-
* viewport through `
|
|
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
|
|
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
|
-
|
|
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
|
|
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 =
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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 =
|
|
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 =
|
|
196
|
+
const scene = viewportRig()?.scene;
|
|
190
197
|
const debugMesh = scene ? nav.debugMesh(scene) : null;
|
|
191
198
|
if (debugMesh) {
|
|
192
199
|
applyWalkableTint(debugMesh);
|
|
193
|
-
|
|
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
|
|
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(
|
|
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;
|