diff --git a/tools/transpile-engine/mapgen_assembly.py b/tools/transpile-engine/mapgen_assembly.py index b42c312a..c99aa028 100644 --- a/tools/transpile-engine/mapgen_assembly.py +++ b/tools/transpile-engine/mapgen_assembly.py @@ -87,7 +87,7 @@ const DEFAULT_TYPE_DATA: Record = { continent_count: { min: 2, max: 4 }, terrain_fractions: { enchanted_forest: 0.01, desert: 0.10, swamp: 0.07, - corrupted_land: 0.04, volcano: 0.02, + volcano: 0.02, }, generation_params: { num_landmass: 35, steepness: 0.20, prevailing_wind_direction: 0, @@ -279,7 +279,6 @@ class GenMap { quality_progress: gt?.quality_progress ?? 0, river_edges: gt?.river_edges ?? [], flow_accumulation: gt?.flow_accumulation ?? 0.0, - corruption_pressure: 0.0, original_terrain_id: '', ley_line_count: 0, ley_school: '', @@ -888,7 +887,7 @@ function assignTerrainPatches( const defaultFractions: Record = { forest: 0.12, jungle: 0.06, boreal_forest: 0.05, enchanted_forest: 0.01, desert: 0.10, swamp: 0.07, - corrupted_land: 0.04, volcano: 0.02, + volcano: 0.02, } const fractions = (typeData['terrain_fractions'] ?? defaultFractions) as Record @@ -899,7 +898,7 @@ function assignTerrainPatches( const order: string[] = [ 'volcano', 'jungle', 'forest', 'boreal_forest', 'enchanted_forest', - 'desert', 'swamp', 'corrupted_land', 'tundra', 'snow', 'grassland', + 'desert', 'swamp', 'tundra', 'snow', 'grassland', ] for (const terrainId of order) { @@ -1013,7 +1012,6 @@ function isEligible( case 'enchanted_forest': return m >= 0.40 case 'desert': return t >= 0.25 && m < 0.25 case 'swamp': return t > 0.25 && m > 0.75 && e < 0.48 - case 'corrupted_land': return true case 'tundra': return t >= 0.10 && t < 0.25 case 'snow': return t < 0.10 case 'grassland': return true diff --git a/tools/transpile-engine/transpile.py b/tools/transpile-engine/transpile.py index 113052a1..c3e45d01 100644 --- a/tools/transpile-engine/transpile.py +++ b/tools/transpile-engine/transpile.py @@ -90,6 +90,8 @@ CLIMATE_DEFAULTS: dict[str, float] = { "lake_thermal_conductivity": 0.05, "river_moisture_transport": 0.075, "mountain_rain_shadow_block": 0.9, + "solar_min": 0.15, + "solar_max": 0.70, } # --------------------------------------------------------------------------- @@ -142,6 +144,8 @@ const CLIMATE_DEFAULTS: Record = { lake_thermal_conductivity: 0.05, river_moisture_transport: 0.075, mountain_rain_shadow_block: 0.9, + solar_min: 0.15, + solar_max: 0.70, } const DEW_DEFAULTS: Record = { @@ -340,6 +344,7 @@ export class ClimatePhysics { processStep(grid: GridState, turn = 0, seed = 42): EcologicalEvent[] { this.ensureOceanDist(grid) this.stepCollectMagicForcing(grid) + this.stepOrbitalForcing(grid, turn) this.stepAerosolForcing(grid) this.stepTemperature(grid) this.stepLakeThermal(grid) @@ -355,6 +360,29 @@ export class ClimatePhysics { return events } + private stepOrbitalForcing(grid: GridState, turn: number): void { + const orbitalRaw = (this.params as Record)['orbital_cycles'] + if (!orbitalRaw) return + const orbital = orbitalRaw as Record + const cycles = (orbital['cycles'] ?? []) as Array> + if (cycles.length === 0) return + + let totalDelta = 0.0 + const t = turn + for (const cycle of cycles) { + const period = cycle['period'] ?? 200.0 + const amplitude = cycle['amplitude'] ?? 0.01 + const phase = cycle['phase'] ?? 0.0 + totalDelta += amplitude * Math.sin(2 * Math.PI * (t / period) + phase) + } + + if (Math.abs(totalDelta) < 0.0001) return + + for (const tile of grid.tiles) { + tile.magic_heat_delta += totalDelta + } + } + """ @@ -779,7 +807,14 @@ def assemble(fns: dict[str, dict[str, str]]) -> str: parts.append(_emit_anchor_decay()) parts.append("\n}\n") - return "".join(parts) + result = "".join(parts) + # Inject solar range params into solarByRow calls so the habitable + # temperature band is controlled by climate_params.json, not hardcoded. + result = result.replace( + "solarByRow(row, h)", + "solarByRow(row, h, this.p('solar_min', 0.15), this.p('solar_max', 0.70))", + ) + return result # ---------------------------------------------------------------------------