本篇教程的视频

(待发布)

本篇教程的源代码

(待发布)

本篇教程目标

  • 学会更改gradle的配置,并将项目更新到1.21.2

注意

本篇教程只讲如何更改Gradle配置,并将项目更新至1.21.2,并修正表面上出现的问题

而涉及具体内容的更改,如物品、方块的注册等,我们将在后续的教程中讲解,将附加于已有教程之后

注意!!!

由于1.21.2改动较多,非常不建议将项目直接升级为1.21.2,尤其是已经有相对完整的项目时

不然那叫一个一改一个不吱声

本篇教程将所有代码回滚至数据生成这那个分支,并在此基础上,再签出一个新分支进行升级作业

后面更改的内容作为单独教程推出,并不会在一篇教程中讲完

更改Gradle配置

关于升级版本这个事情,我在第一期教程也提到过,我们可以到Fabric的官网去查询不同版本的信息

Fabric开发页面:Fabric Develop

其中的Latest Versions,我们可以选择Minecraft的版本,查看其依赖、映射、加载器等是否有更新

Loom中指明了目前最新的Fabric Loom的版本

build.gradle

这个文件中,我们可以更改的是Fabric Loom的版本

目前,截至我写这个教程,Fabric Loom的最新版本是1.11-SNAPSHOT

我们可以将build.gradle中的fabric-loom的版本号改为1.11-SNAPSHOT

1
2
3
4
plugins {
id 'fabric-loom' version '1.11-SNAPSHOT'
id 'maven-publish'
}

但要注意,1.11-SNAPSHOT版本要求的最低Gradle版本为8.14

所以,还要确保项目下的gradle/wrapper中的gradle-wrapper.properties文件中的distributionUrl的版本号大于等于8.14

1
distributionUrl=https\://services.gradle.org/distributions/gradle-8.14-bin.zip

用镜像源的同理

gradle.properties

在这个文件中,我们要修改Minecraft的版本号,以及Fabric加载器及其API的版本号

1
2
3
4
5
minecraft_version=1.21.2
yarn_mappings=1.21.2+build.1
loader_version=0.16.14

fabric_version=0.106.1+1.21.2

当然,其实是应该一个小版本一个小版本这样来升级的,尤其是你真正在开发模组时,有些小版本还是有区别的

不过我们做教程的话,就不考虑这么多了,直接将项目从1.21升级到1.21.2

模组的版本号也可以改一下

1
mod_version=0.1-1.21.2

重新构建项目

那么我们就来对这个项目重新构建,让它来下载1.21.2的那些东西

同样的,大概率是要魔法的

出现BUILD SUCCESSFUL就说明成功了

修复表面上的问题

我们先来修复表面上已经报错的那些代码,在后面的教程中来修复藏在里面的或者因为版本回滚没有出现的问题

这个呢,我们也可以一并打开Fabric的Blog,查看有哪些地方它进行了修改

在IDEA的左侧栏中,我们可以找到问题,通过构建项目来查找问题

这里呢,主要是数据生成的那些问题

ModLootTableProvider

1
2
3
// RegistryWrapper.Impl<Enchantment> impl = this.registryLookup.getWrapperOrThrow(RegistryKeys.ENCHANTMENT);

RegistryWrapper.Impl<Enchantment> impl = this.registryLookup.getOrThrow(RegistryKeys.ENCHANTMENT);

getWrapperOrThrow方法更改为getOrThrow方法

ModRecipesProvider

配方的生成类改动有点大

首先我们继承了FabricRecipeProvider之后,还得重写几个方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@Override
// public void generate(RecipeExporter exporter) {
protected RecipeGenerator getRecipeGenerator(RegistryWrapper.WrapperLookup registryLookup, RecipeExporter exporter) {
return null;
}

@Override
public String getName() {
return "";
}
···
原来的`generate`方法失效了,现在是`getRecipeGenerator`方法

getName方法返回一个字符串,我们随便写点
```java
@Override
public String getName() {
return "Recipe Gen";
}

getRecipeGenerator

我们重点来看这个方法

首先是写它的返回值

1
2
3
4
5
6
return new RecipeGenerator(wrapperLookup, recipeExporter) {
@Override
public void generate() {

}
};

实例化RecipeGenerator,里面重写一个generate方法

在这个方法中,我们先写一个注册表包装器中的注册表项

1
RegistryWrapper.Impl<Item> itemLookup = registries.getOrThrow(RegistryKeys.ITEM);

原有generate方法中的东西可以搬过来,但也要改

熔炉、高炉

1
2
3
4
5
6
7
8
9
// offerSmelting(exporter, ICE_ETHER_LIST, RecipeCategory.MISC, ModItems.ICE_ETHER,
// 0.7f, 200, "ice_ether");
offerSmelting(ICE_ETHER_LIST, RecipeCategory.MISC, ModItems.ICE_ETHER,
0.7f, 200, "ice_ether");

// offerBlasting(exporter, ICE_ETHER_LIST, RecipeCategory.MISC, ModItems.ICE_ETHER,
// 0.7f, 100, "ice_ether");
offerBlasting(ICE_ETHER_LIST, RecipeCategory.MISC, ModItems.ICE_ETHER,
0.7f, 100, "ice_ether");

9->1, 1->9可逆合成

1
2
3
4
// offerReversibleCompactingRecipes(exporter, RecipeCategory.MISC, ModItems.ICE_ETHER,
// RecipeCategory.BUILDING_BLOCKS, ModBlocks.ICE_ETHER_BLOCK);
offerReversibleCompactingRecipes(RecipeCategory.MISC, ModItems.ICE_ETHER,
RecipeCategory.BUILDING_BLOCKS, ModBlocks.ICE_ETHER_BLOCK);

营火

1
2
offerFoodCookingRecipe("campfire_cooking", RecipeSerializer.CAMPFIRE_COOKING, CampfireCookingRecipe::new,
600, ModItems.RAW_ICE_ETHER, ModItems.ICE_ETHER, 0.35f);

有序合成、无序合成

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// ShapedRecipeJsonBuilder.create(RecipeCategory.MISC, Items.SUGAR, 3)
// .pattern("###")
// .input('#', Items.BEETROOT)
// .criterion("has_item", RecipeProvider.conditionsFromItem(Items.BEETROOT))
// .offerTo(exporter, Identifier.of(ReTutorial.MOD_ID, "beetroot_to_sugar"));

ShapedRecipeJsonBuilder.create(itemLookup, RecipeCategory.MISC, Items.SUGAR, 3)
.pattern("###")
.input('#', Items.BEETROOT)
.criterion("has_item", conditionsFromItem(Items.BEETROOT))
.offerTo(recipeExporter);

// ShapelessRecipeJsonBuilder.create(RecipeCategory.BUILDING_BLOCKS, ModBlocks.ICE_ETHER_ORE)
// .input(ModItems.ICE_ETHER)
// .input(Blocks.STONE)
// .criterion("has_item", RecipeProvider.conditionsFromItem(ModItems.ICE_ETHER))
// .criterion("has_item", RecipeProvider.conditionsFromItem(Blocks.STONE))
// .offerTo(exporter, Identifier.of(ReTutorial.MOD_ID, "ice_ether_ore"));

ShapelessRecipeJsonBuilder.create(itemLookup, RecipeCategory.BUILDING_BLOCKS, ModBlocks.ICE_ETHER_ORE)
.input(ModItems.ICE_ETHER)
.input(Blocks.STONE)
.criterion("has_item", conditionsFromItem(ModItems.ICE_ETHER))
.criterion("has_item", conditionsFromItem(Blocks.STONE))
.offerTo(recipeExporter);

表面上要改的东西大概就这些,但是如果你现在去跑数据生成,还是会报错的

那些是物品、方块注册上的问题了,我们在之后的教程中再讲