orbit/dev/save-shot.mjs

103 lines
3.6 KiB
JavaScript

/**
* Dev-only: boot GameScene, pre-fill a few save slots, open the save
* pop-up and park it for screenshots.
*
* node dev/server.mjs 8091
* node dev/cdp-shot.mjs \
* "http://127.0.0.1:8091/dev/save-shot.html" \
* "/tmp/save-panel.png" \
* "window.__SAVE_SHOT && window.__SAVE_SHOT.ready" \
* 60000
*
* Follow-up stages (confirm dialogs, load mode) are driven by evaluating
* `window.__SAVE_SHOT.*` helpers via CDP before the capture.
*/
import Phaser from '../js/vendor/phaser.js';
import { ConfigLoader } from '../js/config/ConfigLoader.js';
import { config } from '../js/config/Config.js';
import { createGameConfig } from '../js/config/GameConfig.js';
import { GameScene } from '../js/scenes/GameScene.js';
const data = await ConfigLoader.load();
config.init(data);
globalThis.__ORBIT_DEV_SEED = 'SAVESHOT';
const errors = [];
const origErr = console.error.bind(console);
console.error = (...a) => { errors.push(a.map(String).join(' ').slice(0, 300)); origErr(...a); };
window.addEventListener('error', (e) => errors.push('window: ' + e.message));
window.addEventListener('unhandledrejection', (e) => errors.push('rejection: ' + e.reason));
const gameConfig = createGameConfig();
gameConfig.scene = [GameScene];
if (typeof Phaser !== 'undefined') Phaser.NoAudioContext = true;
const game = new Phaser.Game(gameConfig);
window.game = game;
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
window.__SAVE_SHOT = { ready: false, stage: 'boot', errors };
async function waitScene() {
const t0 = Date.now();
while (Date.now() - t0 < 120000) {
const s = game.scene.getScene('GameScene');
if (s && s.ship && s.mineralHud && s.savePanel) return s;
await sleep(100);
}
throw new Error('GameScene never booted');
}
game.events.once('ready', async () => {
try {
const s = await waitScene();
await sleep(600);
// Pre-fill a few slots with REAL saves (distinct times + systems).
s.ship.addMinerals(23);
s.savePanel.doSave(1);
await sleep(150);
s.ship.addMinerals(4);
s.savePanel.doSave(3);
await sleep(150);
s.ship.addMinerals(9);
s.savePanel.doSave(5);
await sleep(150);
// Open the pop-up in SAVE mode and park it.
s.savePanel.show('save');
await sleep(1400); // crack open + decodes + footer settle
window.__SAVE_SHOT.ready = true;
window.__SAVE_SHOT.stage = 'panel-save';
window.__SAVE_SHOT.errors = errors;
// Helpers for the capture runner (all return Promises).
window.__SAVE_SHOT.openOverwriteConfirm = async (slot = 1) => {
const sc = game.scene.getScene('GameScene');
sc.savePanel.confirmOverwrite(slot, sc.saveManager.get(slot));
await sleep(900);
return { stage: 'confirm-overwrite', ready: true, errors };
};
window.__SAVE_SHOT.openLoadConfirm = async (slot = 1) => {
const sc = game.scene.getScene('GameScene');
sc.savePanel.close();
await sleep(400);
sc.savePanel.show('load');
await sleep(900);
sc.savePanel.confirmLoad(slot, sc.saveManager.get(slot));
await sleep(900);
return { stage: 'confirm-load', ready: true, errors };
};
window.__SAVE_SHOT.switchLoad = async () => {
const sc = game.scene.getScene('GameScene');
sc.savePanel.close();
await sleep(400);
sc.savePanel.show('load');
await sleep(1400);
return { stage: 'panel-load', ready: true, errors };
};
} catch (err) {
errors.push('FATAL: ' + err.message);
window.__SAVE_SHOT.ready = true;
window.__SAVE_SHOT.fatal = String(err.message);
window.__SAVE_SHOT.errors = errors;
}
});