注意:本页假定你没有任何编写模组的经验。但是,你应该先会一点 Java 语言以使用 Minecraft(参见“前提”段落)。如果你是从其他模组加载器(如 Forge)来的,可以直接阅读 introduction。
本文档是给模组编写的初学者使用的,比如还不知道 BlockState
和 BlockPos
的玩家。如果你有编写数据包的经验并想要将技巧提升到更高水平,或者需要学习面向对象的语言并开启一个有趣的项目,那么本文档适合你。首先从你需要了解的几个概念开始:
模组编写(Modding)是指的往程序的源代码里面增添或者修改内容,这个程序就是指的 Minecraft。你制作的所有模组都需要增添或者修改内容。
Fabric 是一系列用于编写 Minecraft 模组的工具,包括:
为了更好的理解 Minecraft 的代码干了什么,当你使用 Fabric 进行模组编写时,你有机会接触到 Minecraft 的源代码。由于 Java 是编译型语言,我们需要反编译来获得我们能够读懂的代码。这一过程会将它从 Java 字节码转变为人类可读的 Java 源代码。然而,为了阻止盗版,Mojang 混淆 了 Minecraft 的代码。这意味着代码中所有的类、方法和字段的名称是随机的。你可以通过 zip 解压工具中打开 Minecraft 的 .jar 文件亲眼看到这一点 —— 所有的文件都会以类似 abc.class
的形式出现。此外,我们无法保证两个版本同一个对象拥有相同的名称 —— 可能上个版本还是 abc
,下个版本就是 adb
了。所以这使得在不知道对象名称的情况下修改游戏十分困难,因为我们无法知道不同变量的作用。为了解决这个问题,Fabric 使用了一套映射工具来给所有东西起一个人类可读的名称。
但是,在反编译的 Minecraft 代码库中,并不是所有的对象都被 Yarn 映射了 —— 有时你会看到一些变量仍然有中介名称。如果你弄清楚了它们的作用,你可以为 Yarn 贡献一个名称2)。查看 mappings 页面,了解更多关于使用和贡献映射的信息。
Minecraft Java 版是一个巨大的项目,多年来的代码都是建立在彼此之上的。它可能看起来很混乱(因为它就是的),但有几个关键的概念是(大部分)一致的,贯穿始终。
很多游戏中的(方块、物品、UI、实体、区块生成器等的)“特性”(你想添加的)在游戏被加载时候将会被加载进注册表。比如,每一个物品
类型都有一个静态的实例,这些实例将在游戏开始的时候被初始化,接着就会被加载进物品类型的注册表。游戏使用这些实例去获取物品类型的 ItemStack
(所持有物品在物品栏中的内存表示)属性。如果你要添加一些对象到游戏内,你可能需要注册它。然而,这条规定也有例外:Minecraft 中的一些功能是数据驱动的,这意味着它们可以纯粹地用数据(而不是代码)来定义。如果你想知道为什么数据包可以添加一些对象而有些对象不行,这就是原因:数据包只能添加数据驱动的内容。例如在 Minecraft 中,数据驱动的内容包括生物群落、纹理、*一些*区块生成器和制作配方。当一个带有数据包的世界被加载时,游戏会自动将这些功能添加到一个特殊的暂存器中,只会在该世界被加载完毕后使用。如果你以前开发过数据包,你可以非常容易地将数据包整合到你的模组中,这使得一些内容更容易创建。你甚至可以添加你自己的数据驱动规则,从而其他人可以使用 Codecs 为其制作数据包。
Minecraft 运行在两个线程上,通常称为 “端”:服务器端和客户端。客户端总是运行在玩家的电脑上,处理渲染和输入。服务器端可以在专用服务器上独立运行(你可能认为是“Minecraft 服务器”),或者在单人游戏中,与客户端一起在玩家的计算机上运行,作为一个集成服务器。服务器端处理客户端没有处理的一切 —— 物品栏、世界本身,等等。客户端和服务器端必须就某些事情达成一致:世界上有哪些区块,箱子里有什么,玩家的位置等等。由于这些都是由服务器端处理的,所以它向客户端规定这些值应该是什么,而客户端则向玩游戏的人展现这些值。任何由客户端处理的东西都不需要告诉服务器 —— 这包括区块和实体的样子(资源包),以及如何绘制世界(着色器)。这就是客户端模组(如着色器)、服务器端模组(如那些运行小游戏的模组)和双方模组(那些添加机器或新方块和物品的模组)之间的区别。重要的是,不要在服务器端上调用只针对客户端的代码(即与渲染有关),而在客户端调用只针对服务器端的代码。这就是你在 Minecraft 模组制作中经常看到的无处不在的 world.isClient()
检查的原因。
一旦你达到了先决条件并阅读了本文档,就可以开始了!查看 introduction 介绍以更深入了解 Fabric 这个平台,阅读 setup 文档以设置 IDE 来修改 Minecraft,然后前往 items 教程来添加第一个物品!