@combos-fun/plugin-development-tool 0.0.44 → 0.0.46

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/agent-skill.md CHANGED
@@ -1,43 +1,25 @@
1
1
  # `@combos-fun/plugin-development-tool` — Agent notes
2
2
 
3
- In-canvas debugging / inspection plugin. Adds a `CombosDevelopmentToolTarget` Component that, when tapped, draws an outline overlay around the GameObject and posts a parent-frame message identifying the selected node. Used by the Combos Fun editor / inspector to wire up two-way selection between the editor tree and the running game.
3
+ **2D-only editor iframe picker.** It uses the Pixi renderer Event/Graphics plugins to select tagged GameObjects, draw an outline, and exchange selection data with the parent editor. For 3D picking, use `@combos-fun/plugin-renderer-3d-event`.
4
4
 
5
5
  ## When to read
6
6
 
7
- Read whenever building tooling, integrating with the Combos editor, or debugging which GameObject is being tapped at runtime.
7
+ Read when integrating the Combos editor iframe, pick mode, Scene Edit messages, or marker overlays.
8
8
 
9
9
  ## Public API
10
10
 
11
- ```ts
12
- import {
13
- CombosDevelopmentToolSystem,
14
- CombosDevelopmentToolTarget,
15
- COMBOS_DEVELOPMENT_TOOL_GAMEOBJECT_SELECTED,
16
- COMBOS_DEVELOPMENT_TOOL_CLEAR_SELECTION,
17
- COMBOS_DEVELOPMENT_TOOL_GAMEOBJECT_DESELECTED,
18
- COMBOS_DEVELOPMENT_TOOL_REFRESH,
19
- COMBOS_DEVELOPMENT_TOOL_SET_PICK_MODE,
20
- type CombosDevelopmentToolTargetParams,
21
- type CombosDevelopmentToolSystemParams,
22
- type CombosDevelopmentToolSelectScope,
23
- } from '@combos-fun/plugin-development-tool';
24
- ```
11
+ `CombosDevelopmentToolTarget` marks a selectable GameObject. Its optional `payload` is included in snapshots; source persistence requires `payload.source.file` and `payload.source.anchor`.
25
12
 
26
- - `CombosDevelopmentToolTarget` — Component to attach to any GameObject
27
- that should be selectable in editor mode.
28
- - `CombosDevelopmentToolSystem` — System that listens to taps, draws the
29
- outline, and posts `COMBOS_DEVELOPMENT_TOOL_GAMEOBJECT_SELECTED`
30
- messages to the parent window.
13
+ `CombosDevelopmentToolSystem` accepts:
31
14
 
32
- ### `CombosDevelopmentToolTargetParams`
15
+ - `postMessageOrigin`: outbound parent `targetOrigin`, default `'*'`.
16
+ - `allowedMessageOrigins`: inbound origins merged with the default `knoffice.tech` and `converge.ai` host suffixes.
33
17
 
34
- | Field | Type | Notes |
35
- |---|---|---|
36
- | `payload` | `Record<string, unknown>?` | Snapshot extras. Creator persist needs `payload.source.file` + `payload.source.anchor`. Who to tag and how to pick the pair: `$combos-engine-development` → `references/development-tool-target-policy.md`. |
18
+ It exposes `setEnabled`, `requestSceneRescan`, `setMuted`, and `setMarkerOverlay`, plus matching `COMBOS_DEVELOPMENT_TOOL_*` constants and protocol helpers. There is no `CombosDevelopmentToolSelectScope`. `COMBOS_DEVELOPMENT_TOOL_READY` is exported but never posted; wait for engine `combos-game:ready`.
37
19
 
38
20
  ## Required setup
39
21
 
40
- This plugin depends on `@combos-fun/plugin-renderer-event` (for taps) and `@combos-fun/plugin-renderer-graphics` (for the outline). `RendererSystem`, `EventSystem`, `GraphicsSystem`, and `CombosDevelopmentToolSystem` must all be registered before edit mode runs. `RendererSystem` must come before renderer plugins; the relative constructor-array position of Event, Graphics, and Development Tool is not significant when edit mode is enabled only after system bootstrap. Recommended order:
22
+ Register the 2D renderer before Event and Graphics, then the development tool:
41
23
 
42
24
  ```ts
43
25
  new Game({
@@ -45,100 +27,63 @@ new Game({
45
27
  new RendererSystem({ canvas, width, height }),
46
28
  new EventSystem(),
47
29
  new GraphicsSystem(),
48
- new CombosDevelopmentToolSystem({ /* options */ }),
30
+ new CombosDevelopmentToolSystem(),
49
31
  ],
50
32
  });
51
33
  ```
52
34
 
53
- ## Pick-mode behavior
35
+ Attach `CombosDevelopmentToolTarget` only to objects the editor may pick.
54
36
 
55
- - The System starts disabled.
56
- - While enabled, only GameObjects carrying `CombosDevelopmentToolTarget` receive editor pick bindings.
57
- - Existing game `Event` hit targets are soft-disabled by setting their renderer containers non-interactive; they are restored when pick mode is disabled.
58
- - Adding a Target while enabled automatically soft-disables that object's game Event and installs its pick binding through the Component observer.
59
- - Removing a Target automatically releases its pick binding and clears selection when necessary.
60
- - Dynamic Target additions and removals do not require `requestSceneRescan()`. A full rescan exists for parent/tooling-driven structural refreshes.
37
+ ## Runtime behaviour
61
38
 
62
- ## Pick bounds
39
+ The System starts disabled. In pick mode it soft-disables existing game Event containers, installs pick Events only on Target objects, and restores game Events when disabled. Target additions/removals are observed automatically; `requestSceneRescan()` is for parent-driven structural refreshes.
63
40
 
64
- The generated pick Event resolves local bounds in this order:
41
+ Pick bounds resolve in this order: own rendered Graphics bounds, positive `transform.size`, renderer-container bounds, then `1×1`. Set `transform.size` for non-Graphics renderers when precise bounds matter.
65
42
 
66
- 1. A GameObject with `Graphics` uses its own Pixi `Graphics.getLocalBounds()` first.
67
- 2. Other renderers use positive `transform.size` as a `(0, 0, width, height)` box.
68
- 3. The renderer container's local bounds are used as a fallback.
69
- 4. A 1×1 box is the final fallback.
43
+ The marker overlay is independent of pick mode and mute. It currently draws a 28×28 Graphics marker only for `Sound`; the owner still needs a Target for selection and persistence.
70
44
 
71
- Set `transform.size` for `Img`, `Text`, `Sprite`, and `SpriteAnimation` GameObjects so picking matches their displayed box. Graphics GameObjects should draw their actual geometry; the System deliberately prefers rendered Graphics bounds over the Transform size box, including circles and polygons drawn around a local origin.
45
+ ## postMessage protocol
72
46
 
73
- ## Common pitfalls
47
+ Parent iframe:
74
48
 
75
- | Symptom | Fix |
76
- |---------|-----|
77
- | Selection box never appears | Ensure both `EventSystem` and `GraphicsSystem` are registered |
78
- | Parent frame never receives messages | The page must be in an iframe / embedded context; `window.parent !== window` |
79
- | Parent postMessage ignored | Check `allowedMessageOrigins` defaults allow `knoffice.tech` and `converge.ai` (+ subdomains). Pass `['localhost']` to merge local dev hosts |
80
- | Selection stuck after a parent-driven structural replacement | Have the parent/tooling send `COMBOS_DEVELOPMENT_TOOL_REFRESH`; ordinary Target add/remove is automatic |
81
- | Scene Edit cannot persist / object not found after reload | Target is missing `payload.source.file` + `payload.source.anchor` |
49
+ - `set-pick-mode { enabled }`
50
+ - `refresh`, `clear-selection`
51
+ - `apply-property`
52
+ - `set-muted { muted }`
53
+ - `set-marker-overlay { enabled }`
82
54
 
83
- ## Inbound postMessage security
55
+ Iframe parent:
84
56
 
85
- `CombosDevelopmentToolSystem` validates `MessageEvent.origin` before handling parent commands.
57
+ - `pick-mode-success { enabled }`
58
+ - `gameobject-selected { snapshot, pointer }`
59
+ - `gameobject-deselected { reason }`
60
+ - `state-changed { muted }`
61
+ - `marker-overlay-success { enabled, total, markers }`
86
62
 
87
- - Default allowlist: `knoffice.tech`, `converge.ai` (each matches the host and all subdomains).
88
- - `allowedMessageOrigins` **merges** with defaults (deduped). Pass `['localhost']` for local parent pages without repeating the defaults.
89
- - Pass `['*']` alone to accept any origin (disables the check).
90
- - Local dev with a non-knoffice parent (e.g. `http://localhost:9001`): `allowedMessageOrigins: ['localhost']`.
63
+ Inbound messages are origin-checked. `allowedMessageOrigins: ['localhost']` adds local development; `['*']` alone disables the check. `postMessageOrigin` controls outbound delivery separately.
91
64
 
92
- ```ts
93
- new CombosDevelopmentToolSystem({
94
- allowedMessageOrigins: ['localhost'],
95
- });
96
- // effective: knoffice.tech, converge.ai, localhost
97
- ```
65
+ ## Scene Edit fields
98
66
 
99
- Outbound `postMessageOrigin` is separate it limits which parent origin receives selection snapshots.
67
+ Snapshots expose described schema-backed `fieldDescriptors`, not raw fields. For authoritative `@Field` metadata rules, read `@combos-fun/inspector-decorator`.
100
68
 
101
- ## postMessage protocol
69
+ ## Common pitfalls
70
+
71
+ - Selection requires `RendererSystem`, `EventSystem`, and `GraphicsSystem`.
72
+ - Parent messages require an iframe (`window.parent !== window`) and an allowed origin.
73
+ - Structural replacement needs `refresh`; ordinary Target add/remove does not.
74
+ - Persistence fails without both source file and anchor in Target payload.
75
+ - Markers are visual only and do not create a Target.
102
76
 
103
- | Direction | type | Payload | Behavior |
104
- |-----------|------|---------|----------|
105
- | parent → iframe | `combos-development-tool:set-pick-mode` | `{ enabled: boolean }` | Enable/disable pick mode |
106
- | iframe → parent | `combos-development-tool:pick-mode-success` | `{ enabled: boolean }` | Pick mode finished attaching or restoring |
107
- | parent → iframe | `combos-development-tool:clear-selection` | `{}` | Clear in-canvas outline |
108
- | parent iframe | `combos-development-tool:apply-property` | component field mutation | Live preview |
109
- | parent → iframe | `combos-development-tool:set-marker-overlay` | `{ enabled: boolean }` | Toggle the marker overlay (independent of pick mode) |
110
- | iframe → parent | `combos-development-tool:gameobject-selected` | `{ snapshot, pointer }` | Object picked |
111
- | iframe → parent | `combos-development-tool:gameobject-deselected` | `{ reason }` | Selection cleared (`parent-request`, `pick-disabled`, `target-removed`) |
112
- | iframe → parent | `combos-development-tool:marker-overlay-success` | `{ enabled, total, markers: { componentName, count }[] }` | Marker overlay finished (re)building |
113
-
114
- ## Marker overlay (surface invisible components)
115
-
116
- A reusable "pin a persistent icon on every object owning an otherwise invisible
117
- component" layer. Registry-driven (`markerLayer.ts` → `MARKER_COMPONENTS`).
118
- **For now it is `Sound` only** — the mechanism is generic (append `Physics` / `Camera` /
119
- triggers / spawn points later) but nothing else is registered yet.
120
-
121
- - Independent toggle, orthogonal to pick mode and mute: `setMarkerOverlay(true)` or
122
- `postMessage({ type: 'combos-development-tool:set-marker-overlay', enabled: true })`
123
- (also `window` CustomEvent / `game.emit`).
124
- - Draws a fixed **28×28** icon **in-engine** from the owner GameObject's local origin (a `Graphics` child GO pinned to the owner, so it
125
- follows the object). The layer is **purely visual** — it does not wire up its own
126
- selection. Because the icon adds to the owner's rendered bounds, the owner's own
127
- `CombosDevelopmentToolTarget` pick gets a clickable hit area, so selecting and
128
- editing (e.g. `Sound.volume`) go through the normal
129
- selection → snapshot (`fieldDescriptors`) → `apply-property` flow and **persist to source** like any
130
- other scene edit. Sound objects that should be editable need a Target (source
131
- pair and spacing: Target policy).
132
- - On (re)build it posts `combos-development-tool:marker-overlay-success` with per-component counts.
133
-
134
- ## Scene Edit fieldDescriptors
135
-
136
- Selection snapshots no longer dump raw component `fields`. The host receives only
137
- schema-backed `fieldDescriptors` derived from `@Field` metadata (`label`,
138
- `description`, editor hints, min/max/step, etc.). Fields without a non-empty
139
- `description` are omitted. Custom game Components that should appear in Creator
140
- must declare `@Field({ label, description, ... })` in the user's language.
77
+ ## Minimal example
78
+
79
+ ```ts
80
+ editableGo.addComponent(new CombosDevelopmentToolTarget({
81
+ payload: {
82
+ source: { file: 'src/scene.ts', anchor: 'start-button' },
83
+ },
84
+ }));
85
+ ```
141
86
 
142
87
  ## Verification
143
88
 
144
- `pnpm --filter @combos-fun/plugin-development-tool run build`.
89
+ Run `pnpm --filter @combos-fun/plugin-development-tool run build`.
@@ -1375,7 +1375,7 @@ var CombosDevelopmentToolSystem = CombosDevelopmentToolSystem$1;
1375
1375
  /** Auto-generated by scripts/build-package.mjs — do not edit. */
1376
1376
  Object.assign(CombosDevelopmentToolSystem, {
1377
1377
  packageName: "@combos-fun/plugin-development-tool",
1378
- packageVersion: "0.0.44",
1378
+ packageVersion: "0.0.46",
1379
1379
  });
1380
1380
 
1381
1381
  exports.COMBOS_DEVELOPMENT_TOOL_APPLY_PROPERTY = COMBOS_DEVELOPMENT_TOOL_APPLY_PROPERTY;