Fabric 模组开发 - Minecraft1.20.1:#1. 初始化工作区布置
前言
我重生了,上一世我没能坚持学习 Fabric Modding 导致未能幸存,这一世我要拿回属于我的一切😤
一直以来想学着做一个 mod 供自己玩,于是在此记录学习过程,鞭策自己学下去。
平台:Windows11
Java 版本:Java 21
Minecraft 版本:1.20.1
Git 版本:git version 2.50.1.windows.1
IDE:IntelliJ IDEA Community Edition 2025.1.3(以下将简称为 IDEA)
Fabric 模板项目
推荐使用 Fabric 官方提供的模板项目开始学习。你可以点击进行跳转:
Minecraft 版本为 1.20.1 并且在高级选项中,将 Data Generation
勾选上,取消勾选 Split client and common sources
。Data Generation
能让我们可以构建合成配方等资源,取消勾选拆分客户端和服务端代码是因为,初学者基本搞不清哪部分是服务器端代码哪部分是客户端代码,之后我们将手动进行拆解。
下载下来将压缩包解压,将目录中的 LICENSE
和.github
删除(前者为文件,后者为文件夹)。接着我们用 IDEA 将其作为工程项目打开。
项目配置
在使用 IDEA 将项目打开之后,优先检查以下设置:
- 项目结构:将 SDK 设置为受支持的版本,现在 Fabric 模板项目部分依赖已经要求 SDK 为 21 所以我们选择为 21
- IDEA 设置:将 Gradle 用户主目录从 C 盘更改到其他你喜欢的路径,并检查 Gradle 使用的 JVM 版本是否为 SDK 21
都确认无误之后,别忘记点击应用并确定更改。
在打开项目,配置设置的这段时间,IDEA 会自动触发 gradle 下载依赖,构建速度取决于你的网络链接状态。构建完成时,你将会在日志输出界面看到 BUILD SUCCESSFUL
的字样:
若你的 SDK 为 java 17 或其他版本,你可能会在构建的时候遇到下面的报错:
1
2
3
4
5
6
7
8
9
10
11
12
13
A problem occurred configuring root project 'tutorial-mod-template-1.20.1'.
> Could not resolve all artifacts for configuration 'classpath'.
> Could not resolve net.fabricmc:fabric-loom:1.11-SNAPSHOT.
Required by:
root project : > fabric-loom:fabric-loom.gradle.plugin:1.11-SNAPSHOT:20250708.081131-4
> Dependency requires at least JVM runtime version 21. This build uses a Java 17 JVM.
* Try:
> Run this build using a Java 21 or newer JVM.
> Run with --stacktrace option to get the stack trace.
> Run with --info or --debug option to get more log output.
> Run with --scan to get full insights.
> Get more help at https://help.gradle.org.
该报错的原因是 fabric-loom
插件版本内部依赖了 Java 21+ 的功能或库,你可以在 build.gradle
和 gradle.properties
中找到相关的 fabric-loom
版本说明:
1
2
3
4
5
6
7
8
9
10
11
// build.gradle
plugins {
id 'fabric-loom' version "${loom_version}"
id 'maven-publish'
}
//gradle.properties
minecraft_version=1.20.1
yarn_mappings=1.20.1+build.10
loader_version=0.16.14
loom_version=1.11-SNAPSHOT
为什么要使用该版本?Fabric 文档是这么写的…
The recommended loom version is 1.11-SNAPSHOT. This is usually defined near the top of your build.gradle file.
推荐的 loom 版本是 1.11-SNAPSHOT。这通常定义在您的 build.gradle 文件顶部附近。
既然使用 Java21 了,相对应的也把 build.gradle
里面的相关配置项也修改为对应的版本:
1
2
3
4
5
6
7
8
9
10
11
12
13
java {
withSourcesJar()
- sourceCompatibility = JavaVersion.VERSION_17
- targetCompatibility = JavaVersion.VERSION_17
+ sourceCompatibility = JavaVersion.VERSION_21
+ targetCompatibility = JavaVersion.VERSION_21
}
tasks.withType(JavaCompile).configureEach {
- it.options.release = 17
+ it.options.release = 21
}
好了。接着,在项目视图的选项中,将平展相关选项取消勾选,这将使得 IDEA 不再将 com.frozen.tutorialmod
下的 mixin
文件夹显示为 com.frozen.tutorialmod.mixin
格式,方便我们掌握目录层级情况。
Mod ID
mod 的 id 是该 mod 的唯一标识,且该 id 只能为数字
0-9
、小写字母a-z
、下划线_
和短横线-
组成的字符串。
在 java/com/frozen/tutorialmod/TutorialMod.java
中,检查是否已经将 Mod 的 id 进行引入:
1
2
3
4
5
6
7
8
9
public class TutorialMod implements ModInitializer {
public static final String MOD_ID = "tutorial-mod"; // 关键语句
public static final Logger LOGGER = LoggerFactory.getLogger(MOD_ID);
@Override
public void onInitialize() {
LOGGER.info("Hello Fabric world!");
}
}
此 ID 将在后面的开发过程中多次引用,所以这一步骤十分重要。
接着,在 resources/fabric.mod.json
文件中,查看 ID 是否正确,相关配置是否正确:
depends
和 suggests
项,暂不用修改,等以后开发涉及到了视情况修改。
修改 mod 版本(可选)
我比较喜欢语义化版本控制。由于目前我们只是在配置、初始化阶段,所以在 gradle.properties
中,将 mod_version
进行修改:
1
2
3
4
5
# Mod Properties
- mod_version=1.0.0
+ mod_version=0.0.1-1.20.1
maven_group=com.frozen.tutorialmod
archives_base_name=tutorial-mod
以 0.0.1
为例,这种命名的基本语法是:
名称 | 含义 |
---|---|
MAJOR (主版本) |
有不兼容性变更时递增,比如移除 API、重构核心逻辑 |
MINOR (次版本) |
添加了新功能,但向后兼容 |
PATCH (补丁版本) |
修复了 bug,无新增功能,向后兼容 |
具体来说:
版本号 | 说明 |
---|---|
1.2.3 |
主版本 1,添加了 2 个次要功能,修复了 3 个 bug |
0.1.0 |
尚在早期开发阶段,有了基本功能 |
0.0.1 |
刚起步,甚至还不一定稳定 |
2.0.0 |
大版本更新,可能有重大 API 变更或破坏性更改 |
对于我的 0.0.1-1.20.1
版本号,-1.20.1
主要是为了声明所兼容的 Minecraft 版本。
由于我们修改了 gradle.properties
文件,这会影响到构建,所以需要重新加载一遍项目:
这将花费一些时间。
Client 初始化
前面在模板项目生成的时候,我们取消了勾选拆分客户端和服务器端,这里尝试手动初始化客户端。
在 resources/fabric.mod.json
中,修改 entrypoints
节点内容:
1
2
3
4
5
6
7
8
9
10
11
"entrypoints": {
"main": [
"com.frozen.tutorialmod.TutorialMod"
],
+ "client": [
+ "com.frozen.tutorialmod.TutorialModClient"
+ ],
"fabric-datagen": [
"com.frozen.tutorialmod.TutorialModDataGenerator"
]
},
根据这项修改,我们就需要在 com.frozen.tutorialmod
文件夹下新建 Java 类 TutorialModClient
,刚创建好该文件,代码内容为:
1
2
3
4
package com.frozen.tutorialmod;
public class TutorialModClient {
}
我们将 TutorialModClient
修改为实现 ClientModInitializer
接口的类:
1
2
3
4
5
6
7
8
9
10
package com.frozen.tutorialmod;
import net.fabricmc.api.ClientModInitializer;
public class TutorialModClient implements ClientModInitializer {
@Override
public void onInitializeClient() {
}
}
onInitializeClient()
方法暂时不需要做任何事。
下载源码
Minecraft 的源码对我们的开发有着很高的参考价值,这将帮助我们理解各种写法。
检查 JAVA_HOME 版本
请确认自己的 JAVA_HOME
的值指向的是 Java21
而非其他版本。
Gradle 启动的时候 默认使用自己找到的 JDK。如果系统上现在有 多个 JDK 安装,Gradle 会优先使用以下路径之一来选择 JDK:
- 环境变量
JAVA_HOME
(优先级最高) gradle.properties
中指定的org.gradle.java.home
- 系统 PATH 中的 Java 版本(最后才使用)
对我来说,我的 JAVA_HOME
环境变量设为了 %JAVA_HOME21%
,这将和我的 JAVA_HOME17
、JAVA_HOME21
等 JAVA_HOMExx
格式的环境变量进行配合,一般来说,终端将会输出:
1
2
3
4
5
6
7
PS E:\Coding\Fabric\tutorial-mod-template-1.20.1> echo $env:JAVA_HOME
E:\Program Files\jdk-21.0.7
PS E:\Coding\Fabric\tutorial-mod-template-1.20.1> java -version
java version "21.0.7" 2025-04-15 LTS
Java(TM) SE Runtime Environment (build 21.0.7+8-LTS-245)
Java HotSpot(TM) 64-Bit Server VM (build 21.0.7+8-LTS-245, mixed mode, sharing)
PS E:\Coding\Fabric\tutorial-mod-template-1.20.1>
这是正常的输出。
但如果,你的 JAVA_HOME
环境变量设置的是 %JAVA_HOME17%
,只是将 IDEA 中的相关配置为了 Java21 的话,那么可能在终端中执行 gradle
相关命令,例如:
1
.\gradlew -v
此时读取到的还是 17,而执行 java -version
却能正确输出为 java21 版本,这十分诡异对吧?
实际上,$env:JAVA_HOME
和 java -version
读取的项是不一样的。这一点很容易搞混,尤其是初学者。具体来说:
$env:JAVA_HOME
:读取的是环境变量JAVA_HOME
的值,如果是%JAVA_HOME21%
那么就会得到JAVA21
java -version
:读取的是环境变量PATH
的值,java
命令会从PATH
中按照先后顺序找到一个java
有效目录,用以执行命令。
这与 IDEA 设置中设置的 Java21 是不相关的:
如果你确实是上面的诡异情况,请在更改 JAVA_HOME
指向的值之后,重启 IDEA 再另起一个终端窗口。
下载源码
唤起终端窗口(默认唤起的是 PowerShell),执行下面的命令:
1
./gradlew genSources
下载成功将输出:
1
2
3
4
5
6
7
8
9
10
11
12
PS E:\Coding\Fabric\tutorial-mod-template-1.20.1> ./gradlew genSources
Starting a Gradle Daemon, 4 stopped Daemons could not be reused, use --status for details
> Configure project :
Fabric Loom: 1.11.4
> Task :genSourcesWithVineflower
Decompile cache stats: 0 hits, 4786 misses
BUILD SUCCESSFUL in 42s
1 actionable task: 1 executed
PS E:\Coding\Fabric\tutorial-mod-template-1.20.1>
如何查看源码
在 java/com/frozen/tutorialmod/mixin/ExampleMixin.java
文件中,将鼠标选中 MinecraftServer
并按下鼠标中键:
1
2
3
4
5
6
7
@Mixin(MinecraftServer.class)
public class ExampleMixin {
@Inject(at = @At("HEAD"), method = "loadWorld")
private void init(CallbackInfo info) {
// This code is injected into the start of MinecraftServer.loadWorld()V
}
}
这将跳转至我们刚才下载的 Minecraft 源码,如下图所示:
注意,打开的应该是带注释的源码!如果你的 IDEA 版本和我不同,可能打开的是默认的 IDEA 帮你反编译之后的代码,你需要手动选择代码上方的蓝条的 Choose Sources
也就是选择源:
如果选择源之后,代码上方的蓝条变成了红条,这也是正常的。
运行 Minecraft 测试
现在,我们就可以尝试运行一次 Minecraft 来测试我们的一切配置、代码是否正确了。
找到 Gradle 栏,选择 Tasks/fabric/runClient
,如下图所示:
不出意外出来 Minecraft 的窗口之后,我们创建一个存档,进入存档试试功能:
只要在控制台中的日志没有什么 error 错误就行。
Git 版本控制
我十分推荐对项目进行版本控制,这里使用的是 GitHub。
注册账号就不讲了,自己搜索就行。由于我们已经在使用 IDEA,那么直接用 IDEA 的版本控制选项就行(旧版本可能叫 VCS):
IDEA 将会弹出一个对话框,让你填相关信息:
仓库私有与否,顾名思义,私有别人就看不到,如果你想和别人协作或者有别的考虑就可以公开。
接着进行第一次提交:
确认文件无误就可以提交并推送了(如果只是提交,则是只提交到了本地仓库而 GitHub 是没有的)。此后,每次对相关文件的更改都将进行记录。