139 lines
5.9 KiB
JavaScript
139 lines
5.9 KiB
JavaScript
/**
|
|
* Dev-only: boot GameScene, open the MAP console on the GALAXY tab and
|
|
* verify the legend key + the tooltip's FACTION line:
|
|
* - win.gLeg built: the lane row (used/frontier/unexplored + region) and
|
|
* the FACTIONS row drawn from data/factions.json (+ the capital seat)
|
|
* - the slot's label ownership flips with the tab (gLegTexts up on
|
|
* GALAXY, legendTexts up back on CURRENT SYSTEM)
|
|
* - hovering a star names its standing: "<FACTION> TERRITORY" /
|
|
* "<FACTION> CAPITAL" / "WILD SPACE" in the faction's color
|
|
* - console errors
|
|
*
|
|
* node dev/server.mjs 8083 # static server
|
|
* node dev/shot-firefox.mjs \
|
|
* "http://127.0.0.1:8083/dev/galaxy-legend-shot.html" \
|
|
* "window.__GAL_SHOT ? window.__GAL_SHOT.ready : null" \
|
|
* GAL_LEGEND_SHOT.png 40000
|
|
*/
|
|
import Phaser from '../js/vendor/phaser.js';
|
|
import { config } from '../js/config/Config.js';
|
|
import { ConfigLoader } from '../js/config/ConfigLoader.js';
|
|
import { createGameConfig } from '../js/config/GameConfig.js';
|
|
import { GameScene } from '../js/scenes/GameScene.js';
|
|
|
|
const data = await ConfigLoader.load();
|
|
config.init(data);
|
|
|
|
// Capture console errors + uncaught exceptions for the report.
|
|
const errors = [];
|
|
const origErr = console.error.bind(console);
|
|
console.error = (...a) => { errors.push(a.map(String).join(' ')); origErr(...a); };
|
|
window.addEventListener('error', (e) => errors.push(String(e.message)));
|
|
window.addEventListener('unhandledrejection', (e) => errors.push(`rejection: ${e.reason}`));
|
|
|
|
const gameConfig = createGameConfig();
|
|
gameConfig.scene = [GameScene];
|
|
const game = new Phaser.Game(gameConfig);
|
|
window.game = game;
|
|
|
|
// The report lives OUTSIDE the canvas — a DOM <pre> the screenshot can
|
|
// always read (headless canvases don't have to cooperate).
|
|
const report = document.createElement('pre');
|
|
report.id = 'report';
|
|
report.style.cssText = 'position:fixed;left:10px;top:10px;z-index:9999;max-width:70%;margin:0;padding:8px 12px;font:13px/1.5 monospace;color:#eaf6ff;background:rgba(6,20,16,0.92);border:1px solid #1b3a5a;white-space:pre-wrap;';
|
|
document.body.appendChild(report);
|
|
const setReport = (lines) => { report.textContent = (Array.isArray(lines) ? lines : [lines]).join('\n'); };
|
|
setReport('booting…');
|
|
|
|
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
|
|
async function waitScene() {
|
|
for (let i = 0; i < 100; i++) {
|
|
const s = game.scene.getScene('GameScene');
|
|
if (s && s.ship && s.mapWindow) return s;
|
|
await sleep(100);
|
|
}
|
|
throw new Error('GameScene never booted');
|
|
}
|
|
|
|
try {
|
|
const s = await waitScene();
|
|
await sleep(800); // let the boot settle
|
|
|
|
// Open the console (the deck MAP button does exactly this).
|
|
s.deckAction('map');
|
|
await sleep(1400); // the boot reveal + first chart paint
|
|
|
|
const win = s.mapWindow;
|
|
|
|
// ── 1 — the legend key is built (from data/factions.json) ──────────
|
|
const L = win.gLeg;
|
|
const legendOk = !!(
|
|
L &&
|
|
L.lanes?.length === 3 &&
|
|
L.lanes.every((it) => it.x >= 0 && it.label) &&
|
|
L.region?.label === 'CHARTED' &&
|
|
L.facs?.length >= 1 &&
|
|
L.facs.every((f) => typeof f.color === 'number' && f.label) &&
|
|
L.capital?.label === 'CAPITAL'
|
|
);
|
|
const factions = config.get('factions.factions', {});
|
|
const factionNames = Object.values(factions).map((f) => f.label).join(' / ');
|
|
|
|
// ── 2 — switch to the GALAXY tab and let the first poll run ────────
|
|
const gal = win.tabs.find((t) => t.id === 'galaxy');
|
|
win._tabHit(gal);
|
|
win._pollNext = 0;
|
|
await sleep(2600); // the reveal ripple + the poll's stats/legend paint
|
|
const gv = win._galaxy;
|
|
const galMode = win._mode === 'galaxy';
|
|
const textsUp = gv ? win.gLegTexts.filter((t) => t.visible).length : -1;
|
|
const sysTextsHidden = win.legendTexts.filter((t) => !t.visible).length === win.legendTexts.length;
|
|
|
|
// ── 3 — hover a star: the tooltip must name its standing ───────────
|
|
let hoverLine = 'no stars built';
|
|
if (gv?.update) {
|
|
// a faction star first (the interesting case), a capital next, else
|
|
// any star (wild space)
|
|
const st =
|
|
gv._stars.find((x) => x.capital && x.capital !== 'neutral') ??
|
|
gv._stars.find((x) => x.capital) ??
|
|
gv._stars.find((x) => x.faction) ??
|
|
gv._stars[0];
|
|
if (st) {
|
|
gv._setHover({ x: st.lx, y: st.ly });
|
|
gv.update(s.time.now + 16); // one paint pass
|
|
await sleep(120);
|
|
const standing = gv._hover === st ? (gv.ttFaction.text || '—') : 'hover missed';
|
|
hoverLine = `hover ${st.id.toUpperCase()} → "${standing}"${st.capital ? ' [capital]' : st.faction ? ' [territory]' : ' [wild]'}`;
|
|
}
|
|
gv._setHover(null);
|
|
}
|
|
|
|
// ── 4 — back to CURRENT SYSTEM: the slot hands back to its key ──────
|
|
win._tabHit(win.tabs.find((t) => t.id === 'currentSystem'));
|
|
await sleep(300);
|
|
const backOk =
|
|
win._mode === 'currentSystem' &&
|
|
win.gLegTexts.every((t) => !t.visible) &&
|
|
win.legendTexts.every((t) => t.visible);
|
|
|
|
const lines = [
|
|
errors.length === 0 ? 'SMOKE OK — no console errors' : `ERRORS:\n${errors.slice(0, 4).join('\n')}`,
|
|
`mode after galaxy: ${win._mode} · galaxy view=${!!gv}`,
|
|
`legend: ${legendOk ? 'built ✓' : 'MISSING ✗'} · lanes=${L?.lanes?.length} · region="${L?.region?.label}" · facs=${L?.facs?.map((f) => f.label).join('/')} · capital="${L?.capital?.label}"`,
|
|
`factions.json: ${factionNames}`,
|
|
`galaxy slot labels: ${textsUp}/${win.gLegTexts.length} up · system labels hidden=${sysTextsHidden}`,
|
|
hoverLine,
|
|
`switch back: ${backOk ? 'slot restored ✓' : '✗'}`,
|
|
];
|
|
setReport(lines);
|
|
window.__GAL_SHOT = { ready: true, lines, errors };
|
|
console.info('galaxy-legend-shot: report painted');
|
|
} catch (err) {
|
|
errors.push(`FATAL: ${err.message}`);
|
|
setReport(['FATAL: ' + err.message, ...errors.slice(0, 4)]);
|
|
window.__GAL_SHOT = { ready: true, fatal: String(err.message), errors };
|
|
console.error('galaxy-legend-shot: fatal', err);
|
|
}
|