@unboxy/phaser-sdk 0.2.23 → 0.2.25

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.
@@ -2,6 +2,7 @@ import Phaser from 'phaser';
2
2
  import { getEntityRegistry } from '../scene/EntityRegistry.js';
3
3
  import { parseColor, spawnEntity } from '../scene/spawnEntity.js';
4
4
  import { resolveRenderScript } from '../scene/renderScripts.js';
5
+ import { getManifest } from '../scene/SceneLoader.js';
5
6
  import { EditorOverlayScene, EDITOR_OVERLAY_KEY } from './EditorOverlayScene.js';
6
7
  import { getEditorState, setEditorActive, setSelection, } from './EditorState.js';
7
8
  /**
@@ -384,23 +385,49 @@ async function createEntity(game, entity, manifestAsset) {
384
385
  console.warn('[unboxy/editor] createEntity: world scene has no entity registry');
385
386
  return;
386
387
  }
388
+ // Resolve which AssetRecord to use for the lazy-load probe. Three paths:
389
+ // 1. Host passed `manifestAsset` (asset is brand-new) — use that.
390
+ // 2. Already in manifest but not provided (re-drag of existing asset)
391
+ // — look it up via the cached manifest.
392
+ // 3. Non-sprite entity (no asset needed) — leave undefined.
393
+ let assetForLoad = manifestAsset;
394
+ if (!assetForLoad && entity.kind === 'sprite') {
395
+ const visual = entity.visual;
396
+ const assetId = visual?.assetId;
397
+ if (assetId) {
398
+ try {
399
+ const manifest = getManifest(scene);
400
+ assetForLoad = manifest.assets.find((a) => a.id === assetId);
401
+ }
402
+ catch {
403
+ /* manifest not in cache — should not happen in edit mode */
404
+ }
405
+ }
406
+ }
387
407
  // Lazy-load texture if needed (sprite + asset not yet in cache).
388
- if (manifestAsset &&
408
+ if (assetForLoad &&
389
409
  entity.kind === 'sprite' &&
390
- !scene.textures.exists(manifestAsset.textureKey)) {
391
- await loadAssetIntoScene(scene, manifestAsset);
410
+ !scene.textures.exists(assetForLoad.textureKey)) {
411
+ await loadAssetIntoScene(scene, assetForLoad);
392
412
  }
393
413
  const ctx = {
394
414
  scene,
395
415
  registry,
396
416
  resolveAsset: (id) => {
397
- // For ad-hoc creation we may not have full manifest access. Rely on
398
- // the host to have stamped the right textureKey/path into the asset
399
- // we received via manifestAsset; fallback to a synthetic record so
400
- // spawnEntity can still find a textureKey.
401
417
  if (manifestAsset && manifestAsset.id === id)
402
418
  return manifestAsset;
403
- throw new Error(`[unboxy/editor] createEntity: asset '${id}' not in manifest payload host must include manifestAsset`);
419
+ // Fallback: look up in the manifest cache. Covers re-drag of an
420
+ // already-in-manifest asset where the host omitted manifestAsset.
421
+ try {
422
+ const manifest = getManifest(scene);
423
+ const found = manifest.assets.find((a) => a.id === id);
424
+ if (found)
425
+ return found;
426
+ }
427
+ catch {
428
+ /* fall through to throw */
429
+ }
430
+ throw new Error(`[unboxy/editor] createEntity: asset '${id}' not found in manifest`);
404
431
  },
405
432
  resolveRenderScript: undefined,
406
433
  };
@@ -46,9 +46,9 @@ interface EditorOverlayInitData {
46
46
  /**
47
47
  * Forward an editor keyboard shortcut to the host. Set when the iframe has
48
48
  * focus (which is always after the user clicks the canvas to select);
49
- * native Cmd+Z otherwise can't reach the host.
49
+ * native Cmd+Z / Backspace otherwise can't reach the host.
50
50
  */
51
- postShortcut: (action: 'undo' | 'redo' | 'save') => void;
51
+ postShortcut: (action: 'undo' | 'redo' | 'save' | 'delete') => void;
52
52
  }
53
53
  export declare class EditorOverlayScene extends Phaser.Scene {
54
54
  private graphics;
@@ -27,8 +27,6 @@ export class EditorOverlayScene extends Phaser.Scene {
27
27
  constructor() {
28
28
  super({ key: EDITOR_OVERLAY_KEY });
29
29
  this.handleShortcut = (e) => {
30
- if (!(e.metaKey || e.ctrlKey))
31
- return;
32
30
  // Don't swallow keys when the user is typing in a real form control —
33
31
  // shouldn't happen inside the iframe, but be defensive.
34
32
  const target = e.target;
@@ -39,18 +37,27 @@ export class EditorOverlayScene extends Phaser.Scene {
39
37
  if (target.isContentEditable)
40
38
  return;
41
39
  }
42
- const k = e.key.toLowerCase();
43
- if (k === 'z') {
44
- e.preventDefault();
45
- this.postShortcut(e.shiftKey ? 'redo' : 'undo');
46
- }
47
- else if (k === 'y') {
48
- e.preventDefault();
49
- this.postShortcut('redo');
40
+ const k = e.key;
41
+ if (e.metaKey || e.ctrlKey) {
42
+ const lower = k.toLowerCase();
43
+ if (lower === 'z') {
44
+ e.preventDefault();
45
+ this.postShortcut(e.shiftKey ? 'redo' : 'undo');
46
+ }
47
+ else if (lower === 'y') {
48
+ e.preventDefault();
49
+ this.postShortcut('redo');
50
+ }
51
+ else if (lower === 's') {
52
+ e.preventDefault();
53
+ this.postShortcut('save');
54
+ }
55
+ return;
50
56
  }
51
- else if (k === 's') {
57
+ if (k === 'Backspace' || k === 'Delete') {
58
+ // Suppress default (Backspace = browser back-nav inside iframe).
52
59
  e.preventDefault();
53
- this.postShortcut('save');
60
+ this.postShortcut('delete');
54
61
  }
55
62
  };
56
63
  }
@@ -177,7 +177,7 @@ export interface EditorDragEndMessage {
177
177
  */
178
178
  export interface EditorShortcutMessage {
179
179
  type: 'unboxy:editor:shortcut';
180
- action: 'undo' | 'redo' | 'save';
180
+ action: 'undo' | 'redo' | 'save' | 'delete';
181
181
  }
182
182
  export type EditorSdkToHostMessage = EditorSceneLoadedMessage | EditorSelectionPickedMessage | EditorDragEndMessage | EditorShortcutMessage;
183
183
  export type RpcMethod = 'saves.get' | 'saves.set' | 'saves.delete' | 'saves.list' | 'gameData.get' | 'gameData.set' | 'gameData.delete' | 'gameData.list' | 'realtime.getToken';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@unboxy/phaser-sdk",
3
- "version": "0.2.23",
3
+ "version": "0.2.25",
4
4
  "description": "Unboxy Phaser 3 SDK — game infrastructure for the Unboxy platform",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",