@jgengine/editor 0.11.0 → 0.12.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 +26 -0
- package/README.md +12 -0
- package/dist/AssetBrowser.d.ts +26 -1
- package/dist/AssetBrowser.js +54 -1
- package/dist/AssetDropZone.d.ts +9 -0
- package/dist/AssetDropZone.js +65 -0
- package/dist/CatalogsPanel.d.ts +4 -2
- package/dist/CatalogsPanel.js +162 -9
- package/dist/CityPreview.d.ts +11 -0
- package/dist/CityPreview.js +45 -0
- package/dist/CollectionsPanel.js +5 -5
- package/dist/DebugDraw.d.ts +3 -1
- package/dist/DebugDraw.js +37 -19
- package/dist/EditorApp.d.ts +9 -1
- package/dist/EditorApp.js +147 -35
- package/dist/EditorChrome.d.ts +25 -6
- package/dist/EditorChrome.js +310 -130
- package/dist/InspectorPanel.d.ts +17 -7
- package/dist/InspectorPanel.js +173 -27
- package/dist/LightingPanel.d.ts +11 -0
- package/dist/LightingPanel.js +99 -0
- package/dist/MaterialsWorkspacePanel.d.ts +12 -0
- package/dist/MaterialsWorkspacePanel.js +86 -0
- package/dist/ParentPickerMenu.d.ts +13 -0
- package/dist/ParentPickerMenu.js +33 -0
- package/dist/PerfProbe.js +33 -0
- package/dist/PrefabsPanel.js +5 -5
- package/dist/RuntimePlayBridge.d.ts +5 -3
- package/dist/RuntimePlayBridge.js +6 -13
- package/dist/ScatterPreview.d.ts +3 -1
- package/dist/ScatterPreview.js +10 -7
- package/dist/SchemaInspector.js +21 -8
- package/dist/ScriptingPanel.d.ts +15 -0
- package/dist/ScriptingPanel.js +46 -0
- package/dist/SelectionGizmo.js +114 -30
- package/dist/StandaloneEditor.d.ts +16 -9
- package/dist/StandaloneEditor.js +19 -20
- package/dist/TerrainPanel.d.ts +3 -2
- package/dist/TerrainPanel.js +16 -5
- package/dist/TerrainSculpt.js +98 -59
- package/dist/agent/AgentPanel.d.ts +5 -2
- package/dist/agent/AgentPanel.js +11 -6
- package/dist/agent/toolBridge.js +5 -0
- package/dist/assetImport.d.ts +36 -0
- package/dist/assetImport.js +66 -0
- package/dist/authoredComponentMeta.d.ts +25 -0
- package/dist/authoredComponentMeta.js +65 -0
- package/dist/gizmoPivot.d.ts +4 -0
- package/dist/gizmoPivot.js +34 -0
- package/dist/handlers/catalogs.d.ts +3 -0
- package/dist/handlers/catalogs.js +137 -0
- package/dist/handlers/collections.d.ts +3 -0
- package/dist/handlers/collections.js +57 -0
- package/dist/handlers/context.d.ts +36 -0
- package/dist/handlers/context.js +1 -0
- package/dist/handlers/document.d.ts +3 -0
- package/dist/handlers/document.js +350 -0
- package/dist/handlers/grids.d.ts +3 -0
- package/dist/handlers/grids.js +142 -0
- package/dist/handlers/hierarchy.d.ts +3 -0
- package/dist/handlers/hierarchy.js +55 -0
- package/dist/handlers/index.d.ts +8 -0
- package/dist/handlers/index.js +23 -0
- package/dist/handlers/minimap.d.ts +9 -0
- package/dist/handlers/minimap.js +32 -0
- package/dist/handlers/runtime.d.ts +3 -0
- package/dist/handlers/runtime.js +191 -0
- package/dist/handlers/terrain.d.ts +3 -0
- package/dist/handlers/terrain.js +204 -0
- package/dist/index.d.ts +3 -2
- package/dist/index.js +3 -2
- package/dist/listDocumentTriggers.d.ts +42 -0
- package/dist/listDocumentTriggers.js +49 -0
- package/dist/materialAssignments.d.ts +63 -0
- package/dist/materialAssignments.js +84 -0
- package/dist/mcp/fieldSpec.d.ts +32 -0
- package/dist/mcp/fieldSpec.js +173 -0
- package/dist/mcp/rpcRequest.d.ts +8 -5
- package/dist/mcp/rpcRequest.js +72 -93
- package/dist/mcp/tools.js +104 -912
- package/dist/networkSnapshot.d.ts +82 -0
- package/dist/networkSnapshot.js +73 -0
- package/dist/parentCandidates.d.ts +12 -0
- package/dist/parentCandidates.js +25 -0
- package/dist/session.d.ts +77 -4
- package/dist/session.js +36 -1017
- package/dist/shell/AnimationPanel.d.ts +17 -0
- package/dist/shell/AnimationPanel.js +134 -0
- package/dist/shell/AssetThumbnail.d.ts +12 -0
- package/dist/shell/AssetThumbnail.js +23 -0
- package/dist/shell/BottomDock.d.ts +25 -0
- package/dist/shell/BottomDock.js +40 -0
- package/dist/shell/CommandPalette.d.ts +12 -0
- package/dist/shell/CommandPalette.js +56 -0
- package/dist/shell/ConsolePanel.d.ts +8 -0
- package/dist/shell/ConsolePanel.js +45 -0
- package/dist/shell/ContentBrowser.d.ts +21 -0
- package/dist/shell/ContentBrowser.js +130 -0
- package/dist/shell/HierarchyPanel.d.ts +26 -0
- package/dist/shell/HierarchyPanel.js +387 -0
- package/dist/shell/NetworkWorkspacePanel.d.ts +11 -0
- package/dist/shell/NetworkWorkspacePanel.js +49 -0
- package/dist/shell/PlayModeBar.d.ts +12 -0
- package/dist/shell/PlayModeBar.js +27 -0
- package/dist/shell/ProfilerPanel.d.ts +10 -0
- package/dist/shell/ProfilerPanel.js +41 -0
- package/dist/shell/SceneToolbar.d.ts +43 -0
- package/dist/shell/SceneToolbar.js +122 -0
- package/dist/shell/StatusBar.d.ts +18 -0
- package/dist/shell/StatusBar.js +41 -0
- package/dist/shell/TopAppBar.d.ts +33 -0
- package/dist/shell/TopAppBar.js +64 -0
- package/dist/shell/ViewportOverlays.d.ts +23 -0
- package/dist/shell/ViewportOverlays.js +136 -0
- package/dist/shell/WorkspaceRail.d.ts +20 -0
- package/dist/shell/WorkspaceRail.js +31 -0
- package/dist/shell/cameraTelemetry.d.ts +27 -0
- package/dist/shell/cameraTelemetry.js +24 -0
- package/dist/shell/commandRegistry.d.ts +58 -0
- package/dist/shell/commandRegistry.js +133 -0
- package/dist/shell/consoleSink.d.ts +11 -0
- package/dist/shell/consoleSink.js +17 -0
- package/dist/shell/consoleStore.d.ts +27 -0
- package/dist/shell/consoleStore.js +43 -0
- package/dist/shell/fields.d.ts +39 -0
- package/dist/shell/fields.js +104 -0
- package/dist/shell/formatSavedRelative.d.ts +2 -0
- package/dist/shell/formatSavedRelative.js +14 -0
- package/dist/shell/glbThumbnailCache.d.ts +45 -0
- package/dist/shell/glbThumbnailCache.js +241 -0
- package/dist/shell/hierarchyA11y.d.ts +21 -0
- package/dist/shell/hierarchyA11y.js +35 -0
- package/dist/shell/icons.d.ts +13 -0
- package/dist/shell/icons.js +85 -0
- package/dist/shell/layoutStore.d.ts +68 -0
- package/dist/shell/layoutStore.js +156 -0
- package/dist/shell/pathFlythrough.d.ts +37 -0
- package/dist/shell/pathFlythrough.js +54 -0
- package/dist/shell/perfHistory.d.ts +70 -0
- package/dist/shell/perfHistory.js +130 -0
- package/dist/shell/renameObject.d.ts +3 -0
- package/dist/shell/renameObject.js +25 -0
- package/dist/shell/theme.d.ts +36 -0
- package/dist/shell/theme.js +37 -0
- package/dist/shell/ui.d.ts +84 -0
- package/dist/shell/ui.js +90 -0
- package/dist/shell/useGlbThumbnail.d.ts +8 -0
- package/dist/shell/useGlbThumbnail.js +19 -0
- package/dist/uiStore.d.ts +27 -0
- package/dist/uiStore.js +10 -0
- package/dist/viewportContextMenu.d.ts +4 -2
- package/dist/viewportContextMenu.js +5 -1
- package/package.json +4 -4
- package/skills/jgengine/SKILL.md +7 -4
- package/skills/jgengine/api.md +172 -79
- package/skills/jgengine/capabilities.md +104 -2
- package/skills/jgengine/recipes/minimal-game.md +88 -0
- package/skills/jgengine-editor/SKILL.md +18 -3
- package/skills/jgengine-editor/api.md +397 -18
- package/skills/jgengine-editor/capabilities.md +46 -0
- package/skills/jgengine-editor/reference.md +87 -0
- package/skills/level-design/SKILL.md +54 -0
- package/skills/level-design/agents/openai.yaml +4 -0
- package/skills/level-design/references/application-playbook.md +192 -0
- package/skills/level-design/references/field-guide.md +337 -0
- package/skills/level-design/references/live-editor-loop.md +179 -0
- package/dist/OutlinerPanel.d.ts +0 -14
- package/dist/OutlinerPanel.js +0 -84
- package/skills/jgengine/reference-cartridge.md +0 -72
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { type MultiplayerAdapterConfig, type MultiplayerAuthority } from "@jgengine/core/runtime/adapter";
|
|
2
|
+
import type { PresencePoseRow } from "@jgengine/core/runtime/transport";
|
|
3
|
+
/** Transport kind declared by the game, or `"unknown"` when the config is unreadable. */
|
|
4
|
+
export type EditorNetworkAdapterKind = MultiplayerAdapterConfig["kind"] | "unknown";
|
|
5
|
+
/**
|
|
6
|
+
* One online actor from a host-supplied presence feed. Fields mirror
|
|
7
|
+
* {@link PresencePoseRow} so hosts can forward backend rows without inventing shape.
|
|
8
|
+
*/
|
|
9
|
+
export interface EditorNetworkPresenceActor {
|
|
10
|
+
userId: string;
|
|
11
|
+
position: {
|
|
12
|
+
x: number;
|
|
13
|
+
y: number;
|
|
14
|
+
z: number;
|
|
15
|
+
};
|
|
16
|
+
rotationY: number;
|
|
17
|
+
rotationPitch?: number;
|
|
18
|
+
lastSeenAt?: number;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Optional live session identity when a multiplayer backend is attached.
|
|
22
|
+
* Omit entirely when the host has no session — the panel reports offline honestly.
|
|
23
|
+
*/
|
|
24
|
+
export interface EditorNetworkSession {
|
|
25
|
+
userId: string;
|
|
26
|
+
/** Joined room/server id when known; `null` means joined but id not reported. */
|
|
27
|
+
serverId?: string | null;
|
|
28
|
+
feedActions?: readonly string[];
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Host-facing network inspection payload for the editor Network workspace.
|
|
32
|
+
*
|
|
33
|
+
* - Adapter fields come from the game definition (always real config).
|
|
34
|
+
* - `session` is present only when the host attached a live multiplayer backend.
|
|
35
|
+
* - `online` is `undefined` when the host has not supplied a presence feed; `[]` when
|
|
36
|
+
* the feed is connected but empty. Never fabricate actors.
|
|
37
|
+
*/
|
|
38
|
+
export interface EditorNetworkSnapshot {
|
|
39
|
+
gameId: string;
|
|
40
|
+
adapterKind: EditorNetworkAdapterKind;
|
|
41
|
+
/** `null` for offline / single-player games. */
|
|
42
|
+
authority: MultiplayerAuthority | null;
|
|
43
|
+
/** Optional topology string from the adapter when declared. */
|
|
44
|
+
topology?: string;
|
|
45
|
+
/** Optional endpoint hint from the adapter (ws/socketio url, lan port, p2p room). */
|
|
46
|
+
endpoint?: string;
|
|
47
|
+
session?: EditorNetworkSession;
|
|
48
|
+
/**
|
|
49
|
+
* Online presence roster from the host.
|
|
50
|
+
* - `undefined` — no feed supplied (honest empty / waiting).
|
|
51
|
+
* - array — real rows only (may be empty).
|
|
52
|
+
*/
|
|
53
|
+
online?: readonly EditorNetworkPresenceActor[];
|
|
54
|
+
/** Wall-clock ms of the last presence update when the host tracks it. */
|
|
55
|
+
updatedAt?: number;
|
|
56
|
+
}
|
|
57
|
+
/** Optional live presence/session injection from the editor host. */
|
|
58
|
+
export interface EditorNetworkPresenceInput {
|
|
59
|
+
userId?: string;
|
|
60
|
+
serverId?: string | null;
|
|
61
|
+
feedActions?: readonly string[];
|
|
62
|
+
online?: readonly PresencePoseRow[] | readonly EditorNetworkPresenceActor[];
|
|
63
|
+
updatedAt?: number;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Builds a Network workspace snapshot from the game's multiplayer config plus optional live
|
|
67
|
+
* presence rows. Adapter fields always reflect declared config; presence is only included when
|
|
68
|
+
* the host passes it.
|
|
69
|
+
*
|
|
70
|
+
* @internal
|
|
71
|
+
*/
|
|
72
|
+
export declare function buildEditorNetworkSnapshot(args: {
|
|
73
|
+
gameId: string;
|
|
74
|
+
multiplayer: unknown;
|
|
75
|
+
presence?: EditorNetworkPresenceInput;
|
|
76
|
+
}): EditorNetworkSnapshot;
|
|
77
|
+
/**
|
|
78
|
+
* True when the snapshot represents a multiplayer-capable game (not offline/unknown-null).
|
|
79
|
+
*
|
|
80
|
+
* @internal
|
|
81
|
+
*/
|
|
82
|
+
export declare function isNetworkMultiplayerConfigured(snapshot: EditorNetworkSnapshot): boolean;
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { adapterOf, resolveAuthority, } from "@jgengine/core/runtime/adapter";
|
|
2
|
+
function endpointOf(adapter) {
|
|
3
|
+
if (adapter === null)
|
|
4
|
+
return undefined;
|
|
5
|
+
if (adapter.kind === "ws" || adapter.kind === "socketio")
|
|
6
|
+
return adapter.url;
|
|
7
|
+
if (adapter.kind === "lan") {
|
|
8
|
+
const port = adapter.port ?? 8080;
|
|
9
|
+
const path = adapter.path ?? "/ws";
|
|
10
|
+
return `port ${port}${path}`;
|
|
11
|
+
}
|
|
12
|
+
if (adapter.kind === "p2p")
|
|
13
|
+
return adapter.room;
|
|
14
|
+
return undefined;
|
|
15
|
+
}
|
|
16
|
+
function topologyOf(adapter) {
|
|
17
|
+
if (adapter === null || adapter.kind === "offline")
|
|
18
|
+
return undefined;
|
|
19
|
+
return "topology" in adapter ? adapter.topology : undefined;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Builds a Network workspace snapshot from the game's multiplayer config plus optional live
|
|
23
|
+
* presence rows. Adapter fields always reflect declared config; presence is only included when
|
|
24
|
+
* the host passes it.
|
|
25
|
+
*
|
|
26
|
+
* @internal
|
|
27
|
+
*/
|
|
28
|
+
export function buildEditorNetworkSnapshot(args) {
|
|
29
|
+
const adapter = adapterOf(args.multiplayer);
|
|
30
|
+
const adapterKind = adapter?.kind ?? "unknown";
|
|
31
|
+
const authority = resolveAuthority(args.multiplayer);
|
|
32
|
+
const snapshot = {
|
|
33
|
+
gameId: args.gameId,
|
|
34
|
+
adapterKind,
|
|
35
|
+
authority,
|
|
36
|
+
};
|
|
37
|
+
const topology = topologyOf(adapter);
|
|
38
|
+
if (topology !== undefined)
|
|
39
|
+
snapshot.topology = topology;
|
|
40
|
+
const endpoint = endpointOf(adapter);
|
|
41
|
+
if (endpoint !== undefined)
|
|
42
|
+
snapshot.endpoint = endpoint;
|
|
43
|
+
const presence = args.presence;
|
|
44
|
+
if (presence !== undefined) {
|
|
45
|
+
if (typeof presence.userId === "string" && presence.userId.length > 0) {
|
|
46
|
+
snapshot.session = {
|
|
47
|
+
userId: presence.userId,
|
|
48
|
+
...(presence.serverId !== undefined ? { serverId: presence.serverId } : {}),
|
|
49
|
+
...(presence.feedActions !== undefined ? { feedActions: presence.feedActions } : {}),
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
if (presence.online !== undefined) {
|
|
53
|
+
snapshot.online = presence.online.map((row) => ({
|
|
54
|
+
userId: row.userId,
|
|
55
|
+
position: { x: row.position.x, y: row.position.y, z: row.position.z },
|
|
56
|
+
rotationY: row.rotationY,
|
|
57
|
+
...(row.rotationPitch !== undefined ? { rotationPitch: row.rotationPitch } : {}),
|
|
58
|
+
...("lastSeenAt" in row && row.lastSeenAt !== undefined ? { lastSeenAt: row.lastSeenAt } : {}),
|
|
59
|
+
}));
|
|
60
|
+
}
|
|
61
|
+
if (presence.updatedAt !== undefined)
|
|
62
|
+
snapshot.updatedAt = presence.updatedAt;
|
|
63
|
+
}
|
|
64
|
+
return snapshot;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* True when the snapshot represents a multiplayer-capable game (not offline/unknown-null).
|
|
68
|
+
*
|
|
69
|
+
* @internal
|
|
70
|
+
*/
|
|
71
|
+
export function isNetworkMultiplayerConfigured(snapshot) {
|
|
72
|
+
return snapshot.adapterKind !== "offline" && snapshot.adapterKind !== "unknown" && snapshot.authority !== null;
|
|
73
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { type EditorDocument } from "@jgengine/core/editor/index";
|
|
2
|
+
/** One option in the Parent-to… picker / inspector parent field. @internal */
|
|
3
|
+
export interface ParentCandidate {
|
|
4
|
+
id: string;
|
|
5
|
+
label: string;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Placeable objects that may become parents of every id in `childIds` without creating a cycle:
|
|
9
|
+
* excludes the children themselves and all of their descendants.
|
|
10
|
+
* @internal
|
|
11
|
+
*/
|
|
12
|
+
export declare function listParentCandidates(document: EditorDocument, childIds: readonly string[]): ParentCandidate[];
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { collectDescendants, } from "@jgengine/core/editor/index";
|
|
2
|
+
/**
|
|
3
|
+
* Placeable objects that may become parents of every id in `childIds` without creating a cycle:
|
|
4
|
+
* excludes the children themselves and all of their descendants.
|
|
5
|
+
* @internal
|
|
6
|
+
*/
|
|
7
|
+
export function listParentCandidates(document, childIds) {
|
|
8
|
+
if (childIds.length === 0)
|
|
9
|
+
return [];
|
|
10
|
+
const banned = collectDescendants(document, childIds);
|
|
11
|
+
for (const id of childIds)
|
|
12
|
+
banned.add(id);
|
|
13
|
+
const labelOf = (node) => node.label ?? node.id;
|
|
14
|
+
const candidates = [
|
|
15
|
+
...document.markers.map((m) => ({ id: m.id, label: labelOf(m) })),
|
|
16
|
+
...document.volumes.map((v) => ({ id: v.id, label: labelOf(v) })),
|
|
17
|
+
...document.paths.map((p) => ({ id: p.id, label: labelOf(p) })),
|
|
18
|
+
...document.annotations.map((n) => ({
|
|
19
|
+
id: n.id,
|
|
20
|
+
label: n.text.slice(0, 30) || n.id,
|
|
21
|
+
})),
|
|
22
|
+
].filter((entry) => !banned.has(entry.id));
|
|
23
|
+
candidates.sort((a, b) => a.label.localeCompare(b.label) || a.id.localeCompare(b.id));
|
|
24
|
+
return candidates;
|
|
25
|
+
}
|
package/dist/session.d.ts
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
import { type DocumentLiveSync, type DocumentPatch, type EditorCatalogDefinition, type EditorCommand, type EditorDocument, type EditorGridPaletteEntry, type EditorKindVisibility, type EditorLayersInput, type EditorSession, type EditorSessionState, type RuntimeEntityState, type RuntimePlayControl } from "@jgengine/core/editor/index";
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
import type { TerraformMode, TerrainMaterialLayer } from "@jgengine/core/world/terraform";
|
|
3
|
+
import type { ParamSchema } from "@jgengine/core/scene/sceneKinds";
|
|
4
|
+
import type { TerrainField } from "@jgengine/core/world/terrain";
|
|
5
|
+
/** How the editor hosts the game: frozen placement view, roamable world, the real game, or HUD-layout authoring. */
|
|
6
|
+
export type EditorRunMode = "edit" | "walk" | "play" | "hud";
|
|
7
|
+
/** The accepted run modes, in canonical order — the runtime guard behind {@link EditorRunMode}. @internal */
|
|
8
|
+
export declare const EDITOR_RUN_MODES: readonly EditorRunMode[];
|
|
5
9
|
/** RPC request shapes the editor host understands, used by the MCP bridge and UI. */
|
|
6
10
|
export type EditorBridgeRequest = {
|
|
7
11
|
method: "editor_status";
|
|
@@ -24,6 +28,29 @@ export type EditorBridgeRequest = {
|
|
|
24
28
|
entryId: string;
|
|
25
29
|
patch: Record<string, unknown>;
|
|
26
30
|
label?: string;
|
|
31
|
+
} | {
|
|
32
|
+
method: "add_catalog_entry";
|
|
33
|
+
catalogId: string;
|
|
34
|
+
entryId: string;
|
|
35
|
+
meta?: Record<string, unknown>;
|
|
36
|
+
label?: string;
|
|
37
|
+
} | {
|
|
38
|
+
method: "remove_catalog_entry";
|
|
39
|
+
catalogId: string;
|
|
40
|
+
entryId: string;
|
|
41
|
+
} | {
|
|
42
|
+
method: "add_catalog";
|
|
43
|
+
catalogId: string;
|
|
44
|
+
label?: string;
|
|
45
|
+
schema?: ParamSchema;
|
|
46
|
+
} | {
|
|
47
|
+
method: "remove_catalog";
|
|
48
|
+
catalogId: string;
|
|
49
|
+
} | {
|
|
50
|
+
method: "set_catalog_schema";
|
|
51
|
+
catalogId: string;
|
|
52
|
+
schema: ParamSchema;
|
|
53
|
+
label?: string;
|
|
27
54
|
} | {
|
|
28
55
|
method: "list_selection";
|
|
29
56
|
} | {
|
|
@@ -72,6 +99,10 @@ export type EditorBridgeRequest = {
|
|
|
72
99
|
method: "set_meta";
|
|
73
100
|
id: string;
|
|
74
101
|
patch: Record<string, unknown>;
|
|
102
|
+
} | {
|
|
103
|
+
method: "apply_preset";
|
|
104
|
+
id: string;
|
|
105
|
+
preset: string;
|
|
75
106
|
} | {
|
|
76
107
|
method: "select";
|
|
77
108
|
ids: string[];
|
|
@@ -164,6 +195,11 @@ export type EditorBridgeRequest = {
|
|
|
164
195
|
} | {
|
|
165
196
|
method: "convert_scatter";
|
|
166
197
|
pathId: string;
|
|
198
|
+
} | {
|
|
199
|
+
method: "bake_minimap";
|
|
200
|
+
padding?: number;
|
|
201
|
+
resolution?: number;
|
|
202
|
+
waterLevel?: number;
|
|
167
203
|
} | {
|
|
168
204
|
method: "add_foliage";
|
|
169
205
|
points: {
|
|
@@ -236,6 +272,11 @@ export type EditorBridgeRequest = {
|
|
|
236
272
|
} | {
|
|
237
273
|
method: "select_collection";
|
|
238
274
|
id: string;
|
|
275
|
+
} | {
|
|
276
|
+
method: "set_object_flags";
|
|
277
|
+
ids: string[];
|
|
278
|
+
locked?: boolean;
|
|
279
|
+
hidden?: boolean;
|
|
239
280
|
} | {
|
|
240
281
|
method: "batch_set_properties";
|
|
241
282
|
ids: string[];
|
|
@@ -402,6 +443,11 @@ export interface EditorAssetInfo {
|
|
|
402
443
|
}
|
|
403
444
|
/** Rolling frame-rate sample published by the in-canvas PerfProbe. */
|
|
404
445
|
export interface EditorPerfSample {
|
|
446
|
+
/**
|
|
447
|
+
* JS heap used in megabytes when the browser exposes `performance.memory` (Chromium).
|
|
448
|
+
* Omitted entirely when unavailable — never fabricated.
|
|
449
|
+
*/
|
|
450
|
+
memoryMb?: number;
|
|
405
451
|
fps: number;
|
|
406
452
|
frameMs: number;
|
|
407
453
|
drawCalls: number;
|
|
@@ -419,6 +465,25 @@ export interface EditorPerfSample {
|
|
|
419
465
|
rebuildMs?: number;
|
|
420
466
|
/** raycastMs + rebuildMs — total authoring overhead separated from the frame/sim budget. */
|
|
421
467
|
authoringMs?: number;
|
|
468
|
+
/**
|
|
469
|
+
* Average sim-driver time (ms) from core `devtools.frame` when FrameDriver has recorded frames.
|
|
470
|
+
* Same source as `debug_snapshot` / F2+D Perf panel — omitted when no frame samples exist
|
|
471
|
+
* (e.g. pure edit mode with no runtime tick). Never fabricated.
|
|
472
|
+
*/
|
|
473
|
+
simMs?: number;
|
|
474
|
+
/**
|
|
475
|
+
* Average outside-sim time (ms) = frame − sim (render / React / GPU / GC / vsync miss).
|
|
476
|
+
* Same availability rule as `simMs`. Matches `FrameStats.avgOutsideMs`.
|
|
477
|
+
*/
|
|
478
|
+
outsideMs?: number;
|
|
479
|
+
/**
|
|
480
|
+
* Top named sim phases (avg ms) from the same frame window when `measure("name", …)` marks exist.
|
|
481
|
+
* Omitted when the frame tracker has no named phases.
|
|
482
|
+
*/
|
|
483
|
+
phases?: readonly {
|
|
484
|
+
name: string;
|
|
485
|
+
avgMs: number;
|
|
486
|
+
}[];
|
|
422
487
|
}
|
|
423
488
|
/** The live editor's global control surface — session, visibility, camera focus, assets, mode, RPC. */
|
|
424
489
|
export interface EditorHostApi {
|
|
@@ -449,12 +514,20 @@ export interface EditorHostApi {
|
|
|
449
514
|
getCatalogDefinitions(): readonly EditorCatalogDefinition[];
|
|
450
515
|
getPerf(): EditorPerfSample | null;
|
|
451
516
|
setPerf(sample: EditorPerfSample): void;
|
|
517
|
+
/**
|
|
518
|
+
* The live composed ground field (base procedural terrain + document sculpt) from the mounted
|
|
519
|
+
* viewport, or null when no viewport is mounted. `bake_minimap` reads it to rasterize authored
|
|
520
|
+
* terrain; it exists only while the editor world is mounted, so headless CLIs get a null here.
|
|
521
|
+
*/
|
|
522
|
+
getTerrainSampler(): TerrainField | null;
|
|
523
|
+
setTerrainSampler(field: TerrainField | null): void;
|
|
452
524
|
getMode(): EditorRunMode;
|
|
453
525
|
setMode(mode: EditorRunMode): void;
|
|
454
526
|
subscribeMode(listener: (mode: EditorRunMode) => void): () => void;
|
|
455
527
|
/** Play-mode pause/step gate consumed by the runtime publisher. */
|
|
456
528
|
getPlayControl(): RuntimePlayControl;
|
|
457
|
-
|
|
529
|
+
/** Normalizes and stores the play control, notifies listeners, and returns the applied value. */
|
|
530
|
+
setPlayControl(next: RuntimePlayControl): RuntimePlayControl;
|
|
458
531
|
subscribePlayControl(listener: (play: RuntimePlayControl) => void): () => void;
|
|
459
532
|
handle(request: EditorBridgeRequest): EditorBridgeResponse;
|
|
460
533
|
}
|