@umicat/phaser-sdk 1.0.2 → 1.0.3
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/dist/editor/EditorBridge.js +49 -0
- package/package.json +1 -1
|
@@ -43,6 +43,16 @@ export function setupEditorBridge(game) {
|
|
|
43
43
|
return;
|
|
44
44
|
handleMessage(game, data);
|
|
45
45
|
});
|
|
46
|
+
// Boot-time edit flag (2026-06-11). When the host remounts the iframe
|
|
47
|
+
// while edit mode is on (post-save / post-agent-turn rebuild), it appends
|
|
48
|
+
// `umicatEdit=1` to the iframe URL. Enter edit IMMEDIATELY at game
|
|
49
|
+
// construction so scenes pause before their first update. Without this
|
|
50
|
+
// the game visibly plays for a second or two after every rebuild: the
|
|
51
|
+
// host's `enter` postMessage can't arrive any earlier because main.ts
|
|
52
|
+
// awaits font fetches before createUmicatGame installs this listener.
|
|
53
|
+
if (typeof window !== 'undefined' && /[?&]umicatEdit=1/.test(window.location.search)) {
|
|
54
|
+
enterEdit(game);
|
|
55
|
+
}
|
|
46
56
|
}
|
|
47
57
|
function handleMessage(game, msg) {
|
|
48
58
|
switch (msg.type) {
|
|
@@ -134,6 +144,15 @@ function enterEdit(game) {
|
|
|
134
144
|
restoreCanvasAfterEditor(game);
|
|
135
145
|
setEditorActive(game, true);
|
|
136
146
|
pauseActiveNonEditor(game);
|
|
147
|
+
// Continuous pause enforcement (2026-06-11) — the bounded 3s re-attempt
|
|
148
|
+
// loop below misses scenes that finish booting later than 3s after
|
|
149
|
+
// enter (slow CDN fetch of scene assets, etc.), and even within the
|
|
150
|
+
// window a scene can run for up to 100ms before the next tick pauses
|
|
151
|
+
// it. A PRE_STEP hook pauses any newly-active non-editor scene BEFORE
|
|
152
|
+
// its first update, for as long as edit mode is on. pauseActiveNonEditor
|
|
153
|
+
// skips already-paused scenes, so the per-frame cost is a short loop
|
|
154
|
+
// over the scene list.
|
|
155
|
+
installPauseEnforcement(game);
|
|
137
156
|
// P1 infinite canvas — expand the Phaser canvas to fill its container
|
|
138
157
|
// (host's iframe). Without this, the editor surface stays locked to
|
|
139
158
|
// the game's intrinsic aspect ratio (720×1280 portrait, etc.) with
|
|
@@ -199,6 +218,33 @@ function enterEdit(game) {
|
|
|
199
218
|
};
|
|
200
219
|
setTimeout(reattempt, 100);
|
|
201
220
|
}
|
|
221
|
+
const PAUSE_ENFORCER_FLAG = '__umicatEditorPauseEnforcer';
|
|
222
|
+
/**
|
|
223
|
+
* While edit mode is active, pause any non-editor scene before each game
|
|
224
|
+
* step. Catches scenes that boot AFTER enterEdit (iframe rebuild path) no
|
|
225
|
+
* matter how late — the game never visibly plays under the editor.
|
|
226
|
+
* Self-disarms via the active check; uninstalled on exitEdit.
|
|
227
|
+
*/
|
|
228
|
+
function installPauseEnforcement(game) {
|
|
229
|
+
const bag = game;
|
|
230
|
+
if (bag[PAUSE_ENFORCER_FLAG])
|
|
231
|
+
return;
|
|
232
|
+
const handler = () => {
|
|
233
|
+
if (!getEditorState(game).active)
|
|
234
|
+
return;
|
|
235
|
+
pauseActiveNonEditor(game);
|
|
236
|
+
};
|
|
237
|
+
game.events.on(Phaser.Core.Events.PRE_STEP, handler);
|
|
238
|
+
bag[PAUSE_ENFORCER_FLAG] = handler;
|
|
239
|
+
}
|
|
240
|
+
function uninstallPauseEnforcement(game) {
|
|
241
|
+
const bag = game;
|
|
242
|
+
const handler = bag[PAUSE_ENFORCER_FLAG];
|
|
243
|
+
if (!handler)
|
|
244
|
+
return;
|
|
245
|
+
game.events.off(Phaser.Core.Events.PRE_STEP, handler);
|
|
246
|
+
delete bag[PAUSE_ENFORCER_FLAG];
|
|
247
|
+
}
|
|
202
248
|
function pauseActiveNonEditor(game) {
|
|
203
249
|
// P1 infinite canvas (2026-05-17) — use `setActive(false)` instead of
|
|
204
250
|
// `pause()` so scenes STOP updating (game logic frozen) but KEEP
|
|
@@ -250,6 +296,9 @@ function exitEdit(game) {
|
|
|
250
296
|
if (!getEditorState(game).active)
|
|
251
297
|
return;
|
|
252
298
|
setEditorActive(game, false);
|
|
299
|
+
// Active is false now so the enforcer self-disables, but remove the
|
|
300
|
+
// hook too — no point paying the per-frame check during play.
|
|
301
|
+
uninstallPauseEnforcement(game);
|
|
253
302
|
setSelection(game, null);
|
|
254
303
|
// Allow next enter to re-post the snapshot (scene file may have changed).
|
|
255
304
|
delete game[SNAPSHOT_POSTED_FLAG];
|