User Tools

Site Tools


tutorial:features

This is an old revision of the document!


在您的世界中生成Feature

Rocks, trees, ores, and ponds are all examples of Features. They are simple generation additions to the world which generate depending on how they are configured. In this tutorial, we'll look at generating a simple stone spiral feature in our world randomly.

Creating a Feature class

A simple Feature looks like this:

  1. public class StoneSpiralFeature extends Feature<DefaultFeatureConfig> {
  2.  
  3. public StoneSpiralFeature(Function<Dynamic<?>, ? extends DefaultFeatureConfig> config) {
  4. super(config);
  5. }
  6.  
  7. @Override
  8. public boolean generate(IWorld world, ChunkGenerator<? extends ChunkGeneratorConfig> chunkGenerator, Random random, BlockPos pos, DefaultFeatureConfig config) {
  9. BlockPos topPos = world.getTopPosition(Heightmap.Type.WORLD_SURFACE, pos);
  10. Direction offset = Direction.NORTH;
  11.  
  12. for (int y = 1; y < 16; y++) {
  13. offset = offset.rotateYClockwise();
  14. world.setBlockState(topPos.up(y).offset(offset), Blocks.STONE.getDefaultState(), 3);
  15. }
  16.  
  17. return true;
  18. }
  19. }

The constructor takes in a Function<Dynamic<? extends DefaultFeatureConfig», which is a factory for data fixer config instances. You can pass in DefaultFeatureConfig::deserialize for default config features, either directly in the super call or when you instantiate the feature.

`generate` is called when the chunk decides to generate the feature. If the feature is configured to spawn every chunk, this would be called for each chunk being generated as well. In the case of the feature being configured to spawn at a certain rate per biome, `generate` would only be called in instances where the world wants to spawn the structure.

In our implementation, we'll build a simple 16-block tall spiral of stone starting at the top block in the world:

@Override
public boolean generate(IWorld world, ChunkGenerator<? extends ChunkGeneratorConfig> chunkGenerator, Random random, BlockPos pos, DefaultFeatureConfig config) {
    BlockPos topPos = world.getTopPosition(Heightmap.Type.WORLD_SURFACE, pos);
    Direction offset = Direction.NORTH;
 
    for (int y = 1; y < 16; y++) {
        offset = offset.rotateYClockwise();
        world.setBlockState(topPos.up(y).offset(offset), Blocks.STONE.getDefaultState(), 3);
    }
 
    return true;
}

注册一个Feature

可以像注册游戏中的其他大多数内容一样注册Feature,而且您不必担心任何特殊的构建器或机制。

private static final Feature<DefaultFeatureConfig> LAVA_HOLE = Registry.register(
	Registry.FEATURE,
	new Identifier("tutorial", "stone_spiral"),
	new StoneSpiralFeature(DefaultFeatureConfig::deserialize)
);

向生物群落添加Feature

生物群系有一种称为addFeature的方法,用于将特征添加到生物群落的生成过程中。 您可以在每个生物群落类(例如ForestBiomeSavannaBiome)中查看此方法的更详细用法。

我们可以遍历Registry.BIOME以将我们的Feature添加到每个生物群系中。

Registry.BIOME.forEach(biome -> biome.addFeature(
        GenerationStep.Feature.RAW_GENERATION,
	Biome.configureFeature(
		LAVA_HOLE,
		new DefaultFeatureConfig(),
		Decorator.CHANCE_HEIGHTMAP,
		new ChanceDecoratorConfig(100)
	)
));

The first argument of addFeature helps determine when the structure is generated. For above-ground houses you may go with SURFACE_STRUCTURES, and for caves, you might go with RAW_GENERATION.

The second argument of addFeature is a ConfiguredFeature, which you can create through Biome.configureFeature. The latter takes in an instance of your feature, an instance of your feature's config class, a decorator, and a decorator config.

The Decorator represents how the world chooses to place your Feature. CHANCE_HEIGHTMAP works by looking at a heightmap, whereas NOISE_HEIGHTMAP_32 works with noise. To choose the correct Decorator, check out vanilla Features with a similar style to your own. The decorator config branches off this; in the case of CHANCE_HEIGHTMAP, you would pass in an instance of ChanceHeightmapDecorator.

结果

tutorial/features.1578485264.txt.gz · Last modified: 2020/01/08 12:07 by lightcolour