本篇教程的视频

本篇教程的源代码

GitHub地址:

查看源代码

像花这种小植物,在游戏中是以一种叫随机斑块的形式出现的,也就是一些小植被,它也是地物的一种,所以它们也具有构造特征和放置特征

构造特征

构造特征我们可以在VegetationFeatures类中找到

1
2
3
4
5
6
7
8
public static final ResourceKey<ConfiguredFeature<?, ?>> FLOWER_DEFAULT = FeatureUtils.createKey("flower_default");
public static final ResourceKey<ConfiguredFeature<?, ?>> FLOWER_FLOWER_FOREST = FeatureUtils.createKey("flower_flower_forest");
public static final ResourceKey<ConfiguredFeature<?, ?>> FLOWER_SWAMP = FeatureUtils.createKey("flower_swamp");
public static final ResourceKey<ConfiguredFeature<?, ?>> FLOWER_PLAIN = FeatureUtils.createKey("flower_plain");
public static final ResourceKey<ConfiguredFeature<?, ?>> FLOWER_MEADOW = FeatureUtils.createKey("flower_meadow");
public static final ResourceKey<ConfiguredFeature<?, ?>> FLOWER_CHERRY = FeatureUtils.createKey("flower_cherry");
public static final ResourceKey<ConfiguredFeature<?, ?>> FOREST_FLOWERS = FeatureUtils.createKey("forest_flowers");
...

光是涉及的,就有很多种

默认的是FLOWER_DEFAULT

1
2
3
4
5
FeatureUtils.register(p_256132_, FLOWER_DEFAULT, Feature.FLOWER, 
grassPatch(new WeightedStateProvider(
SimpleWeightedRandomList.<BlockState>builder()
.add(Blocks.POPPY.defaultBlockState(), 2)
.add(Blocks.DANDELION.defaultBlockState(), 1)), 64));

在下面的bootstrap方法中,我们可以看到蒲公英的构造特征

其中的grassPatch方法,就是创建一个随机斑块

第一个参数是方块的提供器,第二个是尝试生成的次数,以区块为单位

当然,我们在写时候,和这个并不完全一样

放置特征

放置特征我们可以在VegetationPlacements类中找到

1
2
3
4
5
6
7
8
9
10
11
12
public static final ResourceKey<PlacedFeature> FLOWER_DEFAULT = PlacementUtils.createKey("flower_default");
...
// 下面三段在bootstrap方法中
HolderGetter<ConfiguredFeature<?, ?>> holdergetter = pContext.lookup(Registries.CONFIGURED_FEATURE);

Holder<ConfiguredFeature<?, ?>> holder19 = holdergetter.getOrThrow(VegetationFeatures.FLOWER_DEFAULT);

PlacementUtils.register(pContext, FLOWER_DEFAULT, holder19,
RarityFilter.onAverageOnceEvery(32),
InSquarePlacement.spread(),
PlacementUtils.HEIGHTMAP,
BiomeFilter.biome());

同样的,它也是差不多的,一个注册键,bootstrap方法中注册

RarityFilter.onAverageOnceEvery方法是生成几率,这个就是百分数了

InSquarePlacement.spread()是生成方式,这个就是方块为单位了,应该指按照一个方形平面放置(联想一下笔刷

PlacementUtils.HEIGHTMAP是高度图,按照高度来放置

BiomeFilter.biome()是生物群系,按照生物群系来放置

这些其实就是在世界生成时,尝试生成的一些方法规则

注册花的世界生成

注册构造特征

我们回到之前的ModConfiguredFeatures类中

首先写一个注册键

1
public static final ResourceKey<ConfiguredFeature<?, ?>> SIMPLE_FLOWER_KEY = createKey("simple_flower"); 

之后在bootstrap方法中注册构造特征

1
2
3
4
FeatureUtils.register(context, SIMPLE_FLOWER_KEY, Feature.FLOWER,
new RandomPatchConfiguration(20, 4, 3,
PlacementUtils.onlyWhenEmpty(Feature.SIMPLE_BLOCK,
new SimpleBlockConfiguration(BlockStateProvider.simple(ModBlocks.SIMPLE_FLOWER.get())))));

这里的随机斑块方法,我们就直接实例化RandomPatchConfiguration

第一个参数是尝试生成的次数,第二个参数是xz方向上拓展的距离,第三个参数是y方向上拓展的距离,第四个参数是注册表项

注册表项提供一个简单方块特征和它的配置参数

注册放置特征

我们回到之前的ModPlacedFeatures类中

同样的一个注册键

1
public static final ResourceKey<PlacedFeature> SIMPLE_FLOWER_PLACED_KEY = registerKey("simple_flower_placed");

之后在bootstrap方法中注册放置特征

1
2
3
4
PlacementUtils.register(context, SIMPLE_FLOWER_PLACED_KEY,
holdergetter.getOrThrow(ModConfiguredFeatures.SIMPLE_FLOWER_KEY),
RarityFilter.onAverageOnceEvery(4), InSquarePlacement.spread(),
PlacementUtils.HEIGHTMAP, BiomeFilter.biome());

这里的写法和原版的差不多,可以仿照原版的方法来写

生物群系修改

和前面写树一样,我们要用ForgeAPI来让花生成在某一个生物群系

我们先到ModBiomeModifiers中注册一个注册键

1
public static final ResourceKey<BiomeModifier> ADD_SIMPLE_FLOWER = registerKey("add_simple_flower");

然后在下面的bootstrap方法中注册

1
2
3
4
5
context.register(ADD_SIMPLE_FLOWER, new ForgeBiomeModifiers.AddFeaturesBiomeModifier(
biomes.getOrThrow(Tags.Biomes.IS_PLAINS),
HolderSet.direct(placedFeatures.getOrThrow(ModPlacedFeatures.SIMPLE_FLOWER_PLACED_KEY)),
GenerationStep.Decoration.VEGETAL_DECORATION
));

和前面写树的差不多,不过这里我们只指定了一个生物群系,而且这个是Forge为我们提供的群系标签

测试

在此之后,我们就可以跑数据生成,然后得到对应的构造json文件和放置json文件,之后我们就可以进入游戏进行测试了