diff --git a/src/utils/map/loadMapSceneData.ts b/src/utils/map/loadMapSceneData.ts index ed5446c..8f334eb 100644 --- a/src/utils/map/loadMapSceneData.ts +++ b/src/utils/map/loadMapSceneData.ts @@ -4,6 +4,7 @@ import { parseMapNodes } from "@/utils/map/mapNodeValidation"; const MAP_JSON_PATH = "/map.json"; const MODEL_FILE_NAMES = ["model.glb", "model.gltf"]; const HTML_CONTENT_TYPE = "text/html"; +const MAP_STRUCTURE_NODE_NAMES = new Set(["Scene", "blocking"]); type ModelEntry = [modelName: string, modelUrl: string]; export async function loadMapSceneData(): Promise { @@ -26,7 +27,13 @@ async function createSceneData(mapNodes: MapNode[]): Promise { async function loadMapModelUrls( mapNodes: MapNode[], ): Promise> { - const uniqueModelNames = [...new Set(mapNodes.map((node) => node.name))]; + const uniqueModelNames = [ + ...new Set( + mapNodes + .filter((node) => !MAP_STRUCTURE_NODE_NAMES.has(node.name)) + .map((node) => node.name), + ), + ]; const modelEntries = await Promise.all( uniqueModelNames.map((modelName) => loadModelEntry(modelName)), ); diff --git a/src/world/GameMap.tsx b/src/world/GameMap.tsx index bef9062..dba6662 100644 --- a/src/world/GameMap.tsx +++ b/src/world/GameMap.tsx @@ -22,6 +22,16 @@ interface LoadedMapNode { modelUrl: string | null; } +const MAP_STRUCTURE_NODE_NAMES = new Set(["Scene", "blocking"]); +const LITE_MAP_SKIPPED_NODE_NAMES = new Set([ + "arbre", + "buissons", + "champdeble", + "champdesoja", + "champsdetournesol", + "sapin", +]); + interface ErrorBoundaryProps { children: ReactNode; fallback: ReactNode; @@ -133,7 +143,17 @@ export function GameMap({ status: "loading", }); - const loadedMapNodes = sceneData.mapNodes.map((node) => { + const visibleMapNodes = sceneData.mapNodes.filter(liteMap); + const skippedMapNodeCount = + sceneData.mapNodes.length - visibleMapNodes.length; + + if (skippedMapNodeCount > 0) { + logger.warn("GameMap", "Lite map skipped heavy map nodes", { + skippedMapNodeCount, + }); + } + + const loadedMapNodes = visibleMapNodes.map((node) => { const modelUrl = sceneData.models.get(node.name); return { node, modelUrl: modelUrl ?? null }; }); @@ -214,6 +234,26 @@ export function GameMap({ ); } +/** + * Temporary development-only map reducer. + * + * TODO: replace this with a real map performance pass: merged static geometry, + * instancing for repeated props, LOD, and/or zone-based loading. For now this + * keeps the app usable on local machines by not rendering the densest exported + * nodes from map.json. + */ +function liteMap(node: MapNode): boolean { + if (MAP_STRUCTURE_NODE_NAMES.has(node.name)) { + return false; + } + + if (node.type === "Mesh") { + return false; + } + + return !LITE_MAP_SKIPPED_NODE_NAMES.has(node.name); +} + function MapNodeInstance({ node, modelUrl,