instructed/tilemap/docs/mineral_generation.md
szdytom fcb71be9e8
feat: Add mineral generation pass
Signed-off-by: szdytom <szdytom@qq.com>
2025-08-03 17:08:36 +08:00

4.4 KiB
Raw Blame History

矿物生成系统实现总结

概述

为tilemap库实现了三种新矿石Hematite赤铁矿、Titanomagnetite钛磁铁矿、Gibbsite三水铝石的生成系统。该系统基于Oil生成方式的改进版本专门针对山脉边缘的矿物分布进行了优化。

设计选择

为什么选择基于Oil的方案而不是胞元自动机

  1. 精确控制性Poisson disk采样方式能够精确控制矿物密度和分布间距
  2. 效率优势:单次随机游走比多轮胞元自动机迭代更高效
  3. 参数直观性:密度、集群大小、最小距离等参数更易于调整和平衡
  4. 稀有资源特性:矿物作为稀有资源,稀疏分布更符合游戏设计需求

核心特性

1. 位置限制

  • 矿物只在 BaseTileType::MountainSurfaceTileType::Empty 的瓦片上生成
  • 必须位于山脉边缘(至少有一个相邻瓦片不是山地)
  • 确保矿物出现在山脉与其他地形的交界处,便于开采

2. 分层稀有度

// 默认配置
hematite_density = 51;        // ~0.2 per chunk (最常见)
titanomagnetite_density = 25; // ~0.1 per chunk (中等稀有)
gibbsite_density = 13;        // ~0.05 per chunk (最稀有)

3. 集群生成

  • 最小集群大小2个瓦片
  • 最大集群大小5个瓦片
  • 使用随机游走算法形成自然的小簇分布
  • 40%概率跳过相邻瓦片,形成合适的密度

4. 距离控制

  • 基于密度动态计算最小间距
  • 确保矿物集群不会过于密集
  • 最小间距至少8个瓦片

实现细节

核心算法

  1. Poisson disk采样:生成候选位置,确保合适的分布
  2. 山脉边缘检测:验证位置是否在山脉边缘
  3. 随机游走集群生长:从中心点开始生成小簇
  4. 冲突避免:确保不同矿物集群之间保持距离

山脉边缘检测逻辑

bool is_mountain_edge(const TileMap &tilemap, TilePos pos) const {
    auto neighbors = tilemap.get_neighbors(pos);
    for (const auto neighbor_pos : neighbors) {
        const Tile &neighbor_tile = tilemap.get_tile(neighbor_pos);
        if (neighbor_tile.base != BaseTileType::Mountain) {
            return true; // 找到非山地邻居
        }
    }
    return false; // 所有邻居都是山地,不是边缘
}

配置参数

struct GenerationConfig {
    // 矿物集群生成参数
    std::uint8_t hematite_density = 51;        // ~0.2 per chunk
    std::uint8_t titanomagnetite_density = 25; // ~0.1 per chunk  
    std::uint8_t gibbsite_density = 13;        // ~0.05 per chunk
    
    std::uint8_t mineral_cluster_min_size = 2; // 最小集群大小
    std::uint8_t mineral_cluster_max_size = 5; // 最大集群大小
    std::uint8_t mineral_base_probe = 192;     // 基础放置概率
};

生成流水线集成

矿物生成作为独立的pass添加到地形生成流水线的最后阶段

void TerrainGenerator::operator()(TileMap &tilemap) {
    biome_pass(tilemap);
    base_tile_type_pass(tilemap);
    smoothen_mountains_pass(tilemap);
    smoothen_islands_pass(tilemap);
    mountain_hole_fill_pass(tilemap);
    deepwater_pass(tilemap);
    oil_pass(tilemap);
    mineral_cluster_pass(tilemap);  // 新增的矿物生成pass
}

测试结果

通过mineral_demo测试程序验证

  • 8x8 chunk地图 (262,144个瓦片)
  • 山地瓦片35,916个 (13.7%)
  • 山脉边缘瓦片15,881个 (44.2%的山地)
  • 生成矿物分布:
    • 赤铁矿47个瓦片
    • 钛磁铁矿38个瓦片
    • 三水铝石15个瓦片
  • 山脉边缘矿物覆盖率0.63%

优势

  1. 游戏平衡性:稀有度分层,符合游戏经济设计
  2. 真实感:矿物出现在山脉边缘,符合地质常识
  3. 可扩展性:易于添加新的矿物类型和调整参数
  4. 性能优秀:单次生成,不需要多轮迭代
  5. 确定性:相同种子产生相同结果,支持多人游戏

使用建议

  1. 密度调整根据游戏需求调整各矿物的density参数
  2. 集群大小:可以为不同矿物设置不同的集群大小范围
  3. 生成位置:如需其他位置生成矿物,可修改is_suitable_for_mineral函数
  4. 稀有度平衡建议保持gibbsite < titanomagnetite < hematite的稀有度关系

这个实现提供了灵活、高效且平衡的矿物生成系统,完全满足了"控制生成数量,以小簇方式生成在山的边缘"的需求。