import { readFileSync } from "node:fs"; import { fileURLToPath } from "node:url"; const source = JSON.parse(readFileSync(fileURLToPath(new URL("../shared/arena-stages.json", import.meta.url)), "utf8")); function normalizeStage(stage) { return Object.freeze({ ...stage, assets: Object.freeze([ { id: "visual", url: `${stage.assetBaseUrl}/visual.glb` }, { id: "collision", url: `${stage.assetBaseUrl}/collision.glb` }, { id: "navigation", url: `${stage.assetBaseUrl}/navigation.glb` }, ]), }); } export const ARENA_STAGES = Object.freeze(source.stages.map(normalizeStage)); export const VALIDATED_ARENA_STAGES = Object.freeze(ARENA_STAGES.filter((stage) => ( stage.validation.traversal && stage.validation.collision && stage.validation.spawnSafety && stage.validation.lineOfSight && stage.validation.performance ))); export function arenaStageById(stageId) { return ARENA_STAGES.find((stage) => stage.id === stageId) ?? null; } export function chooseArenaStage({ random = Math.random, previousStageId = null, allowUnvalidated = false } = {}) { const pool = allowUnvalidated ? ARENA_STAGES : VALIDATED_ARENA_STAGES; if (!pool.length) throw new Error("No validated arena stages are available."); const alternatives = pool.length > 1 ? pool.filter((stage) => stage.id !== previousStageId) : pool; return alternatives[Math.floor(random() * alternatives.length)]; }