From 2c9f25256dc3d18cf4fbf90cb57be604e14fba1b Mon Sep 17 00:00:00 2001 From: szdytom Date: Sat, 2 Aug 2025 22:28:00 +0800 Subject: [PATCH] docs: add developer guide for tilemap library and reduce api doc Signed-off-by: szdytom --- tilemap/docs/api.md | 602 ++++---------------------------------------- tilemap/docs/dev.md | 209 +++++++++++++++ 2 files changed, 253 insertions(+), 558 deletions(-) create mode 100644 tilemap/docs/dev.md diff --git a/tilemap/docs/api.md b/tilemap/docs/api.md index 876add6..ea8bf8e 100644 --- a/tilemap/docs/api.md +++ b/tilemap/docs/api.md @@ -1,21 +1,14 @@ -# Tilemap Library API Documentation +# Tilemap Library API ## Overview -The tilemap library provides a flexible system for generating and managing tile-based terrain with biome support. The library consists of several main components: - -- **TileMap**: The main map container holding chunks of tiles -- **Chunk**: 64x64 tile containers with biome information -- **Tile**: Individual map tiles with base and surface types -- **TerrainGenerator**: Pass-based procedural terrain generation system -- **Generation Passes**: Modular generation components (biome, base terrain, hole filling) -- **Biome System**: Climate-based terrain variation +The tilemap library provides a system for generating and managing tile-based terrain with biome support. ## Core Classes ### TileMap -The main container for the entire map, organized as an n×n grid of chunks. +Main container for the map, organized as chunks. ```cpp class TileMap { @@ -24,446 +17,108 @@ public: std::uint8_t get_size() const; Chunk& get_chunk(std::uint8_t chunk_x, std::uint8_t chunk_y); - const Chunk& get_chunk(std::uint8_t chunk_x, std::uint8_t chunk_y) const; - + Tile& get_tile(TilePos pos); const Tile& get_tile(TilePos pos) const; void set_tile(TilePos pos, const Tile& tile); - - bool is_at_boundary(TilePos pos) const; - std::vector get_neighbors(TilePos pos, bool chebyshev = false) const; }; ``` -**Constructor Parameters:** -- `size`: Number of chunks per side (max 100), creating an n×n grid - -**New Methods:** -- `is_at_boundary()`: Checks if a tile position is at the map boundary -- `get_neighbors()`: Returns neighboring tile positions with optional Chebyshev distance support - ### Chunk -Each chunk contains 64×64 tiles and sub-chunk biome information. +64×64 tile container with biome information. ```cpp struct Chunk { - static constexpr uint8_t size = 64; // Tiles per side - static constexpr uint8_t subchunk_size = 4; // Tiles per sub-chunk side - static constexpr uint8_t subchunk_count = size / subchunk_size; // Sub-chunks per side - - Tile tiles[size][size]; // 64x64 tile grid - BiomeType biome[subchunk_count][subchunk_count]; // Sub-chunk biomes - - // Methods for biome access + static constexpr uint8_t size = 64; + + Tile tiles[size][size]; + BiomeType biome[16][16]; // Sub-chunk biomes + BiomeType& get_biome(SubChunkPos pos); - const BiomeType& get_biome(SubChunkPos pos) const; }; ``` ### Tile -Individual map tiles with base terrain and surface features. +Individual map tile with terrain types. ```cpp struct Tile { - BaseTileType base : 4; // Base terrain type + BaseTileType base : 4; // Base terrain SurfaceTileType surface : 4; // Surface features }; ``` **Base Tile Types:** -- `Land`: Standard ground terrain -- `Mountain`: Rocky elevated terrain -- `Sand`: Desert/beach terrain -- `Water`: Water bodies -- `Ice`: Frozen terrain +- `Land`, `Mountain`, `Sand`, `Water`, `Ice` **Surface Tile Types:** -- `Empty`: No surface features -- `Wood`: Trees/vegetation -- `Structure`: Player-built structures +- `Empty`, `Wood`, `Structure` -### TilePos - -Position structure for locating tiles within the map with enhanced coordinate conversion support. +### Position Types ```cpp struct TilePos { - uint8_t chunk_x; // Chunk X coordinate - uint8_t chunk_y; // Chunk Y coordinate - uint8_t local_x; // Tile X within chunk (0-63) - uint8_t local_y; // Tile Y within chunk (0-63) - - // Coordinate conversion methods + uint8_t chunk_x, chunk_y; // Chunk coordinates + uint8_t local_x, local_y; // Tile within chunk (0-63) + std::pair to_global() const; static TilePos from_global(std::uint16_t global_x, std::uint16_t global_y); }; -// Three-way comparison operator for ordering -std::strong_ordering operator<=>(const TilePos& lhs, const TilePos& rhs); -``` - -### SubChunkPos - -Position within a chunk's sub-chunk grid. - -```cpp struct SubChunkPos { - std::uint8_t sub_x; - std::uint8_t sub_y; - - constexpr SubChunkPos(std::uint8_t x, std::uint8_t y); + std::uint8_t sub_x, sub_y; }; - -std::pair subchunk_to_tile_start( - SubChunkPos pos -); ``` ## Terrain Generation -The terrain generation system has been refactored into a modular pass-based architecture, providing better separation of concerns and more flexible generation control. - ### GenerationConfig -Configuration parameters for terrain generation. +Configuration for terrain generation. ```cpp struct GenerationConfig { - Seed seed; // 128-bit seed for random generation - - // Temperature noise parameters - double temperature_scale = 0.05; // Scale for temperature noise - int temperature_octaves = 3; // Number of octaves for temperature noise - double temperature_persistence = 0.4; // Persistence for temperature noise - - // Humidity noise parameters - double humidity_scale = 0.05; // Scale for humidity noise - int humidity_octaves = 3; // Number of octaves for humidity noise - double humidity_persistence = 0.4; // Persistence for humidity noise - - // Base terrain noise parameters - double base_scale = 0.08; // Scale for base terrain noise - int base_octaves = 3; // Number of octaves for base terrain noise - double base_persistence = 0.5; // Persistence for base terrain noise - - // Mountain smoothing parameters - std::uint32_t mountain_remove_threshold = 10; // Remove mountain components smaller than this size + Seed seed; - // Hole filling parameters - std::uint32_t fill_threshold = 10; // Fill holes smaller than this size -}; -``` - -**Parameters:** - -- `seed`: 128-bit seed for all noise generators (see Seed structure) -- `temperature_scale`: Controls the scale/frequency of temperature variation across the map -- `temperature_octaves`: Number of noise octaves for temperature (more octaves = more detail) -- `temperature_persistence`: How much each octave contributes to temperature noise (0.0-1.0) -- `humidity_scale`: Controls the scale/frequency of humidity variation across the map -- `humidity_octaves`: Number of noise octaves for humidity -- `humidity_persistence`: How much each octave contributes to humidity noise (0.0-1.0) -- `base_scale`: Controls the scale/frequency of base terrain variation across the map -- `base_octaves`: Number of noise octaves for base terrain -- `base_persistence`: How much each octave contributes to base terrain noise (0.0-1.0) -- `mountain_remove_threshold`: Maximum size of mountain components to remove for terrain smoothing -- `fill_threshold`: Maximum size of holes to fill with mountains - -### Generation Passes - -The generation system is organized into distinct passes, each responsible for a specific aspect of terrain generation. - -#### BiomeGenerationPass - -Generates biome data for all sub-chunks based on temperature and humidity noise. - -```cpp -class BiomeGenerationPass { -public: - BiomeGenerationPass( - const GenerationConfig& config, - Xoroshiro128PP r1, - Xoroshiro128PP r2 - ); + // Noise parameters + double temperature_scale = 0.05; + double humidity_scale = 0.05; + double base_scale = 0.08; - void operator()(TileMap& tilemap); - -private: - std::pair get_climate(double global_x, double global_y) const; + int temperature_octaves = 3; + int humidity_octaves = 3; + int base_octaves = 3; }; ``` -**Key Features:** -- **Climate Generation**: Uses separate noise generators for temperature and humidity -- **Sub-chunk Resolution**: Assigns biomes to 16×16 sub-chunks for efficient generation -- **Climate Mapping**: Maps noise values to temperature/humidity ranges -- **Biome Determination**: Uses climate values to determine appropriate biomes - -#### BaseTileTypeGenerationPass - -Generates base terrain types for all tiles based on their sub-chunk biomes. - -```cpp -class BaseTileTypeGenerationPass { -public: - BaseTileTypeGenerationPass(const GenerationConfig& config, Xoroshiro128PP rng); - - void operator()(TileMap& tilemap); - void generate_chunk(TileMap& tilemap, std::uint8_t chunk_x, std::uint8_t chunk_y); - void generate_subchunk( - TileMap& tilemap, std::uint8_t chunk_x, std::uint8_t chunk_y, - SubChunkPos sub_pos, BiomeType biome - ); - -private: - BaseTileType determine_base_type( - double noise_value, const BiomeProperties& properties - ) const; -}; -``` - -**Key Features:** -- **Biome-aware Generation**: Uses biome properties to control terrain type ratios -- **Hierarchical Processing**: Processes chunks, then sub-chunks, then individual tiles -- **Noise-based Distribution**: Uses calibrated noise for balanced terrain distribution -- **Tile-level Detail**: Generates terrain at individual tile resolution - -#### HoleFillPass - -Fills small holes in the terrain using breadth-first search (BFS) algorithm. - -```cpp -class HoleFillPass { -public: - explicit HoleFillPass(const GenerationConfig& config); - void operator()(TileMap& tilemap); - -private: - bool is_passable(BaseTileType type) const; - std::uint32_t bfs_component_size( - TileMap& tilemap, TilePos start_pos, - std::vector>& visited, - std::vector& positions - ); - std::vector get_neighbors(TileMap& tilemap, TilePos pos) const; - bool is_at_boundary(TileMap& tilemap, TilePos pos) const; -}; -``` - -**Key Features:** -- **BFS Algorithm**: Uses breadth-first search to identify connected components -- **Boundary Awareness**: Preserves holes that touch the map boundary -- **Size-based Filtering**: Only fills holes smaller than `fill_threshold` -- **Mountain-as-Impassable**: Treats mountains as impassable terrain for connectivity -- **Hole Filling**: Converts small isolated areas to mountains for cleaner terrain - -#### SmoothenMountainsPass - -Removes small mountain components to create smoother terrain using BFS and replacement strategies. - -```cpp -class SmoothenMountainsPass { -public: - SmoothenMountainsPass(const GenerationConfig& config, Xoroshiro128PP rng); - void operator()(TileMap& tilemap); - -private: - std::uint32_t bfs_component_size( - TileMap& tilemap, TilePos start_pos, - std::vector>& visited, - std::vector& positions - ); - void demountainize(TileMap& tilemap, const std::vector& positions); -}; -``` - -**Key Features:** -- **Mountain Component Detection**: Uses BFS to find connected mountain regions -- **Size-based Removal**: Removes mountain components smaller than `mountain_remove_threshold` -- **Boundary Preservation**: Preserves mountain components that touch the map boundary -- **Intelligent Replacement**: Replaces mountains with terrain types based on neighboring tiles -- **Smooth Terrain**: Creates more natural-looking terrain without isolated mountain clusters - -### TerrainGenerator - -Main orchestrator class that manages the generation process using multiple passes. - -```cpp -class TerrainGenerator { -public: - explicit TerrainGenerator(const GenerationConfig& config); - void operator()(TileMap& tilemap); - -private: - void biome_pass(TileMap& tilemap); - void base_tile_type_pass(TileMap& tilemap); - void smoothen_mountains_pass(TileMap& tilemap); - void hole_fill_pass(TileMap& tilemap); -}; -``` - -**Generation Order:** -1. **Biome Pass**: Generates climate-based biome data for sub-chunks -2. **Base Tile Type Pass**: Generates base terrain types based on biomes -3. **Smoothen Mountains Pass**: Removes small mountain components for smoother terrain -4. **Hole Fill Pass**: Fills small holes in the terrain - -**Key Features:** -- **Multi-pass Architecture**: Separates generation concerns for better control -- **RNG Management**: Uses independent RNGs for each pass with proper seeding -- **Deterministic Results**: Same seed produces identical terrain across runs -- **Configurable**: All passes use parameters from GenerationConfig - -**Generation Flow:** -1. **Biome Pass**: Generate climate data and assign biomes to sub-chunks -2. **Base Tile Type Pass**: Generate base terrain types based on biomes and noise -3. **Hole Fill Pass**: Fill small holes in the terrain using BFS algorithm - ### Generation Function -Convenience function for complete map generation. - ```cpp void map_generate(TileMap& tilemap, const GenerationConfig& config); ``` -## Random Number Generation - ### Seed -128-bit seed structure for random number generation. - ```cpp struct Seed { - std::uint64_t s[2]; // 128-bit seed value (two 64-bit components) - - static Seed from_string(const char* str); // Create seed from string - static Seed device_random(); // Create seed from hardware random device + std::uint64_t s[2]; + + static Seed from_string(const char* str); + static Seed device_random(); }; ``` -**Key Features:** -- **128-bit precision**: Uses two 64-bit integers for extended seed space -- **String generation**: Deterministic seed creation from text strings -- **Hardware random**: True random seed generation using system entropy - -### Xoroshiro128++ - -High-performance random number generator using the Xoroshiro128++ algorithm. - -```cpp -class Xoroshiro128PP { -public: - Xoroshiro128PP() = default; - Xoroshiro128PP(Seed seed); - - // STL RandomEngine interface - using result_type = std::uint64_t; - static constexpr result_type min(); - static constexpr result_type max(); - result_type operator()(); - - std::uint64_t next(); // Generate next random number - Xoroshiro128PP jump_64() const; // Jump equivalent to 2^64 calls - Xoroshiro128PP jump_96() const; // Jump equivalent to 2^96 calls -}; -``` - -**Key Features:** -- **High Performance**: Optimized for speed with excellent statistical properties -- **128-bit State**: Internal state provides long period (2^128 - 1) -- **Jump Functions**: Enable parallel random number generation -- **STL Compatible**: Implements standard random engine interface - -## Noise System - -### DiscreteRandomNoise - -Discrete random noise generator using Xoroshiro128++ for terrain replacement operations. - -```cpp -class DiscreteRandomNoise { -public: - explicit DiscreteRandomNoise(Xoroshiro128PP rng); - std::uint64_t noise(std::uint32_t x, std::uint32_t y, std::uint32_t z = 0) const; -}; -``` - -**Key Features:** -- **Discrete Output**: Produces integer values for discrete selections -- **High Quality**: Based on Xoroshiro128++ random number generation -- **3D Support**: Supports optional Z coordinate for 3D noise -- **Fast**: Optimized for performance in terrain processing - -### PerlinNoise - -Standard Perlin noise implementation using Xoroshiro128++ for procedural generation. - -```cpp -class PerlinNoise { -public: - explicit PerlinNoise(Xoroshiro128PP rng); - double noise(double x, double y) const; - double octave_noise(double x, double y, int octaves = 4, double persistence = 0.5) const; -}; -``` - -### UniformPerlinNoise - -Advanced noise generator using Xoroshiro128++ that provides uniform distribution mapping. - -```cpp -class UniformPerlinNoise { -public: - explicit UniformPerlinNoise(Xoroshiro128PP rng); - void calibrate(double scale, int octaves = 1, double persistence = 0.5, int sample_size = 10000); - double uniform_noise(double x, double y) const; - bool is_calibrated() const; -}; -``` - -**Key Features:** -- **Calibration**: Samples noise distribution to build CDF -- **Uniform Mapping**: Maps raw Perlin values to uniform [0,1] distribution -- **Balanced Output**: Ensures even distribution across all value ranges -- **Automatic Use**: TerrainGenerator uses this internally for balanced terrain -- **Xoroshiro128++ Backend**: Uses high-quality random number generation - -## Biome System +## Biomes ### BiomeType -Available biome types based on temperature and humidity. - ```cpp enum class BiomeType : std::uint8_t { - SnowyPeeks, // Cold & Dry - SnowyPlains, // Cold & Moderate - FrozenOcean, // Cold & Wet - Plains, // Temperate & Dry - Forest, // Temperate & Moderate - Ocean, // Temperate & Wet - Desert, // Hot & Dry - Savanna, // Hot & Moderate - LukeOcean, // Hot & Wet -}; -``` - -### BiomeProperties - -Properties that control terrain generation for each biome. - -```cpp -struct BiomeProperties { - std::string_view name; // Biome name - double water_ratio; // Water generation ratio - double ice_ratio; // Ice generation ratio - double sand_ratio; // Sand generation ratio - double land_ratio; // Land generation ratio - int base_octaves = 3; // Noise octaves - double base_persistence = 0.5; // Noise persistence + SnowyPeaks, SnowyPlains, FrozenOcean, + Plains, Forest, Ocean, + Desert, Savanna, LukeOcean }; ``` @@ -476,201 +131,32 @@ BiomeType determine_biome(double temperature, double humidity); ## Usage Examples -### Basic Map Generation +### Basic Usage ```cpp #include "tilemap.h" #include "generation.h" -// Create a 4x4 chunk map -istd::TileMap tilemap(4); - -// Configure generation -istd::GenerationConfig config; -config.seed = istd::Seed::from_string("hello_world"); // 128-bit seed from string - -// Temperature noise settings -config.temperature_scale = 0.05; -config.temperature_octaves = 3; -config.temperature_persistence = 0.4; - -// Humidity noise settings -config.humidity_scale = 0.05; -config.humidity_octaves = 3; -config.humidity_persistence = 0.4; - -// Base terrain noise settings -config.base_scale = 0.08; -config.base_octaves = 3; -config.base_persistence = 0.5; - -// Mountain smoothing settings -config.mountain_remove_threshold = 10; // Remove mountain components smaller than 10 tiles - -// Hole filling settings -config.fill_threshold = 10; // Fill holes smaller than 10 tiles +// Create map +istd::TileMap tilemap(4); // 4x4 chunks // Generate terrain +istd::GenerationConfig config; +config.seed = istd::Seed::from_string("my_world"); istd::map_generate(tilemap, config); // Access tiles -for (int chunk_y = 0; chunk_y < tilemap.get_size(); ++chunk_y) { - for (int chunk_x = 0; chunk_x < tilemap.get_size(); ++chunk_x) { - const auto& chunk = tilemap.get_chunk(chunk_x, chunk_y); - // Process chunk tiles... - } -} -``` - -### Advanced Generation with Custom Passes - -```cpp -#include "tilemap.h" -#include "generation.h" - -// Create map and config -istd::TileMap tilemap(2); -istd::GenerationConfig config; -config.seed = istd::Seed::from_string("custom_world"); - -// Use TerrainGenerator for step-by-step control -istd::TerrainGenerator generator(config); - -// Generate terrain (runs both biome and base tile passes) -generator(tilemap); - -// Access biome data -const auto& chunk = tilemap.get_chunk(0, 0); -for (int sub_y = 0; sub_y < istd::Chunk::subchunk_count; ++sub_y) { - for (int sub_x = 0; sub_x < istd::Chunk::subchunk_count; ++sub_x) { - istd::SubChunkPos pos(sub_x, sub_y); - istd::BiomeType biome = chunk.get_biome(pos); - const auto& props = istd::get_biome_properties(biome); - // Process biome... - } -} -``` -``` - -### Seed Usage Examples - -```cpp -// Create seed from string (deterministic) -istd::Seed seed1 = istd::Seed::from_string("my_world"); - -// Create random seed from hardware -istd::Seed seed2 = istd::Seed::device_random(); - -// Manual seed creation -istd::Seed seed3; -seed3.s[0] = 0x123456789abcdef0; -seed3.s[1] = 0xfedcba9876543210; - -// Use seed in generation -istd::GenerationConfig config; -config.seed = seed1; -``` - -### Accessing Individual Tiles - -```cpp -// Using TilePos -istd::TilePos pos{0, 0, 32, 32}; // Chunk (0,0), tile (32,32) +istd::TilePos pos{0, 0, 32, 32}; // Chunk (0,0), tile (32,32) const auto& tile = tilemap.get_tile(pos); - -// Direct chunk access -const auto& chunk = tilemap.get_chunk(0, 0); -const auto& tile2 = chunk.tiles[32][32]; ``` ### Working with Biomes ```cpp -// Method 1: Direct array access (traditional way) const auto& chunk = tilemap.get_chunk(0, 0); -istd::BiomeType biome = chunk.biome[1][1]; // Sub-chunk (1,1) +istd::SubChunkPos sub_pos(1, 1); +istd::BiomeType biome = chunk.get_biome(sub_pos); -// Method 2: Using SubChunkPos and get_biome method (recommended) -istd::SubChunkPos pos(1, 1); // Sub-chunk (1,1) -istd::BiomeType biome2 = chunk.get_biome(pos); - -// Modify biome using the new method -auto& mutable_chunk = tilemap.get_chunk(0, 0); -mutable_chunk.get_biome(pos) = istd::BiomeType::Forest; - -// Get biome properties const auto& props = istd::get_biome_properties(biome); std::cout << "Biome: " << props.name << std::endl; ``` - -## Performance Notes - -- Each chunk contains 4,096 tiles (64×64) -- Sub-chunks provide efficient biome management -- Tiles are packed into 1 byte each for memory efficiency -- Generation uses Xoroshiro128++ random number generator with uniform distribution mapping for balanced terrain -- Noise calibration is performed once during generator construction -- 128-bit seeds provide excellent randomness and reproducibility - -## Noise Distribution - -The library uses an advanced noise system based on Xoroshiro128++ random number generation that addresses the non-uniform distribution of Perlin noise: - -### Problem with Raw Perlin Noise - -Raw Perlin noise follows a bell-curve distribution, with most values concentrated around 0.5. This leads to unbalanced terrain generation where certain tile types (like Land) dominate the map. - -### Solution: Xoroshiro128++ + Uniform Distribution Mapping - -The library combines two key improvements: - -1. **Xoroshiro128++ RNG**: High-quality pseudo-random number generator with: - - **Long Period**: 2^128 - 1 sequence length before repetition - - **High Performance**: Optimized for speed and memory efficiency - - **Excellent Statistics**: Passes rigorous randomness tests - - **128-bit State**: Two 64-bit values providing extensive seed space - -2. **Uniform Distribution Mapping**: The `UniformPerlinNoise` class: - - **Samples** the noise distribution during calibration - - **Builds a CDF** (Cumulative Distribution Function) from the samples - - **Maps raw noise values** to uniform [0,1] distribution using quantiles - - **Ensures balanced** terrain type distribution according to biome properties - -### Usage in Terrain Generation - -```cpp -// The terrain generator automatically uses Xoroshiro128++ and uniform noise -istd::Seed seed = istd::Seed::from_string("consistent_world"); -istd::GenerationConfig config; -config.seed = seed; - -// TerrainGenerator handles pass coordination and RNG management -istd::TerrainGenerator generator(config); -generator(tilemap); // Uses calibrated uniform noise with Xoroshiro128++ - -// Or use the convenience function -istd::map_generate(tilemap, config); -``` - -### Pass-based Architecture Benefits - -The new pass-based system provides: - -1. **Separation of Concerns**: Each pass handles a specific aspect of generation -2. **RNG Independence**: Each pass uses independent random number generators -3. **Reproducible Results**: Same seed produces identical results across passes -4. **Extensibility**: Easy to add new passes or modify existing ones -5. **Performance**: Efficient memory access patterns and reduced redundant calculations -6. **Terrain Quality**: SmoothenMountainsPass creates more natural-looking terrain - -### Recent Improvements - -**Mountain Smoothing**: The new `SmoothenMountainsPass` removes small isolated mountain components to create more natural terrain formations. Small mountain clusters that don't connect to the boundary are replaced with terrain types based on their neighboring areas. - -**Enhanced TileMap**: Added utility methods for boundary detection and neighbor finding, supporting both Manhattan and Chebyshev distance calculations. - -**Improved Noise**: Added `DiscreteRandomNoise` for high-quality discrete value generation used in terrain replacement operations. - -## Thread Safety - -The library is not inherently thread-safe. External synchronization is required for concurrent access to TileMap objects. diff --git a/tilemap/docs/dev.md b/tilemap/docs/dev.md new file mode 100644 index 0000000..f08ce2f --- /dev/null +++ b/tilemap/docs/dev.md @@ -0,0 +1,209 @@ +# Tilemap Library Developer Guide + +## Project Overview + +The tilemap library is a C++ terrain generation system that creates tile-based worlds with biome support. It uses a multi-pass generation pipeline to create realistic, balanced terrain. + +## Project Structure + +``` +tilemap/ +├── include/ # Public headers +│ ├── tilemap.h # Main map container +│ ├── chunk.h # 64x64 tile chunks +│ ├── tile.h # Individual tile types +│ ├── generation.h # Generation system +│ ├── biome.h # Biome system +│ ├── noise.h # Noise generators +│ └── xoroshiro.h # RNG implementation +├── src/ # Implementation files +│ ├── tilemap.cpp # TileMap implementation +│ ├── chunk.cpp # Chunk utilities +│ ├── generation.cpp # Main generation orchestrator +│ ├── biome.cpp # Biome mapping logic +│ ├── noise.cpp # Noise implementations +│ ├── xoroshiro.cpp # Xoroshiro128++ RNG +│ └── pass/ # Generation passes +│ ├── biome.cpp # Climate-based biome generation +│ ├── base_tile_type.cpp # Base terrain generation +│ ├── smoothen_mountain.cpp # Mountain smoothing +│ ├── mountain_hole_fill.cpp # Hole filling +│ └── deepwater.cpp # Deep water placement +├── examples/ # Usage examples +└── docs/ # Documentation +``` + +## Core Architecture + +### Data Organization + +The system uses a hierarchical structure: +- **TileMap**: n×n grid of chunks +- **Chunk**: 64×64 tiles with biome metadata +- **Tile**: Individual terrain cell (1 byte packed) + +Each chunk also contains a 16×16 grid of sub-chunk biomes, providing efficient biome lookup without per-tile storage. + +### Pass-Based Generation + +Terrain generation uses a multi-pass pipeline for modularity and control: + +1. **Biome Pass**: Generates climate data and assigns biomes to sub-chunks +2. **Base Tile Type Pass**: Creates base terrain based on biomes +3. **Mountain Smoothing Pass**: Removes isolated mountain clusters +4. **Hole Fill Pass**: Fills small terrain holes +5. **Deep Water Pass**: Places deep water areas + +Each pass operates independently with its own RNG state, ensuring deterministic results. + +## Terrain Generation Pipeline + +### Climate Generation + +The biome pass uses dual noise generators for temperature and humidity: +- Separate Perlin noise for temperature/humidity at sub-chunk resolution +- Climate values mapped to 9 biome types in a 3×3 grid +- Sub-chunks store biome data for efficient terrain generation + +### Noise System + +The library addresses Perlin noise distribution issues: +- **Problem**: Raw Perlin noise has bell-curve distribution +- **Solution**: UniformPerlinNoise calibrates distribution to uniform [0,1] +- **Result**: Balanced terrain type ratios according to biome properties + +### Terrain Generation Process + +1. **Climate Sampling**: Sample temperature/humidity at sub-chunk centers +2. **Biome Assignment**: Map climate values to biome types +3. **Terrain Generation**: Generate tiles based on biome properties and noise +4. **Post-processing**: Apply smoothing and hole-filling algorithms + +### Connected Component Analysis + +Several passes use BFS (Breadth-First Search) for terrain analysis: +- **Mountain Smoothing**: Find and remove small mountain components +- **Hole Filling**: Identify and fill isolated terrain holes +- Components touching map boundaries are preserved + +## Random Number Generation + +### Xoroshiro128++ Implementation + +High-quality PRNG with excellent statistical properties: +- 128-bit internal state +- Period of 2^128 - 1 +- Jump functions for parallel generation +- STL-compatible interface + +### Seed Management + +128-bit seeds provide extensive randomness: +- String-based deterministic seed creation +- Hardware random seed generation +- Independent RNG streams for each generation pass + +## Biome System + +### Climate Mapping + +Biomes are determined by temperature/humidity combinations: +``` + Dry Moderate Wet +Cold Snowy Snowy Frozen + Peaks Plains Ocean +Temp Plains Forest Ocean +Hot Desert Savanna Luke Ocean +``` + +### Biome Properties + +Each biome defines terrain generation ratios: +- Water/Ice/Sand/Land ratios +- Noise parameters (octaves, persistence) +- Used by base terrain generation pass + +## Performance Considerations + +### Memory Layout + +- Tiles packed into 1 byte (4 bits base + 4 bits surface) +- Chunks use contiguous 64×64 arrays for cache efficiency +- Sub-chunk biomes reduce memory overhead vs per-tile storage + +### Generation Efficiency + +- Sub-chunk resolution for biome generation (16×16 vs 64×64) +- Single-pass algorithms where possible +- Efficient connected component analysis using BFS + +### Determinism + +- Same seed produces identical results +- Independent RNG streams prevent cross-pass contamination +- Floating-point operations use consistent precision + +## Adding New Generation Passes + +To add a new generation pass: + +1. **Create Pass Implementation**: Add new file in `src/pass/` +2. **Add to Pipeline**: Update `TerrainGenerator::operator()` +3. **RNG Management**: Use jump functions for independent RNG streams +4. **Configuration**: Add parameters to `GenerationConfig` if needed + +Example pass structure: +```cpp +void TerrainGenerator::my_custom_pass(TileMap &tilemap) { + auto rng = master_rng_.jump_96(); // Independent RNG stream + + // Process tilemap... + for (auto chunk_y = 0; chunk_y < tilemap.get_size(); ++chunk_y) { + for (auto chunk_x = 0; chunk_x < tilemap.get_size(); ++chunk_x) { + auto& chunk = tilemap.get_chunk(chunk_x, chunk_y); + // Process chunk... + } + } +} +``` + +## Testing and Validation + +### Determinism Testing + +Verify same seed produces identical output across runs: +```cpp +auto seed = Seed::from_string("test"); +TileMap map1(4), map2(4); +map_generate(map1, {seed}); +map_generate(map2, {seed}); +// Verify map1 == map2 +``` + +### Distribution Analysis + +Check terrain type distributions match biome properties: +- Count tile types per biome +- Verify ratios within acceptable tolerance +- Test with multiple seeds for statistical significance + +### Visual Validation + +Export maps to image formats for visual inspection: +- Check for realistic terrain patterns +- Verify biome transitions look natural +- Ensure no artifacts from generation passes + +## Future Extensions + +### Potential Improvements + +- **Surface Feature Generation**: Trees, structures, resources +- **Elevation System**: Height maps for 3D terrain +- **River Generation**: Connected water systems +- **Chunk Streaming**: Dynamic loading for large worlds +- **Multithreading**: Parallel chunk generation + +### API Stability + +Core interfaces (TileMap, Chunk, Tile) are stable. Generation system is designed for extensibility without breaking existing code.