45 lines
1.8 KiB
JavaScript
45 lines
1.8 KiB
JavaScript
/**
|
|
* Picking a system for the effects demo (?fx=<type>) — pure over the
|
|
* seeded roster, so dev/system-effects.test.mjs can exercise the
|
|
* ranking in bare Node.
|
|
*
|
|
* The demo wants to drop the player into a system of the requested
|
|
* archetype that is GOOD for judging the effect: plenty of structure to
|
|
* warp (worlds, a belt, a gate or two to jump out of). Candidates are
|
|
* therefore ranked richest-first — more objects, then more jump gates —
|
|
* with roster order as the stable tiebreak (seed-deterministic either
|
|
* way: the roster is seed-ordered and the score is a pure function of
|
|
* the record + its cached contents).
|
|
*/
|
|
|
|
/**
|
|
* @param {object} galaxy a seeded galaxy (Galaxy.js) — reads `.records`
|
|
* ({ id, type, ... }[]) and `.contentCache` (Map id -> contents,
|
|
* possibly empty — content is lazy).
|
|
* @param {string} type the requested archetype (systems.types key)
|
|
* @returns {object | null} the chosen record (has `.id`), or null when
|
|
* the roster holds no system of that type.
|
|
*/
|
|
export function pickFxSystem(galaxy, type) {
|
|
const records = Array.isArray(galaxy?.records) ? galaxy.records : [];
|
|
const cache = galaxy?.contentCache instanceof Map ? galaxy.contentCache : null;
|
|
|
|
let best = null;
|
|
let bestKey = null;
|
|
for (const rec of records) {
|
|
if (!rec || rec.type !== type) continue;
|
|
const content = cache?.get(rec.id) ?? null;
|
|
const objects =
|
|
(Array.isArray(content?.planets) ? content.planets.length : 0) +
|
|
(Array.isArray(content?.settlements) ? content.settlements.length : 0) +
|
|
(Array.isArray(content?.asteroids) ? content.asteroids.length : 0);
|
|
const gates = Array.isArray(content?.jumps) ? content.jumps.length : 0;
|
|
const key = objects * 1000 + gates;
|
|
if (!best || key > bestKey) {
|
|
best = rec;
|
|
bestKey = key;
|
|
}
|
|
}
|
|
return best;
|
|
}
|