@jgengine/editor 0.14.0 → 0.15.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 +500 -1
- package/dist/EditorApp.js +2 -2
- package/dist/EditorCameraDriver.d.ts +6 -1
- package/dist/EditorCameraDriver.js +25 -1
- package/dist/EditorChrome.js +2 -4
- package/dist/InspectorPanel.js +12 -1
- package/dist/ParentPickerMenu.js +2 -6
- package/dist/RuntimePlayBridge.js +10 -15
- package/dist/SchemaInspector.js +55 -29
- package/dist/TerrainPanel.js +3 -4
- package/dist/TerrainReadout.js +1 -3
- package/dist/agent/AgentPanel.js +7 -11
- package/dist/camera/orbitFraming.d.ts +62 -0
- package/dist/camera/orbitFraming.js +69 -0
- package/dist/chromeFields.js +9 -4
- package/dist/handlers/document.d.ts +1 -1
- package/dist/handlers/document.js +78 -9
- package/dist/mcp/fieldSpec.js +4 -2
- package/dist/mcp/tools.js +4 -2
- package/dist/session.d.ts +54 -15
- package/dist/shell/AnimationPanel.js +14 -20
- package/dist/shell/CommandPalette.js +1 -5
- package/dist/shell/HierarchyPanel.js +17 -26
- package/dist/shell/PlayModeBar.d.ts +7 -0
- package/dist/shell/PlayModeBar.js +12 -3
- package/dist/shell/SceneToolbar.js +9 -5
- package/dist/shell/fields.js +8 -8
- package/dist/shell/glbThumbnailCache.js +39 -8
- package/dist/shell/scatterCoverage.js +10 -1
- package/dist/useStoreSelector.d.ts +12 -0
- package/dist/useStoreSelector.js +23 -0
- package/package.json +5 -5
- package/skills/ce-handoff/SKILL.md +149 -0
- package/skills/jgengine/SKILL.md +3 -1
- package/skills/jgengine/api.md +17 -7
- package/skills/jgengine/capabilities.md +12 -0
- package/skills/jgengine/recipes/minimal-game.md +7 -4
- package/skills/jgengine-editor/api.md +16 -3
- package/skills/jgengine-editor/reference.md +44 -0
|
@@ -48,6 +48,50 @@ The bridge is trustworthy so agents author instead of hardcoding — every path
|
|
|
48
48
|
- **One decode/migrate boundary.** `decodeEditorDocument` (`@jgengine/core/editor`) validates every field with a path-specific diagnostic (`$.markers[2].position`) and migrates forward; `import_document` and a `push_document_patch` **snapshot** both clear it, so a malformed or old document fails or migrates loudly rather than corrupting a live session.
|
|
49
49
|
- **Document-global id uniqueness.** Placeable ids (markers/volumes/paths/notes) are one namespace: adds re-id on collision, and a single imported document that reuses an id is rejected with its path — a duplicate-id import is impossible. Combine paths (`mergeEditorDocuments`, duplicate, overlay) re-id instead.
|
|
50
50
|
- **Schema-validated input.** `decodeEditorBridgeRequest` type-checks each field a method understands against the per-method schema before it reaches `handle` — a fuzzed value (string where a number belongs, scalar where an object belongs) is rejected at the `--rpc`/HTTP/stdio/agent-tool boundary, never cast in blind. Missing/unknown fields are left to `handle`'s guards so the boundary stays forward-compatible.
|
|
51
|
+
- **Guards name the expected param.** A required field left off (or supplied under the wrong key) is caught by the verb's own guard and answered with the param it wanted, not a downstream crash — e.g. `import_document` without `json` returns `import_document requires a \`json\` param …` instead of letting the missing value reach `JSON.parse` as the literal string `"undefined"`.
|
|
52
|
+
|
|
53
|
+
## Path / route authoring
|
|
54
|
+
|
|
55
|
+
Author a new path (route, road, patrol lane, scatter region outline) headlessly with **`add_path`** — no `export_document`/`import_document` roundtrip. It dispatches the `addPath` session command (one undoable edit) and mutates `EditorDocument.paths`:
|
|
56
|
+
|
|
57
|
+
```sh
|
|
58
|
+
bun packages/editor/src/mcp/cli.ts --game <id> \
|
|
59
|
+
--rpc '{"method":"add_path","id":"patrol_1","points":[{"x":0,"z":0},{"x":10,"z":5},{"x":20,"z":0}],"label":"Patrol"}' --save
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
- **Required:** `id` and `points` (≥2 ordered `{x,z}`; `y` optional, defaults to `0`). Fewer than two points is rejected `ok:false`.
|
|
63
|
+
- **Optional:** `kind` (defaults to `route`), `width`, `color`, `label`, `meta` — `meta` is validated against the kind's registered schema, same as `set_path`.
|
|
64
|
+
- **Id collisions re-id.** Placeable ids are one document-global namespace, so a colliding `id` is minted a `_copy` suffix; the response's `result` carries the id the path actually landed under. Patch it afterwards with `set_path`/`set_meta`, or make gameplay reference the stable id/kind rather than copying coordinates.
|
|
65
|
+
|
|
66
|
+
## Marker authoring
|
|
67
|
+
|
|
68
|
+
Place a new point marker (a spawn, checkpoint, pickup, bounty, or a game's own custom kind) headlessly with **`add_marker`** — the one-shot counterpart to `add_path`, no `export_document`/`import_document` roundtrip and no hand-editing the JSON. It dispatches the `addMarker` session command (one undoable edit) and mutates `EditorDocument.markers`:
|
|
69
|
+
|
|
70
|
+
```sh
|
|
71
|
+
bun packages/editor/src/mcp/cli.ts --game <id> \
|
|
72
|
+
--rpc '{"method":"add_marker","id":"stash_pier","kind":"stash","x":168,"z":232,"label":"Pier'\''s end","meta":{"value":300}}' --save
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
- **Required:** `id`, `kind`, and `x`/`z` (`y` optional, defaults to `0`). A game reads its own custom kinds off the document (`editorLayers.markers.filter(m => m.kind === "stash")`), so no engine change is needed to introduce one.
|
|
76
|
+
- **Optional:** `color`, `label`, `rotationY`, `meta` — `meta` is validated against the kind's registered schema when one exists (custom kinds skip validation), same as `set_marker`.
|
|
77
|
+
- **Id collisions re-id** exactly as `add_path`; the response's `result` carries the id the marker landed under. Use `place_asset` instead when the marker should carry a mesh (it stamps `catalogId`/`meta.assetId`); `add_marker` is for logical, mesh-free markers.
|
|
78
|
+
|
|
79
|
+
### Click-to-place custom kinds in the GUI
|
|
80
|
+
|
|
81
|
+
`add_marker` is the *scripted* path (an agent/CLI types coordinates). To let a **designer click the world to drop** a game's own logical kind (a stash, checkpoint, bounty…), register it as a placeable scene kind with **`definePlaceableMarkerKind`** (`@jgengine/core/scene/sceneKinds`) — the light path that skips a full studio's schema/resolver:
|
|
82
|
+
|
|
83
|
+
```ts
|
|
84
|
+
// Games/<id>/src/editorKinds.ts — imported for its side effect by the game's editorLayers.ts
|
|
85
|
+
import { definePlaceableMarkerKind } from "@jgengine/core/scene/sceneKinds";
|
|
86
|
+
export const STASH_KIND = definePlaceableMarkerKind({
|
|
87
|
+
kind: "stash", label: "Stash", category: "My Game", accent: "#38d6c4",
|
|
88
|
+
fields: [{ type: "number", key: "value", label: "Payout ($)", default: 300, min: 0, step: 50 }],
|
|
89
|
+
});
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
- The kind then appears as a click-to-place tool in the editor `+ Add` menu, grouped under its `category`: pick it, click the world to drop a marker, Shift-click to keep placing, tune the `fields` in the Inspector. The runtime is unchanged — the game still reads the kind off `editorLayers.markers`.
|
|
93
|
+
- **Load path:** register from a module the editor loads. Importing your `editorKinds.ts` (side effect) from `editorLayers.ts` covers it — `loadGameLayers` imports `editorLayers.ts` for every editor session, and the game runtime imports it too, so one registration serves both.
|
|
94
|
+
- `fields` also gives `add_marker`/`set_marker`/`set_meta` a schema to validate that kind's `meta` against; omit `fields` for a bare placeable marker.
|
|
51
95
|
|
|
52
96
|
## Pure API (`@jgengine/editor`)
|
|
53
97
|
|