1.15 到 1.16 更新指南

FledgeXu


Forge 官方更新日志

Mod信息相关的改动

现在mods.toml新增一个强制字段:license,数据类型字符串,这里填入的是你Mod的许可证。

FML 相关的改动

DistExecutor.callWhenOn等方法被弃用,请改用同一个类下带safe前缀的方法例如DistExecutor.safeCallWhenOn

FMLCommonSetupEvent等会并行执行的FML生命周期事件,需要被执行的代码要放到enqueueWork中。

注册系统

new DeferredRegister => DeferredRegister.create

事件系统

现在如果你的事件注册到错误的总线中,将会有报错和错误提示。

方块实体

read(CompoundNBT compound) => read(BlockState state, CompoundNBT nbt)

handleUpdateTag(CompoundNBT tag) => handleUpdateTag(BlockState state, CompoundNBT tag)

特殊渲染

getModelData(@Nonnull ILightReader world, @Nonnull BlockPos pos, @Nonnull BlockState state, @Nonnull IModelData tileData) => getModelData(IBlockDisplayReader world, BlockPos pos, BlockState state, IModelData tileData)

func_230044_c_() => isSideLit()

实体

LivingEntity必须要设置一个Attributes.MAX_HEALTHattributes设置方法:

@Mod.EventBusSubscriber(bus = Mod.EventBusSubscriber.Bus.MOD)
public class AttributesSetEvent {
    @SubscribeEvent
    public static void setupAttributes(FMLCommonSetupEvent event) {
        event.enqueueWork(() -> {
            GlobalEntityTypeAttributes.put(EntityTypeRegistry.obsidianAnimal.get(), MobEntity.func_233666_p_().createMutableAttribute(Attributes.MAX_HEALTH, 10.0D).create());
        });
    }
}

GUI

GUI 在 1.16 之后也改成了 batch 模式的渲染,所以基本上GUI内置的方法都需要加上一个MatrixStack参数。

Widget的构造函数中的title改成了ITextComponent,所有子类都要传入一个ITextComponent,建议传入TranslationTextComponent.

drawString => drawCenteredString

世界生成

随着1.16允许json文件自定义地形生成,地形生成相关的改动相较于其他部分幅度较大。具体的改动还没有研究完毕。

Biome相关的内容

Forge现在提供了一个新的事件用于对Biome进行修改:BiomeLoadingEvent
根据文档,这个事件有三个优先级:

  1. EventPriority#HIGH,用于向Biome内添加内容
  2. EventPriority#NORMAL,用于向Biome删除内容
  3. EventPriority#LOW,其他类型的更改。

此外Feature, Structure等,都放在了Biome下等BiomeGenerationSettings中。
下面是一个利用这个事件添加矿物生成的例子:

@Mod.EventBusSubscriber()
public class OreGen {
    @SubscribeEvent(priority = EventPriority.HIGH)
    public static void onSetUpEvent(BiomeLoadingEvent event) {
        event.getGeneration().withFeature(GenerationStage.Decoration.UNDERGROUND_ORES,
                Feature.ORE.withConfiguration(
                        new OreFeatureConfig(OreFeatureConfig.FillerBlockType.field_241882_a,
                                BlockRegistry.obsidianBlock.get().getDefaultState(),
                                9)
                ).withPlacement(Placement.field_242907_l.configure(new TopSolidRangeConfig(0, 0, 64)))
                        .withPlacement(Placement.field_242903_g.configure(NoPlacementConfig.field_236556_b_))
                        .withPlacement(Placement.field_242899_c.configure(new FeatureSpreadConfig(FeatureSpread.func_242252_a(20))))
        );
    }
}

命令

命令现在将在RegisterCommandsEvent事件下注册

粒子效果

ParticleType类现在必须要实现一个Codec<T IParticleData> func_230522_e_()方法,直接在这个方法里返回一个你的IParticleData实例就行:

@Override
 public Codec<ObsidianParticleData> func_230522_e_() {
    return Codec.unit(new ObsidianParticleData(new Vector3d(0, 0, 0), new Color(0), 0));
}

物品属性覆盖 Item Property Override

ItemModelsProperties.registerProperty现在不能写在item的构造器中了。建议放到FMLClientSetUpEvent事件的enqueueWork中。原来的语句不需要额外的改动。简单的例子:

@Mod.EventBusSubscriber(bus = Mod.EventBusSubscriber.Bus.MOD,value = Dist.CLIENT)
public class ModItemPropertyOverride {
    @SubscribeEvent
    public static void itemPropertyOverride(FMLClientSetupEvent event){
        event.enqueueWork(()->{
            //from BOW's part in ItemModelsProperties.java
            ItemModelsProperties.registerProperty(ModItems.ExampleItem,new ResourceLocation("pulling"),(itemStack, clientWorld, livingEntity) -> {
                return livingEntity != null && livingEntity.isHandActive() && livingEntity.getActiveItemStack() == itemStack ? 1.0F : 0.0F;
            });
        });
    }
}

总结

总体而言如果你的Mod不涉及到世界生成的内容,1.15到1.16的迁移量并不大,如果你是从1.12开始迁移而且你的Mod涉及到世界生成相关的内容,可以直接迁移到1.16版本。


dasffafa


只需要这么点工作量啊,太棒了


FledgeXu


没有,我还在写……


dbydd


世界生成真的是每个版本都在变。。。