@volter/editor-game 0.5.65 → 0.5.67
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/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 +3 -3
- package/contributions/generations.status.tsx +1 -1
- package/contributions/godot.palette.json +99 -0
- package/contributions/godot.style.ts +82 -0
- package/contributions/godot.view.ts +75 -0
- package/contributions/ingest.service.ts +4 -4
- 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 +11 -5
- package/contributions/react/component-board.service.ts +1 -1
- package/contributions/react/design-time-mount.service.ts +1 -1
- package/contributions/react/react-inspector.service.ts +2 -2
- package/contributions/scene-document.service.ts +5 -5
- 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 +8 -8
- package/contributions/three/three-authoring.service.ts +8 -5
- package/contributions/three-story-capture.service.ts +12 -0
- package/contributions/unity.palette.json +102 -0
- package/contributions/unity.style.ts +72 -0
- package/contributions/unity.view.ts +82 -0
- package/contributions/unreal.palette.json +105 -0
- package/contributions/unreal.style.ts +66 -0
- package/contributions/unreal.view.ts +93 -0
- package/dist-node/serving.mjs +16 -0
- package/package.json +33 -16
- package/serving/index.ts +27 -0
- package/src/asset-budget/AssetBudgetPanel.tsx +1 -1
- package/src/asset-budget/asset-budget-model.ts +4 -4
- package/src/asset-budget/optimize-apply.ts +7 -7
- package/src/audio/AudioDebuggerPanel.tsx +1 -1
- package/src/bridge/dispatch.ts +16 -16
- package/src/bridge/live-frames.ts +1 -1
- package/src/bridge/screenshot.ts +6 -6
- package/src/build/BuildProfilesPanel.tsx +3 -3
- package/src/canvas/canvas-board/CanvasBoardDocument.tsx +676 -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 +6 -6
- package/src/coverage/live-project-verbs.ts +2 -2
- package/src/coverage/native-system-coverage.ts +6 -6
- package/src/coverage/root-coverage.ts +1 -1
- package/src/coverage/session-coverage.ts +5 -5
- package/src/design-system-stories/ApplicationChrome.stories.tsx +5 -5
- package/src/design-system-stories/InspectorNarrowBodies.stories.tsx +13 -53
- 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 +2 -2
- package/src/game-document/GameDocument.tsx +2 -2
- package/src/game-document/GamePanel.tsx +8 -8
- 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 +6 -8
- package/src/generation/generation-documents.tsx +8 -8
- package/src/generation/generation-jobs.ts +2 -2
- package/src/generation/generation-presentation.ts +1 -1
- package/src/host/adapter-reach.ts +1 -1
- package/src/host/adapter-runtime-bindings.ts +97 -6
- package/src/host/api/configurations.ts +2 -2
- package/src/host/authoring/babylon-authoring-adapter.ts +8 -8
- package/src/host/authoring/contract-hierarchy-authoring.ts +1 -1
- package/src/host/authoring/contract-scenes-stories.ts +1 -1
- package/src/host/authoring/creation-site-related.ts +2 -2
- package/src/host/authoring/ephemeral-persistence.ts +1 -1
- package/src/host/authoring/gesture-persist.ts +2 -2
- package/src/host/authoring/ingest-data-writer.ts +1 -1
- package/src/host/authoring/ingest-source-persistence.ts +8 -8
- package/src/host/authoring/mount-isolated-pixi-screen.ts +1 -1
- 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 +42 -17
- package/src/host/authoring/pixi-creation-site-write-target.ts +2 -2
- package/src/host/authoring/pixi-live-write-target.ts +7 -7
- package/src/host/authoring/pixi-source-identity.ts +3 -3
- package/src/host/authoring/pixi-source-write-target.ts +1614 -0
- package/src/host/authoring/pixi-still-presentation.ts +2 -2
- package/src/host/authoring/pixi-structure-history.ts +3 -3
- package/src/host/authoring/pixi-transform-channels.ts +16 -14
- package/src/host/authoring/source-persistence-backend.ts +6 -6
- package/src/host/authoring/struct-write-pipe.ts +3 -3
- package/src/host/binding-resolver.ts +8 -9
- package/src/host/browser-transpile.ts +2 -2
- package/src/host/canvas-entry-runtime.ts +59 -48
- package/src/host/canvas-preview-frames.ts +482 -0
- package/src/host/components/CameraAuthoringOverlay.tsx +1 -1
- package/src/host/components/HeaderTelemetry.tsx +9 -16
- package/src/host/components/PixiIsolationSceneContent.tsx +17 -16
- package/src/host/components/ThreeIsolationSceneContent.tsx +5 -5
- 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 +29 -61
- package/src/host/components/utility-view-state.ts +1 -1
- package/src/host/components/world-root-stage-binding.tsx +17 -26
- package/src/host/components/world-root-stage.ts +130 -63
- package/src/host/coverage/capability-coverage.ts +13 -1
- package/src/host/coverage/game-contract-seam-evidence.ts +1 -1
- package/src/host/coverage/project-verb-coverage.ts +2 -17
- package/src/host/coverage/system-adapter-coverage.ts +4 -5
- package/src/host/design-system-stories/fixtures/editor-runtime.tsx +14 -8
- package/src/host/document-preview-three.ts +2 -2
- package/src/host/entry-adjudication.ts +6 -6
- package/src/host/game-css-scope-transform.ts +4 -0
- package/src/host/game-module-access.ts +1 -1
- package/src/host/game-realm-page.ts +16 -8
- package/src/host/game-realm-reclaim.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 +6 -6
- package/src/host/history/json-history-resource.ts +3 -3
- package/src/host/instance-extract-actions.ts +1 -1
- package/src/host/instance-fork-actions.ts +1 -1
- package/src/host/projection/dom.ts +2 -2
- package/src/host/projection/pixi.ts +25 -3
- package/src/host/r3f-entry-runtime.ts +65 -34
- package/src/host/react-mount-runtime.ts +8 -49
- package/src/host/realm-services.ts +2 -2
- package/src/host/roots/canvas-root.tsx +361 -0
- package/src/host/roots/module-root.ts +1 -1
- package/src/host/roots/r3f-root.tsx +473 -0
- package/src/host/roots/react-root.ts +9 -43
- package/src/host/scene-view-drawability.ts +2 -2
- package/src/host/served-bundle-runtime-modules.ts +1 -19
- package/src/host/server-log-bridge.ts +3 -3
- 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/three-ingest-runtime.ts +1 -1
- package/src/host/use-active-performance-source.ts +3 -3
- package/src/host/viewport-pose-memory.ts +1 -1
- package/src/host/viewport-root-presentation.ts +6 -5
- package/src/ingest/active-ingest.ts +2 -2
- package/src/ingest/authoring/ingest-dom-surface-authoring.ts +4 -4
- package/src/ingest/authoring/ingest-root-adapter.ts +13 -13
- package/src/ingest/capture-wait-report.ts +1 -1
- package/src/ingest/deferred-ingest-play.ts +11 -10
- package/src/ingest/discovery-public-ingest.ts +2 -2
- package/src/ingest/ingest-boot-viewport.ts +6 -8
- package/src/ingest/ingest-canvas-scene-document.tsx +17 -16
- package/src/ingest/ingest-canvas-scene.ts +5 -8
- 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 +4 -4
- package/src/ingest/ingest-render-debug.ts +11 -11
- package/src/ingest/ingest-siblings.ts +16 -28
- package/src/ingest/module-mode.ts +18 -19
- package/src/ingest/mount-canvas-ingest-root.ts +27 -27
- package/src/ingest/mount-coverage.ts +4 -4
- package/src/ingest/mount-dom-ingest-root.ts +16 -16
- package/src/ingest/mount-ingest-root.ts +14 -14
- package/src/ingest/mount-three-ingest-root.ts +12 -12
- 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 +7 -7
- package/src/navmesh/navmesh-handler.ts +24 -16
- package/src/network/NetworkInspectorPanel.tsx +449 -14
- package/src/network/network-inspector-model.ts +14 -2
- package/src/play/play-log-events.ts +1 -1
- package/src/play/play-mode.ts +99 -142
- package/src/play/play-recording.ts +2 -2
- 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 +4 -4
- package/src/react/design-time-react-mount.ts +37 -85
- package/src/react/dom-authoring-adapter.ts +11 -11
- package/src/react/react-inspector-section.tsx +13 -13
- package/src/react/react-world-authoring-adapter.ts +31 -143
- package/src/react/story-documents/story-documents.tsx +18 -22
- package/src/react/ui-board-document.tsx +10 -11
- package/src/react/ui-component-board.ts +5 -5
- 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 +169 -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 +657 -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 +4 -3
- package/src/three/authoring/constraint-inspector-section.tsx +8 -7
- package/src/three/authoring/model-asset-inspector-section.tsx +14 -17
- package/src/three/authoring/oid-source-persistence.ts +13 -13
- package/src/three/authoring/r3f-design-session.ts +79 -61
- package/src/three/authoring/r3f-source-authoring-adapter.ts +112 -108
- package/src/three/authoring/reflection-probe-inspector-section.tsx +5 -4
- package/src/three/authoring/spatial-joint-handles.ts +1 -1
- package/src/three/authoring/spatial-lod-handles.ts +1 -1
- package/src/three/authoring/spatial-particle-handles.ts +1 -1
- package/src/three/authoring/three-authoring-adapter.ts +33 -33
- package/src/three/component-verbs/extract-menu.ts +8 -7
- package/src/three/component-verbs/fork-menu.ts +8 -7
- package/src/three/component-verbs/internals-menu.ts +3 -3
- package/src/three/drei-asset-caches.ts +13 -0
- package/src/three/story-documents/three-story-documents.tsx +24 -34
- package/src/three/three-board/ThreeBoardDocument.tsx +25 -25
- package/src/three/three-board/board-scene.ts +7 -7
- package/src/three/three-board/three-component-board.ts +5 -5
- package/contributions/react/pasteboard.action.ts +0 -41
- package/contributions/xstate-behavior.action.ts +0 -42
- package/contributions/xstate-behavior.document.tsx +0 -73
- package/contributions/xstate-behavior.inspector.tsx +0 -28
- package/contributions/xstate-behavior.menu.ts +0 -23
- package/src/react/pasteboard-materialize.ts +0 -154
- package/src/services/game-audio-unlock.ts +0 -48
- package/src/xstate/XStateBehaviorSection.tsx +0 -130
- package/src/xstate/XStateMachineInspector.tsx +0 -566
- package/src/xstate/character-animation-machine.fixture.ts +0 -74
- package/src/xstate/live-behaviors.ts +0 -106
- package/src/xstate/use-live-actor-state.ts +0 -44
- package/src/xstate/xstate-graph.ts +0 -235
- package/src/xstate/xstate-layout.ts +0 -76
package/src/play/play-mode.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { onAssetReload } from '@volter/editor-
|
|
1
|
+
import { onAssetReload } from '@volter/editor-sdk/kit/project-asset-refresh';
|
|
2
|
+
import { evictDreiCaches } from '../three/drei-asset-caches';
|
|
2
3
|
import { editorHost } from '@volter/editor-sdk/host';
|
|
3
4
|
|
|
4
5
|
/**
|
|
@@ -14,45 +15,45 @@ import { editorHost } from '@volter/editor-sdk/host';
|
|
|
14
15
|
*/
|
|
15
16
|
|
|
16
17
|
import { installAdapterRuntimeBindings } from '../host/adapter-runtime-bindings';
|
|
17
|
-
import { getAuthoringOverride, setActiveAuthoring } from '@volter/editor-
|
|
18
|
+
import { getAuthoringOverride, setActiveAuthoring } from '@volter/editor-sdk/kit/authoring/active-adapter';
|
|
18
19
|
import {
|
|
19
20
|
getActiveNetworking,
|
|
20
21
|
inspectedInstanceId,
|
|
21
22
|
setActiveSystems,
|
|
22
23
|
setInspectedInstance,
|
|
23
24
|
updateInstanceSystems,
|
|
24
|
-
} from '@volter/editor-
|
|
25
|
-
import { BoundaryAuthoringAdapter } from '@volter/editor-
|
|
25
|
+
} from '@volter/editor-sdk/kit/authoring/active-systems';
|
|
26
|
+
import { BoundaryAuthoringAdapter } from '@volter/editor-sdk/kit/authoring/boundary-authoring-adapter';
|
|
26
27
|
import {
|
|
27
28
|
CompositeAuthoringAdapter,
|
|
28
29
|
type CompositeChild,
|
|
29
|
-
} from '@volter/editor-
|
|
30
|
+
} from '@volter/editor-sdk/kit/authoring/composite-authoring-adapter';
|
|
30
31
|
import { createEphemeralPersistence } from '../host/authoring/ephemeral-persistence';
|
|
31
32
|
import {
|
|
32
33
|
EPHEMERAL_DESTINATION,
|
|
33
34
|
resolvesLiveOnly,
|
|
34
35
|
runWritePipe,
|
|
35
36
|
type WriteAck,
|
|
36
|
-
} from '@volter/editor-
|
|
37
|
+
} from '@volter/editor-sdk/kit/write-pipe';
|
|
37
38
|
import { resolveAllRootEntries } from '../host/binding-resolver';
|
|
38
|
-
import type { LogEntry } from '@volter/editor-
|
|
39
|
-
import { endLogSession, flushLogEntries, startLogSession } from '@volter/editor-
|
|
40
|
-
import type { ConsoleEntry } from '@volter/editor-
|
|
39
|
+
import type { LogEntry } from '@volter/editor-sdk/kit/editor-api';
|
|
40
|
+
import { endLogSession, flushLogEntries, startLogSession } from '@volter/editor-sdk/kit/editor-api';
|
|
41
|
+
import type { ConsoleEntry } from '@volter/editor-sdk/kit/editor-console';
|
|
41
42
|
import {
|
|
42
43
|
editorConsole,
|
|
43
44
|
formatConsoleArgs,
|
|
44
45
|
resumeEditorConsoleCapture,
|
|
45
46
|
suspendEditorConsoleCapture,
|
|
46
|
-
} from '@volter/editor-
|
|
47
|
-
import { EDITOR_PARTICIPANT_ID, sendControl } from '@volter/editor-
|
|
47
|
+
} from '@volter/editor-sdk/kit/editor-console';
|
|
48
|
+
import { EDITOR_PARTICIPANT_ID, sendControl } from '@volter/editor-sdk/kit/editor-presence';
|
|
48
49
|
import {
|
|
49
50
|
isEditorPresentationActive,
|
|
50
51
|
subscribeEditorPresentationActivity,
|
|
51
|
-
} from '@volter/editor-
|
|
52
|
-
import type { EditorShellStore } from '@volter/editor-
|
|
52
|
+
} from '@volter/editor-sdk/kit/editor-presentation-activity';
|
|
53
|
+
import type { EditorShellStore } from '@volter/editor-threejs/kit/editor-shell-store';
|
|
53
54
|
import { GAME_SURFACE_CONTAINMENT_CSS } from '../host/game-realm-page';
|
|
54
55
|
import { reclaimGameRealm } from '../host/game-realm-reclaim';
|
|
55
|
-
import { toolContributionRecording } from '@volter/editor-
|
|
56
|
+
import { toolContributionRecording } from '@volter/editor-sdk/kit/gameplay-sessions';
|
|
56
57
|
import {
|
|
57
58
|
clearGameSurface,
|
|
58
59
|
currentGameRealmMountId,
|
|
@@ -60,53 +61,52 @@ import {
|
|
|
60
61
|
setGameInputGate,
|
|
61
62
|
setGameSurface,
|
|
62
63
|
} from '../host/gated-globals';
|
|
63
|
-
import { hierarchyProjectionFromProjectConfig } from '@volter/editor-
|
|
64
|
+
import { hierarchyProjectionFromProjectConfig } from '@volter/editor-sdk/kit/hierarchy-projection';
|
|
64
65
|
import { type JournalSubject, playJournal } from '../host/history/json-history-resource';
|
|
65
|
-
import { isEditableTarget, setActiveScope } from '@volter/editor-
|
|
66
|
-
import { projectBootstrapSettled } from '@volter/editor-
|
|
67
|
-
import { registerGameNullSubject } from '@volter/editor-
|
|
68
|
-
import { fetchGameManifest } from '@volter/editor-
|
|
69
|
-
import { registerPerformanceSource } from '@volter/editor-
|
|
66
|
+
import { isEditableTarget, setActiveScope } from '@volter/editor-sdk/kit/hotkeys';
|
|
67
|
+
import { projectBootstrapSettled } from '@volter/editor-sdk/kit/initial-project';
|
|
68
|
+
import { registerGameNullSubject } from '@volter/editor-sdk/kit/inspection/game-subject';
|
|
69
|
+
import { fetchGameManifest } from '@volter/editor-sdk/kit/manifest-project';
|
|
70
|
+
import { registerPerformanceSource } from '@volter/editor-sdk/kit/performance-sources';
|
|
70
71
|
import {
|
|
71
72
|
beginPlayBoot,
|
|
72
73
|
endPlayBoot,
|
|
73
74
|
markPlayBootPhase,
|
|
74
75
|
type PlayBootPhase,
|
|
75
|
-
} from '@volter/editor-
|
|
76
|
-
import { presentationSurface } from '@volter/editor-
|
|
77
|
-
import { getCurrentProject } from '@volter/editor-
|
|
76
|
+
} from '@volter/editor-sdk/kit/play-boot-phase';
|
|
77
|
+
import { presentationSurface } from '@volter/editor-sdk/kit/presentation-surface';
|
|
78
|
+
import { getCurrentProject } from '@volter/editor-sdk/kit/active-project';
|
|
78
79
|
import {
|
|
79
80
|
beginProjectModuleSplitWatch,
|
|
80
81
|
clearProjectModuleSplitReports,
|
|
81
82
|
endProjectModuleSplitWatch,
|
|
82
83
|
formatProjectModuleSplitMessage,
|
|
83
|
-
} from '@volter/editor-
|
|
84
|
-
import { clearRootReadiness, recordRootReadiness } from '@volter/editor-
|
|
85
|
-
import {
|
|
86
|
-
import { mountedStoryHasPixiContent } from '@volter/editor-core/stories/pixi-story-model';
|
|
84
|
+
} from '@volter/editor-sdk/kit/project-module-split';
|
|
85
|
+
import { clearRootReadiness, recordRootReadiness } from '@volter/editor-sdk/kit/readiness';
|
|
86
|
+
import { mountedStoryHasPixiContent } from '../host/stories/pixi-story-model';
|
|
87
87
|
import { domHasRenderableContent, threeSceneHasRenderableContent } from '../host/surface-content';
|
|
88
|
-
import {
|
|
89
|
-
import { publishToolContributionPlay } from '@volter/editor-
|
|
90
|
-
import { liveWorldId } from '../host/viewport-root-presentation';
|
|
88
|
+
import { surfaceHoldsKeyboard } from '@volter/editor-sdk/kit/surface-keyboard';
|
|
89
|
+
import { publishToolContributionPlay } from '@volter/editor-sdk/kit/tool-contribution-play';
|
|
90
|
+
import { liveWorldId, presentThreeRoots } from '../host/viewport-root-presentation';
|
|
91
91
|
import {
|
|
92
92
|
cancelPendingWorkspacePlayUtilities,
|
|
93
93
|
revealWorkspacePlayUtilities,
|
|
94
|
-
} from '@volter/editor-
|
|
94
|
+
} from '@volter/editor-sdk/kit/workspace-play-utilities';
|
|
95
95
|
import { markGameCssScope } from '@volter/editor-sdk/session/game-css-scope';
|
|
96
96
|
import type { EntrypointSelectionOverride } from '@volter/editor-sdk/session/project-module-url';
|
|
97
97
|
import { isEditorLanePath } from '@volter/editor-sdk/session/tool-contribution-convention';
|
|
98
|
-
import { getSeededRandom, type SeededRandom } from '
|
|
99
|
-
import { _engineLogActive } from '
|
|
100
|
-
import type { PerformanceProfiler } from '
|
|
101
|
-
import type { GameSession } from '
|
|
98
|
+
import { getSeededRandom, type SeededRandom } from '../runtime/core/seeded-random';
|
|
99
|
+
import { _engineLogActive } from '../runtime/dev/logger';
|
|
100
|
+
import type { PerformanceProfiler } from '../runtime/dev/performance-profiler';
|
|
101
|
+
import type { GameSession } from '../runtime/create-runtime';
|
|
102
102
|
import {
|
|
103
103
|
type DebugVirtualInputTarget,
|
|
104
104
|
getDebugRegistry,
|
|
105
105
|
type RunTicksOptions,
|
|
106
|
-
} from '
|
|
107
|
-
import type { GameLoop, RootInstance } from '
|
|
108
|
-
import type { PlaytestContext } from '
|
|
109
|
-
import { runTicksWhenSettled } from '
|
|
106
|
+
} from '../runtime/debug-registry';
|
|
107
|
+
import type { GameLoop, RootInstance } from '../runtime/game';
|
|
108
|
+
import type { PlaytestContext } from '../runtime/playtest';
|
|
109
|
+
import { runTicksWhenSettled } from '../runtime/run-ticks-settled';
|
|
110
110
|
import {
|
|
111
111
|
type AuthoringAdapter,
|
|
112
112
|
type InspectorProvider,
|
|
@@ -118,6 +118,7 @@ import { declaredRoots, rootById } from '@volter/editor-project/adapter/manifest
|
|
|
118
118
|
import { readOidSourceAnchors } from '../three/authoring/oid-source-persistence';
|
|
119
119
|
import { oidThree, structuralThree } from '../three/authoring/three-authoring-adapter';
|
|
120
120
|
import type * as THREE from 'three';
|
|
121
|
+
import { threeRoot } from '@volter/editor-threejs/adapter/three-contract';
|
|
121
122
|
import { deviceEmulatedPixelRatio } from '../game-document/device-preview';
|
|
122
123
|
import { exitDeferredIngestPlay, mountDeferredIngestForPlay } from '../ingest/deferred-ingest-play';
|
|
123
124
|
import { getIngestPlayControl } from '../ingest/ingest-play-control';
|
|
@@ -125,6 +126,8 @@ import { withPlayBootStallGuard } from './play-boot-stall';
|
|
|
125
126
|
import { debugEventsToLogEntries } from './play-log-events';
|
|
126
127
|
import { bindPlayRecordingStop, endPlayRecording } from './play-recording';
|
|
127
128
|
import { createReactPlayAuthoringAdapter } from './react-play-live-authoring';
|
|
129
|
+
import { onThreeStore } from '@volter/editor-threejs/kit/three-state';
|
|
130
|
+
import { presentViewportRoots } from '@volter/editor-threejs/viewport-door';
|
|
128
131
|
|
|
129
132
|
/** Context needed by the orchestrator (passed from the world root's stage). */
|
|
130
133
|
export interface PlayModeContext {
|
|
@@ -250,8 +253,8 @@ let _hostMountedReadyRootIds: readonly string[] = [];
|
|
|
250
253
|
// id) resolves to the primary, so the default — and the single-instance case —
|
|
251
254
|
// is "the primary has the keyboard", exactly as before split screen existed.
|
|
252
255
|
// A click on an instance's viewport routes the keyboard to it
|
|
253
|
-
// (`setFocusedInstance`);
|
|
254
|
-
//
|
|
256
|
+
// (`setFocusedInstance`); every instance's input gate reads this, so exactly
|
|
257
|
+
// the focused one is live and the rest are inert.
|
|
255
258
|
let _focusedInstanceId: string | null = null;
|
|
256
259
|
const focusListeners = new Set<() => void>();
|
|
257
260
|
|
|
@@ -292,7 +295,6 @@ export function setFocusedInstance(id: string): void {
|
|
|
292
295
|
setInspectedInstance(id);
|
|
293
296
|
if (focusedInstanceId() === id) return;
|
|
294
297
|
_focusedInstanceId = id;
|
|
295
|
-
resyncInstanceInputs();
|
|
296
298
|
notifyFocusedInstance();
|
|
297
299
|
}
|
|
298
300
|
|
|
@@ -300,59 +302,23 @@ export function setFocusedInstance(id: string): void {
|
|
|
300
302
|
* Game tab is active, this instance holds keyboard focus, AND our surface
|
|
301
303
|
* holds the keyboard.
|
|
302
304
|
*
|
|
303
|
-
* The fourth term is U2's
|
|
304
|
-
*
|
|
305
|
-
*
|
|
306
|
-
*
|
|
307
|
-
*
|
|
308
|
-
*
|
|
309
|
-
* without this a keystroke meant for the source file beside the running game
|
|
310
|
-
* moves the game too. Standalone it is a constant true and nothing changes.
|
|
311
|
-
* See `@editor/surface-keyboard`. */
|
|
305
|
+
* The fourth term is U2's: `gated-globals.ts` ANDs this predicate into every
|
|
306
|
+
* raw `window`/`document` listener a project module registers, and under the
|
|
307
|
+
* Code-OSS frame that window also carries Monaco, so without it a keystroke
|
|
308
|
+
* meant for the source file beside the running game moves the game too.
|
|
309
|
+
* Standalone it is a constant true and nothing changes. See
|
|
310
|
+
* `@editor/surface-keyboard`. */
|
|
312
311
|
function instanceInputActive(id: string): boolean {
|
|
313
312
|
if (!_ctx) return false;
|
|
314
313
|
const { store } = _ctx;
|
|
315
314
|
return (
|
|
316
|
-
store.playState === 'playing' &&
|
|
317
|
-
store.activeViewportTab === 'play' &&
|
|
315
|
+
store.shell.playState === 'playing' &&
|
|
316
|
+
store.shell.activeViewportTab === 'play' &&
|
|
318
317
|
focusedInstanceId() === id &&
|
|
319
318
|
surfaceHoldsKeyboard()
|
|
320
319
|
);
|
|
321
320
|
}
|
|
322
321
|
|
|
323
|
-
/** The first-party `InputManager` for an instance, or `undefined` — a session's
|
|
324
|
-
* game handle may lack one (an ingest mount, a partial double), so resolve it
|
|
325
|
-
* defensively. */
|
|
326
|
-
function instanceInput(inst: PlayInstance): { setEnabled(on: boolean): void } | undefined {
|
|
327
|
-
try {
|
|
328
|
-
return inst.session?.game?.input;
|
|
329
|
-
} catch {
|
|
330
|
-
return undefined;
|
|
331
|
-
}
|
|
332
|
-
}
|
|
333
|
-
|
|
334
|
-
/** Re-apply the enabled/disabled state of every live instance's InputManager
|
|
335
|
-
* from the current play/tab/focus predicate. Called whenever any of those
|
|
336
|
-
* change (store subscription, focus switch, an instance mounting). The raw
|
|
337
|
-
* window/document gates are closures over `instanceInputActive`, so they need
|
|
338
|
-
* no re-registration — they re-read focus on every event. */
|
|
339
|
-
function resyncInstanceInputs(): void {
|
|
340
|
-
if (_instance.id) instanceInput(_instance)?.setEnabled(instanceInputActive(_instance.id));
|
|
341
|
-
for (const inst of _additional) instanceInput(inst)?.setEnabled(instanceInputActive(inst.id));
|
|
342
|
-
}
|
|
343
|
-
|
|
344
|
-
/**
|
|
345
|
-
* THE SURFACE TERM'S OWN EDGE. The store subscription re-gates on play/tab
|
|
346
|
-
* changes and `setFocusedInstance` on focus changes, but the fourth term above
|
|
347
|
-
* moves on neither: a person clicks into Monaco and nothing in the editor's own
|
|
348
|
-
* state has changed. `InputManager` is a LATCHED `setEnabled`, so unlike the
|
|
349
|
-
* raw gates (closures re-read per event) it has to be told. Module scope and
|
|
350
|
-
* never unsubscribed on purpose — the notification is a no-op with no instances
|
|
351
|
-
* mounted, and a lane-scoped subscription would have to be rebuilt on every
|
|
352
|
-
* mount for a predicate that is process-wide.
|
|
353
|
-
*/
|
|
354
|
-
subscribeSurfaceKeyboard(resyncInstanceInputs);
|
|
355
|
-
|
|
356
322
|
let _ctx: PlayModeContext | null = null;
|
|
357
323
|
const playModeBindingWaiters = new Set<() => void>();
|
|
358
324
|
|
|
@@ -512,7 +478,6 @@ export async function runWarmRestartPauseBracket(
|
|
|
512
478
|
if (!wasPaused) session.resume();
|
|
513
479
|
}
|
|
514
480
|
}
|
|
515
|
-
let _unsubStore: (() => void) | null = null;
|
|
516
481
|
/** Browser-mode component-source watch (Phase A2); null in server mode / stopped. */
|
|
517
482
|
/**
|
|
518
483
|
* The authoring override that was active before THIS play session installed its
|
|
@@ -657,7 +622,7 @@ async function installPlayRootAuthoring(
|
|
|
657
622
|
children.push({
|
|
658
623
|
worldId: world.id,
|
|
659
624
|
kind: world.kind,
|
|
660
|
-
adapter: new BoundaryAuthoringAdapter(store, {
|
|
625
|
+
adapter: new BoundaryAuthoringAdapter(store.shell, {
|
|
661
626
|
id: world.id,
|
|
662
627
|
kind: world.kind,
|
|
663
628
|
adapter: declaration.adapter.identity,
|
|
@@ -671,24 +636,25 @@ async function installPlayRootAuthoring(
|
|
|
671
636
|
}
|
|
672
637
|
const mounted = world.mounted;
|
|
673
638
|
if (mounted.kind === 'three') {
|
|
639
|
+
const scene = threeRoot(mounted).scene;
|
|
674
640
|
// The presented subject uses OID identity so Edit→Play selection stays
|
|
675
641
|
// continuous. A headless or non-Three host can omit presentation; its
|
|
676
642
|
// mounted tree still gets an honest structural live projection.
|
|
677
643
|
// `frameControl: 'host'` on the structural branch follows from the same
|
|
678
644
|
// tick-ownership fact: play's own loop drives the root and this adapter
|
|
679
645
|
// holds no handle that can stop it for a gesture.
|
|
680
|
-
const isPresentedSubject = world.id === presentedWorldId &&
|
|
646
|
+
const isPresentedSubject = world.id === presentedWorldId && scene === store.scene;
|
|
681
647
|
const sourceAnchor = isPresentedSubject ? await readOidSourceAnchors() : undefined;
|
|
682
648
|
if (!isCurrentGeneration()) {
|
|
683
649
|
abandon();
|
|
684
650
|
return;
|
|
685
651
|
}
|
|
686
652
|
const adapter = isPresentedSubject
|
|
687
|
-
? oidThree(store,
|
|
653
|
+
? oidThree(store, scene, liveWorldId(world.id), playRunJournal(world.id), {
|
|
688
654
|
explicitSourceCommit: true,
|
|
689
655
|
sourceAnchor,
|
|
690
656
|
})
|
|
691
|
-
: structuralThree(store,
|
|
657
|
+
: structuralThree(store, scene, {
|
|
692
658
|
frameControl: 'host',
|
|
693
659
|
journal: playRunJournal(world.id),
|
|
694
660
|
});
|
|
@@ -733,7 +699,7 @@ async function installPlayRootAuthoring(
|
|
|
733
699
|
}
|
|
734
700
|
if (mounted.substrate.name !== 'pixi') {
|
|
735
701
|
const adapter = new BoundaryAuthoringAdapter(
|
|
736
|
-
store,
|
|
702
|
+
store.shell,
|
|
737
703
|
{
|
|
738
704
|
id: world.id,
|
|
739
705
|
kind: world.kind,
|
|
@@ -751,8 +717,8 @@ async function installPlayRootAuthoring(
|
|
|
751
717
|
const stage = mounted.substrate.root as import('pixi.js').Container;
|
|
752
718
|
const [physicsRegistry, physicsAdapters, pixiAuthoring, pixiWriteTarget, canvasRuntime] =
|
|
753
719
|
await Promise.all([
|
|
754
|
-
import('
|
|
755
|
-
import('
|
|
720
|
+
import('../runtime/pixi/physics-registry'),
|
|
721
|
+
import('../runtime/pixi/system-adapters'),
|
|
756
722
|
import('../host/authoring/pixi-authoring-adapter'),
|
|
757
723
|
import('../host/authoring/pixi-live-write-target'),
|
|
758
724
|
import('../host/canvas-entry-runtime'),
|
|
@@ -826,7 +792,7 @@ async function installPlayRootAuthoring(
|
|
|
826
792
|
// the left hierarchy panel only re-checks `hasAuthoringOverride()` when the
|
|
827
793
|
// store notifies (same reason `ingest/mount-ingest-root.ts` calls this right after
|
|
828
794
|
// installing its own override).
|
|
829
|
-
store.notifyIngestEdit();
|
|
795
|
+
store.shell.notifyIngestEdit();
|
|
830
796
|
|
|
831
797
|
// Dev/e2e diagnostic handle — the SAME pattern `ingest/mount-ingest-root.ts`'s
|
|
832
798
|
// `window.__vgaiIngest`/`window.__vgaiIngest2D` use:
|
|
@@ -868,7 +834,7 @@ function exitPlayRootAuthoring(store: EditorShellStore): void {
|
|
|
868
834
|
// Play edits are session-local by architecture: nothing this run journaled
|
|
869
835
|
// may still be undoable once the run is over.
|
|
870
836
|
if (_instance.journalSession) {
|
|
871
|
-
store.projectHistory?.expireSession(_instance.journalSession);
|
|
837
|
+
store.shell.projectHistory?.expireSession(_instance.journalSession);
|
|
872
838
|
_instance.journalSession = '';
|
|
873
839
|
}
|
|
874
840
|
if (import.meta.env.DEV) {
|
|
@@ -945,7 +911,9 @@ function drainDebugEventsToPlayLog(): void {
|
|
|
945
911
|
}
|
|
946
912
|
|
|
947
913
|
// Asset bytes have changed, but a running game retains its own instances.
|
|
948
|
-
const stopAssetReload = onAssetReload(() => {
|
|
914
|
+
const stopAssetReload = onAssetReload((paths) => {
|
|
915
|
+
// Cleared whether or not a run is live, so the next run loads the new bytes.
|
|
916
|
+
void evictDreiCaches(paths);
|
|
949
917
|
if (!_instance.session) return;
|
|
950
918
|
markRestartRequired(
|
|
951
919
|
'Project assets changed — restart play to load the revised models or textures.',
|
|
@@ -1036,7 +1004,7 @@ function focusGameSurface(): void {
|
|
|
1036
1004
|
* workspace panel names Play to hand it the store; the authored viewport is
|
|
1037
1005
|
* read through `viewport-door.ts` when a session presents its roots.
|
|
1038
1006
|
*/
|
|
1039
|
-
|
|
1007
|
+
onThreeStore((store) => bindPlayMode(store));
|
|
1040
1008
|
|
|
1041
1009
|
export function bindPlayMode(store: EditorShellStore): void {
|
|
1042
1010
|
_ctx = { store, gameContainer: null! }; // set dynamically from the live document's container
|
|
@@ -1044,9 +1012,9 @@ export function bindPlayMode(store: EditorShellStore): void {
|
|
|
1044
1012
|
// game's, and what decides is the workbench: our stage actions carry a
|
|
1045
1013
|
// `when` clause over `vgai.stage.focused`/`vgai.play`, so a bare key reaches
|
|
1046
1014
|
// the game rather than a shell binding, and a ⌘-chord stays the workbench's.
|
|
1047
|
-
// The
|
|
1048
|
-
//
|
|
1049
|
-
//
|
|
1015
|
+
// The realm gate tracks the same predicate independently (`gated-globals.ts`
|
|
1016
|
+
// and `surface-keyboard.ts`), which is what keeps a game's raw
|
|
1017
|
+
// `window.addEventListener('keydown')` gated too.
|
|
1050
1018
|
// The idle auto-stop needs a way to end play without `play-recording.ts`
|
|
1051
1019
|
// importing the play lifecycle it is driven BY. Handed over here rather than
|
|
1052
1020
|
// at module scope so the two directions of the edge stay one-way.
|
|
@@ -1060,7 +1028,7 @@ export function isPlayModeActive(): boolean {
|
|
|
1060
1028
|
}
|
|
1061
1029
|
|
|
1062
1030
|
/**
|
|
1063
|
-
* Narrow relay accessor — the live play session's
|
|
1031
|
+
* Narrow relay accessor — the live play session's virtual input targets
|
|
1064
1032
|
* and the Game root's loop, for `command-listener.ts`'s
|
|
1065
1033
|
* `inject-input`/`set-time-scale`/`set-seed` cases. This is exactly the
|
|
1066
1034
|
* accessor the vgai-sdk honest-gap jsdocs prescribed
|
|
@@ -1070,13 +1038,7 @@ export function isPlayModeActive(): boolean {
|
|
|
1070
1038
|
* `setActiveSystems`/`getActiveSystems` instead.
|
|
1071
1039
|
*
|
|
1072
1040
|
* `getInputTarget(worldId?)` (D15/T-D15.5 — review objection 2's fix)
|
|
1073
|
-
*
|
|
1074
|
-
* `Game.input` always resolves to the DEFAULT world's `InputManager` only,
|
|
1075
|
-
* while the debug bridge's `window.__vgai.input.*` reached whichever world's
|
|
1076
|
-
* `InputManager` last called `DebugRegistry.setVirtualInputTarget` (a
|
|
1077
|
-
* SEPARATE, last-writer-wins slot). In a multi-world project those two could
|
|
1078
|
-
* name DIFFERENT roots — the exact closed-PR review objection. Now both
|
|
1079
|
-
* doors call the SAME `getDebugRegistry(game).getVirtualInputTarget(worldId)`
|
|
1041
|
+
* is one resolution for every input door: both the SAME `getDebugRegistry(game).getVirtualInputTarget(worldId)`
|
|
1080
1042
|
* — one resolution function (`debug-registry.ts`'s `resolveInputRootId`),
|
|
1081
1043
|
* so `inject-input` (this accessor) and `window.__vgai.input.*`
|
|
1082
1044
|
* (`debug-bridge.ts`) can never disagree about which world an unqualified
|
|
@@ -1132,7 +1094,7 @@ export function getPlayRuntimeAccess(): {
|
|
|
1132
1094
|
/** Get the running game's scene (for editor Scene tab rendering). */
|
|
1133
1095
|
export function getGameScene(): THREE.Scene | null {
|
|
1134
1096
|
const mounted = _instance.session?.game.defaultRoot.mounted;
|
|
1135
|
-
return mounted?.kind === 'three' ? mounted.scene : null;
|
|
1097
|
+
return mounted?.kind === 'three' ? threeRoot(mounted).scene : null;
|
|
1136
1098
|
}
|
|
1137
1099
|
|
|
1138
1100
|
export interface GameRootSurfaceFact {
|
|
@@ -1149,7 +1111,7 @@ export function gameRootSurfaceFacts(): readonly GameRootSurfaceFact[] {
|
|
|
1149
1111
|
const mounted = root.mounted;
|
|
1150
1112
|
let hasRenderableContent = false;
|
|
1151
1113
|
if (mounted.kind === 'three') {
|
|
1152
|
-
hasRenderableContent = threeSceneHasRenderableContent(mounted.scene);
|
|
1114
|
+
hasRenderableContent = threeSceneHasRenderableContent(threeRoot(mounted).scene);
|
|
1153
1115
|
} else if (mounted.kind === 'canvas') {
|
|
1154
1116
|
try {
|
|
1155
1117
|
hasRenderableContent =
|
|
@@ -1648,7 +1610,7 @@ async function enterPlayModeInner(
|
|
|
1648
1610
|
editorHost().viewport.transition.begin();
|
|
1649
1611
|
|
|
1650
1612
|
// setPlayState auto-switches to Game tab
|
|
1651
|
-
store.setPlayState('playing');
|
|
1613
|
+
store.shell.setPlayState('playing');
|
|
1652
1614
|
// THE GAME TAKES THE KEYBOARD AS PLAY STARTS. Until the player clicks the
|
|
1653
1615
|
// pane, focus stays on the transport button they pressed and the hotkey
|
|
1654
1616
|
// scope on the workspace — so the next Enter or Space activates that
|
|
@@ -1660,7 +1622,7 @@ async function enterPlayModeInner(
|
|
|
1660
1622
|
editorConsole.log('Play mode started', 'play-mode');
|
|
1661
1623
|
// Apply the project's adapter-declared utilities after transient Play chrome settles.
|
|
1662
1624
|
editorHost().viewport.transition.onSettled(() => {
|
|
1663
|
-
if (epoch === _playEpoch && store.playState === 'playing') revealWorkspacePlayUtilities();
|
|
1625
|
+
if (epoch === _playEpoch && store.shell.playState === 'playing') revealWorkspacePlayUtilities();
|
|
1664
1626
|
});
|
|
1665
1627
|
|
|
1666
1628
|
// WHAT THIS BOOT CREATED, BEFORE ANYTHING ELSE CAN REACH IT. `_instance.id`
|
|
@@ -1743,7 +1705,7 @@ async function enterPlayModeInner(
|
|
|
1743
1705
|
// MEASURED at N=20000: the block that ate three command budgets started
|
|
1744
1706
|
// here and ran for 199.5s with nothing anywhere able to name it.
|
|
1745
1707
|
markPlayBootPhase('mounting the runtime roots');
|
|
1746
|
-
const { mountManifestRoots } = await import('
|
|
1708
|
+
const { mountManifestRoots } = await import('../runtime/mount-manifest');
|
|
1747
1709
|
session = await mountManifestRoots({
|
|
1748
1710
|
manifest,
|
|
1749
1711
|
container: gameContainer,
|
|
@@ -1815,13 +1777,18 @@ async function enterPlayModeInner(
|
|
|
1815
1777
|
}
|
|
1816
1778
|
notifySessionListeners();
|
|
1817
1779
|
// D19: play edits are session-local regardless of world count.
|
|
1818
|
-
store.setPlayEditRegime('ephemeral');
|
|
1780
|
+
store.shell.setPlayEditRegime('ephemeral');
|
|
1819
1781
|
|
|
1820
1782
|
// Swap store to game scene so hierarchy/inspector show game entities.
|
|
1821
1783
|
// liveHierarchy: first-party play mode is the ONLY adoption path that may
|
|
1822
1784
|
// synthesize descriptors for untagged runtime objects (anti-shim rule —
|
|
1823
1785
|
// ingest/module mounts adopt foreign scenes and must never fabricate).
|
|
1824
|
-
|
|
1786
|
+
// With no stage bound to present them (no Scene tab open: the Game tab and a model document
|
|
1787
|
+
// are the whole layout), Play still adopts its roots, so the hierarchy door and every
|
|
1788
|
+
// inspector reach the live objects exactly as they do beside a Scene tab.
|
|
1789
|
+
_instance.presentation =
|
|
1790
|
+
presentViewportRoots(session.game.roots) ??
|
|
1791
|
+
presentThreeRoots(store, session.game.roots);
|
|
1825
1792
|
markPlayBootPhase('installing play authoring for each root');
|
|
1826
1793
|
await installPlayRootAuthoring(
|
|
1827
1794
|
store,
|
|
@@ -1870,8 +1837,7 @@ async function enterPlayModeInner(
|
|
|
1870
1837
|
}) ?? null;
|
|
1871
1838
|
|
|
1872
1839
|
// T6.3: gate game input (raw `window`/`document` listeners in game code via
|
|
1873
|
-
// gated-globals
|
|
1874
|
-
// fire while play is actually running AND the Game tab is the focused
|
|
1840
|
+
// gated-globals) to only fire while play is actually running AND the Game tab is the focused
|
|
1875
1841
|
// viewport — so keystrokes typed into the editor (Scene tab, inspector
|
|
1876
1842
|
// fields) don't leak into the running game.
|
|
1877
1843
|
// The gate is FOCUS-AWARE (`instanceInputActive`): input flows only while
|
|
@@ -1883,14 +1849,11 @@ async function enterPlayModeInner(
|
|
|
1883
1849
|
// baked into their own urls, so the gate has to be registered under it or
|
|
1884
1850
|
// the modules find the default realm's gate instead of their own.
|
|
1885
1851
|
setGameInputGate(() => instanceInputActive(mountId), mountId);
|
|
1886
|
-
//
|
|
1887
|
-
//
|
|
1888
|
-
//
|
|
1889
|
-
//
|
|
1890
|
-
|
|
1891
|
-
// raw window/document gate above.
|
|
1892
|
-
resyncInstanceInputs();
|
|
1893
|
-
_unsubStore = store.subscribe(resyncInstanceInputs);
|
|
1852
|
+
// THE DEFAULT REALM follows the focused instance too. Module-lifetime code
|
|
1853
|
+
// that no mount id reaches lives there — a game's own input store,
|
|
1854
|
+
// attached at module load — and the stop path leaves it open, so a key
|
|
1855
|
+
// aimed at a Model document while the game played still reached it.
|
|
1856
|
+
setGameInputGate(() => instanceInputActive(focusedInstanceId()));
|
|
1894
1857
|
|
|
1895
1858
|
// Node-id keyed only: `setEcsSyncTransform` hands this an editor node id
|
|
1896
1859
|
// and a THREE `Transform`, which a display-keyed carrier has no values for.
|
|
@@ -2005,7 +1968,7 @@ export async function mountAdditionalInstance(
|
|
|
2005
1968
|
}
|
|
2006
1969
|
markGameCssScope(container);
|
|
2007
1970
|
setGameSurface(container, mountId);
|
|
2008
|
-
const { mountManifestRoots } = await import('
|
|
1971
|
+
const { mountManifestRoots } = await import('../runtime/mount-manifest');
|
|
2009
1972
|
const session = await mountManifestRoots({
|
|
2010
1973
|
manifest,
|
|
2011
1974
|
container,
|
|
@@ -2056,15 +2019,12 @@ export async function mountAdditionalInstance(
|
|
|
2056
2019
|
}) ?? null;
|
|
2057
2020
|
// FOCUS-AWARE input, exactly like the primary: this instance takes the shared
|
|
2058
2021
|
// keyboard only while it holds focus. It mounts UNFOCUSED (the primary keeps
|
|
2059
|
-
// focus), so its gate is closed
|
|
2022
|
+
// focus), so its gate is closed until a click
|
|
2060
2023
|
// on its viewport routes focus here (`setFocusedInstance`). This is what stops
|
|
2061
2024
|
// the pre-focus bug where every seat took the same keystroke, AND what lets
|
|
2062
2025
|
// you drive a chosen seat manually rather than only via autoplay.
|
|
2063
2026
|
setGameInputGate(() => instanceInputActive(mountId), mountId);
|
|
2064
2027
|
_additional.push(inst);
|
|
2065
|
-
// Now that it is in `_additional`, sync its (and every) InputManager to the
|
|
2066
|
-
// current focus — disabled here, since the primary is focused.
|
|
2067
|
-
resyncInstanceInputs();
|
|
2068
2028
|
|
|
2069
2029
|
// `setActiveSystems` moved editor focus (`getActiveSystems`) onto the newer
|
|
2070
2030
|
// mount. The user is still authoring the PRIMARY, so restore its focus
|
|
@@ -2139,11 +2099,10 @@ export function unmountAdditionalInstance(id: string): void {
|
|
|
2139
2099
|
inst.container = null;
|
|
2140
2100
|
inst.session = null;
|
|
2141
2101
|
// If the removed instance held keyboard focus, focus falls back to the primary
|
|
2142
|
-
// (`focusedInstanceId` already resolves a stale id to it);
|
|
2143
|
-
//
|
|
2102
|
+
// (`focusedInstanceId` already resolves a stale id to it); notify the
|
|
2103
|
+
// viewport highlight.
|
|
2144
2104
|
if (_focusedInstanceId === id) {
|
|
2145
2105
|
_focusedInstanceId = null;
|
|
2146
|
-
resyncInstanceInputs();
|
|
2147
2106
|
notifyFocusedInstance();
|
|
2148
2107
|
}
|
|
2149
2108
|
notifySessionListeners();
|
|
@@ -2296,7 +2255,7 @@ export function exitPlayMode(): void {
|
|
|
2296
2255
|
exitPlayRootAuthoring(store);
|
|
2297
2256
|
restorePriorAuthoring();
|
|
2298
2257
|
// Readout-only — clear the regime the moment play is no longer active.
|
|
2299
|
-
store.setPlayEditRegime(null);
|
|
2258
|
+
store.shell.setPlayEditRegime(null);
|
|
2300
2259
|
|
|
2301
2260
|
// Always null _instance.session even if stop() throws — otherwise enterPlayMode's
|
|
2302
2261
|
// `if (_instance.session) return` guard would permanently block re-entering play mode.
|
|
@@ -2325,11 +2284,9 @@ export function exitPlayMode(): void {
|
|
|
2325
2284
|
_hostMountedReadyRootIds = [];
|
|
2326
2285
|
|
|
2327
2286
|
// Cleanup subscriptions
|
|
2328
|
-
_unsubStore?.();
|
|
2329
|
-
_unsubStore = null;
|
|
2330
2287
|
|
|
2331
|
-
// T6.3: no game running — game input (raw window/document listeners
|
|
2332
|
-
//
|
|
2288
|
+
// T6.3: no game running — game input (raw window/document listeners) should
|
|
2289
|
+
// never be suppressed again until the next
|
|
2333
2290
|
// play session re-gates it. The mount's own gate is DROPPED rather than set
|
|
2334
2291
|
// to always-true: its id is never reused, so overwriting would retain one
|
|
2335
2292
|
// dead closure per play run.
|
|
@@ -2378,7 +2335,7 @@ export function exitPlayMode(): void {
|
|
|
2378
2335
|
// that FAILED before ever flipping the store to 'playing' never produces
|
|
2379
2336
|
// that edge, so release directly too — `releaseGameDocument` is the one
|
|
2380
2337
|
// idempotent teardown path either way (`game-document.ts`).
|
|
2381
|
-
store.setPlayState('stopped');
|
|
2338
|
+
store.shell.setPlayState('stopped');
|
|
2382
2339
|
editorHost().workspace.liveDocument.release();
|
|
2383
2340
|
// LAST — the run's error window closes only once teardown is done, so every
|
|
2384
2341
|
// error this teardown itself logged still belongs to the run that caused it
|
|
@@ -2403,7 +2360,7 @@ export function pausePlayMode(): void {
|
|
|
2403
2360
|
// Freeze EVERY seat, not just the primary — a paused split with the extras
|
|
2404
2361
|
// still ticking is not paused.
|
|
2405
2362
|
for (const inst of allLiveInstances()) inst.session?.pause();
|
|
2406
|
-
_ctx.store.setPlayState('paused');
|
|
2363
|
+
_ctx.store.shell.setPlayState('paused');
|
|
2407
2364
|
|
|
2408
2365
|
editorConsole.log('Play mode paused', 'play-mode');
|
|
2409
2366
|
}
|
|
@@ -2415,7 +2372,7 @@ export function resumePlayMode(): void {
|
|
|
2415
2372
|
if (!_instance.session || !_ctx) return;
|
|
2416
2373
|
|
|
2417
2374
|
for (const inst of allLiveInstances()) inst.session?.resume();
|
|
2418
|
-
_ctx.store.setPlayState('playing');
|
|
2375
|
+
_ctx.store.shell.setPlayState('playing');
|
|
2419
2376
|
|
|
2420
2377
|
editorConsole.log('Play mode resumed', 'play-mode');
|
|
2421
2378
|
}
|
|
@@ -37,8 +37,8 @@
|
|
|
37
37
|
* recorder's stream never sees, so nothing about the evidence changes.
|
|
38
38
|
*/
|
|
39
39
|
|
|
40
|
-
import { isRootCanvas } from '@volter/editor-
|
|
41
|
-
import { editorConsole } from '@volter/editor-
|
|
40
|
+
import { isRootCanvas } from '@volter/editor-sdk/kit/composite-screenshot';
|
|
41
|
+
import { editorConsole } from '@volter/editor-sdk/kit/editor-console';
|
|
42
42
|
import {
|
|
43
43
|
type GameplayRecordingCapture,
|
|
44
44
|
type GameplayRecordingStarted,
|
|
@@ -44,8 +44,8 @@
|
|
|
44
44
|
* three gizmo drag during play. That is the regime, not a defect.
|
|
45
45
|
*/
|
|
46
46
|
|
|
47
|
-
import type { EditorShellStore } from '@volter/editor-
|
|
48
|
-
import type { SourceWriteBackend } from '@volter/editor-
|
|
47
|
+
import type { EditorShellStore } from '@volter/editor-threejs/kit/editor-shell-store';
|
|
48
|
+
import type { SourceWriteBackend } from '@volter/editor-sdk/kit/ui-source/source-write-backend';
|
|
49
49
|
import {
|
|
50
50
|
type OidElementLike,
|
|
51
51
|
ReactRootAuthoringAdapter,
|
|
@@ -158,7 +158,7 @@ export function createReactPlayAuthoringAdapter(
|
|
|
158
158
|
root: OidElementLike,
|
|
159
159
|
store: EditorShellStore,
|
|
160
160
|
): ReactRootAuthoringAdapter {
|
|
161
|
-
return new ReactRootAuthoringAdapter(root, store, {
|
|
161
|
+
return new ReactRootAuthoringAdapter(root, store.shell, {
|
|
162
162
|
writeBackend: createEphemeralDomWriteBackend(root),
|
|
163
163
|
provenance: EPHEMERAL_DOM_PROVENANCE,
|
|
164
164
|
});
|