## World Generation Pipeline - Add comprehensive 7-phase geological simulation (4.6 billion years) - Implement WindRegions-based climate system with ITCZ zones - Create 18 biome types with scientific classification parameters - Establish Phase 7 budget assignment and natural feature placement ## Resource System Architecture - Add 70+ natural features across 8 categories (geological, water, forest, volcanic, etc.) - Implement complete resource-to-feature mapping for all game materials - Create individual resource files for metals (iron, copper, gold, uranium, etc.) - Add comprehensive cross-referencing between features and game resources ## Biome Integration System - Design scalable blacklist + frequent biomes compatibility system - Implement mass-based feature selection with geological strength requirements - Add 5 spatial distribution patterns (concentrated, uniform, ring, clustered, gradient) - Create region-based feature placement with biome-aware filtering ## Documentation and Architecture - Add detailed geological and climate simulation system documentation - Update project overview with world generation achievements - Establish JSON-driven configuration system for all generation parameters - Create comprehensive system for Phase 8 integration readiness 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
488 lines
16 KiB
Markdown
488 lines
16 KiB
Markdown
# 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<Continent> continents = groupTectonicRegions();
|
||
|
||
// Generate water masses by inverse analysis
|
||
std::vector<WaterMass> 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<int>(region.wind_strength * 10);
|
||
int rain_tokens = static_cast<int>(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<TectonicRegion>& 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. |