MinecraftForge结构生成教程:添加自定义建筑
在Minecraft模组开发中,自定义建筑的生成是提升游戏体验的重要方式。本教程将引导你通过MinecraftForge的结构生成系统,从零开始创建并注册自定义建筑,涵盖数据生成、结构定义和世界生成整合的完整流程。
核心概念与开发环境准备
MinecraftForge提供了一套完整的结构生成框架,主要通过数据生成器(Data Generator) 和结构修饰器(Structure Modifier) 实现自定义建筑的添加。在开始前,请确保你的开发环境包含以下组件:
- MDK基础结构:mdk/目录下的模组开发模板,提供了基础的项目结构和配置文件
- 数据生成API:src/main/java/net/minecraftforge/data/中的相关类,用于自动生成结构数据
- 结构修饰器接口:src/main/java/net/minecraftforge/common/world/StructureModifier.java定义了修改世界结构的核心方法
第一步:创建结构数据生成器
1.1 注册数据生成事件处理器
首先需要创建一个数据生成器类,继承自GlobalLootModifierProvider,并在GatherDataEvent事件中注册。这个类将负责生成结构的NBT数据和配置文件:
public class ModStructureProvider extends GlobalLootModifierProvider {
public ModStructureProvider(PackOutput output, ExistingFileHelper existingFileHelper) {
super(output, "yourmodid", existingFileHelper);
}
@Override
protected void start() {
// 结构数据生成逻辑将在这里实现
}
}
然后在你的主模组类中注册数据生成器:
@Mod("yourmodid")
public class YourMod {
public YourMod() {
MinecraftForge.EVENT_BUS.addListener(this::gatherData);
}
private void gatherData(GatherDataEvent event) {
DataGenerator generator = event.getGenerator();
generator.addProvider(event.includeServer(),
new ModStructureProvider(generator.getPackOutput(), event.getExistingFileHelper()));
}
}
相关API参考:
- 数据生成事件:src/main/java/net/minecraftforge/event/GatherDataEvent.java
- 全局 loot 修饰器:src/main/java/net/minecraftforge/data/GlobalLootModifierProvider.java
1.2 生成结构NBT文件
使用Minecraft的结构方块创建建筑并导出为NBT文件,放置在src/main/resources/data/yourmodid/structures/目录下。对于程序化生成的结构,可以使用StructureNBTProvider类自动生成:
generator.addProvider(event.includeServer(), new StructureNBTProvider(
generator.getPackOutput(),
List.of(new StructureTemplate("custom_house", new ResourceLocation("yourmodid", "structures/custom_house")))
));
第二步:定义结构特征与配置
2.1 创建结构特征类
结构特征(Structure Feature)定义了建筑在世界中的生成规则。创建一个继承自StructureFeature的类:
public class CustomHouseStructure extends StructureFeature<JigsawConfiguration> {
public static final CustomHouseStructure INSTANCE = new CustomHouseStructure(JigsawConfiguration.CODEC);
public CustomHouseStructure(Codec<JigsawConfiguration> codec) {
super(codec);
}
@Override
public StructureStartFactory<JigsawConfiguration> getStartFactory() {
return CustomHouseStructure.Start::new;
}
public static class Start extends StructureStart<JigsawConfiguration> {
public Start(StructureContext context, StructureFeature<JigsawConfiguration> feature,
ChunkPos chunkPos, int references, long seed, JigsawConfiguration config) {
super(context, feature, chunkPos, references, seed, config);
}
@Override
public void generatePieces(RegistryAccess registryAccess, JigsawConfiguration config,
ChunkGenerator chunkGenerator, BiomeManager biomeManager,
StructureManager structureManager, long seed,
StructureTemplateManager templateManager) {
// 结构生成逻辑
JigsawPlacement.addPieces(
new ResourceLocation("yourmodid", "custom_house/start_pool"),
3, // 最大生成深度
HolderGetter.create(registryAccess.lookupOrThrow(Registry.TEMPLATE_POOL_REGISTRY)),
(p_226940_) -> new JigsawConfiguration(() -> p_226940_, 3),
chunkGenerator,
structureManager,
new ChunkPos(this.getChunkPos().x, this.getChunkPos().z),
this,
this.random,
false,
true
);
}
}
}
2.2 注册结构特征与配置
在你的模组初始化类中注册结构特征:
public static final DeferredRegister<StructureFeature<?>> STRUCTURES =
DeferredRegister.create(ForgeRegistries.STRUCTURE_FEATURES, "yourmodid");
public static final RegistryObject<StructureFeature<JigsawConfiguration>> CUSTOM_HOUSE =
STRUCTURES.register("custom_house", () -> CustomHouseStructure.INSTANCE);
// 在构造函数中注册
STRUCTURES.register(FMLJavaModLoadingContext.get().getModEventBus());
相关注册API:src/main/java/net/minecraftforge/registries/ForgeRegistries.java
第三步:配置结构生成规则
3.1 创建结构配置文件
在src/main/resources/data/yourmodid/worldgen/structure_set/目录下创建结构集配置文件custom_houses.json:
{
"structures": [
{
"structure": "yourmodid:custom_house",
"weight": 1
}
],
"placement": {
"type": "minecraft:random_spread",
"spacing": 32,
"separation": 8,
"salt": 12345
}
}
3.2 使用结构修饰器调整生成
MinecraftForge提供了StructureModifier接口,可以动态修改现有结构的生成规则。例如,添加一个结构修饰器使自定义建筑只在平原生物群系生成:
public class BiomeRestrictionModifier implements StructureModifier {
@Override
public void modify(StructureHolder structure, StructureModifierContext context) {
if (structure.value().key() == YourMod.CUSTOM_HOUSE.getKey()) {
context.modifiableStructureInfo().placement().add(
new BiomeFilter(HolderSet.direct(
BuiltInRegistries.BIOME.getHolderOrThrow(Biomes.PLAINS)
))
);
}
}
}
注册结构修饰器:
public static final RegistryObject<StructureModifier> BIOME_RESTRICTION =
STRUCTURE_MODIFIERS.register("biome_restriction", () -> new BiomeRestrictionModifier());
结构修饰器接口定义:src/main/java/net/minecraftforge/common/world/StructureModifier.java
第四步:测试与调试
4.1 使用结构定位命令
在游戏中使用以下命令定位你的自定义结构:
/locate yourmodid:custom_house
如果结构未生成,检查以下可能原因:
- 结构配置文件路径是否正确:src/main/resources/data/yourmodid/worldgen/
- 生物群系过滤条件是否合理
- 结构生成概率是否设置过低
4.2 查看生成日志
启用结构生成调试日志,在run/client.launch.properties中添加:
-Dforge.logging.markers=STRUCTURE
-Dforge.logging.console.level=debug
相关调试类参考:src/main/java/net/minecraftforge/server/ServerLifecycleHooks.java
高级应用:动态结构生成
5.1 程序化结构生成
对于需要随机生成的建筑(如不同大小的村庄),可以使用JigsawManager实现模块化结构拼接:
JigsawManager.addPieces(
new ResourceLocation("yourmodid", "villages/start_pool"),
5, // 最大生成深度
VillagePiece::new,
chunkGenerator,
structureManager,
chunkPos,
this,
this.random,
false,
true
);
5.2 结构生成事件监听
通过监听StructureGenerateEvent可以在结构生成前后修改其属性:
@SubscribeEvent
public void onStructureGenerate(StructureGenerateEvent.Post event) {
if (event.getStructure().value() instanceof CustomHouseStructure) {
// 修改生成后的结构
}
}
总结与扩展阅读
通过本教程,你已经掌握了使用MinecraftForge添加自定义建筑的核心步骤:
- 创建数据生成器生成结构数据
- 定义结构特征和生成规则
- 配置结构生成参数和生物群系限制
- 测试并调试结构生成效果
扩展学习资源:
- 官方结构生成文档:docs/CONTRIBUTING.md
- 结构修饰器示例:src/main/java/net/minecraftforge/common/world/
- Minecraft原版结构代码:patches/minecraft/net/minecraft/world/level/structure/
你可以进一步扩展这个系统,添加结构战利品表、生成条件和自定义结构组件,创造出丰富多样的游戏世界。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考




