Skip to content
游戏世界地形纹理 · 机制与百科资料

地形与群系 ​

你的世界从选择地形生成模式的那一刻就开始塑造了。四种模式决定了大陆轮廓、岛屿分布和整体地势风格,是整个地形系统的第一块基石。

阅读提示

本节内容过多且较为复杂,后续编者会增强可读性,让每位玩家都能理解。

地形生成模式 ​

原版游戏提供四种地形生成模式:

序号地形类型枚举值描述备注
1大陆Continent标准大陆地形,有海洋和陆地原版
2岛屿Island独立岛屿地形原版
3平坦大陆FlatContinent平坦化的大陆地形原版
4平坦岛屿FlatIsland平坦化的岛屿地形原版
5虚空Nihility完全空的世界联机版
6优化地形Better优化版地形,增加盆地生成联机版
7极巨化Huge巨型地形,海平面降低联机版
8极冻高原256Cave倒置地形,顶部为基岩联机版
9空岛SkyIsland漂浮在空中的岛屿联机版
10基岩地形Bedrock低高度基岩骨架大陆联机版
11石头地形Stone被石头包围的岛屿地形联机版

通俗解释:大陆模式适合喜欢长途探险的玩家,世界理论上无限大;岛屿模式则给你一个有边界的生存空间,适合挑战自我。平坦模式减少了极端地形,更适合建筑党。

世界设置参数 ​

在创建世界时,你可以调整温度、湿度、海平面等参数。这些设置直接影响群系分布和地形外观,是定制化你生存体验的关键旋钮。

以下参数来自 WorldSettings.cs,玩家可在创建世界时调整:

参数默认值范围作用
海平面高度0-64 ~ +191海平面偏移,正值升高海平面
温度0-16 ~ +16温度偏移(-16~+16),正值使世界更热
湿度0-16 ~ +16湿度偏移(-16~+16),正值使世界更湿润
生物群系大小1.00.01 ~ +32生物群系缩放因子,越大则群系面积越大
岛屿大小(400, 400)1 ~ +2500岛屿模式下岛屿的尺寸
海岸线粗糙度0.50 ~ 1平坦或平坦岛屿模式下海岸线粗糙度

其中温度偏移和湿度偏移会直接叠加到温湿度计算结果上。例如温度偏移+8会让原本寒冷的区域变得温和,相当于把整个世界的温度带向赤道方向推移。

地形高度计算 ​

每一个方块的 Y 坐标都不是随机的,而是由多层噪声函数叠加而成。理解高度计算,你就能预判哪里有山、哪里是谷、哪里可能藏着河流。

核心机制 ​

高度的基础值为64(即海平面),最终高度被限制在10~251之间。高度的变化由四个因素叠加而成:

高度=clamp( 64+海洋坡度+丘陵+山脉+河流−海洋深度, 10, 251 )\text{高度} = \mathrm{clamp}\Big(\,64 + \text{海洋坡度} + \text{丘陵} + \text{山脉} + \text{河流} - \text{海洋深度},\ 10,\ 251\,\Big)

clamp(x, min, max):限制函数。若 x 小于 min 则返回 min,若 x 大于 max 则返回 max,否则返回 x 本身。这里把地形高度限制在 10~251 之间,防止出现极端值。

其中各参数含义:

参数含义通俗理解
海洋坡度海岸线向深海过渡的坡度(基础值0.006)越靠近海岸线,地势越平缓地下降到海平面以下
丘陵丘陵区域的起伏幅度(强度32)起伏较小,适合建造房屋和农田
山脉山脉区域的起伏幅度(强度220)起伏极大,能到达Y=200以上的高度
河流河谷下切的深度修正(强度1)河流会在地形上切出下陷的河谷
海洋深度离岸越远海床越深控制深海区域的下沉程度

地形三档 ​

世界被分为三种地形区域,由"山脉因子"决定,取值0~1。山脉因子由低频噪声生成:

山脉因子=noise(x, z, 频率=0.0006/群系缩放)\text{山脉因子} = \mathrm{noise}(x,\ z,\ \text{频率}=0.0006/\text{群系缩放})

noise(x, z, freq):噪声函数,根据坐标 (x, z) 和频率生成一个看似随机但连续平滑的值(0~1)。相邻坐标的值相近,远离坐标的值差异大,因此能生成自然的起伏地形而非乱码般的锯齿。

频率极低意味着山脉非常庞大,一个山脉区域可以绵延数百格。根据山脉因子的大小,地形被分为三档:

山脉因子范围地形类型占比特征
0 ~ 0.7平原约70%地势平缓,海拔接近海平面
0.7 ~ 0.87丘陵约17%明显起伏,适合建在山坡或山谷中
0.87 ~ 1山脉约13%高耸入云,海拔可达200以上

山脉区域虽然只占约13%,但高度增幅高达220,是平原的数倍。所以当你发现地面开始剧烈起伏时,你可能已经踏入了山脉区。

群系大小对地形的影响 ​

群系大小设置会影响地形特征的尺度。群系缩放控制温湿度和山脉噪声的采样频率,直接影响群系的大小:

群系缩放=基础系数×群系大小\text{群系缩放} = \text{基础系数} \times \text{群系大小}

模式基础系数效果
大陆模式1.75群系更大,过渡更平缓,走很远才会换气候
岛屿模式1.0群系更小,变化更频繁,小范围内就能体验多种气候

温度与湿度 ​

温度和湿度是决定群系类型的两大核心变量。它们不是固定值,而是随坐标连续变化的噪声场,在世界的每个角落组合出独特的气候。

温度与湿度计算代码

温度计算 ​

温度取值 0~15,由 CalculateTemperature 方法生成:

csharp
public int CalculateTemperature(float x, float z) => Math.Clamp(
    (int)(MathUtils.Saturate(
            3f * SimplexNoise.OctavedNoise(x, z, 0.0015f / TGBiomeScaling, 5, 2f, 0.6f)
            - 1.1f                                    // 偏向寒冷的偏移量
            + m_worldSettings.TemperatureOffset / 16f  // 玩家设置的温度偏移
        )
        * 16f),
    0, 15
);

湿度计算 ​

湿度取值 0~15,由 CalculateHumidity 方法生成:

csharp
public int CalculateHumidity(float x, float z) => Math.Clamp(
    (int)(MathUtils.Saturate(
            3f * SimplexNoise.OctavedNoise(x, z, 0.0012f / TGBiomeScaling, 5, 2f, 0.6f)
            - 0.9f                                    // 偏向干燥的偏移量
            + m_worldSettings.HumidityOffset / 16f     // 玩家设置的湿度偏移
        )
        * 16f),
    0, 15
);

温度 ​

温度取值0~15,数值越高越热。游戏世界的温度分布偏向寒冷,约70%的区域温度不超过7。海拔和季节也会影响实际温度(后面详述)。

温度由噪声采样后经过偏移和映射得到:

温度=clamp( sat(3×噪声−1.1+温度偏移16)×16, 0, 15 )\text{温度} = \mathrm{clamp}\Big(\,\mathrm{sat}\big(3 \times \text{噪声} - 1.1 + \tfrac{\text{温度偏移}}{16}\big) \times 16,\ 0,\ 15\,\Big)

  • clamp(x, min, max):限制函数。若 x 小于 min 则返回 min,若 x 大于 max 则返回 max,否则返回 x 本身。这里把温度限制在 0~15 之间,防止出现极端值。
  • sat(x):饱和函数(同 Saturate)。若 x<0 则返回 0,若 x>1 则返回 1,否则返回 x。作用是把数值限制在 0~1 范围内,防止后续乘法越界

其中:噪声为随坐标变化的随机值(0~1);-1.1是偏移量,使结果偏向寒冷;温度偏移是玩家在创建世界时设置的参数;sat表示将值限制在0~1范围内。

温度范围气候描述
0~3寒带,终年低温,地表常被冰雪覆盖
4~7温带,四季分明,草地和树木最常见
8~11暖温带/亚热带,温暖干燥或温暖湿润
12~15热带,炎热,可能出现沙漠或茂密丛林

湿度 ​

湿度取值0~15,数值越高越湿润。游戏世界的湿度分布偏向干燥,约65%的区域湿度不超过7。

湿度计算逻辑与温度类似,只是偏移量不同:

湿度=clamp( sat(3×噪声−0.9+湿度偏移16)×16, 0, 15 )\text{湿度} = \mathrm{clamp}\Big(\,\mathrm{sat}\big(3 \times \text{噪声} - 0.9 + \tfrac{\text{湿度偏移}}{16}\big) \times 16,\ 0,\ 15\,\Big)

  • clamp(x, min, max):限制函数。若 x 小于 min 则返回 min,若 x 大于 max 则返回 max,否则返回 x 本身。这里把湿度限制在 0~15 之间,防止出现极端值。
  • sat(x):饱和函数(同 Saturate)。若 x<0 则返回 0,若 x>1 则返回 1,否则返回 x。作用是把数值限制在 0~1 范围内,防止后续乘法越界。

其中:-0.9是偏移量,使结果偏向干燥(比温度的-1.1略小,所以世界整体比"偏冷"更"偏干")。

湿度范围气候描述
0~3极干燥,沙漠或荒原
4~7中等湿度,草原或温带森林
8~11湿润,沼泽或热带雨林
12~15极湿润,常年降水充沛

温湿度组合决定群系 ​

温度和湿度共同决定你眼前的景象:

温度湿度环境特征典型植被
高(>8)低(<6)沙漠:地表为沙子,昼夜温差大仙人掌
高(>8)高(>8)热带丛林:温暖湿润,降水丰富茂密阔叶树
中(4~8)中(4~8)温带:四季分明,草地为主普通树木、草丛
低(<4)任意寒带/雪原:地表积雪,植物稀少稀疏针叶树
任意任意高海拔:海拔越高越冷,山顶终年积雪无植被

海拔对温度的影响非常显著。即使地处热带,只要爬得足够高,山顶依然会被冰雪覆盖。反过来,地下深处会温暖得多,深层矿洞永远不会结冰。

地表与地下方块 ​

你脚下踩着的方块,和地底深处的岩石,都不是随机分配的。温度、湿度、海拔和距海距离共同决定了一片区域由什么方块构成。

地下分层 ​

地下岩石分为三层,由浅到深。GenerateTerrain 方法中通过"沙漠标志"判断使用哪种分层:

沙漠=( 温度>8 且 湿度<8 ) 或 ( ∣距海距离∣<16 ),且 山脉因子<0.97\text{沙漠} = \Big(\,\text{温度} > 8\ \text{且}\ \text{湿度} < 8\,\Big)\ \text{或}\ \Big(\,|\text{距海距离}| < 16\,\Big),\quad \text{且}\ \text{山脉因子} < 0.97

其中:温度和湿度为当地气候值(0~15);距海距离为该位置到最近海岸线的格数;山脉因子为 0~1 的地形参数(接近 1 表示高山区域)。满足任一条件即判定为沙漠环境。

条件浅层中层深层
沙漠或海岸附近(isDesert=true)砂岩花岗岩玄武岩
普通区域(isDesert=false)花岗岩花岗岩玄武岩

砂岩只出现在沙漠地下或海岸线附近。如果你在温带地区挖到了砂岩,说明你离海不远了。

地表方块 ​

地表由最上方的覆盖层决定,GenerateSurface 方法按以下优先级判定地表类型:

地表={冰雪若 y>120 且该处冻结石灰岩若砂岩表面且温度∈[5,6]沙子若砂岩表面且温度∉[5,6]沉积物若在水下且湿度>8草地其他情况(默认)\text{地表} = \begin{cases} \text{冰雪} & \text{若}\ y > 120\ \text{且该处冻结} \\ \text{石灰岩} & \text{若砂岩表面且温度} \in [5,6] \\ \text{沙子} & \text{若砂岩表面且温度} \notin [5,6] \\ \text{沉积物} & \text{若在水下且湿度} > 8 \\ \text{草地} & \text{其他情况(默认)} \end{cases}

其中:y为海拔高度;冻结表示该位置有效温度≤0(见后文冰雪章节);砂岩表面指下方岩石为砂岩;水下表示该位置被水覆盖。

条件地表方块说明
沙漠区域沙子(7)高温低湿环境的典型地表
温和气候的砂岩表面石灰岩(6)比沙子更坚硬的地表
高海拔冻结区冰雪(62)温度降到冰点以下的高山或极地
水底沉积物(72)水下特殊方块
默认情况草地(2)最常见、最温暖的地表

地表覆盖层的厚度由海拔和地形起伏共同决定:海拔越高、地形越陡峭,覆盖层越薄,越容易露出下面的岩石。

植被生成 ​

树木、草丛、仙人掌——它们的出现不是随意的,而是被温度、湿度和地表方块严格筛选过的。读懂植被分布规律,你就能从周围的植物反推出此地的气候参数。

树木 ​

  • 树木只生长在草地或高草地表上
  • 海拔必须高于海平面(≥66)
  • 每个区块最多约5棵树
  • 树种由当地温度和湿度决定
  • 树木周围四格不能有阻挡物

仙人掌 ​

GenerateCacti 方法仅在沙漠环境生成仙人掌,生成条件为:

生成仙人掌  ⟺  湿度<6 且 温度>8 且 地表为沙子\text{生成仙人掌} \iff \text{湿度} < 6\ \text{且}\ \text{温度} > 8\ \text{且}\ \text{地表为沙子}

其中:湿度和温度为当地气候值(0~15);地表为沙子是必要条件,仙人掌只能扎根在沙子上。

  • 只出现在高温(>8)且干燥(<6)的区域
  • 必须种在沙子上
  • 典型的沙漠标志

草与植物 ​

  • 由当地温湿度和地表类型共同决定
  • 草地方块可能转变为高草变体
  • 不同气候带生长不同的野花和草丛

冰雪生成 ​

当温度降至冰点以下,水会结冰、地面会覆雪。冰雪的生成遵循严格的温度阈值,而这个阈值还随海拔变化。

海拔温度修正 ​

海拔对温度的影响如下。SubsystemWeather.cs 中的 GetTemperatureAdjustmentAtHeight 方法定义了修正公式:

海拔修正={−round(0.0008×(y−64)2)若 y>64 (海平面以上,二次方降温)round(0.1×(64−y))若 y<64 (海平面以下,线性升温)\text{海拔修正} = \begin{cases} -\mathrm{round}\big(0.0008 \times (y - 64)^2\big) & \text{若}\ y > 64\ \text{(海平面以上,二次方降温)} \\[6pt] \mathrm{round}\big(0.1 \times (64 - y)\big) & \text{若}\ y < 64\ \text{(海平面以下,线性升温)} \end{cases}

round(x):四舍五入取整。把计算结果舍入到最接近的整数,因为温度修正值在游戏中以整数形式生效。

其中:y为海拔高度;64为海平面基准;0.0008和0.1为降温/升温系数。海平面以上按二次方加速降温(越高越冷,Y=200时已降温14度),海平面以下按线性升温(每降低1格升温0.1度,深层矿洞温暖如春)。

海拔温度修正通俗解释
海平面(Y=64)0无影响
Y=100-1略微变冷
Y=150-6明显变冷
Y=200-14非常寒冷
最高点(Y=251)-31极寒
地下浅层(Y=50)+1地下反而更暖
最深处(Y=10)+5深层矿洞温暖如春

海平面以上每升高约35格,温度下降1度。一个原本温度5的温带区域,到了Y=150的高山上,有效温度就变成5-6=-1,已经低于冰点,常年积雪。

冰雪覆盖规则 ​

GenerateSnowAndIce 方法在世界生成时执行。冻结判定由 IsPlaceFrozen 方法决定:

冻结  ⟺  有效温度≤0\text{冻结} \iff \text{有效温度} \le 0

有效温度=基础温度+海拔修正\text{有效温度} = \text{基础温度} + \text{海拔修正}

其中:基础温度为该位置的群系温度(0~15);海拔修正为上文的海拔温度修正值。两者相加若≤0,则该处判定为冻结区域。

  • 冻结区域的水面会变成冰(62),冰面上可能覆雪(61)
  • 冻结区域的方块上方会覆盖雪(61)
  • 冰层厚度1~3格,由噪声随机决定
  • 雪覆盖层厚度与温度相关:越冷越厚

区块生成步骤 ​

一个16×16的区块从空白到可居住,需要经过四个阶段的流水线处理。每个阶段负责不同的内容,理解这个流程有助于排查地形异常或开发模组。

阶段步骤序号生成内容
阶段11计算上半区块温湿度
2生成上半区块基础地形
阶段23计算下半区块温湿度
4生成下半区块基础地形
阶段35生成洞穴
6生成矿袋(泥土、沙砾等)
7生成矿物
8生成地表方块
9流体向下传播
阶段410生成草和植物
11生成原木
12生成树木
13生成仙人掌
14生成南瓜
15生成海带
16生成海草
17生成底栖植物
18生成陷阱
19生成藤蔓
20生成墓碑
21生成石堆
22生成冰雪
23生成基岩和空气
24更新流体顶面状态

出生点选择 ​

游戏会根据你选择的难度,在世界上寻找最适合出生的位置。不同难度对温湿度、海拔和地形起伏有不同偏好。

ScoreSpawnPosition 方法为每个候选位置打分,分数越低越不适合出生:

惩罚条件简单模式中等模式困难模式
距原点>400格-0.25-0.25-0.25
低于海平面-1.5-1.5-1.5
山脉因子>0.9-1.5-1.5-1.5
温度过低<7: -1<3: -0.5>0: -0.5
温度过高—>6: -1>2: -1
湿度极端2~10: -0.53~8: -0.5>6: -1.5
海拔过高>75: -1>80: -1>85: -1
地形起伏大>5: -1>10: -1>15: -1
地形太平坦——<5: -0.5

通俗解释:简单模式倾向于把你放在温带平原(温度适中、湿度适中、地势平坦);困难模式则可能把你推向更极端的环境(寒冷或干燥、地形崎岖)。但所有模式都会避免让你在水下或高山顶上出生。

联机版新地形 ​

联机版快照提供了额外的世界生成模板。

基岩大陆 (Bedrock) ​

核心机制 ​

  • 地表高度:固定在第3-7层(基岩大陆优化)
  • 世界结构:基岩底层 + 骨架大陆 + 虚空顶部
  • 水体:不生成(TGWater = false)
  • 地形特征:极低高度,无高山,平坦骨架

矿石生成逻辑 ​

基岩大陆模式:minHeight = 2, maxHeight = 6, 数量倍率 = 0.3
普通模式:minHeight = 50, maxHeight = 61, 数量倍率 = 1.0
矿石生成高度生成数量公式替换方块
煤矿石Y=2-6(5 + 3 × 山脉因子 × 噪声) × 0.3石头(3)
铁矿石Y=2-6(6 + 2 × 山脉因子 × 噪声) × 0.3石头(3)
铜矿石Y=2-6(5 + 2 × 山脉因子 × 噪声) × 0.3石头(3)
硝石Y=2-6(3 + 3 × 山脉因子 × 噪声) × 0.3石头(3)
硫磺Y=2-6(3 + 2 × 山脉因子 × 噪声) × 0.3石头(3)
锗矿Y=2-6(3 + 2 × 山脉因子 × 噪声) × 0.3石头(3)

石头大陆 (Stone) ​

核心机制 ​

  • 出生平台:固定位置 (-433, 280),21×21大小,结构为基岩(2层)→泥土→草方块
  • 世界结构:除出生平台外,整个世界被石头填充,只在岛屿区域有地形
  • 岛屿生成:半径20格,高度40格,结构为基岩→石头→泥土→草方块
  • 岩浆池:初始岛必生成1-2个岩浆池,其他岛15%概率生成

矿石生成逻辑 ​

石头地形的矿石生成有两种方式:

方式1:标准矿物生成(类似其他地形)方式2:空气填石头时随机生成(5%概率)

矿石高度条件概率方块ID
钻石矿Y < 3010%112
锗矿Y < 6020%148
铁矿Y < 8030%39
铜矿Y < 10040%41
硫磺-50%101
硝石-70%100
煤矿-默认16

空岛地形 (SkyIsland) ​

核心机制 ​

  • 基准高度:30层(BaseHeight = 30)
  • 出生平台:半径128格,连接岛区域,基岩底层防止挖空
  • 岛屿生成:基于噪声阈值(0.3)判断,高于阈值生成岛屿
  • 地形特征:低空、密集、紧凑的岛屿分布

岩浆池生成 ​

  • 概率:8%(每个区块)
  • 位置:岛屿内部,不超出岛屿边界
  • 尺寸:半径2-4格,深度2-3格
  • 生成规则:岩浆顶部 = 岛屿表面下1格,底部 = 表面下N格(不挖穿岛屿)

优化地形 (Better) ​

核心机制 ​

  • 盆地生成:噪声值 < 0.29 的区域生成盆地,深度由噪声计算
  • 海平面:64层
  • 水体:生成(TGWater = true)
  • 河流强度:增强(TGRiversStrength = 5f)

关键参数对比(与标准地形) ​

参数标准值优化值
河流强度1.05.0
山脉高度220250
山脉频率0.0090.0006
山区百分比60%13%
山丘百分比50%15%
密度偏差9655

写给开发者 ​

资料暂存

本小节内容暂时存放于此,后续会移动至"MOD开发"章节。

开发概览

如果你计划开发地形模组或自定义世界生成,以下技术细节将帮助你快速理解系统架构。

核心文件索引 ​

文件职责
TerrainContentsGenerator23.cs地形内容生成器主类,包含所有生成方法
WorldSettings.cs世界生成参数定义
TerrainGenerationMode.cs地形模式枚举
TerrainUpdater.cs季节温度曲线和区块状态更新
SubsystemWeather.cs天气、温度修正、冻结判定
SubsystemSeasons.cs季节划分和转换
Terrain.cs地形数据存取,季节温湿度计算
Season.cs季节枚举(Summer=0, Autumn=1, Winter=2, Spring=3)

全部 TG 参数速查表 ​

csharp
// 群系缩放(影响温湿度和山脉噪声频率)
TGBiomeScaling = (Island ? 1f : 1.75f) * BiomeSize;

// 海洋
TGOceanSlope = 0.006f;
TGOceanSlopeVariation = 0.004f;
TGIslandsFrequency = 0.01f;
TGShoreFluctuations = Clamp(2f * minIslandSize, 0f, 150f);
TGShoreFluctuationsScaling = Clamp(0.04f * minIslandSize, 0.5f, 3f);

// 高度基准
TGDensityBias = 55f;
TGHeightBias = 1f;

// 河流
TGRiversStrength = 1f;

// 山脉
TGMountainsStrength = 220f;
TGMountainRangeFreq = 0.0006f;
TGMountainsPercentage = 0.13f;
TGMountainsDetailFreq = 0.003f;
TGMountainsDetailOctaves = 3;
TGMountainsDetailPersistence = 0.53f;

// 丘陵
TGHillsPercentage = 0.3f;
TGHillsStrength = 32f;
TGHillsOctaves = 1;
TGHillsFrequency = 0.014f;
TGHillsPersistence = 0.5f;

// 湍流(地形扰动)
TGTurbulenceStrength = 55f;
TGTurbulenceFreq = 0.03f;
TGTurbulenceOctaves = 1;
TGTurbulencePersistence = 0.5f;
TGMinTurbulence = 0.04f;
TGTurbulenceZero = 0.84f;

// 地表
TGSurfaceMultiplier = 2f;

// 开关
TGWater = true;        // 生成水
TGExtras = true;       // 生成植被和装饰
TGCavesAndPockets = true;  // 生成洞穴和矿袋

// 海平面
OceanLevel = 64 + SeaLevelOffset;

// 基岩
MaxBedrockHeight = 4;

高度计算完整公式 ​

csharp
public float CalculateHeight(float x, float z) {
    // 1. 海洋坡度(控制海岸坡度)
    float oceanSlope = TGOceanSlope + TGOceanSlopeVariation * noise;

    // 2. 距海距离
    float shoreDist = CalculateOceanShoreDistance(x, z);
    float shoreFactor = Saturate(2f - 0.05f * Abs(shoreDist));
    float islandFactor = Saturate(Sin(TGIslandsFrequency * shoreDist));
    float oceanDepth = Saturate(Saturate(-oceanSlope * shoreDist) - 0.85f * islandFactor);
    float farFromShore = Saturate(Saturate(0.05f * (-shoreDist - 10f)) - islandFactor);

    // 3. 山脉因子
    float mountain = CalculateMountainRangeFactor(x, z);

    // 4. 丘陵/山脉区域权重
    float hillsWeight = (1 - farFromShore) * (1 - shoreFactor) * Squish(mountain, 1 - TGHillsPercentage, 1 - TGMountainsPercentage);
    float mountainsWeight = (1 - farFromShore) * Squish(mountain, 1 - TGMountainsPercentage, 1);

    // 5. 丘陵噪声
    float hillsNoise = SimplexNoise.OctavedNoise(x, z, TGHillsFrequency, TGHillsOctaves, 1.93f, TGHillsPersistence);
    float hills = TGHillsStrength * hillsWeight * hillsNoise;

    // 6. 山脉噪声
    float mountainsNoise = 1.5f * SimplexNoise.OctavedNoise(x, z, TGMountainsDetailFreq, TGMountainsDetailOctaves, 1.98f, persistence) - 0.5f;
    float mountains = TGMountainsStrength * mountainsWeight * mountainsNoise;

    // 7. 河流
    float riverNoise = Saturate(1.5f - riverWidth * Abs(2f * SimplexNoise.OctavedNoise(x, z, 0.001f, 4, 2f, 0.5f) - 1f));
    float rivers = TGRiversStrength * riverNoise;

    // 8. 组合
    float baseHeight = -50f * oceanDepth + TGHeightBias;
    float result = baseHeight + Lerp(0, 8, f) + Lerp(0, -6, f2) + mountains + hills;
    result = Min(Lerp(result, Lerp(-2, -4, ...), rivers), result);

    return Math.Clamp(64f + result, 10f, 251f);
}

温湿度计算关键细节 ​

csharp
// 温度:5层八度噪声,频率0.0015/TGBiomeScaling
// 偏移-1.1使结果偏向寒冷(约70%区域温度≤7)
// 最终结果 × 16 后取整,范围0~15
int temperature = Clamp(
    (int)(Saturate(3f * noise - 1.1f + tempOffset/16f) * 16f),
    0, 15
);

// 湿度:5层八度噪声,频率0.0012/TGBiomeScaling
// 偏移-0.9使结果偏向干燥(约65%区域湿度≤7)
int humidity = Clamp(
    (int)(Saturate(3f * noise - 0.9f + humidOffset/16f) * 16f),
    0, 15
);

地表方块判定完整逻辑 ​

csharp
void GenerateSurface(TerrainChunk chunk) {
    // 遍历每个x,z列,从顶向下找到第一个非透明方块
    int topBlock = FindTopmostSolidBlock(i, j);
    int temperature = terrain.GetTemperature(x, z);
    int humidity = terrain.GetHumidity(x, z);

    int surfaceBlock;
    if (topBlock == 4) {  // 砂岩表面
        // 温和气候→石灰岩,极端气候→沙子
        surfaceBlock = (temperature > 4 && temperature < 7) ? 6 : 7;
    } else {
        int tempBand = temperature / 4;  // 温度带0~3
        int blockAbove = GetBlockAbove(topBlock);

        surfaceBlock =
            // 高海拔冻结→冰雪
            (y > 120 && IsPlaceFrozen(temperature, y)) ? 62 :
            // 特定条件→玄武岩(罕见)
            ((y < 66 || y == 84 + tempBand || y == 103 + tempBand) && humidity == 9 && temperature % 6 == 1) ? 66 :
            // 水下高湿→沉积物
            (blockAbove == 18 && humidity > 8 && humidity % 2 == 0 && temperature % 3 == 0) ? 72 :
            // 默认→草地
            2;
    }

    // 覆盖层厚度
    int thickness;
    if (surfaceBlock == 62) {  // 冰雪
        thickness = Clamp(-temperature, 1, 7);  // 越冷越厚
    } else {
        // 海拔越高、山脉越陡、湿度越低→覆盖层越薄
        float heightFactor = Saturate((y - 100f) * 0.05f);
        float f = Saturate(mountainFactor * heightFactor + surfaceMultiplier * heightFactor);
        thickness = Random(Int(Lerp(4, 0, f), Lerp(7, 0, f)));
    }

    // 将覆盖层方块写入区块
    ReplaceTopBlocks(surfaceBlock, thickness);
}

沙漠标志判定 ​

csharp
// 在 GenerateTerrain 中决定地下方块类型
bool isDesert = (temperatureFast > 8 && humidityFast < 8 && mountainFactor < 0.97f)
             || (Math.Abs(oceanShoreDistance) < 16f && mountainFactor < 0.97f);

// 沙漠/海岸:浅层砂岩(4) → 中层花岗岩(3) → 深层玄武岩(67)
// 普通:    浅层花岗岩(3) → 深层玄武岩(67)
// 沙漠的砂岩层厚度由 mountainFactor 和 humidity 决定:
//   thickness1 = Lerp(100, 0, mountainFactor - 0.01 * humidity)  // 砂岩层
//   thickness2 = Lerp(300, 30, mountainFactor - 0.01 * humidity)  // 花岗岩层

季节温度曲线数据 ​

csharp
// TerrainUpdater.cs 中的 FloatCurve 定义
public FloatCurve TemperatureCurve = new(
    new Vector2(0f, 0f),       // 盛夏:无修正
    new Vector2(0.125f, 0f),   // 仲夏:无修正
    new Vector2(0.25f, 0f),    // 初秋:无修正
    new Vector2(0.375f, -4f),  // 中秋:-4
    new Vector2(0.5f, -12f),   // 初冬:-12
    new Vector2(0.625f, -24f), // 隆冬:-24(全年最冷)
    new Vector2(0.75f, -12f),  // 初春:-12
    new Vector2(0.875f, -4f),  // 仲春:-4
    new Vector2(1f, 0f)        // 回到盛夏:0
);

// 湿度不受季节影响
public FloatCurve HumidityCurve = new(
    new Vector2(0f, 0f),
    new Vector2(1f, 0f)  // 全年不变
);

季节温度的传递链 ​

WorldSettings.TimeOfYear (0~1)
    → TerrainUpdater.Update()
    → TemperatureCurve.Sample(timeOfYear) → SeasonTemperature
    → Terrain.SeasonTemperature = num
    → Terrain.GetSeasonalTemperature(x, z) = GetTemperature(x, z) + SeasonTemperature
    → SubsystemWeather.IsPlaceFrozen(seasonalTemp, y)
    → 决定降水类型(雪/雨/无)和冰雪生成

平坦模式的影响 ​

平坦模式(FlatContinent/FlatIsland)通过降低山脉和丘陵强度来实现平坦效果。虽然源码中 TerrainContentsGenerator23.cs 的 TG 参数在构造函数中统一设置,但平坦模式会在外部调整以下参数:

  • 山脉强度大幅降低(地形不会出现Y=200+的高山)
  • 丘陵强度降低(地势起伏更平缓)
  • 整体高度更接近海平面(Y=64)

方块索引速查 ​

索引方块名用途
0空气—
1基岩不可破坏,Y=0~4
2泥土常见地表
3花岗岩常见地下岩石
4砂岩沙漠地下岩石
6石灰岩温和气候地表
7沙子沙漠地表
8草地草地
18水海洋/河流/湖泊
61雪地面覆雪
62冰水面冻结
66玄武岩深层岩石/特殊地表
67玄武岩深层地下岩石
72沉积物水底特殊方块
127仙人掌沙漠植被
参与共建发现错误或有建议?两种零门槛方式,无需本地环境

玩家共建文档 · 原版、插件版、联机版与插件联机版请注意区分