# Tilemap Library API Documentation ## 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 ## Core Classes ### TileMap The main container for the entire map, organized as an n×n grid of chunks. ```cpp class TileMap { public: explicit TileMap(std::uint8_t size); 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. ```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 BiomeType& get_biome(SubChunkPos pos); const BiomeType& get_biome(SubChunkPos pos) const; }; ``` ### Tile Individual map tiles with base terrain and surface features. ```cpp struct Tile { BaseTileType base : 4; // Base terrain type 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 **Surface Tile Types:** - `Empty`: No surface features - `Wood`: Trees/vegetation - `Structure`: Player-built structures ### TilePos Position structure for locating tiles within the map with enhanced coordinate conversion support. ```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 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::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. ```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 // 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 ); void operator()(TileMap& tilemap); private: std::pair get_climate(double global_x, double global_y) const; }; ``` **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 }; ``` **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 ### 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 }; ``` ### Biome Functions ```cpp const BiomeProperties& get_biome_properties(BiomeType biome); BiomeType determine_biome(double temperature, double humidity); ``` ## Usage Examples ### Basic Map Generation ```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 // Generate terrain 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) 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) // 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.