refactor: clean map gameplay architecture

This commit is contained in:
tom-boullay
2026-05-28 11:15:45 +02:00
parent d9cf87d2d6
commit 1a91b1d7ae
69 changed files with 791 additions and 1112 deletions
+10
View File
@@ -0,0 +1,10 @@
const GENERATED_MAP_MODEL_NAMES = new Set([
"ecole",
"fermeverticale",
"generateur",
"lafabrik",
]);
export function isGeneratedMapModelName(name: string): boolean {
return GENERATED_MAP_MODEL_NAMES.has(name);
}
+36
View File
@@ -0,0 +1,36 @@
export const GRASS_CONFIG = {
enabled: true,
patchSize: 30,
bladeCount: 32000,
bladeWidth: 0.08,
maxBladeHeight: 0.56,
randomHeightAmount: 0.25,
surfaceOffset: 0.025,
heightTextureSize: 128,
windNoiseScale: 0.9,
windStrength: 0.35,
baldPatchModifier: 1.1,
falloffSharpness: 0.35,
heightNoiseFrequency: 9,
heightNoiseAmplitude: 1,
clumpFrequency: 2.6,
clumpThreshold: 0.18,
clumpSoftness: 0.45,
zoneFrequency: 0.035,
noGrassZoneThreshold: 0.2,
sparseZoneThreshold: 0.4,
mediumZoneThreshold: 0.65,
zoneSoftness: 0.08,
noGrassZoneHeight: 0,
sparseZoneHeight: 0.08,
mediumZoneHeight: 0.45,
tallZoneHeight: 1,
noGrassZoneDensity: 0,
sparseZoneDensity: 0.08,
mediumZoneDensity: 0.72,
tallZoneDensity: 1,
maxBendAngle: 14,
} as const;
export const GRASS_COLORS = ["#84C66B", "#67B058", "#A3CA5B"] as const;
export const GRASS_BASE_COLOR = "#1A3A1A" as const;
-10
View File
@@ -89,13 +89,3 @@ export type MapInstancingAssetType =
export type MapInstancingAssetConfig =
(typeof MAP_INSTANCING_ASSETS)[MapInstancingAssetType];
const MAP_INSTANCED_NODE_NAMES: ReadonlySet<string> = new Set(
Object.values(MAP_INSTANCING_ASSETS)
.filter((config) => config.enabled)
.map((config) => config.mapName),
);
export function isInstancedMapNodeName(name: string): boolean {
return MAP_INSTANCED_NODE_NAMES.has(name);
}
+97
View File
@@ -0,0 +1,97 @@
export type MapPerformanceGroupName =
| "vegetation"
| "crops"
| "trees"
| "buildings"
| "landmarks"
| "props"
| "terrain"
| "sky";
export type MapPerformanceModelName =
| "buisson"
| "arbre"
| "sapin"
| "champdeble"
| "champdesoja"
| "champsdetournesol"
| "ecole"
| "generateur"
| "fermeverticale"
| "lafabrik"
| "immeuble1"
| "eolienne"
| "pylone"
| "boiteauxlettres"
| "maison1"
| "panneauaffichage"
| "panneauclassique"
| "panneaufleche"
| "panneausolaire"
| "parcebike"
| "terrain"
| "sky";
export const MAP_PERFORMANCE_GROUP_NAMES: readonly MapPerformanceGroupName[] = [
"vegetation",
"crops",
"trees",
"buildings",
"landmarks",
"props",
"terrain",
"sky",
];
export const MAP_PERFORMANCE_MODEL_NAMES: readonly MapPerformanceModelName[] = [
"buisson",
"arbre",
"sapin",
"champdeble",
"champdesoja",
"champsdetournesol",
"ecole",
"generateur",
"fermeverticale",
"lafabrik",
"immeuble1",
"eolienne",
"pylone",
"boiteauxlettres",
"maison1",
"panneauaffichage",
"panneauclassique",
"panneaufleche",
"panneausolaire",
"parcebike",
"terrain",
"sky",
];
export const MAP_PERFORMANCE_MODEL_GROUPS: Record<
MapPerformanceModelName,
readonly MapPerformanceGroupName[]
> = {
buisson: ["vegetation"],
arbre: ["vegetation", "trees"],
sapin: ["vegetation", "trees"],
champdeble: ["vegetation", "crops"],
champdesoja: ["vegetation", "crops"],
champsdetournesol: ["vegetation", "crops"],
ecole: ["buildings", "landmarks"],
generateur: ["landmarks"],
fermeverticale: ["buildings", "landmarks"],
lafabrik: ["buildings", "landmarks"],
immeuble1: ["buildings"],
eolienne: ["props"],
pylone: ["props"],
boiteauxlettres: ["props"],
maison1: ["buildings"],
panneauaffichage: ["props"],
panneauclassique: ["props"],
panneaufleche: ["props"],
panneausolaire: ["props"],
parcebike: ["props"],
terrain: ["terrain"],
sky: ["sky"],
};
+12
View File
@@ -0,0 +1,12 @@
import { TERRAIN_COLORS, TERRAIN_TILE_SIZE } from "@/data/world/terrainConfig";
export const PATH_SURFACE_KEY = "chemin";
export const PATH_DEBUG_PREVIEW_ENABLED = false;
export const PATH_TILE_RENDER_ENABLED = false;
export const PATH_TILE_MODEL_PATH = TERRAIN_COLORS.chemin.modelPath;
export const PATH_TILE_SIZE =
TERRAIN_COLORS.chemin.tileSize ?? TERRAIN_TILE_SIZE;
export const PATH_TILE_SAMPLE_STEP = 2;
export const PATH_TILE_MAX_COUNT = 1500;
export const PATH_TILE_ROTATION = [0, 0, 0] as const;
export const PATH_TILE_SCALE = [1, 1, 1] as const;
+7
View File
@@ -0,0 +1,7 @@
import type { SceneLoadingState } from "@/types/world/sceneLoading";
export const INITIAL_SCENE_LOADING_STATE: SceneLoadingState = {
currentStep: "Initialisation du jeu",
progress: 0,
status: "loading",
};
+73
View File
@@ -0,0 +1,73 @@
export const VEGETATION_TYPES = {
buissons: {
mapName: "buisson",
modelPath: "/models/buisson/model.gltf",
scaleMultiplier: 1.5,
castShadow: true,
receiveShadow: true,
windStrength: 0.08,
enabled: true,
},
sapin: {
mapName: "sapin",
modelPath: "/models/sapin/model.gltf",
scaleMultiplier: 4,
castShadow: true,
receiveShadow: true,
windStrength: 0.04,
enabled: true,
},
arbre: {
mapName: "arbre",
modelPath: "/models/arbre/model.gltf",
scaleMultiplier: 1,
castShadow: true,
receiveShadow: true,
windStrength: 0.06,
enabled: true,
},
champdeble: {
mapName: "champdeble",
modelPath: "/models/champdeble/model.gltf",
scaleMultiplier: 1,
castShadow: true,
receiveShadow: true,
windStrength: 0.18,
enabled: true,
},
champdesoja: {
mapName: "champdesoja",
modelPath: "/models/champdesoja/model.gltf",
scaleMultiplier: 1,
castShadow: true,
receiveShadow: true,
windStrength: 0.16,
enabled: true,
},
champsdetournesol: {
mapName: "champsdetournesol",
modelPath: "/models/champsdetournesol/model.gltf",
scaleMultiplier: 1,
castShadow: true,
receiveShadow: true,
windStrength: 0.14,
enabled: true,
},
} as const;
export const VEGETATION_TYPE_KEYS = [
"buissons",
"sapin",
"arbre",
"champdeble",
"champdesoja",
"champsdetournesol",
] as const satisfies readonly (keyof typeof VEGETATION_TYPES)[];
export type VegetationType = (typeof VEGETATION_TYPE_KEYS)[number];
export const INSTANCED_MAP_EXCEPTIONS = new Set([
"Scene",
"blocking",
"terrain",
]);
-9
View File
@@ -13,12 +13,3 @@ export const WIND_BOUNDS = {
};
export type WindState = typeof WIND_DEFAULTS;
export function getWindVector(wind: WindState): { x: number; z: number } {
const intensity = wind.speed * wind.strength;
return {
x: Math.cos(wind.direction) * intensity,
z: Math.sin(wind.direction) * intensity,
};
}