GenLayer 生成栈

基本信息

属性 值
源码位置 climateControl/generator/、climateControl/customGenLayer/、climateControl/genLayerPack/
自定义 GenLayer 类 customGenLayer/ 44 个文件 + genLayerPack/ 23 个文件(ls src/main/java/climateControl/{customGenLayer,genLayerPack}/*.java | wc -l)
生成器实现 VanillaCompatibleGenerator(默认)、OneSixCompatibleGenerator(1.6 模式)、CorrectedContinentsGenerator(RTG 世界)
补丁方式 反射改写 WorldChunkManager 的 field_76944_d(genBiomes)与 field_76945_e(biomeIndexLayer)
作用对象 世界生物群系生成,不含方块/物品

功能

Climate Control 不注册任何 IWorldGenerator,而是通过 Forge 的 WorldTypeEvent.InitBiomeGens 事件(ClimateControl.java:240-249,优先级 LOWEST)替换已有的 GenLayerRiverMix 引用,从而接管生物群系生成。

补丁入口 GenLayerUpdater.update()(GenLayerUpdater.java:25-34):

accessGenLayer.setField(provider.worldChunkMgr, riverMix);
accessBiomeIndex.setField(provider.worldChunkMgr, riverMix.voronoi());

两个 Accessor 的字段映射见 GenLayerUpdater.java:18-23(SRG 名 field_76944_d / field_76945_e,MCP 名 genBiomes / biomeIndexLayer)。

生成栈的选择发生在 DimensionManager.patchedGenLayer()(DimensionManager.java:85-126):

条件 结果 出处
ignore() 判定为不接管 返回 null,不接管 :91
No Generation Changes = true 且 1.6Compatibility = true OneSixCompatibleGenerator.fromSeed :92-94
No Generation Changes = true 且 1.6Compatibility = false 返回 null,完全不接管 :95-97
VanillaLandAndClimate = true VanillaCompatibleGenerator.fromSeed → likeVanilla :103-104、VanillaCompatibleGenerator.java:45-47
其余情况(默认路径) CorrectedContinentsGenerator.fromSeed :105-107

注意 VanillaLandAndClimate 的默认值是 false(ClimateControlSettings.java:157-158),因此 CorrectedContinentsGenerator 才是默认生效的生成器;VanillaCompatibleGenerator 需要显式打开 VanillaLandAndClimate 才会被使用。

补丁返回后,若结果是 GenLayerLowlandRiverMix,会把 maxChasm 设为 settings.maxRiverChasm.value()(:117-121),即 综合参数 的 maxChasm。

数值

默认生成栈(CorrectedContinentsGenerator)

这是默认生效的路径(VanillaLandAndClimate = false)。与 1.7 栈最大的结构差别在于:它不使用 GenLayerAddIsland 的多档 seed 播种,而是用 GenLayerOceanicIslands 按频率播种大陆/岛屿,并用 growRound() 做多轮扩张。

大陆与岛屿播种(generator/CorrectedContinentsGenerator.java:105-257):

阶段 GenLayer 类 seed 出处行 频率来源
空白海洋基底 GenLayerConstant 0 :105 常量海洋层
大陆播种 GenLayerOceanicIslands("Large Continent") 1 :106-113 largeContinentFrequency
大陆扩张 growRound(genlayerisland, 2L, 3L, ...) 2 / 3 :114、:274-298 landExpansionRounds 轮
中陆播种 GenLayerOceanicIslands("Medium Continent") 4 :123-129 mediumContinentFrequency
中陆扩张 growRound(mediumContinents, 5L, 7L, ...) 5 / 7 :131 landExpansionRounds 轮
小陆播种 GenLayerOceanicIslands("Small Continent") 8 :141-147 smallContinentFrequency
强制起始大陆 GenLayerForceStartLand — :152-154 forceStartContinent = true 时
小陆扩张 growRound(smallContinents, 2L, 3L, ...) 2 / 3 :159 landExpansionRounds 轮
大岛播种 GenLayerOceanicIslands("Large Island") 11 :176-192 largeIslandFrequency
大岛扩张 growRound(genlayeraddisland, 13L, 15L, ...) 13 / 15 :194 landExpansionRounds 轮
中岛播种 GenLayerOceanicIslands("Medium Island") 17 :215-231 mediumIslandFrequency
中岛调整 GenLayerAdjustIsland 21 :233 固定参数 3, 12, 12, false
边缘缓存 GenLayerLimitedCache 100 :251 固定容量 100
大陆架 GenLayerContinentalShelf 23 :253 —
蘑菇岛 GenLayerOceanicMushroomIsland 24 :254-257 mushroomIslandIncidence

growRound() 的行为(:274-298):separateLandmasses = true 时按 landExpansionRounds 循环,每轮插入 GenLayerAdjustIsland + GenLayerBreakMergers 两次(seed firstSeed + round*50 与 secondSeed + round*50,+1000 用于 BreakMergers);separateLandmasses = false 时只插入一层 GenLayerAdjustIsland,不打断合并。

气候带层的三个插入点由 doFull() / doHalf() / quarterSize 决定(ClimateControlSettings.java:313-319:doFull() = !halfSize && !quarterSize,doHalf() = halfSize && !quarterSize):

条件 插入位置 seed 出处行
doFull()(full-size) 小陆扩张之后 1014 :160-163
doHalf()(half-size,默认值) 大岛扩张之后 1014 :198-203
quarterSize 中岛调整之后 1014 :234-239

三者插入的都是 climateLayer(1014L, ...)(:329-334),返回哪一类取决于 气候带参数 的 bandedClimateWidth:

条件 返回的 GenLayer 出处行
bandedClimateWidth > 0 GenLayerBandedClimate(seed 1014,multiplier 1) :330-331
bandedClimateWidth <= 0(默认 -1) GenLayerIdentifiedClimate :333

插入后 climatesAssigned 置为 true;之后岛屿播种改用 islandClimates(...) 而非 landmassIdentifier()(:174-192、:213-231)。islandClimates(level)(:300-314)在 bandedClimateWidth > 0 时同样返回 GenLayerBandedClimate(seed 0,multiplier 随 doFull() / doHalf() 与 level 取 4 / 2 / 1,:302-310);否则按 separateLandmasses 在 identifiedClimate() 与 islandClimates() 间二选一(:313)。

末端分岔(:264-267):smootherCoasts = true(默认)走 climateControlExpansion(...),其中大量使用 GenLayerSmoothCoast(:390、:406、:416、:420)与 GenLayerLowlandRiverMix(:448);否则走 vanillaExpansion(...),即 AbstractWorldGenerator.oneSevenExpansion(generator/AbstractWorldGenerator.java:114-170)。

1.7 兼容生成栈(VanillaLandAndClimate = true)

VanillaCompatibleGenerator.likeVanilla()(generator/VanillaCompatibleGenerator.java:49-135)。下表的类名与 seed 全部取自源码字面量:

顺序 GenLayer 类 seed 出处行 作用
1 GenLayerIsland 1 :57 噪声基础层
2 GenLayerFuzzyZoom 2000 :58 模糊缩放
3 GenLayerAddIsland 1 :59 播种大岛
4 GenLayerZoom 2001 :60 缩放
5 GenLayerAddIsland 2 :61 播种小岛
6 GenLayerAddIsland 50 :62 播种陆地
7 GenLayerAddIsland 70 :63 播种陆地
8 GenLayerRemoveTooMuchOcean 2 :64 削减过多海洋
9 GenLayerAddSnow 2 :65 加雪
10 GenLayerAddIsland 3 :66 播种
11 GenLayerEdge(Mode.COOL_WARM) 2 :67 气候带边缘
12 GenLayerEdge(Mode.HEAT_ICE) 2 :68 冷热边缘
13 GenLayerEdge(Mode.SPECIAL) 3 :69 特殊边缘
14 GenLayerZoom 2002 :70 缩放
15 GenLayerZoom 2003 :71 缩放
16 GenLayerAddIsland 4 :72 播种
— smoothClimates(settings(), worldSeed, parent, 0L) — :74 气候平滑(masterSeed 传 0L)
17 GenLayerAddMushroomIsland 5 :77 蘑菇岛
18 GenLayerDeepOcean 4 :78 深海
19 GenLayerLessRiver 100 :86 河流初始化(RTG 下强制 100)
20 GenLayerBiomeByClimate 或 GenLayerRandomBiomes worldSeed :90 / :92 按气候带或随机分配生物群系
— GenLayerZoom.magnify(1000L, object, 2) 1000 :96 放大 2 次
21 GenLayerBiomeEdge 1000 :97 生物群系边缘
22 GenLayerSubBiome 1000 :100-106 次级生物群系(hills / BoP)
23 GenLayerRiver 1 :111 河流
24 GenLayerSmooth 1000 :112 平滑
25 GenLayerRareBiome 1001 :113 稀有生物群系
26 GenLayerZoom × b0 1000 + j :115-116 按 Biome Size 循环缩放
27 GenLayerAddIsland(仅 j == 0) 3 :118-119 播种
28 GenLayerShore(仅 j == 1) 1000 :122-123 海岸
29 GenLayerSmooth 1000 :127 末端平滑
30 GenLayerRiverMix 100 :128 河流混合(返回对象)
31 GenLayerVoronoiZoom 10 :129 Voronoi 缩放(作为 biomeIndexLayer)

其中 b0 = settings().biomeSize.value()(:80-81),即 综合参数 的 Biome Size,默认 4。j == 1 的 GenLayerShore 只在 b0 >= 2 时才会被插入。

smoothClimates() 只有一个分支生效:if (false) 内的旧版平滑(GenLayerTemperClimate + 三层 GenLayerEdge)是死代码(generator/AbstractWorldGenerator.java:60-66,注释保留了原始条件 settings.climateControlcompatibility),实际走 else 分支返回 new GenLayerSmoothClimate(masterSeed, parent)(:67-70)。

第 20 层的二选一由 综合参数 的 Random Biomes 决定(:89-93)。第 19 层的 seed 经 rtgAwareRiverReduction() 处理,RTG 世界类型下强制为 100(generator/AbstractWorldGenerator.java:99-103)。

1.6 兼容模式生成栈

oneSixCompatibility = true 时走 OneSixCompatibleGenerator.strictVanilla()(generator/OneSixCompatibleGenerator.java:143-190)。前段与 1.7 栈的岛屿/缩放链相同但用 1.6 变体:

顺序 GenLayer 类 seed 出处行 说明
1 GenLayerIsland 1 :144 同 1.7
2 GenLayerFuzzyZoom 2000 :145 同 1.7
3 GenLayerAddIsland 1 :146 同 1.7
4 GenLayerZoom 2001 :147 同 1.7
5 GenLayerAddIsland 2 :148 同 1.7
6 GenLayerAddSnowOneSix 2 :149 1.6 变体(替代 GenLayerAddSnow + 额外的 AddIsland(50) / AddIsland(70))
7 GenLayerZoom 2002 :150 缩放
8 GenLayerAddIsland 3 :151 播种
9 GenLayerZoom 2003 :152 缩放
10 GenLayerAddIsland 4 :153 播种
11 GenLayerAddMushroomIsland 5 :154 蘑菇岛
12 GenLayerRiverInit 100 :160 河流初始化(1.7 路径用 GenLayerLessRiver)
— GenLayerZoom.magnify(1000L, genlayerriverinit, b0 + 2) 1000 :161 放大 b0 + 2 次(1.7 路径放大 b0 次)
13 GenLayerRiver 1 :162 河流
14 GenLayerSmooth 1000 :163 平滑
15 GenLayerOneSixBiome 200 :165 1.6 变体(替代 GenLayerBiomeByClimate / GenLayerRandomBiomes)
16 GenLayerHillsOneSix 1000 :167 1.6 变体(替代 GenLayerSubBiome)
17 GenLayerZoom × b0 1000 + j :169-170 循环缩放
18 GenLayerAddIsland(仅 j == 0) 3 :172-173 播种
19 GenLayerShore(仅 j == 1) 1000 :176-177 海岸
20 GenLayerSwampRivers(仅 j == 1) 1000 :180-181 1.6 专属:沼泽河流
21 GenLayerSmooth 1000 :185 末端平滑
22 GenLayerRiverMix 100 :186 河流混合(返回对象)
23 GenLayerVoronoiZoom 10 :187 Voronoi 缩放

1.6 路径与 1.7 路径的关键差异:

  • b0 被硬编码为 4(:155-157 连续两次赋值 b0 = 4),因此 综合参数 的 Biome Size 在 1.6 模式下无效
  • 不包含 GenLayerBiomeEdge、GenLayerRareBiome、GenLayerSubBiome、GenLayerBiomeByClimate、GenLayerRandomBiomes、GenLayerRemoveTooMuchOcean、GenLayerLessRiver
  • 不直接调用 subBiomeChooser.set(...)、setOceanSubBiomes()、mBiomeChooser.set(...)——对比 1.7 路径的 :50-54。因此 1.6 模式下 生物群系设置 的 incidence、气候带分配与次级生物群系均不生效(setRules() 仍会经由 AbstractWorldGenerator 构造函数执行,见 村庄生物群系)
  • 多出一层 GenLayerSwampRivers

交互

  • Mystcraft 深度改造:GenLayerUpdater.update() 末尾在 try 中调用 new Myst11GenLayerUpdater().update(riverMix, provider),捕获 NoClassDefFoundError 后记录 “no class for Myst update” 并跳过(GenLayerUpdater.java:29-33)。Mystcraft 1.1 的更新器会替换 WorldProviderMyst 的 AgeController.biomeController,并改写 SymbolBiomeControllerNative 的 genBiomes / biomeIndexLayer(Myst11GenLayerUpdater.java:40-53);Myst10GenLayerUpdater 是 1.0 版本的对应实现(Myst10GenLayerUpdater.java:41-44)。
  • Biomes O’ Plenty 次级生物群系:GenLayerSubBiome 在 ClimateControl.isBoPLoaded && doBoP 时插入 BoP 次级生物群系(customGenLayer/GenLayerSubBiome.java:47);isBoPLoaded 由 Loader.isModLoaded("BiomesOPlenty") 在 preInit 设定(ClimateControl.java:115),doBoP 来自 settings().doBoPSubBiomes()(VanillaCompatibleGenerator.java:106)。
  • 边缘缓存:climateRingsNotSaved / biomeRingsNotSaved / subBiomeRingsNotSaved 控制边缘若干圈不写入存档(ClimateControlSettings.java:163-174)。

未被调用的生成方法(死代码)

以下方法在全仓库无调用点,复现命令 grep -rn 'strict17Vanilla\|strictVanilla\|likeVanilla' --include=*.java src/(public GenLayerRiverMix 声明除外):

方法 出处 调用者
VanillaCompatibleGenerator.strictVanilla(long) generator/VanillaCompatibleGenerator.java:141 无(fromSeed 走 likeVanilla)
OneSixCompatibleGenerator.likeVanilla(long) generator/OneSixCompatibleGenerator.java:52 无(fromSeed 走 strictVanilla)
OneSixCompatibleGenerator.strict17Vanilla(long) generator/OneSixCompatibleGenerator.java:193 无

相关条目