@jgengine/editor 0.10.0
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/CHANGELOG.md +325 -0
- package/dist/AssetBrowser.d.ts +20 -0
- package/dist/AssetBrowser.js +49 -0
- package/dist/CatalogsPanel.d.ts +10 -0
- package/dist/CatalogsPanel.js +41 -0
- package/dist/CollectionsPanel.d.ts +10 -0
- package/dist/CollectionsPanel.js +35 -0
- package/dist/DebugDraw.d.ts +17 -0
- package/dist/DebugDraw.js +233 -0
- package/dist/EditorApp.d.ts +26 -0
- package/dist/EditorApp.js +333 -0
- package/dist/EditorCameraDriver.d.ts +5 -0
- package/dist/EditorCameraDriver.js +18 -0
- package/dist/EditorChrome.d.ts +22 -0
- package/dist/EditorChrome.js +559 -0
- package/dist/EditorContextMenu.d.ts +11 -0
- package/dist/EditorContextMenu.js +12 -0
- package/dist/InspectorPanel.d.ts +14 -0
- package/dist/InspectorPanel.js +110 -0
- package/dist/MaterialDropZone.d.ts +10 -0
- package/dist/MaterialDropZone.js +77 -0
- package/dist/OutlinerPanel.d.ts +14 -0
- package/dist/OutlinerPanel.js +84 -0
- package/dist/PerfProbe.d.ts +5 -0
- package/dist/PerfProbe.js +34 -0
- package/dist/PrefabsPanel.d.ts +13 -0
- package/dist/PrefabsPanel.js +42 -0
- package/dist/RuntimePlayBridge.d.ts +18 -0
- package/dist/RuntimePlayBridge.js +140 -0
- package/dist/ScatterPreview.d.ts +11 -0
- package/dist/ScatterPreview.js +30 -0
- package/dist/SchemaInspector.d.ts +19 -0
- package/dist/SchemaInspector.js +78 -0
- package/dist/SelectionGizmo.d.ts +25 -0
- package/dist/SelectionGizmo.js +455 -0
- package/dist/StandaloneEditor.d.ts +44 -0
- package/dist/StandaloneEditor.js +92 -0
- package/dist/TerrainPanel.d.ts +7 -0
- package/dist/TerrainPanel.js +59 -0
- package/dist/TerrainSculpt.d.ts +14 -0
- package/dist/TerrainSculpt.js +415 -0
- package/dist/TriggerInspector.d.ts +13 -0
- package/dist/TriggerInspector.js +60 -0
- package/dist/agent/AgentPanel.d.ts +13 -0
- package/dist/agent/AgentPanel.js +156 -0
- package/dist/agent/context.d.ts +27 -0
- package/dist/agent/context.js +39 -0
- package/dist/agent/endpoint.d.ts +68 -0
- package/dist/agent/endpoint.js +186 -0
- package/dist/agent/toolBridge.d.ts +35 -0
- package/dist/agent/toolBridge.js +93 -0
- package/dist/agent/turn.d.ts +71 -0
- package/dist/agent/turn.js +113 -0
- package/dist/chromeFields.d.ts +15 -0
- package/dist/chromeFields.js +13 -0
- package/dist/chromeStyles.d.ts +3 -0
- package/dist/chromeStyles.js +3 -0
- package/dist/index.d.ts +20 -0
- package/dist/index.js +19 -0
- package/dist/mcp/bridgeServer.d.ts +13 -0
- package/dist/mcp/bridgeServer.js +1 -0
- package/dist/mcp/loadGameCatalogs.d.ts +24 -0
- package/dist/mcp/loadGameCatalogs.js +87 -0
- package/dist/mcp/rpcRequest.d.ts +22 -0
- package/dist/mcp/rpcRequest.js +97 -0
- package/dist/mcp/tools.d.ts +8 -0
- package/dist/mcp/tools.js +764 -0
- package/dist/outlinerModel.d.ts +76 -0
- package/dist/outlinerModel.js +95 -0
- package/dist/perfMarks.d.ts +25 -0
- package/dist/perfMarks.js +36 -0
- package/dist/session.d.ts +400 -0
- package/dist/session.js +1032 -0
- package/dist/uiStore.d.ts +108 -0
- package/dist/uiStore.js +128 -0
- package/dist/useF2Chord.d.ts +2 -0
- package/dist/useF2Chord.js +32 -0
- package/dist/useStoreSelector.d.ts +31 -0
- package/dist/useStoreSelector.js +51 -0
- package/dist/viewportContextMenu.d.ts +24 -0
- package/dist/viewportContextMenu.js +32 -0
- package/package.json +58 -0
- package/skills/jgengine/SKILL.md +823 -0
- package/skills/jgengine/api.md +416 -0
- package/skills/jgengine/capabilities.md +21 -0
- package/skills/jgengine/reference-cartridge.md +72 -0
- package/skills/jgengine/reference-orphans.md +9 -0
- package/skills/jgengine/reference-systems.md +60 -0
- package/skills/jgengine-editor/SKILL.md +382 -0
- package/skills/jgengine-editor/api.md +416 -0
- package/skills/jgengine-editor/capabilities.md +29 -0
- package/skills/jgengine-editor/reference.md +64 -0
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { type EditorDocument } from "@jgengine/core/editor/index";
|
|
2
|
+
/** A distinct label under a kind, backing one or more object ids (×N dedup rows). */
|
|
3
|
+
export interface OutlinerRow {
|
|
4
|
+
label: string;
|
|
5
|
+
ids: string[];
|
|
6
|
+
}
|
|
7
|
+
/** A kind group in the "By kind" outliner view. */
|
|
8
|
+
export interface OutlinerGroup {
|
|
9
|
+
kind: string;
|
|
10
|
+
rows: OutlinerRow[];
|
|
11
|
+
total: number;
|
|
12
|
+
}
|
|
13
|
+
interface OutlinerDocument {
|
|
14
|
+
markers: readonly {
|
|
15
|
+
id: string;
|
|
16
|
+
kind: string;
|
|
17
|
+
label?: string;
|
|
18
|
+
}[];
|
|
19
|
+
volumes: readonly {
|
|
20
|
+
id: string;
|
|
21
|
+
kind: string;
|
|
22
|
+
label?: string;
|
|
23
|
+
}[];
|
|
24
|
+
paths: readonly {
|
|
25
|
+
id: string;
|
|
26
|
+
kind: string;
|
|
27
|
+
label?: string;
|
|
28
|
+
}[];
|
|
29
|
+
annotations: readonly {
|
|
30
|
+
id: string;
|
|
31
|
+
text: string;
|
|
32
|
+
}[];
|
|
33
|
+
}
|
|
34
|
+
/** Groups every object by kind, deduping identical labels into ×N rows.
|
|
35
|
+
* @internal — outliner rendering helper. */
|
|
36
|
+
export declare function buildOutlinerGroups(document: OutlinerDocument): OutlinerGroup[];
|
|
37
|
+
/** Filters groups by a case-insensitive query against kind and row labels.
|
|
38
|
+
* @internal — outliner rendering helper. */
|
|
39
|
+
export declare function filterOutlinerGroups(groups: readonly OutlinerGroup[], query: string): OutlinerGroup[];
|
|
40
|
+
/** One rendered outliner line — a kind header, a deduped kind row, or a hierarchy tree node. */
|
|
41
|
+
export type OutlinerFlatRow = {
|
|
42
|
+
type: "group";
|
|
43
|
+
key: string;
|
|
44
|
+
kind: string;
|
|
45
|
+
total: number;
|
|
46
|
+
collapsed: boolean;
|
|
47
|
+
} | {
|
|
48
|
+
type: "kindItem";
|
|
49
|
+
key: string;
|
|
50
|
+
kind: string;
|
|
51
|
+
label: string;
|
|
52
|
+
ids: string[];
|
|
53
|
+
} | {
|
|
54
|
+
type: "treeItem";
|
|
55
|
+
key: string;
|
|
56
|
+
id: string;
|
|
57
|
+
label: string;
|
|
58
|
+
kind: string;
|
|
59
|
+
depth: number;
|
|
60
|
+
hasChildren: boolean;
|
|
61
|
+
};
|
|
62
|
+
/** How the outliner is displayed and folded — the state a flat row list is built from. */
|
|
63
|
+
export interface OutlinerViewState {
|
|
64
|
+
view: "kind" | "tree";
|
|
65
|
+
query: string;
|
|
66
|
+
collapsedKinds: Record<string, boolean>;
|
|
67
|
+
collapsedNodes: Record<string, boolean>;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Flattens either outliner view into a single uniform row list (headers + rows / nested tree nodes),
|
|
71
|
+
* honoring the query and collapse state — the input a fixed-height virtual list windows over, so the
|
|
72
|
+
* DOM never holds more than the visible slice regardless of scene size.
|
|
73
|
+
* @internal — outliner rendering helper.
|
|
74
|
+
*/
|
|
75
|
+
export declare function flattenOutliner(document: EditorDocument, state: OutlinerViewState): OutlinerFlatRow[];
|
|
76
|
+
export {};
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { editorChildren, editorRoots } from "@jgengine/core/editor/index";
|
|
2
|
+
/** Groups every object by kind, deduping identical labels into ×N rows.
|
|
3
|
+
* @internal — outliner rendering helper. */
|
|
4
|
+
export function buildOutlinerGroups(document) {
|
|
5
|
+
const byKind = new Map();
|
|
6
|
+
const push = (kind, label, id) => {
|
|
7
|
+
let labels = byKind.get(kind);
|
|
8
|
+
if (labels === undefined) {
|
|
9
|
+
labels = new Map();
|
|
10
|
+
byKind.set(kind, labels);
|
|
11
|
+
}
|
|
12
|
+
const row = labels.get(label);
|
|
13
|
+
if (row === undefined)
|
|
14
|
+
labels.set(label, { label, ids: [id] });
|
|
15
|
+
else
|
|
16
|
+
row.ids.push(id);
|
|
17
|
+
};
|
|
18
|
+
for (const marker of document.markers)
|
|
19
|
+
push(marker.kind, marker.label ?? marker.id, marker.id);
|
|
20
|
+
for (const volume of document.volumes)
|
|
21
|
+
push(volume.kind, volume.label ?? volume.id, volume.id);
|
|
22
|
+
for (const path of document.paths)
|
|
23
|
+
push(path.kind, path.label ?? path.id, path.id);
|
|
24
|
+
for (const note of document.annotations)
|
|
25
|
+
push("note", note.text.slice(0, 40) || note.id, note.id);
|
|
26
|
+
return [...byKind.entries()]
|
|
27
|
+
.map(([kind, labels]) => {
|
|
28
|
+
const rows = [...labels.values()];
|
|
29
|
+
return { kind, rows, total: rows.reduce((sum, row) => sum + row.ids.length, 0) };
|
|
30
|
+
})
|
|
31
|
+
.sort((a, b) => a.kind.localeCompare(b.kind));
|
|
32
|
+
}
|
|
33
|
+
/** Filters groups by a case-insensitive query against kind and row labels.
|
|
34
|
+
* @internal — outliner rendering helper. */
|
|
35
|
+
export function filterOutlinerGroups(groups, query) {
|
|
36
|
+
const normalized = query.trim().toLowerCase();
|
|
37
|
+
if (normalized.length === 0)
|
|
38
|
+
return [...groups];
|
|
39
|
+
return groups
|
|
40
|
+
.map((group) => {
|
|
41
|
+
const kindMatches = group.kind.toLowerCase().includes(normalized);
|
|
42
|
+
const rows = kindMatches
|
|
43
|
+
? group.rows
|
|
44
|
+
: group.rows.filter((row) => row.label.toLowerCase().includes(normalized));
|
|
45
|
+
return { ...group, rows, total: rows.reduce((sum, row) => sum + row.ids.length, 0) };
|
|
46
|
+
})
|
|
47
|
+
.filter((group) => group.rows.length > 0);
|
|
48
|
+
}
|
|
49
|
+
function objectLabels(document) {
|
|
50
|
+
const label = new Map();
|
|
51
|
+
for (const marker of document.markers)
|
|
52
|
+
label.set(marker.id, { label: marker.label ?? marker.id, kind: marker.kind });
|
|
53
|
+
for (const volume of document.volumes)
|
|
54
|
+
label.set(volume.id, { label: volume.label ?? volume.id, kind: volume.kind });
|
|
55
|
+
for (const path of document.paths)
|
|
56
|
+
label.set(path.id, { label: path.label ?? path.id, kind: path.kind });
|
|
57
|
+
for (const note of document.annotations)
|
|
58
|
+
label.set(note.id, { label: note.text.slice(0, 40) || note.id, kind: "note" });
|
|
59
|
+
return label;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Flattens either outliner view into a single uniform row list (headers + rows / nested tree nodes),
|
|
63
|
+
* honoring the query and collapse state — the input a fixed-height virtual list windows over, so the
|
|
64
|
+
* DOM never holds more than the visible slice regardless of scene size.
|
|
65
|
+
* @internal — outliner rendering helper.
|
|
66
|
+
*/
|
|
67
|
+
export function flattenOutliner(document, state) {
|
|
68
|
+
if (state.view === "tree") {
|
|
69
|
+
const labels = objectLabels(document);
|
|
70
|
+
const rows = [];
|
|
71
|
+
const visit = (id, depth) => {
|
|
72
|
+
const info = labels.get(id) ?? { label: id, kind: "?" };
|
|
73
|
+
const children = editorChildren(document, id).sort((a, b) => (labels.get(a)?.label ?? a).localeCompare(labels.get(b)?.label ?? b));
|
|
74
|
+
rows.push({ type: "treeItem", key: id, id, label: info.label, kind: info.kind, depth, hasChildren: children.length > 0 });
|
|
75
|
+
if (state.collapsedNodes[id] === true)
|
|
76
|
+
return;
|
|
77
|
+
for (const child of children)
|
|
78
|
+
visit(child, depth + 1);
|
|
79
|
+
};
|
|
80
|
+
for (const root of editorRoots(document))
|
|
81
|
+
visit(root, 0);
|
|
82
|
+
return rows;
|
|
83
|
+
}
|
|
84
|
+
const groups = filterOutlinerGroups(buildOutlinerGroups(document), state.query);
|
|
85
|
+
const rows = [];
|
|
86
|
+
for (const group of groups) {
|
|
87
|
+
const collapsed = state.collapsedKinds[group.kind] === true;
|
|
88
|
+
rows.push({ type: "group", key: `g:${group.kind}`, kind: group.kind, total: group.total, collapsed });
|
|
89
|
+
if (collapsed)
|
|
90
|
+
continue;
|
|
91
|
+
for (const row of group.rows)
|
|
92
|
+
rows.push({ type: "kindItem", key: `${group.kind}:${row.label}`, kind: group.kind, label: row.label, ids: row.ids });
|
|
93
|
+
}
|
|
94
|
+
return rows;
|
|
95
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/** Editor-authoring cost the {@link PerfProbe} folds into its sample, separate from frame/sim cost. */
|
|
2
|
+
export type PerfMarkKind = "raycast" | "rebuild";
|
|
3
|
+
/** Rolling averages (ms) of the authoring marks recorded since the last flush. */
|
|
4
|
+
export interface PerfMarkSummary {
|
|
5
|
+
raycastMs: number;
|
|
6
|
+
rebuildMs: number;
|
|
7
|
+
authoringMs: number;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Accumulates editor-authoring timings (viewport raycasts, preview-mesh rebuilds) and flushes them
|
|
11
|
+
* as rolling averages — so the perf probe can report authoring cost apart from frame/sim cost, and
|
|
12
|
+
* "the editor feels laggy" resolves to a number instead of a guess.
|
|
13
|
+
*/
|
|
14
|
+
export interface PerfAccumulator {
|
|
15
|
+
record(kind: PerfMarkKind, ms: number): void;
|
|
16
|
+
/** Average ms per mark since the last flush, then reset the window. */
|
|
17
|
+
flush(): PerfMarkSummary;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Creates an isolated authoring-perf accumulator.
|
|
21
|
+
* @internal — the editor's `PerfProbe` folds `editorPerfMarks` into the perf sample; not game-facing.
|
|
22
|
+
*/
|
|
23
|
+
export declare function createPerfAccumulator(): PerfAccumulator;
|
|
24
|
+
/** Shared accumulator the sculpt/paint layer records into and the perf probe flushes each window. */
|
|
25
|
+
export declare const editorPerfMarks: PerfAccumulator;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Creates an isolated authoring-perf accumulator.
|
|
3
|
+
* @internal — the editor's `PerfProbe` folds `editorPerfMarks` into the perf sample; not game-facing.
|
|
4
|
+
*/
|
|
5
|
+
export function createPerfAccumulator() {
|
|
6
|
+
let raycastSum = 0;
|
|
7
|
+
let raycastCount = 0;
|
|
8
|
+
let rebuildSum = 0;
|
|
9
|
+
let rebuildCount = 0;
|
|
10
|
+
const round = (value) => Math.round(value * 1000) / 1000;
|
|
11
|
+
return {
|
|
12
|
+
record(kind, ms) {
|
|
13
|
+
if (!Number.isFinite(ms) || ms < 0)
|
|
14
|
+
return;
|
|
15
|
+
if (kind === "raycast") {
|
|
16
|
+
raycastSum += ms;
|
|
17
|
+
raycastCount += 1;
|
|
18
|
+
}
|
|
19
|
+
else {
|
|
20
|
+
rebuildSum += ms;
|
|
21
|
+
rebuildCount += 1;
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
flush() {
|
|
25
|
+
const raycastMs = raycastCount === 0 ? 0 : round(raycastSum / raycastCount);
|
|
26
|
+
const rebuildMs = rebuildCount === 0 ? 0 : round(rebuildSum / rebuildCount);
|
|
27
|
+
raycastSum = 0;
|
|
28
|
+
raycastCount = 0;
|
|
29
|
+
rebuildSum = 0;
|
|
30
|
+
rebuildCount = 0;
|
|
31
|
+
return { raycastMs, rebuildMs, authoringMs: round(raycastMs + rebuildMs) };
|
|
32
|
+
},
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
/** Shared accumulator the sculpt/paint layer records into and the perf probe flushes each window. */
|
|
36
|
+
export const editorPerfMarks = createPerfAccumulator();
|
|
@@ -0,0 +1,400 @@
|
|
|
1
|
+
import { type DocumentLiveSync, type DocumentPatch, type EditorCatalogDefinition, type EditorCommand, type EditorDocument, type EditorKindVisibility, type EditorLayersInput, type EditorSession, type EditorSessionState, type RuntimeEntityState, type RuntimePlayControl } from "@jgengine/core/editor/index";
|
|
2
|
+
import { type TerraformMode, type TerrainMaterialLayer } from "@jgengine/core/world/terraform";
|
|
3
|
+
/** How the editor hosts the game: frozen placement view, roamable world, or the real game. */
|
|
4
|
+
export type EditorRunMode = "edit" | "walk" | "play";
|
|
5
|
+
/** RPC request shapes the editor host understands, used by the MCP bridge and UI. */
|
|
6
|
+
export type EditorBridgeRequest = {
|
|
7
|
+
method: "editor_status";
|
|
8
|
+
} | {
|
|
9
|
+
method: "set_mode";
|
|
10
|
+
mode: EditorRunMode;
|
|
11
|
+
} | {
|
|
12
|
+
method: "perf_report";
|
|
13
|
+
} | {
|
|
14
|
+
method: "list_layers";
|
|
15
|
+
} | {
|
|
16
|
+
method: "list_catalogs";
|
|
17
|
+
} | {
|
|
18
|
+
method: "get_catalog_entry";
|
|
19
|
+
catalogId: string;
|
|
20
|
+
entryId: string;
|
|
21
|
+
} | {
|
|
22
|
+
method: "set_catalog_entry";
|
|
23
|
+
catalogId: string;
|
|
24
|
+
entryId: string;
|
|
25
|
+
patch: Record<string, unknown>;
|
|
26
|
+
label?: string;
|
|
27
|
+
} | {
|
|
28
|
+
method: "list_selection";
|
|
29
|
+
} | {
|
|
30
|
+
method: "get_marker";
|
|
31
|
+
id: string;
|
|
32
|
+
} | {
|
|
33
|
+
method: "get_volume";
|
|
34
|
+
id: string;
|
|
35
|
+
} | {
|
|
36
|
+
method: "set_transform";
|
|
37
|
+
id: string;
|
|
38
|
+
x?: number;
|
|
39
|
+
y?: number;
|
|
40
|
+
z?: number;
|
|
41
|
+
rotationY?: number;
|
|
42
|
+
} | {
|
|
43
|
+
method: "set_volume";
|
|
44
|
+
id: string;
|
|
45
|
+
radius?: number;
|
|
46
|
+
height?: number;
|
|
47
|
+
x?: number;
|
|
48
|
+
y?: number;
|
|
49
|
+
z?: number;
|
|
50
|
+
} | {
|
|
51
|
+
method: "set_path";
|
|
52
|
+
id: string;
|
|
53
|
+
kind?: string;
|
|
54
|
+
width?: number;
|
|
55
|
+
color?: string;
|
|
56
|
+
label?: string;
|
|
57
|
+
meta?: Record<string, unknown>;
|
|
58
|
+
} | {
|
|
59
|
+
method: "set_marker";
|
|
60
|
+
id: string;
|
|
61
|
+
kind?: string;
|
|
62
|
+
color?: string;
|
|
63
|
+
label?: string;
|
|
64
|
+
rotationY?: number;
|
|
65
|
+
meta?: Record<string, unknown>;
|
|
66
|
+
} | {
|
|
67
|
+
method: "set_note";
|
|
68
|
+
id: string;
|
|
69
|
+
text?: string;
|
|
70
|
+
meta?: Record<string, unknown>;
|
|
71
|
+
} | {
|
|
72
|
+
method: "set_meta";
|
|
73
|
+
id: string;
|
|
74
|
+
patch: Record<string, unknown>;
|
|
75
|
+
} | {
|
|
76
|
+
method: "select";
|
|
77
|
+
ids: string[];
|
|
78
|
+
} | {
|
|
79
|
+
method: "clear_selection";
|
|
80
|
+
} | {
|
|
81
|
+
method: "camera_goto";
|
|
82
|
+
id?: string;
|
|
83
|
+
x?: number;
|
|
84
|
+
y?: number;
|
|
85
|
+
z?: number;
|
|
86
|
+
} | {
|
|
87
|
+
method: "camera_frame";
|
|
88
|
+
} | {
|
|
89
|
+
method: "scene_summary";
|
|
90
|
+
} | {
|
|
91
|
+
method: "export_document";
|
|
92
|
+
} | {
|
|
93
|
+
method: "import_document";
|
|
94
|
+
json: string;
|
|
95
|
+
} | {
|
|
96
|
+
method: "dispatch";
|
|
97
|
+
command: EditorCommand;
|
|
98
|
+
} | {
|
|
99
|
+
method: "undo";
|
|
100
|
+
} | {
|
|
101
|
+
method: "redo";
|
|
102
|
+
} | {
|
|
103
|
+
method: "list_assets";
|
|
104
|
+
} | {
|
|
105
|
+
method: "place_asset";
|
|
106
|
+
id: string;
|
|
107
|
+
kind?: string;
|
|
108
|
+
x?: number;
|
|
109
|
+
y?: number;
|
|
110
|
+
z?: number;
|
|
111
|
+
} | {
|
|
112
|
+
method: "create_terrain";
|
|
113
|
+
width?: number;
|
|
114
|
+
depth?: number;
|
|
115
|
+
cellSize?: number;
|
|
116
|
+
centerX?: number;
|
|
117
|
+
centerZ?: number;
|
|
118
|
+
} | {
|
|
119
|
+
method: "sculpt_terrain";
|
|
120
|
+
mode: TerraformMode;
|
|
121
|
+
x: number;
|
|
122
|
+
z: number;
|
|
123
|
+
radius?: number;
|
|
124
|
+
strength?: number;
|
|
125
|
+
target?: number;
|
|
126
|
+
toX?: number;
|
|
127
|
+
toZ?: number;
|
|
128
|
+
seed?: number;
|
|
129
|
+
shape?: "circle" | "square";
|
|
130
|
+
} | {
|
|
131
|
+
method: "terrain_summary";
|
|
132
|
+
} | {
|
|
133
|
+
method: "paint_terrain";
|
|
134
|
+
surface: string;
|
|
135
|
+
x: number;
|
|
136
|
+
z: number;
|
|
137
|
+
radius?: number;
|
|
138
|
+
shape?: "circle" | "square";
|
|
139
|
+
} | {
|
|
140
|
+
method: "fill_terrain";
|
|
141
|
+
surface: string | null;
|
|
142
|
+
} | {
|
|
143
|
+
method: "auto_paint";
|
|
144
|
+
surface: string;
|
|
145
|
+
minSlope?: number;
|
|
146
|
+
maxSlope?: number;
|
|
147
|
+
minHeight?: number;
|
|
148
|
+
maxHeight?: number;
|
|
149
|
+
} | {
|
|
150
|
+
method: "terrain_materials";
|
|
151
|
+
} | {
|
|
152
|
+
method: "terrain_layers";
|
|
153
|
+
} | {
|
|
154
|
+
method: "set_terrain_layers";
|
|
155
|
+
layers: TerrainMaterialLayer[];
|
|
156
|
+
} | {
|
|
157
|
+
method: "blend_terrain";
|
|
158
|
+
surface: string;
|
|
159
|
+
x: number;
|
|
160
|
+
z: number;
|
|
161
|
+
radius?: number;
|
|
162
|
+
strength?: number;
|
|
163
|
+
shape?: "circle" | "square";
|
|
164
|
+
} | {
|
|
165
|
+
method: "convert_scatter";
|
|
166
|
+
pathId: string;
|
|
167
|
+
} | {
|
|
168
|
+
method: "add_foliage";
|
|
169
|
+
points: {
|
|
170
|
+
x: number;
|
|
171
|
+
z: number;
|
|
172
|
+
}[];
|
|
173
|
+
density?: number;
|
|
174
|
+
item?: string;
|
|
175
|
+
seed?: string;
|
|
176
|
+
minSpacing?: number;
|
|
177
|
+
} | {
|
|
178
|
+
method: "scatter_summary";
|
|
179
|
+
} | {
|
|
180
|
+
method: "set_parent";
|
|
181
|
+
ids: string[];
|
|
182
|
+
parentId: string | null;
|
|
183
|
+
} | {
|
|
184
|
+
method: "hierarchy";
|
|
185
|
+
} | {
|
|
186
|
+
method: "list_prefabs";
|
|
187
|
+
} | {
|
|
188
|
+
method: "create_prefab";
|
|
189
|
+
id: string;
|
|
190
|
+
name: string;
|
|
191
|
+
ids: string[];
|
|
192
|
+
} | {
|
|
193
|
+
method: "insert_prefab";
|
|
194
|
+
prefabId: string;
|
|
195
|
+
x?: number;
|
|
196
|
+
y?: number;
|
|
197
|
+
z?: number;
|
|
198
|
+
} | {
|
|
199
|
+
method: "detach_prefab_instance";
|
|
200
|
+
instanceId: string;
|
|
201
|
+
} | {
|
|
202
|
+
method: "delete_prefab";
|
|
203
|
+
prefabId: string;
|
|
204
|
+
} | {
|
|
205
|
+
method: "list_collections";
|
|
206
|
+
} | {
|
|
207
|
+
method: "create_collection";
|
|
208
|
+
id: string;
|
|
209
|
+
name: string;
|
|
210
|
+
memberIds?: string[];
|
|
211
|
+
} | {
|
|
212
|
+
method: "rename_collection";
|
|
213
|
+
id: string;
|
|
214
|
+
name: string;
|
|
215
|
+
} | {
|
|
216
|
+
method: "delete_collection";
|
|
217
|
+
id: string;
|
|
218
|
+
} | {
|
|
219
|
+
method: "set_collection_members";
|
|
220
|
+
id: string;
|
|
221
|
+
memberIds: string[];
|
|
222
|
+
} | {
|
|
223
|
+
method: "add_to_collection";
|
|
224
|
+
id: string;
|
|
225
|
+
ids: string[];
|
|
226
|
+
} | {
|
|
227
|
+
method: "remove_from_collection";
|
|
228
|
+
id: string;
|
|
229
|
+
ids: string[];
|
|
230
|
+
} | {
|
|
231
|
+
method: "set_collection_flags";
|
|
232
|
+
id: string;
|
|
233
|
+
color?: string;
|
|
234
|
+
locked?: boolean;
|
|
235
|
+
visible?: boolean;
|
|
236
|
+
} | {
|
|
237
|
+
method: "select_collection";
|
|
238
|
+
id: string;
|
|
239
|
+
} | {
|
|
240
|
+
method: "batch_set_properties";
|
|
241
|
+
ids: string[];
|
|
242
|
+
color?: string;
|
|
243
|
+
label?: string;
|
|
244
|
+
meta?: Record<string, unknown>;
|
|
245
|
+
} | {
|
|
246
|
+
method: "assign_material";
|
|
247
|
+
ids: string[];
|
|
248
|
+
materialId: string;
|
|
249
|
+
} | {
|
|
250
|
+
method: "push_document_patch";
|
|
251
|
+
patch: DocumentPatch;
|
|
252
|
+
force?: boolean;
|
|
253
|
+
} | {
|
|
254
|
+
method: "pull_document_patches";
|
|
255
|
+
sinceRevision?: number;
|
|
256
|
+
} | {
|
|
257
|
+
method: "document_revision";
|
|
258
|
+
includeDocument?: boolean;
|
|
259
|
+
} | {
|
|
260
|
+
method: "push_runtime_delta";
|
|
261
|
+
at?: number;
|
|
262
|
+
entities?: RuntimeEntityState[];
|
|
263
|
+
removeIds?: string[];
|
|
264
|
+
tunables?: Record<string, unknown>;
|
|
265
|
+
} | {
|
|
266
|
+
method: "pull_runtime_deltas";
|
|
267
|
+
sinceSeq?: number;
|
|
268
|
+
includeSnapshot?: boolean;
|
|
269
|
+
} | {
|
|
270
|
+
method: "runtime_snapshot";
|
|
271
|
+
} | {
|
|
272
|
+
method: "runtime_summary";
|
|
273
|
+
} | {
|
|
274
|
+
method: "runtime_get";
|
|
275
|
+
id: string;
|
|
276
|
+
path?: string;
|
|
277
|
+
} | {
|
|
278
|
+
method: "runtime_set";
|
|
279
|
+
id: string;
|
|
280
|
+
path?: string;
|
|
281
|
+
value?: unknown;
|
|
282
|
+
position?: {
|
|
283
|
+
x: number;
|
|
284
|
+
y: number;
|
|
285
|
+
z: number;
|
|
286
|
+
};
|
|
287
|
+
rotationY?: number;
|
|
288
|
+
values?: Record<string, unknown>;
|
|
289
|
+
writeBack?: boolean;
|
|
290
|
+
} | {
|
|
291
|
+
method: "runtime_pause";
|
|
292
|
+
} | {
|
|
293
|
+
method: "runtime_resume";
|
|
294
|
+
} | {
|
|
295
|
+
method: "runtime_step";
|
|
296
|
+
frames?: number;
|
|
297
|
+
} | {
|
|
298
|
+
method: "set_runtime_override";
|
|
299
|
+
entity: RuntimeEntityState;
|
|
300
|
+
} | {
|
|
301
|
+
method: "clear_runtime_override";
|
|
302
|
+
id: string;
|
|
303
|
+
} | {
|
|
304
|
+
method: "write_back_override";
|
|
305
|
+
id: string;
|
|
306
|
+
};
|
|
307
|
+
/** Result envelope returned by every editor host RPC call. */
|
|
308
|
+
export type EditorBridgeResponse = {
|
|
309
|
+
ok: boolean;
|
|
310
|
+
result?: unknown;
|
|
311
|
+
error?: string;
|
|
312
|
+
};
|
|
313
|
+
/** A placeable asset entry offered in the editor's asset browser. */
|
|
314
|
+
export interface EditorAssetInfo {
|
|
315
|
+
id: string;
|
|
316
|
+
label: string;
|
|
317
|
+
kind: string;
|
|
318
|
+
url?: string;
|
|
319
|
+
}
|
|
320
|
+
/** Rolling frame-rate sample published by the in-canvas PerfProbe. */
|
|
321
|
+
export interface EditorPerfSample {
|
|
322
|
+
fps: number;
|
|
323
|
+
frameMs: number;
|
|
324
|
+
drawCalls: number;
|
|
325
|
+
triangles: number;
|
|
326
|
+
sampledAt: number;
|
|
327
|
+
/** Avg viewport raycast (pick) time this window — editor-authoring cost, not sim cost. */
|
|
328
|
+
raycastMs?: number;
|
|
329
|
+
/** Avg preview-mesh rebuild (displace) time this window — editor-authoring cost, not sim cost. */
|
|
330
|
+
rebuildMs?: number;
|
|
331
|
+
/** raycastMs + rebuildMs — total authoring overhead separated from the frame/sim budget. */
|
|
332
|
+
authoringMs?: number;
|
|
333
|
+
}
|
|
334
|
+
/** The live editor's global control surface — session, visibility, camera focus, assets, mode, RPC. */
|
|
335
|
+
export interface EditorHostApi {
|
|
336
|
+
gameId: string;
|
|
337
|
+
getSession(): EditorSession;
|
|
338
|
+
/** Two-way document/runtime live-sync bus shared with AuthoredScene and the bridge. */
|
|
339
|
+
getLiveSync(): DocumentLiveSync;
|
|
340
|
+
getVisibility(): EditorKindVisibility;
|
|
341
|
+
setVisibility(next: EditorKindVisibility): void;
|
|
342
|
+
subscribeVisibility(listener: () => void): () => void;
|
|
343
|
+
getFocusTarget(): {
|
|
344
|
+
x: number;
|
|
345
|
+
y: number;
|
|
346
|
+
z: number;
|
|
347
|
+
} | null;
|
|
348
|
+
setFocusTarget(target: {
|
|
349
|
+
x: number;
|
|
350
|
+
y: number;
|
|
351
|
+
z: number;
|
|
352
|
+
} | null): void;
|
|
353
|
+
subscribeFocus(listener: (target: {
|
|
354
|
+
x: number;
|
|
355
|
+
y: number;
|
|
356
|
+
z: number;
|
|
357
|
+
} | null) => void): () => void;
|
|
358
|
+
getAssets(): readonly EditorAssetInfo[];
|
|
359
|
+
setAssets(assets: readonly EditorAssetInfo[]): void;
|
|
360
|
+
getCatalogDefinitions(): readonly EditorCatalogDefinition[];
|
|
361
|
+
getPerf(): EditorPerfSample | null;
|
|
362
|
+
setPerf(sample: EditorPerfSample): void;
|
|
363
|
+
getMode(): EditorRunMode;
|
|
364
|
+
setMode(mode: EditorRunMode): void;
|
|
365
|
+
subscribeMode(listener: (mode: EditorRunMode) => void): () => void;
|
|
366
|
+
/** Play-mode pause/step gate consumed by the runtime publisher. */
|
|
367
|
+
getPlayControl(): RuntimePlayControl;
|
|
368
|
+
setPlayControl(next: RuntimePlayControl): void;
|
|
369
|
+
subscribePlayControl(listener: (play: RuntimePlayControl) => void): () => void;
|
|
370
|
+
handle(request: EditorBridgeRequest): EditorBridgeResponse;
|
|
371
|
+
}
|
|
372
|
+
/** Publishes an editor host globally so devtools and MCP agents can reach it; returns a cleanup fn. */
|
|
373
|
+
export declare function installEditorHost(api: EditorHostApi): () => void;
|
|
374
|
+
/** Retrieves the globally installed editor host, or null if none is mounted. @internal */
|
|
375
|
+
export declare function getEditorHost(): EditorHostApi | null;
|
|
376
|
+
/** Builds and installs an editor host for a game: session, visibility, assets, and RPC handling. @internal */
|
|
377
|
+
export declare function createEditorHost(options: {
|
|
378
|
+
gameId: string;
|
|
379
|
+
layers: EditorLayersInput | undefined;
|
|
380
|
+
/** Game-exported gameplay catalog definitions (schemas + defaults); seeds document.catalogs. */
|
|
381
|
+
catalogs?: readonly EditorCatalogDefinition[];
|
|
382
|
+
assets?: readonly EditorAssetInfo[];
|
|
383
|
+
onFocus?: (target: {
|
|
384
|
+
x: number;
|
|
385
|
+
y: number;
|
|
386
|
+
z: number;
|
|
387
|
+
} | null) => void;
|
|
388
|
+
}): {
|
|
389
|
+
session: EditorSession;
|
|
390
|
+
api: EditorHostApi;
|
|
391
|
+
dispose: () => void;
|
|
392
|
+
};
|
|
393
|
+
/** The full authored scene: every marker, volume, path, and note for a game. */
|
|
394
|
+
export type { EditorDocument };
|
|
395
|
+
/** Per-kind show/hide flags for the editor's layer panel. */
|
|
396
|
+
export type { EditorKindVisibility };
|
|
397
|
+
/** Stateful, undoable handle for driving scene edits from UI or an MCP agent. */
|
|
398
|
+
export type { EditorSession };
|
|
399
|
+
/** The document plus current selection at a point in editor history. */
|
|
400
|
+
export type { EditorSessionState };
|