@umicat/phaser-sdk 1.0.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/SDK-GUIDE.md +1726 -0
- package/dist/core/Transport.d.ts +28 -0
- package/dist/core/Transport.js +7 -0
- package/dist/core/Umicat.d.ts +45 -0
- package/dist/core/Umicat.js +60 -0
- package/dist/core/UmicatGame.d.ts +43 -0
- package/dist/core/UmicatGame.js +64 -0
- package/dist/core/UmicatScene.d.ts +19 -0
- package/dist/core/UmicatScene.js +38 -0
- package/dist/core/transports/LocalStorageTransport.d.ts +22 -0
- package/dist/core/transports/LocalStorageTransport.js +78 -0
- package/dist/core/transports/PostMessageTransport.d.ts +28 -0
- package/dist/core/transports/PostMessageTransport.js +105 -0
- package/dist/editor/EditorBridge.d.ts +114 -0
- package/dist/editor/EditorBridge.js +2608 -0
- package/dist/editor/EditorOverlayScene.d.ts +333 -0
- package/dist/editor/EditorOverlayScene.js +1896 -0
- package/dist/editor/EditorState.d.ts +251 -0
- package/dist/editor/EditorState.js +197 -0
- package/dist/gamedata/GameDataModule.d.ts +45 -0
- package/dist/gamedata/GameDataModule.js +59 -0
- package/dist/index.d.ts +43 -0
- package/dist/index.js +43 -0
- package/dist/orientation.d.ts +5 -0
- package/dist/orientation.js +4 -0
- package/dist/protocol.d.ts +807 -0
- package/dist/protocol.js +3 -0
- package/dist/realtime/RealtimeModule.d.ts +93 -0
- package/dist/realtime/RealtimeModule.js +115 -0
- package/dist/realtime/UmicatRoom.d.ts +197 -0
- package/dist/realtime/UmicatRoom.js +353 -0
- package/dist/recording/RecordingManager.d.ts +11 -0
- package/dist/recording/RecordingManager.js +59 -0
- package/dist/saves/SavesModule.d.ts +23 -0
- package/dist/saves/SavesModule.js +37 -0
- package/dist/scene/EditorMode.d.ts +17 -0
- package/dist/scene/EditorMode.js +22 -0
- package/dist/scene/EntityRegistry.d.ts +39 -0
- package/dist/scene/EntityRegistry.js +103 -0
- package/dist/scene/GameConfig.d.ts +60 -0
- package/dist/scene/GameConfig.js +50 -0
- package/dist/scene/HudRuntime.d.ts +131 -0
- package/dist/scene/HudRuntime.js +1224 -0
- package/dist/scene/Prefabs.d.ts +92 -0
- package/dist/scene/Prefabs.js +175 -0
- package/dist/scene/Rules.d.ts +73 -0
- package/dist/scene/Rules.js +164 -0
- package/dist/scene/SceneLoader.d.ts +118 -0
- package/dist/scene/SceneLoader.js +615 -0
- package/dist/scene/Waves.d.ts +85 -0
- package/dist/scene/Waves.js +365 -0
- package/dist/scene/autotile.d.ts +103 -0
- package/dist/scene/autotile.js +321 -0
- package/dist/scene/renderScripts.d.ts +53 -0
- package/dist/scene/renderScripts.js +67 -0
- package/dist/scene/spawnEntity.d.ts +201 -0
- package/dist/scene/spawnEntity.js +1326 -0
- package/dist/scene/types.d.ts +1166 -0
- package/dist/scene/types.js +34 -0
- package/dist/screenshot/ScreenshotManager.d.ts +14 -0
- package/dist/screenshot/ScreenshotManager.js +33 -0
- package/package.json +35 -0
|
@@ -0,0 +1,333 @@
|
|
|
1
|
+
import Phaser from 'phaser';
|
|
2
|
+
/**
|
|
3
|
+
* Editor overlay — slice 2.
|
|
4
|
+
*
|
|
5
|
+
* Runs ABOVE the world/HUD scenes. Its job:
|
|
6
|
+
*
|
|
7
|
+
* 1. Render selection rectangle around the currently selected entity
|
|
8
|
+
* 2. Render world bounds rectangle (visual cue for "edge of the game world")
|
|
9
|
+
* 3. Capture pointer events:
|
|
10
|
+
* - pointerdown on an entity → posts pickEntity to host
|
|
11
|
+
* - drag → mutates the entity's x/y in real time (visual only)
|
|
12
|
+
* - pointerup → posts dragEnd with before/after to host
|
|
13
|
+
*
|
|
14
|
+
* The overlay scene is launched by EditorBridge when entering Edit mode,
|
|
15
|
+
* stopped on exit. It holds no persistent state of its own — selection +
|
|
16
|
+
* drag info live in the shared EditorState attached to the Phaser game.
|
|
17
|
+
*/
|
|
18
|
+
export declare const EDITOR_OVERLAY_KEY = "__UmicatEditorOverlay";
|
|
19
|
+
interface EditorOverlayInitData {
|
|
20
|
+
/** World bounds rect to draw (slice 2 draws but doesn't allow editing). */
|
|
21
|
+
worldBounds?: {
|
|
22
|
+
x: number;
|
|
23
|
+
y: number;
|
|
24
|
+
width: number;
|
|
25
|
+
height: number;
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* Callback to resolve the entity at a given world point. Provided by the
|
|
29
|
+
* EditorBridge so the overlay doesn't have to know about the EntityRegistry.
|
|
30
|
+
* Returns the topmost (highest depth) entity at that point or null.
|
|
31
|
+
*/
|
|
32
|
+
hitTest: (worldX: number, worldY: number) => Phaser.GameObjects.GameObject | null;
|
|
33
|
+
/**
|
|
34
|
+
* FB.9a — return ALL entities at (worldX, worldY), sorted by depth desc.
|
|
35
|
+
* Used by Alt+click cycle (selecting underlying entities when 2+ overlap).
|
|
36
|
+
*/
|
|
37
|
+
hitTestAll: (worldX: number, worldY: number) => Phaser.GameObjects.GameObject[];
|
|
38
|
+
/**
|
|
39
|
+
* postMessage helpers (so the scene can send pickEntity / dragEnd).
|
|
40
|
+
*
|
|
41
|
+
* `prefabId` is set when the picked GameObject was spawned via `spawnPrefab`
|
|
42
|
+
* (tagged with `entityPrefabId` by the SDK at spawn time). The host uses
|
|
43
|
+
* it to open the Prefab Inspector instead of the Entity Inspector — see
|
|
44
|
+
* `EditorSelectionPickedMessage` in protocol.ts.
|
|
45
|
+
*/
|
|
46
|
+
postPick: (entityId: string | null, modifiers: {
|
|
47
|
+
shift: boolean;
|
|
48
|
+
cmdOrCtrl: boolean;
|
|
49
|
+
alt: boolean;
|
|
50
|
+
}, prefabId?: string) => void;
|
|
51
|
+
postDragEnd: (entityId: string, before: {
|
|
52
|
+
x: number;
|
|
53
|
+
y: number;
|
|
54
|
+
}, after: {
|
|
55
|
+
x: number;
|
|
56
|
+
y: number;
|
|
57
|
+
}) => void;
|
|
58
|
+
/**
|
|
59
|
+
* Forward an editor keyboard shortcut to the host. Set when the iframe has
|
|
60
|
+
* focus (which is always after the user clicks the canvas to select);
|
|
61
|
+
* native Cmd+Z / Backspace otherwise can't reach the host.
|
|
62
|
+
*/
|
|
63
|
+
postShortcut: (action: 'undo' | 'redo' | 'save' | 'delete') => void;
|
|
64
|
+
/**
|
|
65
|
+
* P1 infinite canvas — apply pan/zoom to the world camera. Called from
|
|
66
|
+
* the overlay scene's wheel + middle-button + space-drag handlers.
|
|
67
|
+
* Routed through EditorBridge (not called directly here) to keep the
|
|
68
|
+
* pan/zoom mutation in one place + avoid a circular import between
|
|
69
|
+
* overlay scene and bridge.
|
|
70
|
+
*/
|
|
71
|
+
applyPanZoom: (msg: {
|
|
72
|
+
scrollX?: number;
|
|
73
|
+
scrollY?: number;
|
|
74
|
+
zoom?: number;
|
|
75
|
+
relative?: boolean;
|
|
76
|
+
}) => void;
|
|
77
|
+
}
|
|
78
|
+
export declare class EditorOverlayScene extends Phaser.Scene {
|
|
79
|
+
private graphics;
|
|
80
|
+
private worldBounds?;
|
|
81
|
+
private hitTest;
|
|
82
|
+
private hitTestAll;
|
|
83
|
+
private postPick;
|
|
84
|
+
private postDragEnd;
|
|
85
|
+
private postShortcut;
|
|
86
|
+
private applyPanZoom;
|
|
87
|
+
private panActive;
|
|
88
|
+
private spaceHeld;
|
|
89
|
+
private panStartScreen;
|
|
90
|
+
private panStartScroll;
|
|
91
|
+
private wheelHandler?;
|
|
92
|
+
constructor();
|
|
93
|
+
init(data: EditorOverlayInitData): void;
|
|
94
|
+
create(): void;
|
|
95
|
+
private handleShortcut;
|
|
96
|
+
/**
|
|
97
|
+
* Pointer coords mode-aware. World mode uses world coords (camera-relative);
|
|
98
|
+
* HUD mode transforms pointer through the HUD scene's camera to land in
|
|
99
|
+
* HUD-intrinsic coords (the coord space widget positions live in).
|
|
100
|
+
*
|
|
101
|
+
* Pre-0.2.90 this returned `pointer.x/y` (canvas pixels) for HUD mode
|
|
102
|
+
* — fine when HUD cam was an identity camera (viewport == canvas,
|
|
103
|
+
* zoom == 1). But 0.2.89 changed HUD cam to render INSIDE the camera-
|
|
104
|
+
* viewport rect on the editor canvas with editor-cam zoom, so canvas
|
|
105
|
+
* pixels no longer equal HUD-intrinsic coords. Hit-test against
|
|
106
|
+
* widgets (positioned in HUD-intrinsic) would only match a tiny
|
|
107
|
+
* patch near the canvas top-left, hence the user's "have to click
|
|
108
|
+
* many times" complaint. Using `hudCam.getWorldPoint(...)` applies
|
|
109
|
+
* the cam's inverse transform (subtract viewport offset, divide by
|
|
110
|
+
* zoom) and lands in widget coord space.
|
|
111
|
+
*/
|
|
112
|
+
private pointerCoords;
|
|
113
|
+
private handlePointerDown;
|
|
114
|
+
private handlePointerMove;
|
|
115
|
+
private handlePointerUp;
|
|
116
|
+
/**
|
|
117
|
+
* Pointer-down inside paint mode. Returns true when the pointer hit the
|
|
118
|
+
* active layer (stroke began); false when the pointer fell outside the
|
|
119
|
+
* tilemap's bounds (caller falls through to normal selection).
|
|
120
|
+
*
|
|
121
|
+
* Begins a stroke + applies the first cell. brush/eraser tools paint
|
|
122
|
+
* incrementally per pointermove; rect/fill/picker (Phase B.4) handle
|
|
123
|
+
* pointerdown specially — for now only brush + eraser are wired.
|
|
124
|
+
*/
|
|
125
|
+
private handleTilemapPaintDown;
|
|
126
|
+
private handleTilemapPaintMove;
|
|
127
|
+
/**
|
|
128
|
+
* Compose stroke into one TilemapEditOp + post to host. Host records the
|
|
129
|
+
* undo command + persists on next flush. Stroke state is cleared.
|
|
130
|
+
*
|
|
131
|
+
* Brush stroke → `paint` op with all cells. Eraser stroke → `erase` op.
|
|
132
|
+
* (Phase B.4 adds rect / fill emit paths.)
|
|
133
|
+
*/
|
|
134
|
+
private handleTilemapPaintUp;
|
|
135
|
+
/**
|
|
136
|
+
* Compose a `fillRect` op from the completed rect drag + apply it live +
|
|
137
|
+
* post tilemapEdited. `previousCells` captures every cell the rect
|
|
138
|
+
* overwrites so undo replays them onto the layer.
|
|
139
|
+
*/
|
|
140
|
+
private commitTilemapRect;
|
|
141
|
+
/**
|
|
142
|
+
* Bucket fill (4-connected flood). Captures every cell the flood
|
|
143
|
+
* touches into previousCells before applying, then posts one tilemapEdited
|
|
144
|
+
* so undo restores the whole flooded area.
|
|
145
|
+
*
|
|
146
|
+
* Reads the layer in one pass to compute the visited set + previous
|
|
147
|
+
* indices, then commits via Phaser's putTileAt. Single-pass because
|
|
148
|
+
* applyTilemapOp would re-walk + duplicate work.
|
|
149
|
+
*/
|
|
150
|
+
private applyBucketFill;
|
|
151
|
+
/**
|
|
152
|
+
* Slice 6 Phase D — autotile bucket fill. 4-connected flood over cells
|
|
153
|
+
* with matching tile index (or all empties), then runs the wang cascade
|
|
154
|
+
* for each flooded cell. The resulting `autotilePaint` op carries every
|
|
155
|
+
* flooded cell as a clicked cell; `previousCells` covers the flood +
|
|
156
|
+
* its 1-cell border for cascade-correct undo.
|
|
157
|
+
*/
|
|
158
|
+
private applyAutotileBucketFill;
|
|
159
|
+
/**
|
|
160
|
+
* Look up the active TilemapLayer in the world scene's entity registry,
|
|
161
|
+
* then walk the container's children for the layer with matching
|
|
162
|
+
* `tilemapLayerId` data tag.
|
|
163
|
+
*/
|
|
164
|
+
private findActiveTilemapLayer;
|
|
165
|
+
/**
|
|
166
|
+
* Same as findActiveTilemapLayer but returns the container too. Callers
|
|
167
|
+
* that need to convert world coords to tile coords need the container's
|
|
168
|
+
* position to shift the input — `TilemapLayer.worldToTileXY` doesn't
|
|
169
|
+
* apply the container transform on its own (the layer's `x`/`y` are
|
|
170
|
+
* local to the container, not world coords).
|
|
171
|
+
*/
|
|
172
|
+
private findActiveTilemapLayerWithContainer;
|
|
173
|
+
/**
|
|
174
|
+
* Apply one stroke cell: read prev index (for undo), apply the new
|
|
175
|
+
* value via Phaser's tilemap API, push the cell into the stroke
|
|
176
|
+
* accumulator. Dedup happens in `appendTilemapStrokeCell` so dragging
|
|
177
|
+
* over the same cell multiple times only records once.
|
|
178
|
+
*/
|
|
179
|
+
private applyStrokeCell;
|
|
180
|
+
/**
|
|
181
|
+
* Slice 6 Phase D — resolve `{ asset, terrain }` for the layer's
|
|
182
|
+
* tileset + a requested terrain id. Returns null when:
|
|
183
|
+
* - the layer has no `tilemapTilesetId` stamp (legacy / unattached layer)
|
|
184
|
+
* - the manifest has no asset for that id
|
|
185
|
+
* - the asset's tileset metadata lacks `autotile.terrains` with that id
|
|
186
|
+
* Callers fall back to stamp-mode behavior on null.
|
|
187
|
+
*/
|
|
188
|
+
private resolveAutotileTerrainContext;
|
|
189
|
+
/**
|
|
190
|
+
* Slice 6 Phase D — autotile-mode stroke cell. Runs the Wang cascade
|
|
191
|
+
* via `applyAutotile`, threads every affected cell (clicked + cascade
|
|
192
|
+
* neighbors) into the stroke accumulator so the pointerup commit can
|
|
193
|
+
* emit one `autotilePaint` op + a previousCells array that captures
|
|
194
|
+
* the entire region the click changed.
|
|
195
|
+
*
|
|
196
|
+
* Per-frame metadata + sub-tile body sync is handled by the host-
|
|
197
|
+
* driven `handleEditTilemap` path when undo replays inverse ops; the
|
|
198
|
+
* live stroke only touches `layer.data` (cell indices) — fine because
|
|
199
|
+
* cell-rect collision is re-armed at the next handleEditTilemap call.
|
|
200
|
+
*/
|
|
201
|
+
private applyAutotileStrokeCell;
|
|
202
|
+
/**
|
|
203
|
+
* Sync every tilemap entity's TilemapLayers to its container's
|
|
204
|
+
* current world position. Runs every frame in edit mode (see update()).
|
|
205
|
+
* Matches the play-mode hook in SceneLoader#installTilemapLayerSync —
|
|
206
|
+
* same logic, different trigger source (overlay vs world scene event).
|
|
207
|
+
* Cheap: handful of number assignments per tilemap.
|
|
208
|
+
*/
|
|
209
|
+
private syncTilemapLayersFromContainers;
|
|
210
|
+
/**
|
|
211
|
+
* Read the selected tilemap entity's bounds + return the 8 handle
|
|
212
|
+
* positions in world coords. Returns null when the selected entity
|
|
213
|
+
* is not a tilemap (no handles to draw / hit-test).
|
|
214
|
+
*/
|
|
215
|
+
private tilemapHandlePositions;
|
|
216
|
+
/**
|
|
217
|
+
* Hit-test the resize handles. Corners (NW/NE/SW/SE) use a dedicated
|
|
218
|
+
* ~14px square click target. Edges (N/S/E/W) are grabbable along the
|
|
219
|
+
* ENTIRE edge line (Figma / Sketch convention) — clicking anywhere on
|
|
220
|
+
* the blue bounds line resizes that edge. Corner zones take priority
|
|
221
|
+
* over edges so dragging right at a corner gives diagonal resize, not
|
|
222
|
+
* single-axis.
|
|
223
|
+
*
|
|
224
|
+
* All click targets are zoom-invariant via `1/zoom` scaling so they
|
|
225
|
+
* stay constant size on screen regardless of how zoomed in/out.
|
|
226
|
+
*/
|
|
227
|
+
private hitTestTilemapResizeHandle;
|
|
228
|
+
/**
|
|
229
|
+
* Set canvas cursor to a resize-arrow when hovering a handle, or restore
|
|
230
|
+
* default. Direction matches the handle's axis (Figma / Sketch / browser
|
|
231
|
+
* native convention):
|
|
232
|
+
* NW/SE corners → `nwse-resize` (↖↘)
|
|
233
|
+
* NE/SW corners → `nesw-resize` (↗↙)
|
|
234
|
+
* N/S edges → `ns-resize` (↕)
|
|
235
|
+
* E/W edges → `ew-resize` (↔)
|
|
236
|
+
*
|
|
237
|
+
* Active drag (getTilemapResize non-null) pins the cursor to the dragged
|
|
238
|
+
* handle so it doesn't flicker back to default when the cursor briefly
|
|
239
|
+
* leaves the handle's 14px target box during fast drag.
|
|
240
|
+
*/
|
|
241
|
+
private updateResizeCursor;
|
|
242
|
+
/**
|
|
243
|
+
* Begin a resize-handle drag. Snapshots the starting size + center so
|
|
244
|
+
* pointermove can compute deltas relative to drag-start.
|
|
245
|
+
*/
|
|
246
|
+
private beginTilemapResizeDrag;
|
|
247
|
+
/**
|
|
248
|
+
* Update preview dims based on cursor position. Snaps to integer cells.
|
|
249
|
+
* The handle dictates which edges move — opposite edges stay fixed.
|
|
250
|
+
*
|
|
251
|
+
* Algorithm: from the cursor position + handle, compute the new L/R/T/B
|
|
252
|
+
* edges; opposite edges are pinned to start values. New size = R-L, B-T
|
|
253
|
+
* in pixels → divide by tileSize for cell counts. New center = midpoint
|
|
254
|
+
* of new L/R/T/B.
|
|
255
|
+
*/
|
|
256
|
+
private updateTilemapResizeDrag;
|
|
257
|
+
/**
|
|
258
|
+
* Commit the resize drag — post a `resize` op via `editTilemap` channel,
|
|
259
|
+
* carrying the new dims + transformDelta to keep the opposite edge
|
|
260
|
+
* anchored. Posted directly to host (skipping the local SDK apply path)
|
|
261
|
+
* because the host's draft + iframe runtime BOTH need the op — host
|
|
262
|
+
* records the command for undo + applies the same op back via the
|
|
263
|
+
* normal editTilemap dispatch (which mutates the live runtime).
|
|
264
|
+
*/
|
|
265
|
+
private commitTilemapResize;
|
|
266
|
+
update(): void;
|
|
267
|
+
/**
|
|
268
|
+
* Render the 8 resize handles (when paint mode is active) and the
|
|
269
|
+
* orange ghost-rect preview (when a resize drag is in progress).
|
|
270
|
+
* Handles are zoom-invariant ~12px squares; preview rect snaps to
|
|
271
|
+
* cell boundaries via the resize-drag's running preview state.
|
|
272
|
+
*/
|
|
273
|
+
private drawTilemapResizeOverlay;
|
|
274
|
+
/**
|
|
275
|
+
* Walks the world entity registry and draws each sprite's `hitbox` rect +
|
|
276
|
+
* `depthAnchor` crosshair (when present on the entity's Asset). Sprites
|
|
277
|
+
* without metadata get nothing drawn — chat-only Workflow A respect.
|
|
278
|
+
*
|
|
279
|
+
* Per-frame mode: reads the sprite's CURRENT frame index and looks up the
|
|
280
|
+
* override (falls back to default) so the rendered rect tracks what the
|
|
281
|
+
* SDK is actually applying to the body at runtime.
|
|
282
|
+
*/
|
|
283
|
+
private drawHitboxDebug;
|
|
284
|
+
/**
|
|
285
|
+
* For per-frame hitboxes, pick the shape the SDK would currently be
|
|
286
|
+
* applying — the override for the playing frame, falling back to default.
|
|
287
|
+
* For single-shape hitboxes, just return the rect.
|
|
288
|
+
*/
|
|
289
|
+
private resolveCurrentHitboxShape;
|
|
290
|
+
private findWorldSceneInstance;
|
|
291
|
+
/**
|
|
292
|
+
* Find the world scene's main camera so the overlay can mirror it.
|
|
293
|
+
* In edit mode, the world scene is paused but its camera state is what
|
|
294
|
+
* the overlay's pointer math should use.
|
|
295
|
+
*/
|
|
296
|
+
private findWorldSceneCamera;
|
|
297
|
+
/**
|
|
298
|
+
* P1 infinite canvas — read the editor camera installed by
|
|
299
|
+
* `installEditorCameras` in EditorBridge. Returns null on the boot race
|
|
300
|
+
* when the overlay scene's `create` runs before the bridge attaches it
|
|
301
|
+
* (resolved by the next `applyEditorPanZoom` mirror).
|
|
302
|
+
*/
|
|
303
|
+
private findEditorCamera;
|
|
304
|
+
/**
|
|
305
|
+
* The camera the editor is currently viewing through. Prefers the
|
|
306
|
+
* editor cam; falls back to the game's cameras.main if the editor cam
|
|
307
|
+
* hasn't been installed yet (boot race). All pan/zoom math + selection
|
|
308
|
+
* rects should use this, NOT cameras.main directly.
|
|
309
|
+
*/
|
|
310
|
+
private findActiveEditorCamera;
|
|
311
|
+
/**
|
|
312
|
+
* P1 infinite canvas — install native DOM listeners for wheel + space
|
|
313
|
+
* tracking. Phaser's pointer events don't surface `wheel`, and we want
|
|
314
|
+
* Space to be a global modifier (held while moving cursor), not tied to
|
|
315
|
+
* a specific GameObject. Listeners are torn down on scene shutdown.
|
|
316
|
+
*
|
|
317
|
+
* World mode only: HUD has identity camera + anchor-positioned widgets,
|
|
318
|
+
* panning/zooming it would rip widgets off their anchors.
|
|
319
|
+
*/
|
|
320
|
+
private installPanZoomInput;
|
|
321
|
+
/**
|
|
322
|
+
* Be polite to text input — don't intercept Space when the user is
|
|
323
|
+
* typing into a form control inside the iframe (shouldn't normally
|
|
324
|
+
* happen, but be defensive).
|
|
325
|
+
*/
|
|
326
|
+
private isTypingTarget;
|
|
327
|
+
/**
|
|
328
|
+
* Mode-aware registry lookup. World mode skips the HUD scene; HUD mode
|
|
329
|
+
* picks the HUD scene specifically.
|
|
330
|
+
*/
|
|
331
|
+
private findEntityRegistry;
|
|
332
|
+
}
|
|
333
|
+
export {};
|