# Climate Simulation System **Status**: Designed - Ready for Implementation **Scope**: Realistic climate patterns through mobile wind regions and convergence zones **Integration**: Uses existing TectonicRegions framework ## System Overview Revolutionary climate simulation using **mobile wind regions** that spawn, evolve, and interact to create emergent weather patterns. Solves the "Sahara vs Congo" problem through **Inter-Tropical Convergence Zones (ITCZ)** and **planetary rotation bands** without complex 3D atmospheric physics. ### Key Innovations - **Mobile WindRegions** with token-based distribution system - **ITCZ gravitational zones** based on continental mass - **Planetary rotation bands** for realistic circulation patterns - **Emergent storm evolution** from simple wind interactions - **Destruction token system** for persistent terrain effects ## Core Concepts ### WindRegion Mobile Entities ```json "wind_region": { "position": [x, y], "wind_strength": 1.0, // Base intensity (decays over time) "wetness": 0.0, // Moisture content (gained over ocean) "velocity": [vx, vy], // Movement vector "wind_tokens": 100, // Distributed to tiles "decay_per_move": 0.02, // -2% strength per movement "decay_per_tile": 0.01 // -1% strength per tile crossed } ``` ### ITCZ Convergence Zones ```json "itcz_zone": { "center": [x, y], "gravitational_range": "sqrt(landmass_area) * 50", "aspiration_strength": "landmass_mass / distance^2", "amplification_factor": 3.0, // Wind strength multiplier at center "latitude_requirement": [0.45, 0.55] // Equatorial band only } ``` ## Simulation Architecture ### Phase 1: Landmass Analysis and ITCZ Generation **Uses Existing TectonicRegions:** ```cpp // Analyze continental masses from existing tectonic data std::vector continents = groupTectonicRegions(); // Generate water masses by inverse analysis std::vector oceans = detectOceanBasins(continents); // Place ITCZ zones on qualifying equatorial landmasses for (auto& continent : continents) { if (continent.latitude >= 0.45 && continent.latitude <= 0.55 && continent.area > MIN_LANDMASS_SIZE) { createITCZ(continent.center, sqrt(continent.area)); } } ``` **ITCZ Requirements:** - **Latitude Band**: 45-55% of map height (equatorial) - **Minimum Landmass**: 10,000+ tiles - **Ocean Proximity**: Within 800km for moisture source - **Continental Heating**: Large thermal mass for convection ### Phase 2: WindRegion Spawning System **Procedural Spawn Rules:** ```json "wind_spawn_system": { "spawn_locations": "ocean_masses_only", "spawn_frequency": "water_mass_size / 1000", "initial_strength": "water_temperature * evaporation_factor", "region_size": "sqrt(water_mass_area) / 10", "tokens_per_region": "base_tokens * size_factor", "spawn_distribution": "random_within_water_region_biased_toward_center" } ``` **Note**: WindRegions spawn aléatoirement dans le rayon de la waterRegion avec une distribution de spawn plutôt vers le centre pour éviter les spawns en bordure systématiques. **Spawn Distribution:** - **Large Oceans** (Pacific): Big regions, high frequency - **Medium Seas** (Mediterranean): Medium regions, moderate frequency - **Small Bays**: Small regions, low frequency - **No Land Spawning**: All weather originates from water bodies ### Phase 3: Movement and Planetary Circulation **Planetary Rotation Bands** (based on real 10hPa atmospheric data): ```json "planetary_circulation": { "polar_jet_north": { "latitude_range": [0.10, 0.25], "direction": "west_to_east", "strength": 1.8 }, "calm_transition_1": { "latitude_range": [0.25, 0.40], "movement": "chaos_plus_procedural" }, "equatorial_trades": { "latitude_range": [0.40, 0.60], "direction": "east_to_west", "strength": 1.5 }, "calm_transition_2": { "latitude_range": [0.60, 0.75], "movement": "chaos_plus_procedural" }, "polar_jet_south": { "latitude_range": [0.75, 0.95], "direction": "west_to_east", "strength": 1.8 } } ``` **Movement Calculation:** ```cpp Vector2 movement = planetary_rotation_band * 0.6 + // 60% planetary circulation equator_to_pole_bias * 0.2 + // 20% thermal circulation terrain_deflection * 0.1 + // 10% topographic influence random_variation * 0.1; // 10% chaos ``` ### Phase 4: WindRegion Evolution and Interactions **Dynamic Evolution:** ```cpp void updateWindRegion(WindRegion& region) { // Gain moisture over water if (currentTile.isOcean()) { region.wetness += OCEAN_MOISTURE_GAIN; } // Repulsion from other regions = acceleration // NOTE: Not physical repulsion - proxy for spatial competition and turbulence // Prevents region stacking while creating realistic dispersion patterns // CRITIQUE POINT: May cause "force field" effect around ITCZ zones where regions // oscillate/scatter instead of converging due to attraction vs repulsion conflict. // Alternative approaches: density-based drift, no interaction, or collision division. // TODO: Implement as configurable algorithm options for empirical testing. float repulsion = calculateRepulsionForce(region, nearbyRegions); region.wind_strength += repulsion * ACCELERATION_FACTOR; // Movement decay region.wind_strength *= (1.0 - DECAY_PER_MOVE); // Tile crossing cost region.wind_strength *= (1.0 - DECAY_PER_TILE); // Die when too weak if (region.wind_strength < MINIMUM_THRESHOLD) { destroyRegion(region); } } ``` **ITCZ Gravitational Effects:** ```cpp void applyITCZGravity(WindRegion& region) { for (auto& itcz : active_itcz_zones) { float distance = calculateDistance(region.position, itcz.center); if (distance < itcz.gravitational_range) { // Attraction force (inverse square law) // NOTE: "Gravitational" metaphor for influence strength, not literal physics // Like saying someone has "gravitas" - clear semantic meaning for developers float attraction = itcz.mass / (distance * distance); Vector2 pull_direction = normalize(itcz.center - region.position); // Apply attraction region.velocity += pull_direction * attraction; // Amplification effect as region approaches float proximity = (itcz.range - distance) / itcz.range; float amplification = 1.0 + (itcz.max_amplification * proximity); region.wind_strength *= amplification; region.wetness *= amplification; } } } ``` ### Phase 5: Storm Classification and Token Distribution **Climate Zone Classification:** ```cpp // Simple thresholds for climate zone determination const float HIGH_WIND_THRESHOLD = 2.0; const float FLOOD_THRESHOLD = 1.5; const float HURRICANE_WIND = 2.5; const float HURRICANE_RAIN = 2.0; bool isHighWindZone(const WindRegion& region) { return region.wind_strength >= HIGH_WIND_THRESHOLD; } bool isFloodZone(const WindRegion& region) { return region.wetness >= FLOOD_THRESHOLD; } bool isHurricaneZone(const WindRegion& region) { return region.wind_strength >= HURRICANE_WIND && region.wetness >= HURRICANE_RAIN; } ``` **Token Distribution System:** ```cpp void distributeTokens(WindRegion& region) { // Basic climate tokens for all regions int wind_tokens = static_cast(region.wind_strength * 10); int rain_tokens = static_cast(region.wetness * 10); WorldTile& tile = world_map.getTile(region.position); tile.addTokens("wind", wind_tokens); tile.addTokens("rain", rain_tokens); // Special climate zone tokens for extreme weather if (isHighWindZone(region)) { tile.addTokens("highWind", 1); // Hostile to forests } if (isFloodZone(region)) { tile.addTokens("flood", 1); // Forces wetlands/marshes } if (isHurricaneZone(region)) { tile.addTokens("hurricane", 1); // Specialized hurricane biome } // Consume distributed tokens from region region.wind_tokens -= wind_tokens; region.rain_tokens -= rain_tokens; } ``` ## Geographic Climate Patterns ### Realistic Climate Formation **Congo Basin (Rainforest):** ``` 1. Large African landmass → Strong ITCZ at equator 2. Atlantic wind regions spawn → Move east via trade winds 3. ITCZ aspiration → Convergence at Congo → Amplification ×3 4. Super-humid storms → Massive rain token distribution 5. Result: Dense rainforest biome ``` **Sahara Desert:** ``` 1. Sahara latitude (25-35°N) → Outside ITCZ band 2. No convergence zone → Wind regions pass through 3. Continental distance → Low initial moisture 4. Subtropical high pressure → Air descends (simulated via movement patterns) 5. Result: Minimal rain tokens → Desert biome ``` **Egypt/Algeria Coastal:** ``` 1. Mediterranean wind regions → Moderate moisture 2. Coastal proximity → Some rain tokens 3. Sahara interior → Moisture depleted inland 4. Result: Mediterranean coastal climate → Desert interior gradient ``` ### Emergent Seasonal Patterns **ITCZ Strength Variation:** ```json "seasonal_modulation": { "itcz_strength_summer": 1.5, // Stronger convection "itcz_strength_winter": 0.8, // Weaker convection "spawn_rate_summer": 1.3, // More wind regions "spawn_rate_winter": 0.7 // Fewer wind regions } ``` **Results:** - **Monsoon Seasons**: ITCZ amplification cycles - **Hurricane Seasons**: Increased spawn rates + ITCZ amplification - **Dry Seasons**: Reduced ITCZ strength + lower spawn rates ## Climate Zone Effects on Biome Generation ### Token-Based Biome Classification **Climate Token Usage:** ```cpp BiomeType classifyBiome(const WorldTile& tile) { int total_rain = tile.getAccumulatedTokens("rain"); int total_wind = tile.getAccumulatedTokens("wind"); int highWind_tokens = tile.getAccumulatedTokens("highWind"); int flood_tokens = tile.getAccumulatedTokens("flood"); int hurricane_tokens = tile.getAccumulatedTokens("hurricane"); // Special climate zones override normal biome classification if (hurricane_tokens > 0) { return BiomeType::HURRICANE_ZONE; // Specialized storm-resistant vegetation } if (flood_tokens > FLOOD_THRESHOLD) { return BiomeType::WETLANDS; // Forced marshes/swamps } if (highWind_tokens > STORM_THRESHOLD) { // High wind prevents forest growth if (total_rain > 300) { return BiomeType::STORM_PRAIRIE; // Grasslands that can handle wind } else { return BiomeType::BADLANDS; // Sparse, wind-resistant vegetation } } // Normal biome classification using basic rain/wind tokens if (total_rain > 500) { return BiomeType::TROPICAL_RAINFOREST; } else if (total_rain < 50) { return BiomeType::HOT_DESERT; } // ... additional normal biome logic } ``` **Climate Zone Characteristics:** - **Hurricane Zones** → Storm-resistant palms, specialized coastal vegetation - **Flood Zones** → Wetlands, marshes, swamp vegetation mandatory - **High Wind Zones** → No forests allowed, prairie/badlands only - **Normal Zones** → Standard biome classification by rain/temperature ## Performance Characteristics ### Computational Complexity - **Wind Regions**: O(n) for n active regions (~50-200 simultaneously) - **ITCZ Calculations**: O(m) for m convergence zones (~5-15 globally) - **Token Distribution**: O(tiles_visited) per region movement - **Total per cycle**: O(n × average_movement_distance) ### Memory Usage - **WindRegion**: 32 bytes per region - **ITCZ Zone**: 24 bytes per zone - **Token accumulation**: Uses existing tile data structure - **Estimated total**: <5MB for global weather simulation ### Generation Time - **Landmass analysis**: 1-2 seconds (one-time setup) - **Per simulation cycle**: 10-50ms for 100-200 wind regions - **Full climate stabilization**: 100-500 cycles → 10-30 seconds total ## Integration with Existing Systems ### TectonicRegions Reuse ```cpp // Leverage existing tectonic analysis class ClimateSystem { void initializeFromTectonics(const std::vector& regions) { auto continents = groupRegionsByProximity(regions); auto oceans = calculateOceanBasins(continents); generateITCZFromContinents(continents); setupWindSpawnFromOceans(oceans); } }; ``` ### RegionalInfluence Framework ```cpp // Wind regions as mobile regional influences class WindRegion : public RegionalInfluence { void applyInfluenceToTile(WorldTile& tile) override { distributeTokens(tile); // Create regional influence for persistent effects if (isStormLevel()) { createPersistentInfluence(tile, getStormType()); } } }; ``` ### Biome Generation Integration ```cpp // Use accumulated climate tokens for biome classification BiomeType classifyBiome(const WorldTile& tile) { int total_rain = tile.getAccumulatedTokens("rain"); int total_wind = tile.getAccumulatedTokens("wind"); float temperature = tile.getTemperature(); if (total_rain > 500 && temperature > 20.0f) { return BiomeType::TROPICAL_RAINFOREST; } else if (total_rain < 50 && temperature > 15.0f) { return BiomeType::HOT_DESERT; } // ... additional biome logic } ``` ## Implementation Priority ### Phase 1: Core Framework (1-2 weeks) 1. WindRegion class and basic movement 2. Token distribution system 3. Simple spawn from ocean detection 4. Basic planetary circulation bands ### Phase 2: ITCZ System (1-2 weeks) 1. Landmass analysis from TectonicRegions 2. ITCZ generation and gravitational effects 3. Wind region amplification mechanics 4. Storm classification system ### Phase 3: Advanced Features (1-2 weeks) 1. Destruction token system and persistent effects 2. Seasonal variation and modulation 3. Performance optimization 4. Integration with biome generation ### Phase 4: Tuning and Validation (1 week) 1. Parameter adjustment for realistic patterns 2. Verification of Congo/Sahara differentiation 3. Performance profiling and optimization 4. Documentation and examples ## Configuration Example ```json { "climate_simulation": { "wind_spawn_system": { "base_spawn_rate": 0.1, "ocean_size_factor": 0.001, "max_concurrent_regions": 200 }, "planetary_circulation": { "trade_winds_strength": 1.5, "jet_stream_strength": 1.8, "calm_zone_chaos": 0.3 }, "itcz_system": { "latitude_band": [0.45, 0.55], "min_landmass_size": 10000, "max_ocean_distance": 800, "amplification_max": 3.0 }, "storm_thresholds": { "high_wind_min": 2.0, "flood_wetness_min": 1.5, "hurricane_wind_min": 2.5, "hurricane_rain_min": 2.0 }, "token_distribution": { "wind_token_factor": 10, "rain_token_factor": 10, "climate_zone_rate": 1 } } } ``` **Note**: All parameters are hot-reloadable via the modular configuration system. Magic numbers are intentionally externalizable for real-time tuning during development - adjust values, save config, see immediate results without recompilation. ``` ## Scientific Accuracy vs Gameplay ### Scientifically Inspired Elements - ✅ ITCZ formation from continental heating - ✅ Planetary circulation bands (trade winds, jet streams) - ✅ Storm formation from wind-moisture interaction - ✅ Geographic influence on climate patterns - ✅ Persistent landscape effects from weather ### Gameplay Simplifications - ⚠️ 2D simulation instead of 3D atmospheric layers - ⚠️ Simplified storm evolution (no pressure systems) - ⚠️ Discrete token system instead of continuous fields - ⚠️ Accelerated timeframes for practical simulation ### Result **Plausible climate science** that creates **engaging gameplay** with **emergent complexity** from **simple, understandable rules**. --- **Status**: System designed and ready for implementation. Provides realistic climate differentiation (Sahara vs Congo) through elegant mobile region simulation using existing tectonic framework.