@volter/editor-game 0.5.65
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/LICENSE +661 -0
- package/NOTICE +23 -0
- package/contributions/asset-budget-asset.menu.ts +26 -0
- package/contributions/asset-budget.action.ts +18 -0
- package/contributions/asset-budget.document.tsx +21 -0
- package/contributions/asset-budget.menu.ts +22 -0
- package/contributions/audio-unlock.service.ts +17 -0
- package/contributions/audio.utility.tsx +15 -0
- package/contributions/autoplay.service.ts +48 -0
- package/contributions/bridge.command.ts +172 -0
- package/contributions/build-profiles.document.tsx +21 -0
- package/contributions/build-progress.status.tsx +45 -0
- package/contributions/build.action.ts +26 -0
- package/contributions/build.command.ts +27 -0
- package/contributions/build.header.tsx +37 -0
- package/contributions/build.menu.ts +31 -0
- package/contributions/build.service.ts +31 -0
- package/contributions/connection.status.tsx +43 -0
- package/contributions/coverage.service.ts +118 -0
- package/contributions/edit-mode-audio.service.ts +23 -0
- package/contributions/edit-mode-networking.service.ts +30 -0
- package/contributions/game-document.service.ts +25 -0
- package/contributions/game-eval.command.ts +210 -0
- package/contributions/game.layout.ts +19 -0
- package/contributions/gameplay.command.ts +255 -0
- package/contributions/generation.service.ts +96 -0
- package/contributions/generations.status.tsx +53 -0
- package/contributions/ingest.service.ts +80 -0
- package/contributions/instances.command.ts +75 -0
- package/contributions/navmesh.menu.ts +39 -0
- package/contributions/navmesh.service.ts +19 -0
- package/contributions/network.utility.tsx +17 -0
- package/contributions/play.command.ts +355 -0
- package/contributions/profiler.action.ts +16 -0
- package/contributions/profiler.menu.ts +22 -0
- package/contributions/profiler.utility.tsx +17 -0
- package/contributions/react/component-board.service.ts +21 -0
- package/contributions/react/design-time-mount.service.ts +60 -0
- package/contributions/react/pasteboard.action.ts +41 -0
- package/contributions/react/react-inspector.service.ts +85 -0
- package/contributions/react/story-documents.service.ts +44 -0
- package/contributions/scene-document.service.ts +32 -0
- package/contributions/state-watch.action.ts +17 -0
- package/contributions/state-watch.menu.ts +23 -0
- package/contributions/state-watch.utility.tsx +20 -0
- package/contributions/team-playtest.service.ts +124 -0
- package/contributions/three/camera-runtime.inspector.tsx +34 -0
- package/contributions/three/component-board.service.ts +24 -0
- package/contributions/three/component-verbs.command.ts +110 -0
- package/contributions/three/component-verbs.service.ts +92 -0
- package/contributions/three/constraints.inspector.tsx +34 -0
- package/contributions/three/model-asset-sections.service.ts +26 -0
- package/contributions/three/reflection-probe-capture.inspector.tsx +32 -0
- package/contributions/three/story-documents.service.ts +31 -0
- package/contributions/three/three-authoring.service.ts +66 -0
- package/contributions/transport.header.tsx +19 -0
- package/contributions/xstate-behavior.action.ts +42 -0
- package/contributions/xstate-behavior.document.tsx +73 -0
- package/contributions/xstate-behavior.inspector.tsx +28 -0
- package/contributions/xstate-behavior.menu.ts +23 -0
- package/package.json +144 -0
- package/src/asset-budget/AssetBudgetPanel.tsx +1172 -0
- package/src/asset-budget/asset-budget-model.ts +799 -0
- package/src/asset-budget/basis-encoder.ts +165 -0
- package/src/asset-budget/gltf-io.ts +154 -0
- package/src/asset-budget/gltf-optimize.ts +384 -0
- package/src/asset-budget/image-dims.ts +78 -0
- package/src/asset-budget/optimize-apply.ts +221 -0
- package/src/audio/AudioDebuggerPanel.tsx +457 -0
- package/src/audio/audio-debugger-model.ts +87 -0
- package/src/bridge/call.ts +60 -0
- package/src/bridge/dispatch.ts +459 -0
- package/src/bridge/live-frames.ts +25 -0
- package/src/bridge/screenshot.ts +316 -0
- package/src/build/BuildProfilesPanel.tsx +476 -0
- package/src/build/build-session.ts +247 -0
- package/src/build/format-bytes.ts +14 -0
- package/src/command-results.ts +36 -0
- package/src/coverage/live-authoring-surface.ts +30 -0
- package/src/coverage/live-project-verbs.ts +162 -0
- package/src/coverage/native-system-coverage.ts +143 -0
- package/src/coverage/root-coverage.ts +79 -0
- package/src/coverage/session-coverage.ts +193 -0
- package/src/design-system-stories/ApplicationChrome.stories.tsx +100 -0
- package/src/design-system-stories/InspectorNarrowBodies.stories.tsx +406 -0
- package/src/edit-mode/edit-mode-audio.ts +56 -0
- package/src/edit-mode/edit-mode-networking.ts +112 -0
- package/src/game-document/DevicePresetPicker.tsx +84 -0
- package/src/game-document/GameCaptureFrameButton.tsx +45 -0
- package/src/game-document/GameDocument.tsx +215 -0
- package/src/game-document/GamePanel.tsx +662 -0
- package/src/game-document/InstanceInspectorPicker.tsx +183 -0
- package/src/game-document/crowd-debug.ts +183 -0
- package/src/game-document/device-preview.ts +336 -0
- package/src/game-document/game-view-store.ts +107 -0
- package/src/game-document/physics-debug.ts +187 -0
- package/src/generation/GenerationActivity.tsx +421 -0
- package/src/generation/GenerationGallery.css +231 -0
- package/src/generation/generation-documents.tsx +338 -0
- package/src/generation/generation-jobs.ts +128 -0
- package/src/generation/generation-presentation.ts +257 -0
- package/src/host/adapter-reach.ts +445 -0
- package/src/host/adapter-runtime-bindings.ts +303 -0
- package/src/host/after-paint.ts +112 -0
- package/src/host/api/configurations.ts +66 -0
- package/src/host/authoring/babylon-authoring-adapter.ts +703 -0
- package/src/host/authoring/canvas-runtime-recognition.ts +50 -0
- package/src/host/authoring/contract-hierarchy-authoring.ts +144 -0
- package/src/host/authoring/contract-scenes-stories.ts +204 -0
- package/src/host/authoring/creation-site-related.ts +55 -0
- package/src/host/authoring/ephemeral-persistence.ts +29 -0
- package/src/host/authoring/gesture-persist.ts +84 -0
- package/src/host/authoring/ingest-data-writer.ts +232 -0
- package/src/host/authoring/ingest-source-persistence.ts +826 -0
- package/src/host/authoring/mount-isolated-pixi-screen.ts +250 -0
- package/src/host/authoring/mounted-authoring.ts +41 -0
- package/src/host/authoring/owned-pixi-ticker-listeners.ts +96 -0
- package/src/host/authoring/phaser-live-authoring-adapter.ts +265 -0
- package/src/host/authoring/pixi-authoring-adapter.ts +1554 -0
- package/src/host/authoring/pixi-creation-site-write-target.ts +60 -0
- package/src/host/authoring/pixi-isolation-assets.ts +25 -0
- package/src/host/authoring/pixi-live-write-target.ts +979 -0
- package/src/host/authoring/pixi-source-identity.ts +141 -0
- package/src/host/authoring/pixi-still-presentation.ts +71 -0
- package/src/host/authoring/pixi-structure-history.ts +237 -0
- package/src/host/authoring/pixi-transform-channels.ts +205 -0
- package/src/host/authoring/selection-remount-handoff.ts +23 -0
- package/src/host/authoring/source-persistence-backend.ts +373 -0
- package/src/host/authoring/source-refresh-revisions.ts +81 -0
- package/src/host/authoring/struct-write-pipe.ts +143 -0
- package/src/host/auto-frame-window.ts +89 -0
- package/src/host/binding-resolver.ts +393 -0
- package/src/host/browser-transpile.ts +631 -0
- package/src/host/canvas-entry-runtime.ts +95 -0
- package/src/host/components/CameraAuthoringOverlay.tsx +216 -0
- package/src/host/components/HeaderTelemetry.tsx +341 -0
- package/src/host/components/PixiIsolationSceneContent.tsx +280 -0
- package/src/host/components/ResolutionPicker.tsx +89 -0
- package/src/host/components/ThreeIsolationSceneContent.tsx +180 -0
- package/src/host/components/frame-debugger-model.ts +579 -0
- package/src/host/components/header-telemetry-model.ts +74 -0
- package/src/host/components/scene-document.tsx +447 -0
- package/src/host/components/utility-view-state.ts +87 -0
- package/src/host/components/world-root-stage-binding.tsx +133 -0
- package/src/host/components/world-root-stage.ts +1046 -0
- package/src/host/coverage/authoring-read-probe.ts +583 -0
- package/src/host/coverage/capability-coverage.ts +1587 -0
- package/src/host/coverage/coverage-accounting.ts +261 -0
- package/src/host/coverage/game-contract-seam-evidence.ts +82 -0
- package/src/host/coverage/project-verb-coverage.ts +148 -0
- package/src/host/coverage/system-adapter-coverage.ts +373 -0
- package/src/host/design-system-stories/StoryLayout.tsx +104 -0
- package/src/host/design-system-stories/fixtures/authoring.ts +247 -0
- package/src/host/design-system-stories/fixtures/editor-runtime.tsx +115 -0
- package/src/host/document-preview-three.ts +110 -0
- package/src/host/entry-adjudication.ts +89 -0
- package/src/host/game-location-guard.ts +150 -0
- package/src/host/game-module-access.ts +196 -0
- package/src/host/game-realm-page.ts +358 -0
- package/src/host/game-realm-reclaim.ts +55 -0
- package/src/host/game-realm-storage.ts +104 -0
- package/src/host/gameplay-export.ts +288 -0
- package/src/host/gameplay-recording.ts +717 -0
- package/src/host/gated-globals.ts +1511 -0
- package/src/host/history/json-history-resource.ts +254 -0
- package/src/host/ingest/registry.ts +261 -0
- package/src/host/instance-extract-actions.ts +120 -0
- package/src/host/instance-fork-actions.ts +120 -0
- package/src/host/play-control-hook.ts +26 -0
- package/src/host/playwright-shim.ts +479 -0
- package/src/host/projection/dom.ts +295 -0
- package/src/host/projection/pixi.ts +288 -0
- package/src/host/r3f-entry-runtime.ts +77 -0
- package/src/host/react-mount-runtime.ts +162 -0
- package/src/host/realm-services.ts +148 -0
- package/src/host/recording-preview.ts +106 -0
- package/src/host/roots/module-root.ts +203 -0
- package/src/host/roots/react-root.ts +181 -0
- package/src/host/same-realm-loop-gate.ts +544 -0
- package/src/host/scene-view-drawability.ts +69 -0
- package/src/host/sdk/tools.ts +31 -0
- package/src/host/served-bundle-runtime-modules.ts +331 -0
- package/src/host/server-log-bridge.ts +60 -0
- package/src/host/staged-projects.ts +24 -0
- package/src/host/stories/mounted-story-viewport-source.ts +64 -0
- package/src/host/stories/story-arg-descriptors.ts +50 -0
- package/src/host/stories/story-media-presence.ts +152 -0
- package/src/host/surface-content.ts +87 -0
- package/src/host/take-named-export.ts +23 -0
- package/src/host/three-ingest-runtime.ts +76 -0
- package/src/host/types-fastnoise-lite.d.ts +7 -0
- package/src/host/types-mikktspace.d.ts +20 -0
- package/src/host/types-troika-three-text.d.ts +7 -0
- package/src/host/use-active-performance-source.ts +53 -0
- package/src/host/viewport-pose-memory.ts +48 -0
- package/src/host/viewport-root-presentation.ts +40 -0
- package/src/ingest/active-ingest.ts +251 -0
- package/src/ingest/active-scene-navigation.ts +43 -0
- package/src/ingest/authoring/ingest-dom-surface-authoring.ts +191 -0
- package/src/ingest/authoring/ingest-root-adapter.ts +897 -0
- package/src/ingest/capture-wait-report.ts +122 -0
- package/src/ingest/deferred-ingest-play.ts +216 -0
- package/src/ingest/deferred-ingest-session.ts +23 -0
- package/src/ingest/discovery-public-ingest.ts +242 -0
- package/src/ingest/dom-stub-mark.ts +7 -0
- package/src/ingest/entry-load.ts +56 -0
- package/src/ingest/game-contract-realm.ts +34 -0
- package/src/ingest/game-pointer-lock.ts +89 -0
- package/src/ingest/held-scene-repaint.ts +73 -0
- package/src/ingest/host-surface-box.ts +174 -0
- package/src/ingest/ingest-boot-viewport.ts +54 -0
- package/src/ingest/ingest-canvas-scene-document.tsx +177 -0
- package/src/ingest/ingest-canvas-scene.ts +50 -0
- package/src/ingest/ingest-evidence-hook.ts +131 -0
- package/src/ingest/ingest-frame-snapshot.ts +183 -0
- package/src/ingest/ingest-play-commands.ts +134 -0
- package/src/ingest/ingest-play-control.ts +299 -0
- package/src/ingest/ingest-render-debug.ts +320 -0
- package/src/ingest/ingest-siblings.ts +487 -0
- package/src/ingest/ingest-status.ts +62 -0
- package/src/ingest/live-ingest-facet.ts +46 -0
- package/src/ingest/module-mode.ts +229 -0
- package/src/ingest/mount-canvas-ingest-root.ts +899 -0
- package/src/ingest/mount-coverage.ts +296 -0
- package/src/ingest/mount-dom-ingest-root.ts +282 -0
- package/src/ingest/mount-ingest-root.ts +744 -0
- package/src/ingest/mount-three-ingest-root.ts +366 -0
- package/src/ingest/resolve-canvas.ts +47 -0
- package/src/ingest/resolve-three.ts +123 -0
- package/src/ingest/served-bundle.ts +109 -0
- package/src/ingest/served-html-boot.ts +292 -0
- package/src/ingest/surface-canvas.ts +84 -0
- package/src/ingest/surface-dom.ts +84 -0
- package/src/ingest/surface-three.ts +128 -0
- package/src/ingest/types.ts +76 -0
- package/src/ingest/unmount-ingest-root.ts +224 -0
- package/src/navmesh/navmesh-actions.ts +27 -0
- package/src/navmesh/navmesh-handler.ts +237 -0
- package/src/navmesh/navmesh-workflow-store.ts +78 -0
- package/src/network/NetworkInspectorPanel.tsx +644 -0
- package/src/network/network-inspector-model.ts +225 -0
- package/src/play/play-boot-stall.ts +118 -0
- package/src/play/play-log-events.ts +26 -0
- package/src/play/play-mode.ts +2553 -0
- package/src/play/play-recording.ts +335 -0
- package/src/play/react-play-live-authoring.ts +165 -0
- package/src/play-bar/PlayBar.tsx +488 -0
- package/src/play-bar/PlayerCountPicker.tsx +100 -0
- package/src/profiler/FrameDebuggerPanel.tsx +458 -0
- package/src/profiler/PerformancePanel.tsx +1068 -0
- package/src/profiler/ProfilerPanel.tsx +53 -0
- package/src/profiler/frame-debugger-store.ts +97 -0
- package/src/profiler/main-thread-busy.ts +90 -0
- package/src/react/design-time-react-mount.ts +782 -0
- package/src/react/dom-authoring-adapter.ts +764 -0
- package/src/react/pasteboard-materialize.ts +154 -0
- package/src/react/react-inspector-section.tsx +2496 -0
- package/src/react/react-world-authoring-adapter.ts +3795 -0
- package/src/react/story-documents/story-args-section.ts +19 -0
- package/src/react/story-documents/story-documents.tsx +1380 -0
- package/src/react/story-paint-bounds.ts +94 -0
- package/src/react/ui-board-document.tsx +101 -0
- package/src/react/ui-board-title.ts +9 -0
- package/src/react/ui-component-board.ts +72 -0
- package/src/services/audio-pose-guard.ts +81 -0
- package/src/services/game-audio-unlock.ts +48 -0
- package/src/state-watch/StateWatchPanel.tsx +535 -0
- package/src/three/authoring/camera-runtime-inspector-section.tsx +135 -0
- package/src/three/authoring/constraint-inspector-section.tsx +189 -0
- package/src/three/authoring/design-time-renderer.ts +189 -0
- package/src/three/authoring/model-asset-inspector-section.css +41 -0
- package/src/three/authoring/model-asset-inspector-section.tsx +869 -0
- package/src/three/authoring/oid-source-persistence.ts +557 -0
- package/src/three/authoring/r3f-design-session.ts +1174 -0
- package/src/three/authoring/r3f-source-authoring-adapter.ts +5949 -0
- package/src/three/authoring/reflection-probe-inspector-section.tsx +76 -0
- package/src/three/authoring/spatial-audio-handles.ts +215 -0
- package/src/three/authoring/spatial-collider-handles.ts +229 -0
- package/src/three/authoring/spatial-joint-handles.ts +114 -0
- package/src/three/authoring/spatial-light-handles.ts +178 -0
- package/src/three/authoring/spatial-lod-handles.ts +93 -0
- package/src/three/authoring/spatial-particle-handles.ts +368 -0
- package/src/three/authoring/three-authoring-adapter.ts +1953 -0
- package/src/three/authoring/three-scene-identity.ts +19 -0
- package/src/three/authoring/three-spatial-handles.ts +161 -0
- package/src/three/authoring/typed-three-inspector.ts +528 -0
- package/src/three/component-verbs/extract-menu.ts +71 -0
- package/src/three/component-verbs/fork-menu.ts +78 -0
- package/src/three/component-verbs/internals-menu.ts +91 -0
- package/src/three/story-documents/three-story-documents.tsx +607 -0
- package/src/three/three-board/ThreeBoardDocument.tsx +888 -0
- package/src/three/three-board/board-framing.ts +412 -0
- package/src/three/three-board/board-layout.ts +401 -0
- package/src/three/three-board/board-scene.ts +901 -0
- package/src/three/three-board/three-component-board.ts +62 -0
- package/src/xstate/XStateBehaviorSection.tsx +130 -0
- package/src/xstate/XStateMachineInspector.tsx +566 -0
- package/src/xstate/character-animation-machine.fixture.ts +74 -0
- package/src/xstate/live-behaviors.ts +106 -0
- package/src/xstate/use-live-actor-state.ts +44 -0
- package/src/xstate/xstate-graph.ts +235 -0
- package/src/xstate/xstate-layout.ts +76 -0
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CAPABILITY COVERAGE (`@volter/editor-sdk/services`, a `workspace.service`
|
|
3
|
+
* contribution): the four derived families that GRADE a mounted game's
|
|
4
|
+
* adapters, and the union headline the editor console says out loud.
|
|
5
|
+
*
|
|
6
|
+
* ## Why this is the game skew's and not the host's
|
|
7
|
+
*
|
|
8
|
+
* Every row here is a question about a GAME — which providers this root's
|
|
9
|
+
* `AuthoringAdapter` exposes, which `SystemAdapters` slots the running game
|
|
10
|
+
* bound, whether the open project can build and prove itself, whether its
|
|
11
|
+
* adapter table became real Edit documents. A host with no game skew loaded
|
|
12
|
+
* (the models build) has no adapters to grade and asked none of it; it kept
|
|
13
|
+
* paying for the derivation anyway, because the families were host fields on
|
|
14
|
+
* `collectState` and a direct call in the host's vitals tick.
|
|
15
|
+
*
|
|
16
|
+
* ## The two doors, both the host's own, neither of them new vocabulary
|
|
17
|
+
*
|
|
18
|
+
* - `session.reportFacet(collect, { reusableKeys })` — the four `vgai status`
|
|
19
|
+
* facets. The keys are declared REUSABLE because grading a root re-walks
|
|
20
|
+
* its tree (76ms–1.3s, measured), which is exactly the cost
|
|
21
|
+
* `command-listener.ts`'s `REUSABLE_DERIVED_FACETS` exists to keep off the
|
|
22
|
+
* interaction path: a collect handed a `reuse` snapshot copies them, and
|
|
23
|
+
* the host strips them from an interaction PATCH by name.
|
|
24
|
+
* - `session.onSample(fn)` — the host's own five-second vitals sample
|
|
25
|
+
* (`coverage/session-vitals.ts`), which `reportSessionCoverage` used to be
|
|
26
|
+
* a direct call inside. Subscribing keeps the promise that module's header
|
|
27
|
+
* makes: ONE watcher, one instant, one answer per cadence. A second
|
|
28
|
+
* interval here would sample the same session a fraction of a second later
|
|
29
|
+
* and publish a second story about one moment.
|
|
30
|
+
*
|
|
31
|
+
* A `restart` says "my project's files changed", so the project family's file
|
|
32
|
+
* cache is dropped on it — through `session.onCommandDispatched`, the door
|
|
33
|
+
* that already reports every relayed command, rather than a line in the
|
|
34
|
+
* host's dispatch naming this package.
|
|
35
|
+
*/
|
|
36
|
+
import { editorHost } from '@volter/editor-sdk/host';
|
|
37
|
+
import { authoringSurfaceCoverage } from '../src/coverage/live-authoring-surface';
|
|
38
|
+
import {
|
|
39
|
+
invalidateProjectFileFacts,
|
|
40
|
+
projectVerbCoverage,
|
|
41
|
+
} from '../src/coverage/live-project-verbs';
|
|
42
|
+
import { nativeSystemCoverage } from '../src/coverage/native-system-coverage';
|
|
43
|
+
import { rootCoverageFacet } from '../src/coverage/root-coverage';
|
|
44
|
+
import { reportSessionCoverage } from '../src/coverage/session-coverage';
|
|
45
|
+
|
|
46
|
+
export const point = 'workspace.service';
|
|
47
|
+
|
|
48
|
+
/** The four keys this facet serves, and the ones the host strips from an
|
|
49
|
+
* interaction patch. Named once. */
|
|
50
|
+
const REUSABLE_KEYS = [
|
|
51
|
+
'rootCoverage',
|
|
52
|
+
'systemCoverage',
|
|
53
|
+
'projectCoverage',
|
|
54
|
+
'authoringCoverage',
|
|
55
|
+
] as const;
|
|
56
|
+
|
|
57
|
+
function coverageFacets(reuse: Record<string, unknown> | null): Record<string, unknown> {
|
|
58
|
+
if (reuse)
|
|
59
|
+
return {
|
|
60
|
+
rootCoverage: reuse['rootCoverage'] ?? [],
|
|
61
|
+
systemCoverage: reuse['systemCoverage'] ?? null,
|
|
62
|
+
projectCoverage: reuse['projectCoverage'] ?? null,
|
|
63
|
+
authoringCoverage: reuse['authoringCoverage'] ?? null,
|
|
64
|
+
};
|
|
65
|
+
const systems = nativeSystemCoverage();
|
|
66
|
+
const project = projectVerbCoverage();
|
|
67
|
+
const authoring = authoringSurfaceCoverage();
|
|
68
|
+
return {
|
|
69
|
+
// THE DERIVED COVERAGE, per mounted root — native and ingested alike. The
|
|
70
|
+
// row vocabulary is generated from the `AuthoringAdapter` contract itself
|
|
71
|
+
// (`src/coverage/root-coverage.ts`), so a capability nobody remembered to
|
|
72
|
+
// enumerate still appears here as a standing row. `[]` when nothing is
|
|
73
|
+
// mounted, which is not the same as "no gaps".
|
|
74
|
+
rootCoverage: rootCoverageFacet().map((entry) => ({
|
|
75
|
+
worldId: entry.worldId,
|
|
76
|
+
surface: entry.surface,
|
|
77
|
+
summary: entry.report.summary,
|
|
78
|
+
rows: entry.report.rows.map((row) => ({ ...row })),
|
|
79
|
+
})),
|
|
80
|
+
// The GAME-scoped companion to `rootCoverage`: one row per
|
|
81
|
+
// `SystemAdapters` slot, read off the editor's own live registry. `null`
|
|
82
|
+
// for an ingested mount, whose declared-carrier measurement in
|
|
83
|
+
// `ingest.coverage` is stronger, and for a session with no open project.
|
|
84
|
+
systemCoverage: systems
|
|
85
|
+
? { summary: systems.summary, rows: systems.rows.map((row) => ({ ...row })) }
|
|
86
|
+
: null,
|
|
87
|
+
// The THIRD derived family, and the one that lives outside both adapter
|
|
88
|
+
// contracts: the native verbs whose subject is the PROJECT rather than a
|
|
89
|
+
// mounted root — its committed proof route, whether `vgai add` can land a
|
|
90
|
+
// capability here, and whether it can produce a standalone build at all
|
|
91
|
+
// (`@editor/coverage/project-verb-coverage`). Without it a project could
|
|
92
|
+
// be green in the other two families and silently have none of the three.
|
|
93
|
+
// `null` only when no project is open.
|
|
94
|
+
projectCoverage: project
|
|
95
|
+
? { summary: project.summary, rows: project.rows.map((row) => ({ ...row })) }
|
|
96
|
+
: null,
|
|
97
|
+
// The PROJECT-level authoring surface: whether the resolved adapter table
|
|
98
|
+
// became real Edit documents and Content pieces. Runtime/root coverage can
|
|
99
|
+
// be green while both are absent, so this family has its own status facet.
|
|
100
|
+
authoringCoverage: authoring
|
|
101
|
+
? { summary: authoring.summary, rows: authoring.rows.map((row) => ({ ...row })) }
|
|
102
|
+
: null,
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export function start(): () => void {
|
|
107
|
+
const session = editorHost().session;
|
|
108
|
+
const stopFacet = session.reportFacet(coverageFacets, { reusableKeys: REUSABLE_KEYS });
|
|
109
|
+
const stopSample = session.onSample(reportSessionCoverage);
|
|
110
|
+
const stopCommands = session.onCommandDispatched((type) => {
|
|
111
|
+
if (type === 'restart') invalidateProjectFileFacts();
|
|
112
|
+
});
|
|
113
|
+
return () => {
|
|
114
|
+
stopFacet();
|
|
115
|
+
stopSample();
|
|
116
|
+
stopCommands();
|
|
117
|
+
};
|
|
118
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* EDIT-TIME AUDIO (`@volter/editor-sdk/services`, a `workspace.service`
|
|
3
|
+
* contribution): the first-party Three/Web Audio graph the editor inspects
|
|
4
|
+
* while nothing is playing, so Stop falls back to a real adapter instead of
|
|
5
|
+
* making audio disappear.
|
|
6
|
+
*
|
|
7
|
+
* Install-once and project-independent, like `audio-unlock.service.ts` beside
|
|
8
|
+
* it — the graph is the page's, not the open project's — so this has no
|
|
9
|
+
* `onProjectChange` re-install, unlike edit-time networking.
|
|
10
|
+
*
|
|
11
|
+
* It was `components/EditModeAudioBootstrap.tsx`, a component that rendered
|
|
12
|
+
* `null` so the shell's layout could run an effect, and through it the host
|
|
13
|
+
* imported `@volter/game-runtime/setup/setup-audio`, `@volter/game-runtime/audio/bus-mixer` and
|
|
14
|
+
* `@volter/game-runtime/audio/pose-guard` — the engine's audio RUNTIME — into every editor
|
|
15
|
+
* boot (WORK.md §The open-source launch, phase 1 unit 7).
|
|
16
|
+
*/
|
|
17
|
+
import { installEditModeAudio } from '../src/edit-mode/edit-mode-audio';
|
|
18
|
+
|
|
19
|
+
export const point = 'workspace.service';
|
|
20
|
+
|
|
21
|
+
export function start(): () => void {
|
|
22
|
+
return installEditModeAudio();
|
|
23
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* EDIT-TIME NETWORKING (`@volter/editor-sdk/services`, a `workspace.service`
|
|
3
|
+
* contribution): the networking adapter the editor inspects while nothing is
|
|
4
|
+
* playing, bound to the open project's own Colyseus client/room exports.
|
|
5
|
+
*
|
|
6
|
+
* Unlike audio (universal, install-once), it is project-dependent — it
|
|
7
|
+
* installs only when the open project declares a server — so it re-installs
|
|
8
|
+
* on every project change.
|
|
9
|
+
*
|
|
10
|
+
* It was `components/EditModeNetworkingBootstrap.tsx`, a component that
|
|
11
|
+
* rendered `null` so the shell's layout could run an effect. A service is what
|
|
12
|
+
* that always was, and the shell no longer names it (WORK.md §The workbench,
|
|
13
|
+
* P3b).
|
|
14
|
+
*/
|
|
15
|
+
import { onProjectChange } from '@volter/editor-core/project-manager';
|
|
16
|
+
import { installEditModeNetworking } from '../src/edit-mode/edit-mode-networking';
|
|
17
|
+
|
|
18
|
+
export const point = 'workspace.service';
|
|
19
|
+
|
|
20
|
+
export function start(): () => void {
|
|
21
|
+
let dispose = installEditModeNetworking();
|
|
22
|
+
const stop = onProjectChange(() => {
|
|
23
|
+
dispose();
|
|
24
|
+
dispose = installEditModeNetworking();
|
|
25
|
+
});
|
|
26
|
+
return () => {
|
|
27
|
+
stop();
|
|
28
|
+
dispose();
|
|
29
|
+
};
|
|
30
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* THE GAME DOCUMENT's content, registered (`@volter/editor-sdk/services`, a
|
|
3
|
+
* `workspace.service` contribution). The host owns the live document's
|
|
4
|
+
* LIFETIME — `workspace:game` opens when a lane acquires it and closes on the
|
|
5
|
+
* playing → stopped edge (`live-document.ts`) — and this package owns what it
|
|
6
|
+
* DRAWS: the panel a runtime mounts into and the document-local toolbar
|
|
7
|
+
* (resolution, device emulation, instance inspection, debug draw, frame
|
|
8
|
+
* capture).
|
|
9
|
+
*
|
|
10
|
+
* A service rather than a module-load side effect, so the registration is
|
|
11
|
+
* paired with an unregistration the host runs before the next contribution
|
|
12
|
+
* pass — a build that drops `@volter/editor-game` leaves the host with no live content
|
|
13
|
+
* and the door's own `NoLiveContent` placeholder, which is the honest state.
|
|
14
|
+
*/
|
|
15
|
+
import { editorHost } from '@volter/editor-sdk/host';
|
|
16
|
+
import { GameDocumentContent, GameDocumentToolbar } from '../src/game-document/GameDocument';
|
|
17
|
+
|
|
18
|
+
export const point = 'workspace.service';
|
|
19
|
+
|
|
20
|
+
export function start(): () => void {
|
|
21
|
+
return editorHost().workspace.liveDocument.register({
|
|
22
|
+
Content: GameDocumentContent,
|
|
23
|
+
Toolbar: GameDocumentToolbar,
|
|
24
|
+
});
|
|
25
|
+
}
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The STEP verbs of the session wire (`@volter/editor-sdk/commands`, a
|
|
3
|
+
* `workspace.command` contribution): `game-eval`, the module lane behind
|
|
4
|
+
* `vgai eval`'s `game.run(...)`, and `page-script`, the in-page Playwright
|
|
5
|
+
* shim behind `page(...)`. Both carry a step function's own SOURCE over the
|
|
6
|
+
* wire and reconstruct it here — closures do not survive the trip — so both
|
|
7
|
+
* are gated on a live game surface (a play session or an ingest mount) and
|
|
8
|
+
* rooted at the game container, never editor chrome.
|
|
9
|
+
*
|
|
10
|
+
* The module lane's page-side door (`window.__vgaiGameEval`) and the two
|
|
11
|
+
* providers it needs are installed when this module loads, which is when the
|
|
12
|
+
* verbs themselves become available: one handler, two doors, registered
|
|
13
|
+
* together.
|
|
14
|
+
*
|
|
15
|
+
* Play mode, the module resolver and the shim are the game skew's own
|
|
16
|
+
* modules, still housed in the editor until Play leaves the host (WORK.md
|
|
17
|
+
* §The workbench, G); they are reached through the `@editor/*` alias the
|
|
18
|
+
* editor's Vite serves to every contribution, and become this package's own
|
|
19
|
+
* imports when they move. Nothing here is host API.
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
import { createGameModuleResolver, setFocusedInstanceProvider } from '../src/host/game-module-access';
|
|
23
|
+
import { createPageShim, PageShimUnsupportedError } from '../src/host/playwright-shim';
|
|
24
|
+
import type {
|
|
25
|
+
CommandContribution,
|
|
26
|
+
EditorCommandMessage,
|
|
27
|
+
EditorCommandResult,
|
|
28
|
+
} from '@volter/editor-sdk/commands';
|
|
29
|
+
import { notPlayingResult } from '../src/command-results';
|
|
30
|
+
import { isIngestActive } from '../src/ingest/active-ingest';
|
|
31
|
+
import { focusedInstanceId, getGameContainer, isPlayModeActive } from '../src/play/play-mode';
|
|
32
|
+
|
|
33
|
+
export const point = 'workspace.command';
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* `game-eval` relay op — THE MODULE LANE. Reconstructs a step function's
|
|
37
|
+
* source in the editor page (same wire contract as `page-script`: closures do
|
|
38
|
+
* not survive) and runs it against a scope of { page, modules, instanceId } —
|
|
39
|
+
* `modules(path)` importing the RUNNING mount's own module instances
|
|
40
|
+
* (`game-module-access.ts`). This is what makes `vgai eval` able to touch the
|
|
41
|
+
* game's exported modules directly, in the browser, with no registry: the
|
|
42
|
+
* step is literal JS against the game's real functions.
|
|
43
|
+
*
|
|
44
|
+
* The result must survive the wire: anything unserializable is refused BY
|
|
45
|
+
* NAME rather than mangled — return plain data, not live objects.
|
|
46
|
+
*/
|
|
47
|
+
/**
|
|
48
|
+
* The Playwright-host door to the SAME handler: a real `page.evaluate` cannot
|
|
49
|
+
* reach relay ops, so the hook exposes `game-eval` inside the page itself.
|
|
50
|
+
* One handler, two doors — the lanes cannot drift.
|
|
51
|
+
*/
|
|
52
|
+
declare global {
|
|
53
|
+
interface Window {
|
|
54
|
+
__vgaiGameEval?: (src: string, instance?: string) => Promise<unknown>;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
if (typeof window !== 'undefined') {
|
|
58
|
+
setFocusedInstanceProvider(focusedInstanceId);
|
|
59
|
+
window.__vgaiGameEval = async (src: string, instance?: string) => {
|
|
60
|
+
const result = await handleGameEval({
|
|
61
|
+
type: 'game-eval',
|
|
62
|
+
src,
|
|
63
|
+
...(instance === undefined ? {} : { instance }),
|
|
64
|
+
} as unknown as EditorCommandMessage);
|
|
65
|
+
if (!result.ok) throw new Error(result.error ?? 'game-eval failed');
|
|
66
|
+
return (result.data as { result?: unknown } | undefined)?.result ?? null;
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
async function handleGameEval(cmd: EditorCommandMessage): Promise<EditorCommandResult> {
|
|
71
|
+
if (!isPlayModeActive() && !isIngestActive()) return notPlayingResult();
|
|
72
|
+
const src = cmd['src'];
|
|
73
|
+
if (typeof src !== 'string') {
|
|
74
|
+
return { ok: false, error: 'game-eval requires a string "src" (the step\'s toString())' };
|
|
75
|
+
}
|
|
76
|
+
const container = getGameContainer();
|
|
77
|
+
if (!container) {
|
|
78
|
+
return {
|
|
79
|
+
ok: false,
|
|
80
|
+
error: 'game-eval: no play-mode game container is mounted yet',
|
|
81
|
+
data: { code: 'GAME_EVAL_ERROR' },
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
const instanceRaw = cmd['instance'];
|
|
85
|
+
const instanceId = typeof instanceRaw === 'string' ? instanceRaw : undefined;
|
|
86
|
+
let step: (scope: unknown) => unknown;
|
|
87
|
+
try {
|
|
88
|
+
step = new Function('scope', `return (${src})(scope)`) as (scope: unknown) => unknown;
|
|
89
|
+
} catch (err) {
|
|
90
|
+
return {
|
|
91
|
+
ok: false,
|
|
92
|
+
error: `game-eval: failed to reconstruct the step function from source — ${
|
|
93
|
+
err instanceof Error ? err.message : String(err)
|
|
94
|
+
}`,
|
|
95
|
+
data: { code: 'GAME_EVAL_ERROR' },
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
const scope = {
|
|
99
|
+
page: createPageShim(container),
|
|
100
|
+
modules: createGameModuleResolver(instanceId),
|
|
101
|
+
instanceId: instanceId ?? focusedInstanceId(),
|
|
102
|
+
};
|
|
103
|
+
try {
|
|
104
|
+
const result = await step(scope);
|
|
105
|
+
const value = result === undefined ? null : result;
|
|
106
|
+
try {
|
|
107
|
+
JSON.stringify(value);
|
|
108
|
+
} catch {
|
|
109
|
+
return {
|
|
110
|
+
ok: false,
|
|
111
|
+
error:
|
|
112
|
+
'game-eval: the step returned an unserializable value ' +
|
|
113
|
+
`(${Object.prototype.toString.call(value)}) — return plain data (numbers, strings, ` +
|
|
114
|
+
'arrays, plain objects), not live module objects.',
|
|
115
|
+
data: { code: 'GAME_EVAL_UNSERIALIZABLE' },
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
return { ok: true, data: { result: value } };
|
|
119
|
+
} catch (err) {
|
|
120
|
+
return {
|
|
121
|
+
ok: false,
|
|
122
|
+
error: `game-eval step failed: ${err instanceof Error ? (err.stack ?? err.message) : String(err)}`,
|
|
123
|
+
data: { code: 'GAME_EVAL_ERROR' },
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* `page-script` relay op handler — "the playwright shim in the editor
|
|
130
|
+
* page + script-mode wire op". Standalone command (like `bridge-screenshot`,
|
|
131
|
+
* its sibling in `bridge.command.ts`),
|
|
132
|
+
* NOT a `bridge-call` method: this is editor-page UI automation, not the
|
|
133
|
+
* game-debug seam, so it deliberately stays outside `dispatchBridgeMethod`'s
|
|
134
|
+
* switch — the bridge↔wire parity gate (`bridge-wire-parity.test.ts`) only
|
|
135
|
+
* walks THAT switch, and must never need to know about this op.
|
|
136
|
+
*
|
|
137
|
+
* `cmd['src']` is a UI-automation step's `Function.prototype.toString()`
|
|
138
|
+
* source (`@volter/editor-live`'s `RelayTransport.runPageScript` — see that file's
|
|
139
|
+
* doc comment for the client-facing half of the wire contract). Reconstructed
|
|
140
|
+
* here with `new Function` and run against a fresh `createPageShim` rooted at
|
|
141
|
+
* the SAME game container `bridge-screenshot`'s composite capture uses
|
|
142
|
+
* (`getGameContainer` — never editor chrome). `PageShimUnsupportedError`
|
|
143
|
+
* (thrown the instant the step touches an unimplemented `Page`/`Locator`
|
|
144
|
+
* member) is distinguished from any other step failure so a caller can tell
|
|
145
|
+
* "this shim doesn't support that yet" apart from "the step's own assertion
|
|
146
|
+
* failed" — both are structured failures, never a hang or a silent
|
|
147
|
+
* mis-report.
|
|
148
|
+
*/
|
|
149
|
+
async function handlePageScript(cmd: EditorCommandMessage): Promise<EditorCommandResult> {
|
|
150
|
+
// An ingest mount IS the live game surface even though it never creates a
|
|
151
|
+
// first-party `play-mode.ts` session. Keep the Playwright-style page door on
|
|
152
|
+
// the same reachability rule as bridge calls/screenshots: a real ingest
|
|
153
|
+
// container is sufficient, while the genuinely-unmounted case still
|
|
154
|
+
// refuses below. Without this, `vgai play` could start an ingested game and
|
|
155
|
+
// `game.commands()` would work, yet `page(...)` answered "not in play mode"
|
|
156
|
+
// against that very same visible game.
|
|
157
|
+
if (!isPlayModeActive() && !isIngestActive()) return notPlayingResult();
|
|
158
|
+
const src = cmd['src'];
|
|
159
|
+
if (typeof src !== 'string') {
|
|
160
|
+
return { ok: false, error: 'page-script requires a string "src" (the step\'s toString())' };
|
|
161
|
+
}
|
|
162
|
+
const container = getGameContainer();
|
|
163
|
+
if (!container) {
|
|
164
|
+
return {
|
|
165
|
+
ok: false,
|
|
166
|
+
error: 'page-script: no play-mode game container is mounted yet',
|
|
167
|
+
data: { code: 'PAGE_SCRIPT_ERROR' },
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
let step: (page: unknown) => unknown;
|
|
171
|
+
try {
|
|
172
|
+
// Reconstructing a wire-carried step's source is the documented wire
|
|
173
|
+
// contract (decision 2) — the same limitation class as
|
|
174
|
+
// Playwright's own evaluate serialization: closures over anything
|
|
175
|
+
// outside the step's own body do NOT survive the trip.
|
|
176
|
+
step = new Function('page', `return (${src})(page)`) as (page: unknown) => unknown;
|
|
177
|
+
} catch (err) {
|
|
178
|
+
return {
|
|
179
|
+
ok: false,
|
|
180
|
+
error: `page-script: failed to reconstruct the step function from source — ${
|
|
181
|
+
err instanceof Error ? err.message : String(err)
|
|
182
|
+
}`,
|
|
183
|
+
data: { code: 'PAGE_SCRIPT_ERROR' },
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
const page = createPageShim(container);
|
|
187
|
+
try {
|
|
188
|
+
const result = await step(page);
|
|
189
|
+
return { ok: true, data: { result: result === undefined ? null : result } };
|
|
190
|
+
} catch (err) {
|
|
191
|
+
if (err instanceof PageShimUnsupportedError) {
|
|
192
|
+
return {
|
|
193
|
+
ok: false,
|
|
194
|
+
error: err.message,
|
|
195
|
+
data: { code: 'PAGE_SHIM_UNSUPPORTED', member: err.member, supported: [...err.supported] },
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
return {
|
|
199
|
+
ok: false,
|
|
200
|
+
error: `page-script: step threw — ${err instanceof Error ? err.message : String(err)}`,
|
|
201
|
+
data: { code: 'PAGE_SCRIPT_ERROR' },
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
export const commands: CommandContribution['commands'] = {
|
|
207
|
+
// THE MODULE LANE: an in-page step over { page, modules, instanceId }.
|
|
208
|
+
'game-eval': { timeoutMs: 60_000, derivedRefresh: 'always', handle: handleGameEval },
|
|
209
|
+
'page-script': { timeoutMs: 60_000, derivedRefresh: 'always', handle: handlePageScript },
|
|
210
|
+
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The GAME workspace — building and playing the game: the editor's standing
|
|
3
|
+
* arrangement, unchanged (`@volter/editor-sdk/looks`, a `workspace.layout`
|
|
4
|
+
* contribution). It applies to every project the game editor opens: a
|
|
5
|
+
* project with no root yet is a game not yet begun, and the Game workspace is
|
|
6
|
+
* where its first root is added. No captured state: the dock's own reconcile
|
|
7
|
+
* builds the standing arrangement from nothing.
|
|
8
|
+
*/
|
|
9
|
+
import type { WorkspaceLayoutContribution } from '@volter/editor-sdk/looks';
|
|
10
|
+
|
|
11
|
+
export const point = 'workspace.layout';
|
|
12
|
+
export const layout: WorkspaceLayoutContribution = {
|
|
13
|
+
id: 'game',
|
|
14
|
+
title: 'Game',
|
|
15
|
+
description:
|
|
16
|
+
"Building and playing the game: the editor's standing arrangement, unchanged. The default.",
|
|
17
|
+
// Game authoring uses the viewport's floating controls; Blender owns its header row.
|
|
18
|
+
regions: { header: 'hidden' },
|
|
19
|
+
};
|