地物生成

地物生成

地物生成 26.2 ​使用数据生成器在世界中生成地物的指南。

前置知识

请先确保你已经完成了数据生成设置流程。

Minecraft 中的地物是世界中的自然或生成图案,例如树木、花、矿石或湖泊。地物不同于结构(例如村庄、神殿等),后者可以通过 /locate 命令查找。

Minecraft 世界中的地物生成可分为 3 个部分:

已配置地物:定义地物是什么;例如,一棵单独的树已放置地物:定义地物应如何分布,包括方向、相对位置等;例如,森林中树木的分布方式生物群系修改:定义地物会被放置在世界中的什么位置;例如,整片森林所在的坐标范围设置 ​首先,我们需要创建自己的 provider。在 main 包中创建一个继承自 FabricDynamicRegistryProvider 的类,并完善其基本方法:

javapublic class ExampleModWorldgenProvider extends FabricDynamicRegistryProvider {

public ExampleModWorldgenProvider(FabricPackOutput output, CompletableFuture registriesFuture) {

super(output, registriesFuture);

}

@Override

protected void configure(HolderLookup.Provider registries, Entries entries) {

entries.addAll(registries.lookupOrThrow(Registries.CONFIGURED_FEATURE));

entries.addAll(registries.lookupOrThrow(Registries.PLACED_FEATURE));

}

@Override

public String getName() {

return "World Generation";

}

}12345678910111213141516在 configure 方法中,我们将调用 addAll 以确保生成地物所需的所有文件。

javaentries.addAll(registries.lookupOrThrow(Registries.CONFIGURED_FEATURE));

entries.addAll(registries.lookupOrThrow(Registries.PLACED_FEATURE));12然后,在你的 DataGeneratorEntrypoint 类的 onInitializeDataGenerator 方法中添加该 provider:

javapack.addProvider(ExampleModWorldgenProvider::new);1接下来,为已配置地物和已放置地物分别创建一个类。这些类不需要继承任何内容。

已配置地物类和已放置地物类都应包含一个公共方法,用于注册并定义你的地物。该方法的参数(这里我们将其命名为 context)对于已配置地物应为 BootstrapContext>,对于已放置地物则应为 BootstrapContext。

在你的 DataGeneratorEntrypoint 类中,将下面的代码行添加到 buildRegistry 方法中,并将方法名替换为你自己选择的名称:

javaregistryBuilder.add(Registries.CONFIGURED_FEATURE, ExampleModWorldConfiguredFeatures::configure);

registryBuilder.add(Registries.PLACED_FEATURE, ExampleModWorldPlacedFeatures::configure);12如果你还没有 buildRegistry 方法,请创建它,并使用 @Override 注解标注。

已配置地物 ​若要让一个地物自然生成在世界中,我们应先在已配置地物类中定义一个已配置地物。

在开始之前,我们先在 main 包中创建已配置的地物类,并声明一个 configure 方法:

javapublic class ExampleModWorldConfiguredFeatures {

public static void configure(BootstrapContext> context) {

}

}1234现在,我们为钻石矿脉添加一个自定义配置地物。首先,在你的已配置地物类中注册 ConfiguredFeature 的键:

javapublic static final ResourceKey> DIAMOND_BLOCK_VEIN_CONFIGURED_KEY =

ResourceKey.create(

Registries.CONFIGURED_FEATURE,

ExampleMod.id("diamond_block_vein")

);12345TIP

Identifier 的第二个参数(在本例中为 diamond_block_vein)就是你通过 /place 命令生成该结构时使用的名称,这对于调试很有帮助。

矿石 ​接下来,我们将在 configure 方法中创建一个 RuleTest,用于控制你的地物可以替换哪些方块。例如,下面这个 RuleTest 允许替换带有 DEEPSLATE_ORE_REPLACEABLES 标签的所有方块:

javaRuleTest deepslateReplaceableRule = new TagMatchTest(BlockTags.DEEPSLATE_ORE_REPLACEABLES);1接下来,同样在 configure 方法中,我们需要创建 OreConfiguration,它告诉游戏要用什么来替换方块。

javaList diamondBlockOreConfig =

List.of(

OreConfiguration.target(deepslateReplaceableRule, Blocks.DIAMOND_BLOCK.defaultBlockState())

);1234你可以在列表中加入多个情况,以支持不同变体。例如,我们可以为石头和深板岩设置不同的变体:

javaList ironAndDiamondBlockOreConfig =

List.of(

OreConfiguration.target(deepslateReplaceableRule, Blocks.DIAMOND_BLOCK.defaultBlockState()),

OreConfiguration.target(stoneReplaceableRule, Blocks.IRON_BLOCK.defaultBlockState())

);12345最后,我们要在 configure 方法中将我们配置好的地物注册到游戏中!

javacontext.register(

DIAMOND_BLOCK_VEIN_CONFIGURED_KEY,

new ConfiguredFeature<>(

Feature.ORE,

new OreConfiguration(diamondBlockOreConfig, 10)) // 10 is the blocks per vein

);123456树木 ​若要创建自定义树,首先需要在 configure 方法中创建一个 TreeConfiguration:

javaTreeConfiguration diamondTree = new TreeConfiguration.TreeConfigurationBuilder(

// Trunk / Logs

BlockStateProvider.simple(Blocks.DIAMOND_BLOCK),

new StraightTrunkPlacer(4, 2, 0),

// Leaves

BlockStateProvider.simple(Blocks.GOLD_BLOCK),

new BlobFoliagePlacer(ConstantInt.of(2), ConstantInt.of(0), 3),

new TwoLayersFeatureSize(0, 0, 0),

// Block underneath the tree

BlockStateProvider.simple(Blocks.DIRT)

).build();123456789101112各参数的含义如下:

指定树干的方块类型;例如钻石块使用树干放置器配置树干的形状和高度行为指定树叶的方块类型;例如金块使用树叶放置器定义树冠的形状和大小控制树干在不同高度处如何收束,主要用于较大的树干TIP

我们强烈建议你自行调整这些值,制作出让你满意的自定义树木!

你可以参考原版树木中内置的树干放置器和树叶放置器。

接下来,我们需要在 ExampleModWorldConfiguredFeatures 的 configure 方法中添加以下代码行,以注册我们的树木:

javacontext.register(DIAMOND_TREE_CONFIGURED_KEY, new ConfiguredFeature<>(Feature.TREE, diamondTree));1已放置地物 ​向游戏添加地物的下一步,是创建它的已放置地物。

我们在 main 包中创建已放置地物类,并像以前一样为其添加一个 configure 方法:

javapublic class ExampleModWorldPlacedFeatures {

public static void configure(BootstrapContext context) {

}

}1234在你的已放置地物类的 configure 方法中,创建如下变量:

javaHolderGetter> configuredFeatures = context.lookup(Registries.CONFIGURED_FEATURE);1在你的已放置地物类中,定义已放置地物的键:

javapublic static final ResourceKey DIAMOND_BLOCK_ORE_PLACED_KEY =

ResourceKey.create(

Registries.PLACED_FEATURE,

ExampleMod.id("diamond_block_ore_placed")

);12345放置修饰器 ​接下来,我们需要在 configure 方法中定义放置修饰符,这些属性是在生成地物时设置的。可以是任意内容:从生成频率,到起始 y 层级都可以。你可以按需要设置任意数量的修饰器。

javaList diamondBlockVeinModifiers = List.of(

CountPlacement.of(6),

BiomeFilter.biome(),

InSquarePlacement.spread(),

HeightRangePlacement.of(BiasedToBottomHeight.of(VerticalAnchor.BOTTOM, VerticalAnchor.absolute(0), 3))

);123456上面列出的各修饰器作用如下:

CountPlacement:大致表示每个区块中该地物(在本例中为矿脉)的实例数量BiomeFilter:允许我们控制地物生成的生物群系/维度(我们稍后会进一步利用)InSquarePlacement:使地物以更接近伪随机的方式分散HeightRangePlacement:指定地物可生成的 y 坐标范围;它支持三种主要分布类型: Uniform: 范围内所有 y 值生成该地物的概率相同。如果你不确定该用哪种,就使用这一种。

Trapezoid: 越接近中位 y 值的位置,生成该地物的概率越高。

Biased-Bottom:

采用对数尺度,其中较低的 y 值更有可能生成地物。它接收一个起始 y 坐标,低于该坐标时地物绝不会生成。第二个参数是地物可以生成的最大高度。第三个参数定义一个以方块为单位的范围,用于延伸最大概率区间。

TIP

树木和其他地表结构应使用 PlacedFeatures.WORLD_SURFACE_WG_HEIGHTMAP 修饰器,而不是 HeightRangePlacement,以确保树木生成在地表上。

现在我们有了修饰符,就可以在 configure 方法中注册我们放置的地物:

javacontext.register(

DIAMOND_BLOCK_ORE_PLACED_KEY,

new PlacedFeature(

configuredFeatures.getOrThrow(ExampleModWorldConfiguredFeatures.DIAMOND_BLOCK_VEIN_CONFIGURED_KEY),

diamondBlockVeinModifiers

)

);1234567生物群系修改 ​最后,我们需要在模组初始化期间将已放置地物添加到 BiomeModifications 中。我们可以通过向模组初始化器添加以下内容来实现:

java// Spawns everywhere in the overworld

BiomeModifications.addFeature(

BiomeSelectors.foundInOverworld(),

GenerationStep.Decoration.UNDERGROUND_ORES,

ExampleModWorldPlacedFeatures.DIAMOND_BLOCK_ORE_PLACED_KEY

);123456TIP

对于树木,第二个参数应设置为 GenerationStep.Decoration.VEGETAL_DECORATION,

指定生物群系生成 ​通过修改 BiomeSelectors 参数,可以让地物只在特定类型的生物群系中生成:

java// Spawns in forest biomes only

BiomeModifications.addFeature(

BiomeSelectors.tag(BiomeTags.IS_FOREST),

GenerationStep.Decoration.VEGETAL_DECORATION,

ExampleModWorldPlacedFeatures.DIAMOND_TREE_PLACED_KEY

);123456这样,该地物只会生成在带有 minecraft:is_forest 生物群系标签的生物群系中。

运行数据生成 ​现在运行数据生成后,对于你添加的每个已配置地物,都应能在 src/main/generated/data/example-mod/worldgen/configured_feature 下看到一个 .json 文件;对于每个已放置地物,也应能在 src/main/generated/data/example-mod/worldgen/placed_feature 下看到对应文件!

已配置地物生成文件json{

"type": "minecraft:ore",

"config": {

"discard_chance_on_air_exposure": 0.0,

"size": 10,

"targets": [

{

"state": {

"Name": "minecraft:diamond_block"

},

"target": {

"predicate_type": "minecraft:tag_match",

"tag": "minecraft:deepslate_ore_replaceables"

}

}

]

}

}123456789101112131415161718已放置地物生成文件json{

"feature": "example-mod:diamond_block_vein",

"placement": [

{

"type": "minecraft:count",

"count": 6

},

{

"type": "minecraft:biome"

},

{

"type": "minecraft:in_square"

},

{

"type": "minecraft:height_range",

"height": {

"type": "minecraft:biased_to_bottom",

"inner": 3,

"max_inclusive": {

"absolute": 0

},

"min_inclusive": {

"above_bottom": 0

}

}

}

]

}12345678910111213141516171819202122232425262728

相关数据

雷神加速器深度评测,2026年你的吃鸡搭档!
beat365倍率

雷神加速器深度评测,2026年你的吃鸡搭档!

📅 07-12 👁️ 4698
剑网3醉烟波宠物奇遇攻略
beat365倍率

剑网3醉烟波宠物奇遇攻略

📅 09-27 👁️ 8167