@volter/editor-game 0.5.65 → 0.5.66

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (141) hide show
  1. package/contributions/generation.service.ts +2 -2
  2. package/contributions/generations.status.tsx +1 -1
  3. package/contributions/godot.palette.json +99 -0
  4. package/contributions/godot.style.ts +62 -0
  5. package/contributions/godot.view.ts +69 -0
  6. package/contributions/ingest.service.ts +3 -3
  7. package/contributions/play.command.ts +1 -1
  8. package/contributions/react/react-inspector.service.ts +2 -2
  9. package/contributions/scene-document.service.ts +3 -3
  10. package/contributions/three/component-verbs.command.ts +3 -3
  11. package/contributions/unity.palette.json +102 -0
  12. package/contributions/unity.style.ts +62 -0
  13. package/contributions/unity.view.ts +76 -0
  14. package/contributions/unreal.palette.json +105 -0
  15. package/contributions/unreal.style.ts +58 -0
  16. package/contributions/unreal.view.ts +88 -0
  17. package/dist-node/serving.mjs +16 -0
  18. package/package.json +21 -14
  19. package/serving/index.ts +27 -0
  20. package/src/asset-budget/asset-budget-model.ts +3 -3
  21. package/src/asset-budget/optimize-apply.ts +7 -7
  22. package/src/bridge/dispatch.ts +2 -2
  23. package/src/bridge/screenshot.ts +3 -3
  24. package/src/coverage/live-authoring-surface.ts +1 -1
  25. package/src/coverage/live-project-verbs.ts +1 -1
  26. package/src/coverage/native-system-coverage.ts +1 -1
  27. package/src/coverage/session-coverage.ts +2 -2
  28. package/src/design-system-stories/InspectorNarrowBodies.stories.tsx +10 -50
  29. package/src/game-document/GameCaptureFrameButton.tsx +1 -1
  30. package/src/game-document/GamePanel.tsx +4 -4
  31. package/src/generation/GenerationActivity.tsx +3 -5
  32. package/src/generation/generation-documents.tsx +3 -3
  33. package/src/generation/generation-jobs.ts +1 -1
  34. package/src/generation/generation-presentation.ts +1 -1
  35. package/src/host/adapter-reach.ts +1 -1
  36. package/src/host/adapter-runtime-bindings.ts +1 -1
  37. package/src/host/api/configurations.ts +2 -2
  38. package/src/host/authoring/babylon-authoring-adapter.ts +2 -2
  39. package/src/host/authoring/contract-hierarchy-authoring.ts +1 -1
  40. package/src/host/authoring/contract-scenes-stories.ts +1 -1
  41. package/src/host/authoring/creation-site-related.ts +2 -2
  42. package/src/host/authoring/ephemeral-persistence.ts +1 -1
  43. package/src/host/authoring/gesture-persist.ts +1 -1
  44. package/src/host/authoring/ingest-source-persistence.ts +4 -4
  45. package/src/host/authoring/mount-isolated-pixi-screen.ts +1 -1
  46. package/src/host/authoring/pixi-authoring-adapter.ts +2 -2
  47. package/src/host/authoring/pixi-live-write-target.ts +3 -3
  48. package/src/host/authoring/pixi-still-presentation.ts +1 -1
  49. package/src/host/authoring/pixi-structure-history.ts +1 -1
  50. package/src/host/authoring/source-persistence-backend.ts +3 -3
  51. package/src/host/authoring/struct-write-pipe.ts +2 -2
  52. package/src/host/browser-transpile.ts +1 -1
  53. package/src/host/canvas-entry-runtime.ts +1 -1
  54. package/src/host/components/HeaderTelemetry.tsx +5 -12
  55. package/src/host/components/PixiIsolationSceneContent.tsx +8 -7
  56. package/src/host/components/ThreeIsolationSceneContent.tsx +2 -2
  57. package/src/host/components/scene-document.tsx +15 -47
  58. package/src/host/components/world-root-stage-binding.tsx +6 -15
  59. package/src/host/components/world-root-stage.ts +60 -14
  60. package/src/host/coverage/capability-coverage.ts +13 -1
  61. package/src/host/coverage/game-contract-seam-evidence.ts +1 -1
  62. package/src/host/coverage/project-verb-coverage.ts +2 -17
  63. package/src/host/coverage/system-adapter-coverage.ts +1 -1
  64. package/src/host/design-system-stories/fixtures/editor-runtime.tsx +9 -1
  65. package/src/host/document-preview-three.ts +1 -1
  66. package/src/host/game-module-access.ts +1 -1
  67. package/src/host/game-realm-page.ts +15 -7
  68. package/src/host/game-realm-reclaim.ts +1 -1
  69. package/src/host/gated-globals.ts +4 -4
  70. package/src/host/history/json-history-resource.ts +2 -2
  71. package/src/host/instance-extract-actions.ts +1 -1
  72. package/src/host/instance-fork-actions.ts +1 -1
  73. package/src/host/projection/dom.ts +2 -2
  74. package/src/host/projection/pixi.ts +1 -1
  75. package/src/host/r3f-entry-runtime.ts +1 -1
  76. package/src/host/react-mount-runtime.ts +1 -1
  77. package/src/host/realm-services.ts +1 -1
  78. package/src/host/roots/module-root.ts +1 -1
  79. package/src/host/scene-view-drawability.ts +2 -2
  80. package/src/host/server-log-bridge.ts +1 -1
  81. package/src/host/three-ingest-runtime.ts +1 -1
  82. package/src/host/use-active-performance-source.ts +1 -1
  83. package/src/ingest/active-ingest.ts +1 -1
  84. package/src/ingest/authoring/ingest-root-adapter.ts +5 -5
  85. package/src/ingest/capture-wait-report.ts +1 -1
  86. package/src/ingest/deferred-ingest-play.ts +5 -4
  87. package/src/ingest/ingest-boot-viewport.ts +4 -6
  88. package/src/ingest/ingest-canvas-scene-document.tsx +9 -8
  89. package/src/ingest/ingest-canvas-scene.ts +2 -5
  90. package/src/ingest/ingest-play-control.ts +3 -3
  91. package/src/ingest/ingest-render-debug.ts +1 -1
  92. package/src/ingest/ingest-siblings.ts +3 -3
  93. package/src/ingest/module-mode.ts +4 -5
  94. package/src/ingest/mount-canvas-ingest-root.ts +6 -6
  95. package/src/ingest/mount-coverage.ts +2 -2
  96. package/src/ingest/mount-dom-ingest-root.ts +5 -5
  97. package/src/ingest/mount-ingest-root.ts +7 -7
  98. package/src/ingest/mount-three-ingest-root.ts +4 -4
  99. package/src/ingest/unmount-ingest-root.ts +2 -2
  100. package/src/play/play-mode.ts +30 -16
  101. package/src/play/play-recording.ts +1 -1
  102. package/src/profiler/PerformancePanel.tsx +1 -1
  103. package/src/react/design-time-react-mount.ts +17 -23
  104. package/src/react/dom-authoring-adapter.ts +2 -2
  105. package/src/react/react-inspector-section.tsx +8 -8
  106. package/src/react/react-world-authoring-adapter.ts +20 -132
  107. package/src/react/story-documents/story-documents.tsx +9 -13
  108. package/src/react/ui-board-document.tsx +3 -4
  109. package/src/react/ui-component-board.ts +3 -3
  110. package/src/three/authoring/camera-runtime-inspector-section.tsx +1 -1
  111. package/src/three/authoring/constraint-inspector-section.tsx +3 -3
  112. package/src/three/authoring/model-asset-inspector-section.tsx +7 -11
  113. package/src/three/authoring/oid-source-persistence.ts +6 -6
  114. package/src/three/authoring/r3f-design-session.ts +21 -7
  115. package/src/three/authoring/r3f-source-authoring-adapter.ts +17 -17
  116. package/src/three/authoring/reflection-probe-inspector-section.tsx +3 -3
  117. package/src/three/authoring/spatial-joint-handles.ts +1 -1
  118. package/src/three/authoring/spatial-lod-handles.ts +1 -1
  119. package/src/three/authoring/spatial-particle-handles.ts +1 -1
  120. package/src/three/authoring/three-authoring-adapter.ts +4 -4
  121. package/src/three/component-verbs/extract-menu.ts +1 -1
  122. package/src/three/component-verbs/fork-menu.ts +1 -1
  123. package/src/three/component-verbs/internals-menu.ts +1 -1
  124. package/src/three/drei-asset-caches.ts +13 -0
  125. package/src/three/story-documents/three-story-documents.tsx +11 -21
  126. package/src/three/three-board/ThreeBoardDocument.tsx +12 -13
  127. package/src/three/three-board/board-scene.ts +1 -1
  128. package/src/three/three-board/three-component-board.ts +3 -3
  129. package/contributions/react/pasteboard.action.ts +0 -41
  130. package/contributions/xstate-behavior.action.ts +0 -42
  131. package/contributions/xstate-behavior.document.tsx +0 -73
  132. package/contributions/xstate-behavior.inspector.tsx +0 -28
  133. package/contributions/xstate-behavior.menu.ts +0 -23
  134. package/src/react/pasteboard-materialize.ts +0 -154
  135. package/src/xstate/XStateBehaviorSection.tsx +0 -130
  136. package/src/xstate/XStateMachineInspector.tsx +0 -566
  137. package/src/xstate/character-animation-machine.fixture.ts +0 -74
  138. package/src/xstate/live-behaviors.ts +0 -106
  139. package/src/xstate/use-live-actor-state.ts +0 -44
  140. package/src/xstate/xstate-graph.ts +0 -235
  141. package/src/xstate/xstate-layout.ts +0 -76
@@ -1,154 +0,0 @@
1
- /**
2
- * "MATERIALIZE PASTEBOARD" (queue item 4): turn the UI board's DERIVED,
3
- * ephemeral auto-grid into an AUTHORED pasteboard `.tsx` — the one action the
4
- * ratified design names ("ephemeral auto-grid when no file; one action
5
- * materializes it"). The generated file is ordinary project source: it
6
- * imports each board story's OWNER COMPONENT and places it under `<At x y>`
7
- * at the position the auto-grid gave its frame, so the derived layout becomes
8
- * literals a drag can then rewrite. Nothing regenerates the file afterwards —
9
- * it is the project's, exactly like every `vgai add` copy.
10
- *
11
- * Refusals are loud and name their remedy: no open project, no storage, no
12
- * pasteboard helpers (`vgai add pasteboard`), a file already at the target
13
- * path, or a board with nothing on it. A story whose owner component cannot
14
- * be resolved to an importable export is SKIPPED BY NAME in the returned
15
- * sentence rather than emitting an import that does not compile.
16
- *
17
- * ## Why it is this package's
18
- *
19
- * Its subject is THE UI BOARD — the design-time surface `@volter/editor-game` registers
20
- * a mount for (`design-time-react-mount.ts`, unit 12) — and it reads that
21
- * board's own frame placements. It stayed a host file only because its one
22
- * caller was a host `action-registry.ts` row; the action POINT
23
- * (`@volter/editor-sdk/chrome`, `workspace.action`) is what that row becomes,
24
- * and `contributions/pasteboard.action.ts` is the row now. Unit 12's header
25
- * called this file "NOT the dom lane's" on the strength of that caller; the
26
- * caller is what moved (WORK.md §The open-source launch item 17, the edge map
27
- * in `scripts/validate-editor-closure.mjs`).
28
- */
29
-
30
- import { commandLine } from '@volter/editor-core/product-command';
31
- import { listProjectComponents } from '@volter/editor-core/api/assets';
32
- import type { ProjectComponentEntry } from '@volter/editor-core/asset-workflow/project-content';
33
- import { reactStoryBoardFramePlacements } from '@volter/editor-core/authoring/react-story-board';
34
- import { getProjectPreviewStories } from '@volter/editor-core/stories/story-registry';
35
- import { domStoryBoardMembers } from '@volter/editor-core/stories/three-story-model';
36
- import { createProjectSourceFile } from '@volter/editor-core/ui-source/source-write-backend';
37
-
38
- export const PASTEBOARD_HELPERS_PATH = 'src/lib/pasteboard/pasteboard.tsx';
39
- export const MATERIALIZED_PASTEBOARD_PATH = 'src/design/pasteboard.tsx';
40
-
41
- /** The story's owner-module convention: `Hud.stories.tsx` → `Hud.tsx`. */
42
- function storyOwnerModulePath(storyModulePath: string): string {
43
- return storyModulePath.replace(/\.stories(?=\.[^.]+$)/, '');
44
- }
45
-
46
- /** Relative import specifier from `src/design/` to a project-relative path. */
47
- function importSpecifierFromDesign(componentPath: string): string {
48
- const withoutExtension = componentPath.replace(/\.[cm]?[jt]sx?$/, '');
49
- return `../${withoutExtension.replace(/^src\//, '')}`;
50
- }
51
-
52
- function componentForOwnerModule(
53
- components: readonly ProjectComponentEntry[],
54
- ownerModulePath: string,
55
- ): ProjectComponentEntry | null {
56
- const inModule = components.filter(
57
- (entry) => entry.path === ownerModulePath && (entry.exported || entry.defaultExport),
58
- );
59
- return (
60
- inModule.find((entry) => entry.defaultExport) ?? (inModule.length === 1 ? inModule[0]! : null)
61
- );
62
- }
63
-
64
- export async function materializePasteboard(): Promise<string> {
65
- const helpers = await fetch('/__ui-source/read', {
66
- method: 'POST',
67
- headers: { 'Content-Type': 'application/json' },
68
- body: JSON.stringify({ file: PASTEBOARD_HELPERS_PATH }),
69
- });
70
- if (!helpers.ok) {
71
- throw new Error(
72
- `Materialize pasteboard needs the pasteboard helpers at ${PASTEBOARD_HELPERS_PATH} — ` +
73
- `run ${commandLine('add pasteboard')} first.`,
74
- );
75
- }
76
- const layer = document.querySelector<HTMLElement>('[data-vgai-react-story-board="true"]');
77
- const placements = reactStoryBoardFramePlacements(layer);
78
- if (!placements || placements.length === 0) {
79
- throw new Error(
80
- 'Materialize pasteboard reads the live UI board and it has no frames — open the UI ' +
81
- 'document (a project with dom stories) first.',
82
- );
83
- }
84
- const stories = domStoryBoardMembers(getProjectPreviewStories());
85
- const listing = await listProjectComponents();
86
- const components = listing.ok ? listing.entries : [];
87
- const placed: Array<{ importLine: string; name: string; x: number; y: number }> = [];
88
- const skipped: string[] = [];
89
- const importsBySpecifier = new Map<string, string>();
90
- for (const placement of placements) {
91
- const story = stories.find((candidate) => candidate.id === placement.storyId);
92
- if (!story) continue;
93
- const owner = storyOwnerModulePath(story.modulePath);
94
- const component = componentForOwnerModule(components, owner);
95
- if (!component) {
96
- skipped.push(story.label ?? story.id);
97
- continue;
98
- }
99
- const specifier = importSpecifierFromDesign(component.path);
100
- const importLine = component.defaultExport
101
- ? `import ${component.name} from '${specifier}';`
102
- : `import { ${component.name} } from '${specifier}';`;
103
- importsBySpecifier.set(specifier, importLine);
104
- placed.push({ importLine, name: component.name, x: placement.x, y: placement.y });
105
- }
106
- if (placed.length === 0) {
107
- throw new Error(
108
- 'Materialize pasteboard resolved no importable owner component for any board frame ' +
109
- `(skipped: ${skipped.join(', ') || 'none'}). A story's owner module must export the ` +
110
- 'component its frames render.',
111
- );
112
- }
113
- const width = Math.max(...placed.map((entry) => entry.x)) + 960;
114
- const height = Math.max(...placed.map((entry) => entry.y)) + 720;
115
- const body = placed
116
- .map(
117
- (entry) => ` <At x={${entry.x}} y={${entry.y}}>\n <${entry.name} />\n </At>`,
118
- )
119
- .join('\n');
120
- const code = `${[...importsBySpecifier.values()].sort().join('\n')}
121
- import { At, Pasteboard } from '../lib/pasteboard/pasteboard';
122
-
123
- /**
124
- * Materialized from the UI board's derived auto-grid — this file is now the
125
- * AUTHORED canvas: edit freely, and a drag in the editor writes each At's
126
- * x/y literals right here.
127
- */
128
- export default function DesignPasteboard() {
129
- return (
130
- <Pasteboard width={${width}} height={${height}}>
131
- ${body}
132
- </Pasteboard>
133
- );
134
- }
135
- `;
136
- const created = await createProjectSourceFile(MATERIALIZED_PASTEBOARD_PATH, code);
137
- if (!created.created) {
138
- throw new Error(
139
- created.error ??
140
- `${MATERIALIZED_PASTEBOARD_PATH} already exists — the pasteboard is already authored; ` +
141
- 'edit it directly (there is deliberately no regeneration).',
142
- );
143
- }
144
- // The AssetBrowser owns asset-open routing; the event is its documented door.
145
- window.dispatchEvent(
146
- new CustomEvent('editor:open-project-asset', {
147
- detail: { path: MATERIALIZED_PASTEBOARD_PATH, kind: 'source' },
148
- }),
149
- );
150
- return (
151
- `Materialized ${placed.length} frame(s) into ${MATERIALIZED_PASTEBOARD_PATH}` +
152
- (skipped.length > 0 ? ` (skipped, no importable owner component: ${skipped.join(', ')})` : '')
153
- );
154
- }
@@ -1,130 +0,0 @@
1
- /**
2
- * The compact **Behavior** Inspector section (§4.3): the selected entity's
3
- * live machine — its id, where the actor IS, the machine's FULL state chart
4
- * with the active path marked, and the way into the Behavior document.
5
- *
6
- * It renders ONLY when `xstate-behavior.inspector.tsx`'s `match` found a real
7
- * live behavior mark on the selected node, so a template entity (no machine)
8
- * never sees it.
9
- */
10
-
11
- import { Button, themeVars } from '@volter/editor-sdk/widgets';
12
- import {
13
- subscribeXStateBehaviorInspections,
14
- xstateBehaviorInspectionsVersion,
15
- } from '@volter/threejs-runtime/behavior/xstate-inspection';
16
- import { useSyncExternalStore } from 'react';
17
- import type { AnyStateMachine, AnyStateNode } from 'xstate';
18
- import { liveBehaviorFor, openBehaviorDocument } from './live-behaviors';
19
- import { useLiveActorState } from './use-live-actor-state';
20
-
21
- /** Every descendant state node of the machine (depth-first, root excluded),
22
- * for the full-state-list readout below — the same direct `.states` walk
23
- * `xstate-graph.ts` documents as the sanctioned traversal. */
24
- function allMachineStates(machine: AnyStateMachine): AnyStateNode[] {
25
- const out: AnyStateNode[] = [];
26
- const visit = (node: AnyStateNode): void => {
27
- for (const child of Object.values(node.states)) {
28
- out.push(child);
29
- visit(child);
30
- }
31
- };
32
- visit(machine.root);
33
- return out;
34
- }
35
-
36
- export function XStateMachineSection({ nodeId }: { nodeId: string | null }) {
37
- useSyncExternalStore(
38
- subscribeXStateBehaviorInspections,
39
- xstateBehaviorInspectionsVersion,
40
- xstateBehaviorInspectionsVersion,
41
- );
42
- const behavior = nodeId ? liveBehaviorFor(nodeId) : undefined;
43
- const machine = behavior?.machine;
44
- // Follow live transitions (re-render per snapshot) — the state list and
45
- // layer readout below re-derive from each.
46
- const activeIds = useLiveActorState(machine as AnyStateMachine, behavior?.actor);
47
- if (!behavior || !machine || !nodeId) return null;
48
- const activeIdSet = new Set(activeIds ?? []);
49
- const states = allMachineStates(machine);
50
- return (
51
- <div
52
- data-testid="inspector-xstate-section"
53
- style={{
54
- pointerEvents: 'auto',
55
- padding: 8,
56
- borderBottom: `1px solid ${themeVars.boundary.default}`,
57
- }}
58
- >
59
- <div
60
- style={{
61
- fontSize: 11,
62
- color: themeVars.content.dim,
63
- textTransform: 'uppercase',
64
- marginBottom: 4,
65
- }}
66
- >
67
- Behavior
68
- </div>
69
- <div
70
- style={{ fontSize: 11, color: themeVars.content.primary, fontWeight: 600, marginBottom: 2 }}
71
- >
72
- {machine.id}
73
- </div>
74
- <div style={{ fontSize: 10, color: themeVars.content.muted, marginBottom: 4 }}>
75
- <span style={{ color: themeVars.semantic.success, fontWeight: 700 }}>●</span> Live —{' '}
76
- {activeIds?.map((stateId, index) => (
77
- <span key={stateId}>
78
- {index > 0 && ' · '}
79
- <span
80
- style={{ fontFamily: themeVars.typography.mono, color: themeVars.accent.default }}
81
- >
82
- {stateId.startsWith(`${machine.id}.`)
83
- ? stateId.slice(machine.id.length + 1)
84
- : stateId}
85
- </span>
86
- </span>
87
- ))}
88
- </div>
89
- {/* The FULL state chart, active path highlighted — the section must
90
- show what the machine can do, not only where it is (owner
91
- feedback, 2026-08-06). */}
92
- <div data-testid="xstate-section-states" style={{ marginBottom: 6 }}>
93
- {states.map((state) => {
94
- const relative = state.id.startsWith(`${machine.root.id}.`)
95
- ? state.id.slice(machine.root.id.length + 1)
96
- : state.id;
97
- const depth = relative.split('.').length - 1;
98
- const active = activeIdSet.has(state.id);
99
- return (
100
- <div
101
- key={state.id}
102
- data-testid={`xstate-section-state-${relative}`}
103
- style={{
104
- paddingLeft: 4 + depth * 12,
105
- fontSize: 10,
106
- lineHeight: 1.7,
107
- fontFamily: themeVars.typography.mono,
108
- color: active ? themeVars.accent.default : themeVars.content.muted,
109
- fontWeight: active ? 700 : 400,
110
- }}
111
- >
112
- {active ? '● ' : '○ '}
113
- {state.key}
114
- </div>
115
- );
116
- })}
117
- </div>
118
- <div style={{ fontSize: 10, color: themeVars.content.dim, marginBottom: 6 }}>
119
- Source: hand-authored XState TypeScript — inspect-only.
120
- </div>
121
- <Button
122
- size="compact"
123
- data-testid="xstate-open-graph"
124
- onClick={() => void openBehaviorDocument(nodeId)}
125
- >
126
- Inspect Behavior
127
- </Button>
128
- </div>
129
- );
130
- }