orbit/js/dev/NavDiag.js

132 lines
4.8 KiB
JavaScript

/**
* js/dev/NavDiag.js — in-game diagnostics for the SYSTEM category's NAV chart.
*
* Installed by js/main.js on every real page load (index.html). Read-only and
* defensive: it observes the live game and prints a report — it never mutates
* state.
*
* The jumpgate tech unlocks only when EVERY NAV point of the current system
* is discovered (js/research/SystemCategory.js — navChart). This tells you
* exactly which ones are still missing, so "I visited everything but the
* gates stay locked" resolves in one glance instead of by guesswork.
*
* Console commands (DevTools → Console, in the RUNNING game — the space view,
* not a planet surface):
*
* orbitNav() → full chart (also logged). Copy-paste the returned
* string when asking for help.
* orbitNavBrief() → one-line summary.
*
* If `orbitNav` is NOT DEFINED in your console, the browser served an OLDER
* js/main.js (stale module cache) — hard-reload with the cache bypassed
* (Ctrl+Shift+R, or DevTools → Network → Disable cache) and check again. The
* version marker below changes with each revision.
*/
import { config } from '../config/Config.js';
import { navChart } from '../research/SystemCategory.js';
export const NAV_DIAG_V = 1;
const KIND_LABEL = {
home: 'home world',
planet: 'planet',
station: 'space station',
gate: 'jump gate',
};
function sceneOf(key) {
try {
return globalThis.window?.game?.scene?.getScene(key) ?? null;
} catch {
return null;
}
}
/**
* The current system's live NAV chart, with readable names + type labels
* (resolved from the scene's discoverable set — the same names the compass
* and discovery toasts show).
*/
function chartOf(gs) {
const systemId = gs?.systemRecord?.id ?? null;
const system = gs?.systemRecord?.name ?? systemId ?? '?';
const chart = navChart(gs?.discovery, systemId, gs?.systemContent);
const names = new Map((gs?.discoverableObjects?.() ?? []).map((o) => [o.id, o]));
const points = chart.points.map((p) => {
const o = names.get(p.id);
const name = o?.name ?? (p.id === 'home' ? gs?.homeWorldName ?? p.id : p.id);
return { ...p, name, typeLabel: o?.typeLabel ?? KIND_LABEL[p.kind] ?? p.kind };
});
return { system, systemId, chart, points };
}
const ABSENT = `[orbit-nav v${NAV_DIAG_V}] GameScene absent — run this from the space view (not a planet surface)`;
/** One-line summary — the same facts a support request needs. */
export function brief() {
const gs = sceneOf('GameScene');
if (!gs) {
console.info(ABSENT);
return ABSENT;
}
const { system, systemId, chart, points } = chartOf(gs);
const missing = points.filter((p) => !p.discovered).map((p) => p.name);
const state = chart.complete
? 'COMPLETE → jumpgates RESEARCHABLE'
: 'INCOMPLETE → jumpgates LOCKED';
const line =
`[orbit-nav v${NAV_DIAG_V}] ` +
`system=${system}[${systemId ?? '?'}] ` +
`chart=${chart.discovered}/${chart.total} ${state} ` +
`missing=${JSON.stringify(missing)}`;
console.info(line);
return line;
}
/** Full report. Logs it, returns the string (copy-paste friendly). */
export function full() {
const gs = sceneOf('GameScene');
if (!gs) {
console.info(ABSENT);
return ABSENT;
}
const { system, systemId, chart, points } = chartOf(gs);
const dist = config.get('game.discovery.distance', 540);
const state = chart.complete
? 'COMPLETE — the jumpgate tech should be RESEARCHABLE'
: 'INCOMPLETE — the jumpgate tech is LOCKED';
const missing = points.filter((p) => !p.discovered);
const lines = [
`ORBIT NAV CHART v${NAV_DIAG_V}`,
`[system] ${system} [${systemId ?? '?'}]`,
`[chart] ${chart.discovered} of ${chart.total} NAV points discovered → ${state}`,
];
for (const p of points) {
lines.push(
` ${p.discovered ? '✓' : '✗'} ${p.kind.padEnd(7)} ${String(p.name).padEnd(22)} ` +
`(${p.typeLabel})${p.discovered ? '' : ' ← undiscovered'}`,
);
}
if (missing.length) {
lines.push(`[missing] ${missing.map((p) => p.name).join(', ')}`);
lines.push(
`[tip] fly within ${dist} px of each missing object to discover it — ` +
'jump gates and free-space stations are the ones easy to fly past',
);
} else {
lines.push(`[ok] every NAV point is discovered — research the jumpgate tech in the console`);
}
const text = lines.join('\n');
console.info(text);
return text;
}
/** Install the console commands. Idempotent. */
export function installNavDiag() {
if (typeof globalThis === 'undefined') return;
if (!globalThis.addEventListener) return;
globalThis.orbitNav = () => full();
globalThis.orbitNavBrief = () => brief();
console.info(`[orbit-nav v${NAV_DIAG_V}] installed — type orbitNav() in the console to see this system's NAV chart`);
}