树的世界生成 1.20 Fabric 长线教程计划
本篇教程的视频
(待发布)
本篇教程的源代码
(待发布)
本篇教程目标
- 理解原版的树的放置特征
- 学会自己编写基本的树的放置特征
查看源代码
那么这一篇教程我们来讲树的世界生成,前面已经讲过了TreeConfiguredFeatures
这个类
那么今天讲世界生成还要涉及一个TreePlacedFeatures
,这个是树的放置特征,
意思就是这些树是以怎样的方式放置在世界中的
这里我们就来看看TreePlacedFeatures
1 | public static final RegistryKey<PlacedFeature> OAK_CHECKED = PlacedFeatures.of("oak_checked"); |
还是以橡木
相关的内容为例,这里有一个放置特征的注册键
PlacedFeatures.of
方法同样是一个公共方法,但我们使用时还得带上模组的命名空间
再往下翻就能看到一个bootstrap
方法,那还是用来数据生成的
1 | public static void bootstrap(Registerable<PlacedFeature> featureRegisterable) { |
这里面我们就看和橡木
相关的内容
1 | RegistryEntryLookup<ConfiguredFeature<?, ?>> registryEntryLookup = featureRegisterable.getRegistryLookup(RegistryKeys.CONFIGURED_FEATURE); |
首先先看第一个registryEntryLookup,这个方法就是获取注册键为RegistryKeys.CONFIGURED_FEATURE
的注册表
然后registryEntry3则是获取注册表中,注册键为TreeConfiguredFeatures.OAK
的注册表条目
最后,用PlacedFeatures.register
方法则是注册一个放置特征
PlacedFeatures.register
方法有三个参数,第一个是注册键
,第二个是注册表条目
,第三个是放置条件
不过我们实际写的时候,第三个参数是直接用植被的放置特征相关的方法来写的
这里我多提一嘴,按照上面的注册键继续深挖下去,我们就能看到它在VegetationConfiguredFeatures
的bootstrap
方法中,
也被调用了
植被
这一大块也是有自己的构造特征
和放置特征
的,稍微捋一下,植被是很多种植物组合在一起形成的,
比如繁花森林
、黑森林
等等,而我们写的单个的树或者其他东西,它是植被中的一部分,所以深挖下去还能了解更多东西,
不过我们这里就不展开讲了,感兴趣的同学可以自行研究
注册世界生成
放置特征
这里我们来创建ModPlacedFeatures
类,用来注册放置特征
1 | public class ModPlacedFeatures { |
同样的,我们还是先写一个注册键
1 | public static final RegistryKey<PlacedFeature> ICE_ETHER_TREE_PLACED_KEY = ModPlacedFeatures.of("ice_ether_tree_placed"); |
同样的,of
方法也是用了原版的方法,但加上了模组的命名空间
当然,为了与前面的构造特征有所区分,我们这里注册名上可以加上一个placed
然后就是写一个bootstrap
方法
1 | public static void bootstrap(Registerable<PlacedFeature> featureRegisterable) { |
参数上与原版的bootstrap
方法一致
1 | RegistryEntryLookup<ConfiguredFeature<?, ?>> registryEntryLookup = featureRegisterable.getRegistryLookup(RegistryKeys.CONFIGURED_FEATURE); |
获取注册键为RegistryKeys.CONFIGURED_FEATURE
的注册表
1 | PlacedFeatures.register(featureRegisterable, ICE_ETHER_TREE_PLACED_KEY, |
然后我们就直接用PlacedFeatures.register
来注册放置特征
第一个参数是注册键,第二个参数是注册表条目,第三个参数是放置条件
这里第三个参数我们用了VegetationPlacedFeatures.treeModifiersWithWouldSurvive
方法,PlacedFeatures.createCountExtraModifier
则是用来修改生成的数量,以区块
为单位
第一个参数是一个区块中基本的生成数量
,第二个是额外生成的概率
,第三个是额外生成的数量
后面就传入我们先前写的树苗
方块即可
树的生成器
接下来我们还要写树的世界生成器,与前面写的树苗生成器不同,它是指定我们的树在哪些生物群系
中生成
原版的地物配置已经写好了,所以这里我们要用Fabric API
来注册
我们创建一个ModTreeGeneration
类
1 | public class ModTreeGeneration { |
然后在里面写一个registerTrees
方法
1 | public static void registerTrees(){ |
在这里面我们用BiomeModifications.addFeature
方法来添加一个生物群系特征,就是指定我们的树生成在哪些生物群系中
当然这种做法是会影响原版已经配置的地物生成,不过关系不大
第一个参数是生物群系选择器,这里我们用了BiomeSelectors.includeByKey
方法,我们选择了平原
和森林
第二个参数是生成阶段,这里我们用了GenerationStep.Feature.VEGETAL_DECORATION
,也就是在植被生成阶段,加入我们的树
第三个参数则是我们的放置特征的注册键
注册世界生成
接下来我们再写一个ModWorldGeneration
类,注册世界生成
1 | public class ModWorldGeneration { |
里面写一个registerWorldGeneration
方法,调用我们先前写的registerTrees
方法
这个方法还要在主类调用
1 | ModWorldGeneration.registerWorldGeneration(); |
数据生成
和前面一样,我们要配置数据生成
TutorialModReDataGenerator
在模组的数据生成主类中的buildRegistry
方法下,添加一行代码
1 | registryBuilder.addRegistry(RegistryKeys.PLACED_FEATURE, ModPlacedFeatures::bootstrap); |
调用ModPlacedFeatures
中的bootstrap
方法
ModWorldGenerator
在ModWorldGenerator
类中的configure
方法中,我们也要将放置特征的注册键加入
1 | entries.addAll(wrapperLookup.getWrapperOrThrow(RegistryKeys.PLACED_FEATURE)); |
测试
随后我们就可以进行数据生成,同样它会在数据文件夹中的world_gen/placed_feature
下生成一个树的放置特征文件
然后我们就可以在游戏中测试了,在平原和森林中,我们就可以看到我们的树了