@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,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The compact `Capture frame` control in the Game document toolbar while play
|
|
3
|
+
* runs (`GameDocumentToolbar`, CenterDocuments.tsx). Captures one frame into
|
|
4
|
+
* the shared ring (`frame-debugger-store.ts`) and opens the Frame view of the
|
|
5
|
+
* Profiler utility. Disabled — with honest title text — when the world
|
|
6
|
+
* registered no render-debug adapter.
|
|
7
|
+
*
|
|
8
|
+
* It sits HERE rather than beside the panel it opens because the panel moved
|
|
9
|
+
* to `@volter/editor-game` (the game skew as a package) and this button's caller is a
|
|
10
|
+
* host module: the host imports no package (WORKBENCH.md §The invariants), so
|
|
11
|
+
* the button stays on this side of the line with the store and model it reads.
|
|
12
|
+
*/
|
|
13
|
+
import { getInspectedRenderDebug } from '@volter/editor-core/authoring/active-systems';
|
|
14
|
+
import { useAvailabilitySelector } from '@volter/editor-core/availability-tick';
|
|
15
|
+
import { deriveRenderDebugCapabilities } from '../host/components/frame-debugger-model';
|
|
16
|
+
import { profilerView } from '../host/components/utility-view-state';
|
|
17
|
+
import { Button } from '@volter/editor-sdk/widgets';
|
|
18
|
+
import { captureFrame } from '../profiler/frame-debugger-store';
|
|
19
|
+
|
|
20
|
+
export function GameCaptureFrameButton() {
|
|
21
|
+
const adapter = useAvailabilitySelector(() => getInspectedRenderDebug() ?? null);
|
|
22
|
+
const caps = deriveRenderDebugCapabilities(adapter);
|
|
23
|
+
const available = caps?.capture === true;
|
|
24
|
+
return (
|
|
25
|
+
<Button
|
|
26
|
+
type="button"
|
|
27
|
+
size="compact"
|
|
28
|
+
variant="ghost"
|
|
29
|
+
data-testid="game-capture-frame"
|
|
30
|
+
className="vgai-frame-capture-game-button"
|
|
31
|
+
disabled={!available}
|
|
32
|
+
title={
|
|
33
|
+
available
|
|
34
|
+
? 'Capture one rendered frame and open the Frame debugger'
|
|
35
|
+
: 'No render-debug adapter registered for this world — frame capture is unavailable'
|
|
36
|
+
}
|
|
37
|
+
onClick={() => {
|
|
38
|
+
void captureFrame(adapter);
|
|
39
|
+
profilerView.open('frame');
|
|
40
|
+
}}
|
|
41
|
+
>
|
|
42
|
+
Capture frame
|
|
43
|
+
</Button>
|
|
44
|
+
);
|
|
45
|
+
}
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
import { HeaderTelemetry } from '../host/components/HeaderTelemetry';
|
|
2
|
+
import { PlayBar } from '../play-bar/PlayBar';
|
|
3
|
+
/**
|
|
4
|
+
* THE GAME DOCUMENT's CONTENT AND TOOLBAR — what the host's live document
|
|
5
|
+
* (`workspace:game`) draws while a runtime is live. Registered through
|
|
6
|
+
* `workspace.liveDocument.register` by `contributions/game-document.service.ts`.
|
|
7
|
+
*
|
|
8
|
+
* It moved out of `components/CenterDocuments.tsx` when Play left the host
|
|
9
|
+
* (WORK.md §The workbench, P3b). `ResolutionPicker` stayed behind — the
|
|
10
|
+
* host's story documents read it — so it is reached through the `@editor/*`
|
|
11
|
+
* alias, like every other editor internal this document still holds.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import { ResolutionPicker } from '../host/components/ResolutionPicker';
|
|
15
|
+
import { useEditorStore } from '@volter/editor-core/editor-runtime';
|
|
16
|
+
import { getCurrentProject, onProjectChange } from '@volter/editor-core/project-manager';
|
|
17
|
+
import type { LiveDocumentContentProps } from '@volter/editor-sdk/host';
|
|
18
|
+
import {
|
|
19
|
+
AnchoredMenu,
|
|
20
|
+
Button,
|
|
21
|
+
DisclosureIcon,
|
|
22
|
+
MenuItem,
|
|
23
|
+
themeVars,
|
|
24
|
+
} from '@volter/editor-sdk/widgets';
|
|
25
|
+
import { useRef, useState, useSyncExternalStore } from 'react';
|
|
26
|
+
import { crowdDebugEnabled, setCrowdDebugEnabled } from './crowd-debug';
|
|
27
|
+
import { DevicePresetPicker } from './DevicePresetPicker';
|
|
28
|
+
import {
|
|
29
|
+
devicePreviewVersion,
|
|
30
|
+
FIT_PRESET_ID,
|
|
31
|
+
setDevicePreset,
|
|
32
|
+
subscribeDevicePreview,
|
|
33
|
+
} from './device-preview';
|
|
34
|
+
import { GameCaptureFrameButton } from './GameCaptureFrameButton';
|
|
35
|
+
import { GamePanel } from './GamePanel';
|
|
36
|
+
import {
|
|
37
|
+
applyGameDevicePreset,
|
|
38
|
+
displayedGameResolution,
|
|
39
|
+
gameDocumentResolution,
|
|
40
|
+
gameDocumentScale,
|
|
41
|
+
gameResolutionOptions,
|
|
42
|
+
gameViewVersion,
|
|
43
|
+
notifyGameView,
|
|
44
|
+
setGameDocumentResolution,
|
|
45
|
+
subscribeGameView,
|
|
46
|
+
} from './game-view-store';
|
|
47
|
+
import { InstanceInspectorPicker } from './InstanceInspectorPicker';
|
|
48
|
+
import { physicsDebugEnabled, setPhysicsDebugEnabled } from './physics-debug';
|
|
49
|
+
|
|
50
|
+
function GameDebugMenu() {
|
|
51
|
+
const [open, setOpen] = useState(false);
|
|
52
|
+
const ref = useRef<HTMLButtonElement>(null);
|
|
53
|
+
return (
|
|
54
|
+
<div style={{ position: 'relative' }}>
|
|
55
|
+
<Button
|
|
56
|
+
ref={ref}
|
|
57
|
+
type="button"
|
|
58
|
+
variant="outline"
|
|
59
|
+
size="compact"
|
|
60
|
+
data-testid="game-debug-menu"
|
|
61
|
+
aria-haspopup="menu"
|
|
62
|
+
aria-expanded={open}
|
|
63
|
+
aria-controls={open ? 'vgai-game-debug-menu' : undefined}
|
|
64
|
+
onClick={() => setOpen((value) => !value)}
|
|
65
|
+
>
|
|
66
|
+
<span>Debug</span>
|
|
67
|
+
<DisclosureIcon direction="down" />
|
|
68
|
+
</Button>
|
|
69
|
+
{open && (
|
|
70
|
+
<AnchoredMenu
|
|
71
|
+
id="vgai-game-debug-menu"
|
|
72
|
+
anchorRef={ref}
|
|
73
|
+
gap={3}
|
|
74
|
+
onDismiss={() => setOpen(false)}
|
|
75
|
+
style={{
|
|
76
|
+
minWidth: 190,
|
|
77
|
+
}}
|
|
78
|
+
>
|
|
79
|
+
<MenuItem
|
|
80
|
+
onClick={() => {
|
|
81
|
+
setCrowdDebugEnabled(!crowdDebugEnabled());
|
|
82
|
+
notifyGameView();
|
|
83
|
+
}}
|
|
84
|
+
>
|
|
85
|
+
{crowdDebugEnabled() ? '✓ ' : ' '}Crowd debug draw
|
|
86
|
+
</MenuItem>
|
|
87
|
+
<MenuItem
|
|
88
|
+
onClick={() => {
|
|
89
|
+
setPhysicsDebugEnabled(!physicsDebugEnabled());
|
|
90
|
+
notifyGameView();
|
|
91
|
+
}}
|
|
92
|
+
>
|
|
93
|
+
{physicsDebugEnabled() ? '✓ ' : ' '}Physics debug draw
|
|
94
|
+
</MenuItem>
|
|
95
|
+
</AnchoredMenu>
|
|
96
|
+
)}
|
|
97
|
+
</div>
|
|
98
|
+
);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* The Game document's LOCAL toolbar (§7.1 toolbar contribution, drawn in the
|
|
103
|
+
* document's own header strip while it is active): resolution picker + mute — the V4 remainder deferred from W1.
|
|
104
|
+
* The global header keeps the launcher; running-session transport and telemetry belong here.
|
|
105
|
+
*/
|
|
106
|
+
export function GameDocumentToolbar(_props: LiveDocumentContentProps) {
|
|
107
|
+
const project = useSyncExternalStore(onProjectChange, getCurrentProject);
|
|
108
|
+
const store = useEditorStore();
|
|
109
|
+
useSyncExternalStore(store.subscribe, store.getShellSnapshot ?? store.getSnapshot);
|
|
110
|
+
useSyncExternalStore(subscribeGameView, gameViewVersion);
|
|
111
|
+
useSyncExternalStore(subscribeDevicePreview, devicePreviewVersion);
|
|
112
|
+
return (
|
|
113
|
+
<div
|
|
114
|
+
data-testid="game-doc-toolbar"
|
|
115
|
+
style={{
|
|
116
|
+
display: 'grid',
|
|
117
|
+
alignItems: 'center',
|
|
118
|
+
gridTemplateColumns: 'minmax(0, 1fr) auto minmax(0, 1fr)',
|
|
119
|
+
width: '100%',
|
|
120
|
+
gap: 6,
|
|
121
|
+
padding: '2px 8px',
|
|
122
|
+
}}
|
|
123
|
+
>
|
|
124
|
+
<div style={{ display: 'flex', alignItems: 'center', minWidth: 0, overflow: 'auto' }}>
|
|
125
|
+
<InstanceInspectorPicker />
|
|
126
|
+
<DevicePresetPicker
|
|
127
|
+
onPresetChange={(preset) => {
|
|
128
|
+
applyGameDevicePreset(preset);
|
|
129
|
+
notifyGameView();
|
|
130
|
+
}}
|
|
131
|
+
/>
|
|
132
|
+
<ResolutionPicker
|
|
133
|
+
resolution={displayedGameResolution(gameDocumentResolution(), project?.config.resolution)}
|
|
134
|
+
options={gameResolutionOptions(project?.config.resolution)}
|
|
135
|
+
onResolutionChange={(resolution) => {
|
|
136
|
+
// A plain resolution pick is a deliberate exit from device
|
|
137
|
+
// emulation: keep the chosen dimensions, drop DPR/safe-area/touch.
|
|
138
|
+
setDevicePreset(FIT_PRESET_ID);
|
|
139
|
+
setGameDocumentResolution(resolution);
|
|
140
|
+
}}
|
|
141
|
+
scale={gameDocumentScale()}
|
|
142
|
+
title="Change game resolution"
|
|
143
|
+
/>
|
|
144
|
+
<GameDebugMenu />
|
|
145
|
+
{/* F11: capture one rendered frame into the Frame debugger.
|
|
146
|
+
Play-gated; honestly disabled when the world registered no
|
|
147
|
+
render-debug adapter (headless/non-real-context). Lives in the
|
|
148
|
+
toolbar (not floating over the panel) so it tiles with the rest of
|
|
149
|
+
the chrome when paused Play reveals the editor. */}
|
|
150
|
+
{store.playState !== 'stopped' && <GameCaptureFrameButton />}
|
|
151
|
+
</div>
|
|
152
|
+
<PlayBar placement="runtime" />
|
|
153
|
+
<div style={{ display: 'flex', justifyContent: 'flex-end', minWidth: 0 }}>
|
|
154
|
+
<HeaderTelemetry />
|
|
155
|
+
</div>
|
|
156
|
+
</div>
|
|
157
|
+
);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/** The Game document's content host. It exists only while a runtime is live —
|
|
161
|
+
* see this file's header. */
|
|
162
|
+
export function GameDocumentContent(_props: LiveDocumentContentProps) {
|
|
163
|
+
const store = useEditorStore();
|
|
164
|
+
useSyncExternalStore(store.subscribe, store.getShellSnapshot ?? store.getSnapshot);
|
|
165
|
+
const isPlaying = store.playState !== 'stopped';
|
|
166
|
+
return (
|
|
167
|
+
<div style={{ flex: 1, position: 'relative', display: 'flex', flexDirection: 'column' }}>
|
|
168
|
+
<GamePanel
|
|
169
|
+
style={{
|
|
170
|
+
flex: 1,
|
|
171
|
+
position: 'relative',
|
|
172
|
+
display: 'flex',
|
|
173
|
+
flexDirection: 'column',
|
|
174
|
+
pointerEvents: 'auto',
|
|
175
|
+
// L-20 — playing/paused edge treatment from the shared themeVars.semantic.success/themeVars.semantic.warning
|
|
176
|
+
// tokens (same "healthy"/"attention" semantic SaveStatus uses).
|
|
177
|
+
...(store.playState === 'playing'
|
|
178
|
+
? { outline: `2px solid ${themeVars.semantic.success}`, outlineOffset: -2 }
|
|
179
|
+
: isPlaying
|
|
180
|
+
? { outline: `2px solid ${themeVars.semantic.warning}`, outlineOffset: -2 }
|
|
181
|
+
: {}),
|
|
182
|
+
}}
|
|
183
|
+
/>
|
|
184
|
+
{store.playState === 'paused' && (
|
|
185
|
+
// THE EDITOR PAUSED THE GAME, AND SAYS SO ON THE GAME. Escape belongs
|
|
186
|
+
// to play-mode while playing (pause on Escape), so a player who
|
|
187
|
+
// pressed it — once to free the mouse, once more by habit — froze the
|
|
188
|
+
// game with input gated off while the game's own card still read
|
|
189
|
+
// PRESS ENTER TO REDEPLOY; two testers in a row reported "Enter ain't
|
|
190
|
+
// working" from exactly that sequence (runhuman passes 124, 125). The
|
|
191
|
+
// yellow outline alone did not read as "paused". This label sits over
|
|
192
|
+
// the game and points at the one control that resumes it.
|
|
193
|
+
<div
|
|
194
|
+
data-testid="game-paused-notice"
|
|
195
|
+
style={{
|
|
196
|
+
position: 'absolute',
|
|
197
|
+
left: '50%',
|
|
198
|
+
top: 12,
|
|
199
|
+
transform: 'translateX(-50%)',
|
|
200
|
+
padding: '6px 12px',
|
|
201
|
+
borderRadius: 6,
|
|
202
|
+
background: 'rgba(0,0,0,.72)',
|
|
203
|
+
color: themeVars.content.primary,
|
|
204
|
+
fontSize: 12,
|
|
205
|
+
letterSpacing: '.04em',
|
|
206
|
+
pointerEvents: 'none',
|
|
207
|
+
zIndex: 2,
|
|
208
|
+
}}
|
|
209
|
+
>
|
|
210
|
+
Paused by the editor — press ▶ Play to resume (Escape pauses)
|
|
211
|
+
</div>
|
|
212
|
+
)}
|
|
213
|
+
</div>
|
|
214
|
+
);
|
|
215
|
+
}
|