世界生成

基本信息

属性 值 来源
注册点 GameRegistry.registerWorldGenerator(new DraconicWorldGenerator(), 0) CommonProxy.java:258(registerWorldGen(),由 CommonProxy.java:156 调用)
注册优先级 0 同上
实现类 DraconicWorldGenerator implements IWorldGenerator common/world/DraconicWorldGenerator.java:16
源码规模 common/world/ 4 个类:DraconicWorldGenerator / ChaosWorldGenHandler / WorldGenEnderComet / WorldGenEnderIsland 目录枚举
产物 龙矿 draconiumOre、末影彗星、混沌岛 见下

本条目是本 wiki 中唯一记录世界生成的页面。生成逻辑全部在服务端侧(common/),客户端不做任何补偿。

三个分支的总入口

DraconicWorldGenerator.generate 按 world.provider.dimensionId 分派(DraconicWorldGenerator.java:23-66,switch 在 :25):

dimensionId 方法 生成内容
0(主世界) generateSurface 仅龙矿
1(末地) generateEnd 末影彗星 + 混沌岛 + 龙矿
-1(下界) generateNether 仅龙矿
其它 匿名分支 仅龙矿,受黑白名单控制

主世界与下界不生成彗星与混沌岛 —— 这两项是末地专属。

龙矿生成

四个分支共用 addOreSpawn(block, world, random, chunkX*16, chunkZ*16, minVainSize, maxVainSize, chancesToSpawn, minY, maxY)(DraconicWorldGenerator.java:106-118)。

维度 最小矿脉 最大矿脉 生成权重 minY maxY 开关配置项 权重配置项
主世界 3 4 2 2 8 disableOreSpawnOverworld(默认 false) oreWeightOverworld(2)
末地 4 5 10 1 70 disableOreSpawnEnd(默认 false) oreWeightEnd(10)
下界 3 4 5 1 125 disableOreSpawnNether(默认 false) oreWeightNether(5)
其它维度 3 4 2 2 8 黑白名单 oreWeightDefault(2)

引用:DraconicWorldGenerator.java:68-72(主世界)、74-86(末地)、88-101(下界)、53-65(其它维度)。全部权重与开关的默认值见配置项总览。

末地龙矿的权重(10)与垂直跨度(Y 1–70)都明显高于其它维度,是寻找龙矿的主战场。

addOreSpawn 的三宿主方块

addOreSpawn 的循环体对每一次尝试都连续生成三条矿脉(DraconicWorldGenerator.java:112-116):

宿主方块 矿脉大小 引用
Blocks.end_stone(末地石) minVainSize + random.nextInt(maxVainSize - minVainSize)(随机) DraconicWorldGenerator.java:112
Blocks.stone(石头) 固定 3 DraconicWorldGenerator.java:114
Blocks.netherrack(下界岩) 随机(同 end_stone) DraconicWorldGenerator.java:115-116

即:在任何维度中,代码都会尝试在末地石、石头、下界岩三种宿主上各替换一次。在主世界只有 stone 那一条会命中,另外两条因为世界里不存在对应方块而空转。这是无害的冗余,但读源码时容易误以为「主世界会生成末地石」。

坐标计算:posX = chunkXPos + random.nextInt(16),posZ 同理;posY = minY + random.nextInt(maxY - minY)(不含上界 maxY)。

自定义维度的黑白名单

其它维度分支(DraconicWorldGenerator.java:35-65)依次做两次判定:

  1. 白名单优先:oreGenDimensionWhitelist 长度 > 0 时,当前 dimensionId 不在其中则直接 return(DraconicWorldGenerator.java:36-47)
  2. 黑名单:oreGenDimentionBlacklist 中的任一维度则 return(DraconicWorldGenerator.java:48-52)

两个列表默认为空 int[]。因为白名单先判定,同时填两者时白名单胜出。oreGenDimentionBlacklist 的拼写错误(Dimention)来自源码本身。

末影彗星

仅末地,DraconicWorldGenerator.generateEnd(DraconicWorldGenerator.java:74-86)。四个条件全部满足才生成:

条件 来源
cometsEnabled(静态开关,默认 true) DraconicWorldGenerator.java:19
ConfigHandler.generateEnderComets(配置项,默认 true) DraconicWorldGenerator.java:78
Math.sqrt(x * x + z * z) > 200 DraconicWorldGenerator.java:79
random.nextInt(Math.max(1, cometRarity)) == 0 DraconicWorldGenerator.java:80

cometRarity 默认 10000,即平均每 10000 次末地区块生成尝试才命中 1 次(ConfigHandler.java 的 cometRarity 声明)。

⚠️ 半径 200 的判定用的是区块角坐标:generateEnd 收到的 x / z 已经是 chunkX * 16 / chunkZ * 16(DraconicWorldGenerator.java:27),而彗星实际落点 x1 / z1 是该角坐标再加 random.nextInt(16)(DraconicWorldGenerator.java:75、:77)。因此判定与落点之间存在最多 16 格的偏差,且靠近半径边界时表现不是严格圆形。

落点高度:y = 20 + random.nextInt(170),即 Y 20–189(DraconicWorldGenerator.java:76)。

生成器为 WorldGenEnderComet(common/world/WorldGenEnderComet.java)。

混沌岛

仅末地,双开关同时打开才生成(DraconicWorldGenerator.java:82-83):chaosIslandsEnabled(静态,默认 true,DraconicWorldGenerator.java:18)与 ConfigHandler.generateChaosIslands(默认 true)。调用 ChaosWorldGenHandler.generateChunk(world, x / 16, z / 16, null, random),第三个参数 null 表示由网格自动决定岛屿中心。

岛屿中心网格

ChaosWorldGenHandler.getClosestChaosSpawn(ChaosWorldGenHandler.java:174-178):

new DataUtils.XZPair<>(
    Utils.getNearestMultiple(chunkX * 16, ConfigHandler.chaosIslandSeparation),
    Utils.getNearestMultiple(chunkZ * 16, ConfigHandler.chaosIslandSeparation))

即岛屿中心落在间距为 chaosIslandSeparation 的方格网上,间距默认 10000 格(ConfigHandler.java:290-295)。源码 Javadoc 写的是「a 10000 by 10000 grid」(ChaosWorldGenHandler.java:31-32)—— 这只是默认值,实际间距可配置。

⚠️ 原点 (0, 0) 处的岛屿永不生成:generateChunk 开头有 if (closestSpawn.x == 0 && closestSpawn.z == 0) return;(ChaosWorldGenHandler.java:39)。GeneratorOverride.getNearestChaosIslandCenter 也重复了这一约定。

地形与结构

generateChunk 先做 180 格的快速排除(copyStartDistance = 180,ChaosWorldGenHandler.java:42-44),随后按 y 从 0 到 254 遍历,用三层衰减函数算出 density,仅当 density > 0.1 时才在 y + 64 处放置方块(ChaosWorldGenHandler.java:51-99)。地形替换规则是 (dist > 60 || dist > random.nextInt(60)) ? end_stone : obsidian(ChaosWorldGenHandler.java:96)—— 距中心 60 格内大多被替换为黑曜石。

generateStructures 只在中心落在本区块范围内时被调用(ChaosWorldGenHandler.java:46-49),内容包括:

结构 参数 引用
混沌核心(洞窟) shardY = 80(:106),coreHeight = 10(:108,核心跨 Y 70–90),coreWidth = 20(:109),outerRadius = 330(:103) ChaosWorldGenHandler.java:102-120
混沌晶体 中心放置 ModBlocks.chaosCrystal,并写入 locationHash ChaosWorldGenHandler.java:122-125
混沌守卫 晶体处生成并立刻 spawnEntityInWorld 一个 EntityChaosGuardian ChaosWorldGenHandler.java:127-129
4 圈环带 rings = 4(:132),width = 20(:133),spacing = 8(:134),高度 90 + (islandCenter.x - x) * 0.1 + (random.nextInt(10) - 5)(:141,随机项取 -5…4) ChaosWorldGenHandler.java:131-147
方尖碑 内圈 7 座(半径 45,i * 0.9D 弧度,:182-187)+ 外圈 14 座(半径 90,i * 0.45D 弧度,:189-194),均从 Y 90 起;方法在 :180-195 ChaosWorldGenHandler.java:180-195

环带上每格有两次随机填充(注意 0.1F 与 0.001F 的量级差别):

概率 方块 引用
10%(0.1F) Blocks.end_stone ChaosWorldGenHandler.java:142
0.1%(0.001F) ModBlocks.draconiumOre ChaosWorldGenHandler.java:143

龙矿那 0.1% 是末地除常规龙矿外唯一的额外龙矿来源。

环带高度公式里用的是 islandCenter.x - x 而不是 islandCenter.z - z(ChaosWorldGenHandler.java:141),因此环带整体只沿 X 方向倾斜,沿 Z 方向是平的。

对外 API:GeneratorOverride

api/GeneratorOverride.java 是本模组 3 个 api/ 类之一(另两个为 IExtendedRFStorage 与 package-info),供附属模组接管生成逻辑。

方法 作用 引用
spawnCometAt(World, x, y, z, Random) 实例方法,在指定坐标生成一颗彗星 GeneratorOverride.java:25-27
generateChaosChunk(World, chunkX, chunkZ, centerX, centerZ, Random) 静态,在指定中心生成混沌岛区块(绕过网格)。Javadoc 要求对 360×360 区块区域内的每个区块都调用一次(GeneratorOverride.java:37-47) GeneratorOverride.java:48-52
setChaosIslandsEnabled(boolean) 静态,运行时改 chaosIslandsEnabled GeneratorOverride.java:57-59
setCometsEnabled(boolean) 静态,运行时改 cometsEnabled GeneratorOverride.java:64-66
setOreEnabledInEnd(boolean) 静态,运行时改 oreEnabledInEnd GeneratorOverride.java:72-74
getNearestChaosIslandCenter(chunkX, chunkZ) 静态,查询某区块所属的岛屿中心,返回 ChunkCoordinates(x, 80, z) 或 null(Y 硬编码 80,见 :93) GeneratorOverride.java:88-94
spawnChaosIslendAt(...) @Deprecated(:32),Javadoc 自述「This nolonger dose anything!」(:30) GeneratorOverride.java:33-35

setOreEnabledInEnd 的参数名与实际字段不符

public static void setOreEnabledInEnd(boolean cometsEnabled) {   // 参数名 cometsEnabled
    DraconicWorldGenerator.oreEnabledInEnd = cometsEnabled;
}

参数名 cometsEnabled 是从上一个方法复制粘贴残留(GeneratorOverride.java:71-73)。赋值目标是正确的 oreEnabledInEnd,只是参数名会误导调用方 —— 位置参数不影响行为。

另外 WorldGenEnderIsland 类只被这个 @Deprecated 方法使用(GeneratorOverride.java:34);该方法被标注为无效,正常生成流程不经过它。

已知的 API 交互细节

GeneratorOverride 提供的三个 set*Enabled 直接写 DraconicWorldGenerator 的 public static 字段,因此必须在启动阶段调用(源码 Javadoc 明确写「Use this at startup」,GeneratorOverride.java:55,62,69)。运行中改值只会影响此后新生成的区块,不会回溯已有区块。

getNearestChaosIslandCenter 的 Y 固定返回 80,与 generateStructures 中 shardY = 80 一致(ChaosWorldGenHandler.java:106)。

相关条目