import { config } from '../config/Config.js'; /** * Formats a generated system into a readable "dossier" for UI. * * Pure — no Phaser — so it's testable in Node and reusable anywhere a * system needs describing (the HUD today; the star map, tooltips, saves, * or a terminal UI later). Scenes stay thin: they render what this * returns. * * const report = formatSystemReport(content); * // { title, subtitle, settlements: [{ text, color, population }], * // summary, population } */ export function formatSystemReport(content, typeDefs = null, kindDefs = null) { const types = typeDefs ?? config.get('systems.types', {}); const kinds = kindDefs ?? config.get('settlements.kinds', {}); const typeDef = types[content.type] ?? {}; const planetName = (ordinal) => { const p = content.planets.find((pl) => pl.ordinal === ordinal); return p ? p.name : `planet ${ordinal}`; }; const settlements = []; for (const s of content.settlements ?? []) { const def = kinds[s.kind] ?? {}; const where = s.anchor?.type === 'planet' ? `on ${planetName(s.anchor.ordinal)}` : 'in open space'; settlements.push({ text: `${s.name} · ${def.label ?? s.kind} ${where}`, color: def.theme?.color ?? '#8fa0c9', population: s.population ?? 0, }); } const population = settlements.reduce((sum, s) => sum + s.population, 0); const n = settlements.length; const summary = n === 0 ? 'charted · unclaimed' : `${n} settlement${n === 1 ? '' : 's'} · pop ~${formatPop(population)}`; const planetN = content.planets.length; return { title: content.name, subtitle: `${typeDef.label ?? content.type} system · star ${content.star.class} · ${planetN} planet${planetN === 1 ? '' : 's'}`, settlements, summary, population, }; } /** 1234 → "1.2k", 9000000 → "9.0M" */ export function formatPop(n) { if (n >= 1e6) return `${(n / 1e6).toFixed(1)}M`; if (n >= 1e3) return `${(n / 1e3).toFixed(1)}k`; return String(n); }