===== 自定义区块生成器 ===== ''区块生成器'' 是游戏生成世界的机制。它们处理地形塑造,表面构建以及生物群落的放置。 原版我的世界的 ''噪声区块生成器'' 非常强大并且可配置。使用好 ''DensityFunction'' 以及 ''SurfaceRule'' ,自定义的可能性几乎是无穷无尽的。 **如果你正在想 “我可以用 ''噪声区块生成器'' 和数据包做到某件事吗?”,那么答案往往为是。** 大多数情况下不要自定义一个 ''区块生成器'',并且由于重建一个需要大量的样板代码, **如果可能的话强烈建议你避免创建一个自定义的 ''区块生成器''。** 根据经验,只有当您需要创建一个 **不是** 基于随机噪声的世界时,才应该实现 "区块生成器"。这方面的例子可能包括由外部体素引擎生成的世界,或像SethBling的Skygrid这样的自定义地图。如果你不确定 ''区块生成器'' 是否适合你,请询问Discord中的某人。 准备好了吗?让我们开始吧。 ==== 创建一个区块生成器 ==== 创建区块生成器的第一步是创建一个新的 ''ChunkGenerator'' 类。扩展原版的 ''ChunkGenerator'',让IDE生成所有必需的函数模板。以下是您可能需要担心的所有问题的解释: public class ExampleChunkGenerator extends ChunkGenerator { /* this is a very important field, we will come back to the codec later */ public static final Codec CODEC; /* you can add whatever fields you want to this constructor, as long as they're added to the codec as well */ public ExampleChunkGenerator() { } /* the method that creates non-noise caves (i.e., all the caves we had before the caves and cliffs update) */ @Override public void carve(ChunkRegion chunkRegion, long seed, NoiseConfig noiseConfig, BiomeAccess biomeAccess, StructureAccessor structureAccessor, Chunk chunk, GenerationStep.Carver carverStep) { } /* the method that places grass, dirt, and other things on top of the world, as well as handling the bedrock and deepslate layers, as well as a few other miscellaneous things. without this method, your world is just a blank stone (or whatever your default block is) canvas (plus any ores, etc) */ @Override public void buildSurface(ChunkRegion region, StructureAccessor structures, NoiseConfig noiseConfig, Chunk chunk) { } /* the method that paints biomes on top of the already-generated terrain. if you leave this method alone, the entire world will be a River biome. note that this does not mean that the world will all be water; but drowned and salmon will spawn. */ @Override public CompletableFuture populateBiomes(Registry biomeRegistry, Executor executor, NoiseConfig noiseConfig, Blender blender, StructureAccessor structureAccessor, Chunk chunk) { return super.populateBiomes(biomeRegistry, executor, noiseConfig, blender, structureAccessor, chunk); } /* this method spawns entities in the world */ @Override public void populateEntities(ChunkRegion region) { } /* the distance between the highest and lowest points in the world. in vanilla, this is 384 (64+320) */ @Override public int getWorldHeight() { return 0; } /* this method builds the shape of the terrain. it places stone everywhere, which will later be overwritten with grass, terracotta, snow, sand, etc by the buildSurface method. it also is responsible for putting the water in oceans. it returns a CompletableFuture-- you'll likely want this to be delegated to worker threads. */ @Override public CompletableFuture populateNoise(Executor executor, Blender blender, NoiseConfig noiseConfig, StructureAccessor structureAccessor, Chunk chunk) { } @Override public int getSeaLevel() { return 0; } /* the lowest value that blocks can be placed in the world. in a vanilla world, this is -64. */ @Override public int getMinimumY() { return 0; } /* this method returns the height of the terrain at a given coordinate. it's used for structure generation */ @Override public int getHeight(int x, int z, Heightmap.Type heightmap, HeightLimitView world, NoiseConfig noiseConfig) { return 0; } /* this method returns a "core sample" of the world at a given coordinate. it's used for structure generation */ @Override public VerticalBlockSample getColumnSample(int x, int z, HeightLimitView world, NoiseConfig noiseConfig) { } /* this method adds text to the f3 menu. for NoiseChunkGenerator, it's the NoiseRouter line */ @Override public void getDebugHudText(List text, NoiseConfig noiseConfig, BlockPos pos) { } @Override protected Codec getCodec() { return CODEC; } } 几乎所有这些方法都需要重写,生成器才能正常工作。您可以从 ''NoiseChunkGenerator'' 中复制其中一些。特别建议您也从 ''NoiseChunkGenerator'' 中实现私有的 ''populationNoise'' 方法,只需复制公共方法即可。''NoiseChunkGenerator'' 中的公共方法只是将实际生成委派给工作线程,每个工作线程都运行专用方法。这是一种获得并行生成的简单方法—— **区块生成器默认情况下不是多线程的**! ==== 注册和编码器 ==== 与游戏中的其他功能一样,''ChunkGenerators'' 也必须注册。但是,您不向注册表传递静态实例,而是给它一个 ''Codec'' 实例。您可以在编码器中放入您想要的任何内容—— Mojang 为许多有用的对象(包括整个注册表)提供序列化编码器。然后,剩下的就是注册区块生成器。将以下代码放入您的模组 initializer 中的 ''onInitialize'' 方法中: Registry.register(Registry.CHUNK_GENERATOR, new Identifier("wiki-example", "example"), ExampleChunkGenerator.CODEC); 然后就完成了!如果你想用你的新生成器,用一个[[zh_cn:tutorial:world_presets|世界预设]]包装一下可能会很有帮助。