世界生成

在 Minecraft 中,世界生成是一个十分复杂的过程,当然 Sponge 本身也增加了它的复杂程度。这里我们为感兴趣的读者提供一个关于世界是如何生成的基本描述。你可以选择跳过此步骤,并直接转到 API 的详细信息:

Minecraft 中的世界是如何生成的

Minecraft 中的世界生成单位是 区块 。当游戏请求一个不存在的区块时,世界生成系统就会在该处生成一个区块。生成这个区块的过程分为两个阶段: GenerationPopulation

Generation 阶段

生成一个区块的第一个阶段是 Generation 阶段 。该阶段主要负责生成基本地形、生物群系、以及村庄、洞穴等较大的地形特征。

備註

这一生成阶段中的方块放置完全在缓冲区内进行,也就是说在该阶段的最后一步结束后才会创建 Chunk 对象。

首先,游戏将会在一个 2D 的生物群系图的缓存下生成生物群系,该缓存下的每一格都将对应真实世界地图区块中的 1x1 的一竖列方块。然后,基础的 GenerationPopulator 生成地形的基本形状。这时的世界是完全由石头组成的。默认生成只是简单地根据柏林噪声(Perlin Noise)生成的高度图,然后进行填充——在高于海平面的地方填充空气,在低于海平面的地方填充水。这一步可以通过 WorldGenerator#setBaseGenerationPopulator(GenerationPopulator) 方法将默认的行为替换成你自己的世界生成行为。

然后,使用上面提到的生物群系缓存,世界生成器开始把世界表层的方块以生物群系的 GroundCoverLayer 所指定的替换层数替换为同样由其所指定的 BlockState 。生物群系由 BiomeGenerator 提供——这可以当作 WorldGenerator#setBiomeGenerator(BiomeGenerator) 的参数传入。

现在我们注意到基础的地形生成已经完成了,这时该轮到 GenerationPopulator 开始工作了。 GenerationPopulator 分为两种类型:用于普适的世界生成与用于特定生物群系的世界生成。用于特定区块的世界生成的 GenerationPopulator 的集合,是所有该区块内存在的生物群系适用的 GenerationPopulator 的联合。

GenerationPopulator 被设计成用于大型的密集操作,也就是说被设计应用于缓冲区而不是尚未存在的 Chunk 对象。这意味着必须限制 GenerationPopulator 不得放置位于当前生成的区块外的方块。也就是说如果一个 GenerationPopulator 生成的方块跨越了多个区块,那么它们必须按照区块边界切开成小块,并且按照世界种子及其所在的区块坐标决定目前在世界上生成的是哪一小块。

最后,当基本的地形生成完毕,生物群系已应用其上, GenerationPopulator 也已运行完成后,我们就完成了世界生成的 Generation 阶段,同时 Chunk 对象将构建生成并返回。

Population 阶段

Population 阶段 只会在一个区块及其 X 轴与 Z 轴相邻的正方向的三个区块都被加载时进行世界生成。这允许在这一阶段的某种特性(Object)在不需要为 GenerationPopulator 进行部分生成的情况下,扩展到已经生成的 16x16 区块外。为了支持这一点,实际的 16x16 大小区块的生成会在 X 轴和 Z 轴的方向进行各 8 格的偏移。

只有位于 (x*16+16, 0, z*16+16) 处的生物群系中的 Populator 才会应用于这一块。也就是说游戏不会将所有该区域中的 GenerationPopulator 联合到一起。

Populator 可以用于生成小的建筑(如沙漠水井等)或者附加的地形特征(如树等)。Sponge 提供了大量的原版的可复用的世界生成的 Populator ,开发者可以通过对它们的配置进行复用。