From d31f31dd628366d0ba94ab7fcd84487069f1d0b7 Mon Sep 17 00:00:00 2001 From: Claude Code Date: Thu, 26 Mar 2026 02:22:25 -0700 Subject: [PATCH] =?UTF-8?q?refactor(engine-ts):=20=E2=99=BB=EF=B8=8F=20Upd?= =?UTF-8?q?ate=20physics=20engine=20models=20and=20refactor=20runner=20log?= =?UTF-8?q?ic=20for=20new=20algorithms=20and=20optimizations?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Lilith Autocommit --- .../engine-ts/src/ClimatePhysics.generated.ts | 17 +++++++++++++++-- .../engine-ts/src/EcologyPhysics.generated.ts | 9 ++------- .../engine-ts/src/MapGenerator.generated.ts | 15 --------------- packages/engine-ts/src/runner.ts | 3 +++ packages/engine-ts/src/types.ts | 1 + 5 files changed, 21 insertions(+), 24 deletions(-) diff --git a/packages/engine-ts/src/ClimatePhysics.generated.ts b/packages/engine-ts/src/ClimatePhysics.generated.ts index 54848e43..69c77a8f 100644 --- a/packages/engine-ts/src/ClimatePhysics.generated.ts +++ b/packages/engine-ts/src/ClimatePhysics.generated.ts @@ -27,7 +27,7 @@ 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_min: 0.05, solar_max: 0.70, } @@ -245,6 +245,19 @@ export class ClimatePhysics { const aerosol_cfg = ((this.spec['aerosol'] ?? {}) as Record) if (Object.keys(aerosol_cfg).length === 0) return const { tiles, width: w, height: h } = grid + + // Phase 0: Natural aerosol sources — background, desert dust, volcanic outgassing + const bg = this.p('aerosol_background', 0.002) + const dustRate = this.p('aerosol_desert_dust', 0.005) + const volcanicRate = this.p('aerosol_volcanic_outgas', 0.015) + for (let i = 0; i < tiles.length; i++) { + const tile = tiles[i] + let inject = bg + if (tile.biome_id === 'desert') inject += dustRate + else if (tile.biome_id === 'volcano') inject += volcanicRate + ;(tile as any).sulfate_aerosol = Math.max(0.0, ((tile as any).sulfate_aerosol ?? 0) + inject) + } + let any_aerosol = false for (let i = 0; i < tiles.length; i++) { if (((tiles[i] as any).sulfate_aerosol ?? 0) > 0.001) { any_aerosol = true; break } @@ -310,7 +323,7 @@ export class ClimatePhysics { for (let i = 0; i < tiles.length; i++) { const tile = tiles[i] const { col, row } = tile - let solar = solarByRow(row, h, this.p('solar_min', 0.15), this.p('solar_max', 0.70)) + let solar = solarByRow(row, h, this.p('solar_min', 0.05), this.p('solar_max', 0.70)) let current_temp = oldTemp[i] let terrain_data = (this.terrainCache.get(tile.biome_id) ?? {}) diff --git a/packages/engine-ts/src/EcologyPhysics.generated.ts b/packages/engine-ts/src/EcologyPhysics.generated.ts index 8d70e245..a5057ad7 100644 --- a/packages/engine-ts/src/EcologyPhysics.generated.ts +++ b/packages/engine-ts/src/EcologyPhysics.generated.ts @@ -390,19 +390,14 @@ function updateHabitatSuitability( function updateFishStock(tiles: TileState[], w: number, h: number): void { for (let i = 0; i < tiles.length; i++) { const tile = tiles[i] - if (!isWater(tile)) continue + if (!isWater(tile) || (tile.fish_stock ?? 0) <= 0) continue let tempMult = 0.5 // polar if (tile.temperature > 0.55) tempMult = 1.0 // tropical else if (tile.temperature > 0.25) tempMult = 0.8 // temperate let cap = 100.0 if (tile.reef_health > 0.5) cap *= 1.5 else if (tile.reef_health < 0.1) cap *= 0.5 - let stock = tile.fish_stock ?? 0 - // Seed fish on water tiles that have none yet (spontaneous colonization) - if (stock <= 0) { - stock = Math.round(cap * 0.1 * tempMult) // start at 10% of capacity - if (stock <= 0) stock = 1 - } + const stock = tile.fish_stock ?? 0 const growth = 0.05 * tempMult * stock * (1.0 - stock / cap) tile.fish_stock = Math.max(0, Math.min(Math.round(stock + growth), cap)) } diff --git a/packages/engine-ts/src/MapGenerator.generated.ts b/packages/engine-ts/src/MapGenerator.generated.ts index 79dd9f6a..9c5bda93 100644 --- a/packages/engine-ts/src/MapGenerator.generated.ts +++ b/packages/engine-ts/src/MapGenerator.generated.ts @@ -264,21 +264,6 @@ class GenMap { wonder_anchor_schools: [], wonder_tier: 0, river_source_type: gt?.river_source_type || undefined, - // Ecology fields (initialized to zero, populated by EcologyPhysics) - canopy_cover: 0.0, - undergrowth: 0.0, - fungi_network: 0.0, - drought_counter: 0, - succession_progress: 0, - regrowth_stage: -1, - regrowth_turns: 0, - habitat_suitability: 0.0, - habitat_low_turns: 0, - landmark_name: '', - substrate_id: '', - water_body_id: -1, - depth_from_coast: -1, - fish_stock: 0, } } } diff --git a/packages/engine-ts/src/runner.ts b/packages/engine-ts/src/runner.ts index 821d3e47..a0e613b9 100644 --- a/packages/engine-ts/src/runner.ts +++ b/packages/engine-ts/src/runner.ts @@ -188,6 +188,7 @@ export function computeTurnStats( let waterCount = 0 let aerosolSum = 0 let etSum = 0 + let windSpeedSum = 0 let landCount = 0 const terrain_counts: Record = {} const substrate_counts: Record = {} @@ -210,6 +211,7 @@ export function computeTurnStats( solarSum += solar * (1.0 - albedo) aerosolSum += (tile as Record).sulfate_aerosol ?? 0 + windSpeedSum += tile.wind_speed ?? 0 if (isWater) { waterCount++ @@ -253,6 +255,7 @@ export function computeTurnStats( avg_land_quality: landCount > 0 ? landQualitySum / landCount : 1, avg_water_quality: waterCount > 0 ? waterQualitySum / waterCount : 1, avg_aerosol: aerosolSum / n, + avg_wind_speed: windSpeedSum / n, avg_evapotranspiration: landCount > 0 ? etSum / landCount : 0, net_energy: prevStats ? (landCount > 0 ? tempSum / landCount : 0.5) - prevStats.avg_temp : 0, net_hydro: prevStats ? (landCount > 0 ? moistSum / landCount : 0.5) - prevStats.avg_moisture : 0, diff --git a/packages/engine-ts/src/types.ts b/packages/engine-ts/src/types.ts index eac0168d..7e88e018 100644 --- a/packages/engine-ts/src/types.ts +++ b/packages/engine-ts/src/types.ts @@ -76,6 +76,7 @@ export interface TurnStats { avg_land_quality: number // average quality across land tiles (1-5) avg_water_quality: number // average quality across water tiles (1-5) avg_aerosol: number // global average sulfate aerosol opacity + avg_wind_speed: number // global average wind speed (0=calm, 1=gale) avg_evapotranspiration: number // average ET contribution across land tiles net_energy: number // net energy balance: solar_in - radiative_loss (positive=warming, negative=cooling) net_hydro: number // net water balance: evap+ET - decay-loss (positive=wetting, negative=drying)