szdytom 06a60b1a19
feat: Xoroshiro128++ Random Engine
Signed-off-by: szdytom <szdytom@qq.com>
2025-08-02 00:05:12 +08:00

437 lines
13 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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**: Procedural terrain generation system
- **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);
};
```
**Constructor Parameters:**
- `size`: Number of chunks per side (max 100), creating an n×n grid
### 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
// Get biome for a specific sub-chunk position
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.
```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)
};
```
### 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<std::uint8_t, std::uint8_t> subchunk_to_tile_start(
SubChunkPos pos
);
```
## Terrain Generation
### GenerationConfig
Configuration parameters for terrain generation.
```cpp
struct GenerationConfig {
Seed seed; // 128-bit seed for random generation
// Temperature noise parameters
double temperature_scale = 0.005; // 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.005; // 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
};
```
**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 height variation
- `base_octaves`: Number of noise octaves for base terrain
- `base_persistence`: How much each octave contributes to base terrain noise (0.0-1.0)
### TerrainGenerator
Main class for procedural terrain generation.
```cpp
class TerrainGenerator {
public:
explicit TerrainGenerator(const GenerationConfig& config);
void generate_map(TileMap& tilemap);
};
```
### Generation Function
Convenience function for 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
### 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.005;
config.temperature_octaves = 3;
config.temperature_persistence = 0.4;
// Humidity noise settings
config.humidity_scale = 0.005;
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;
// Generate terrain
istd::map_generate(tilemap, config);
// Access tiles
for (int chunk_y = 0; chunk_y < Chunk::subchunk_count; ++chunk_y) {
for (int chunk_x = 0; chunk_x < Chunk::subchunk_count; ++chunk_x) {
const auto& chunk = tilemap.get_chunk(chunk_x, chunk_y);
// Process chunk tiles...
}
}
```
### 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 generator(config);
generator.generate_map(tilemap); // Uses calibrated uniform noise with Xoroshiro128++
```
## Thread Safety
The library is not inherently thread-safe. External synchronization is required for concurrent access to TileMap objects.