Minecraft 1.18.2 Fabric模组:替换原版白桦树配置方案求助
Fabric 1.18.2 替换原版白桦树解决方案
问题原因分析
你之前尝试的方法失败的核心原因:
- 用
FeatureUtils.register报错:该方法仅用于数据生成阶段注册配置,运行时调用会触发注册表锁定,且原版已注册minecraft:birch,直接注册会冲突,提示的.set()是Holder类的方法,需针对Holder对象操作而非直接注册。 Registry.register重复注册错误:原版已完成minecraft:birch的注册,Fabric会阻止同名ID的重复注册。- Datapack未生效:原版内置datapack优先级高于模组datapack,无法覆盖原版配置。
方法一:Mixin修改原版Holder(推荐,稳定覆盖所有场景)
通过Mixin直接替换TreeFeatures.BIRCH这个Holder指向的自定义树配置,覆盖世界生成、树苗生长等所有使用原版白桦树的场景:
- 创建Mixin类:
@Mixin(TreeFeatures.class) public class TreeFeaturesMixin { @Shadow @Final private static Holder<ConfiguredFeature<TreeConfiguration, ?>> BIRCH; @Inject(method = "<clinit>", at = @At("TAIL")) private static void overwriteBirchTree(CallbackInfo ci) { // 构建自定义白桦树配置(可根据需求修改参数) TreeConfiguration customBirch = TreeFeatures.createBirch() // 示例:修改树干高度范围、叶子密度 .trunkHeight(UniformIntProvider.create(7, 12)) .foliageRadius(UniformIntProvider.create(2, 4)) .foliageProvider(FoliagePlanners.fancy( FoliagePlanners.range(0.4F), BlockStateProvider.simple(Blocks.BIRCH_LEAVES), FoliagePlanners.blurry(0.15F) )) .build(); // 创建自定义ConfiguredFeature并替换Holder的引用 ConfiguredFeature<TreeConfiguration, ?> customFeature = new ConfiguredFeature<>(Feature.TREE, customBirch); // 强制修改Holder的内部值(Parchment映射下可直接访问Holder.Reference的set方法) ((Holder.Reference<ConfiguredFeature<TreeConfiguration, ?>>) BIRCH).set(customFeature); } }
- 在
fabric.mod.json中注册Mixin:
{ "mixins": [ "your-mod-id.mixins.json" ] }
- 在
your-mod-id.mixins.json中添加Mixin类路径:
{ "client": [], "server": [], "common": [ "com.yourname.yourmod.mixin.TreeFeaturesMixin" ] }
方法二:注册表事件+反射替换(无需Mixin,稳定性稍差)
通过监听ConfiguredFeature注册表的注册事件,在原版白桦树注册完成后替换为自定义配置:
public class YourModInitializer implements ModInitializer { @Override public void onInitialize() { RegistryEntryAddedCallback.event(Registry.CONFIGURED_FEATURE).register((rawId, id, feature) -> { if (id.equals(new Identifier("minecraft", "birch"))) { // 构建自定义白桦树配置 TreeConfiguration customBirchConfig = TreeFeatures.createBirch() .trunkHeight(UniformIntProvider.create(6, 10)) .foliageRadius(UniformIntProvider.create(2, 3)) .build(); ConfiguredFeature<TreeConfiguration, ?> customBirch = new ConfiguredFeature<>(Feature.TREE, customBirchConfig); // 反射替换注册表条目和Holder引用 try { // 替换注册表中的条目 Field entriesField = Registry.class.getDeclaredField("entries"); entriesField.setAccessible(true); Map<Identifier, ?> entries = (Map<Identifier, ?>) entriesField.get(Registry.CONFIGURED_FEATURE); entries.put(id, customBirch); // 替换TreeFeatures中的BIRCH Holder Field birchField = TreeFeatures.class.getDeclaredField("BIRCH"); birchField.setAccessible(true); birchField.set(null, Holder.direct(customBirch)); } catch (NoSuchFieldException | IllegalAccessException e) { e.printStackTrace(); } } }); } }
注意事项
- 自定义树配置时,可参考原版
TreeFeatures.createBirch()的代码结构,调整树干、叶子、树根等参数。 - Mixin方法兼容性更好,反射方法可能因映射更新失效,优先推荐Mixin方案。
内容的提问来源于stack exchange,提问作者LanGvest
相关产品推荐
相关产品推荐

