Skip to main content
Version: 1.21.4

模组文件(Mod Files)

模组文件负责决定哪些模组会被打包进你的 JAR 文件、在 "Mods" 菜单中显示哪些信息,以及你的模组应如何在游戏中加载。

gradle.properties

gradle.properties 文件包含了你的模组的一些常用属性,例如模组 ID(mod id)或模组版本(mod version)。在构建过程中,Gradle 会读取这个文件中的值,并在多个地方进行内联替换,比如在 neoforge.mods.toml 文件中。这样,你只需在一个地方修改属性值,所有相关配置都会自动同步更新。

大多数属性在 MDK 的 gradle.properties 文件 中也有注释进行详细说明。

属性(Property)描述(Description)示例(Example)
org.gradle.jvmargs允许你为 Gradle 传递额外的 JVM 参数。最常见的用途是为 Gradle 分配更多或更少的内存。注意,这只影响 Gradle 本身,不影响 Minecraft。org.gradle.jvmargs=-Xmx3G
org.gradle.daemon构建时 Gradle 是否应使用守护进程(daemon)。org.gradle.daemon=false
org.gradle.parallelGradle 是否应通过分叉 JVM 实现并行执行项目。org.gradle.parallel=false
org.gradle.cachingGradle 是否应复用之前构建任务的输出结果。org.gradle.caching=false
org.gradle.configuration-cacheGradle 是否应复用之前构建的配置信息。org.gradle.configuration-cache=false
org.gradle.debug是否将 Gradle 设置为调试模式。调试模式主要会增加 Gradle 的日志输出。注意,这只影响 Gradle 本身,不影响 Minecraft。org.gradle.debug=false
minecraft_version你正在开发的 Minecraft 版本。必须与 neo_version 保持一致。minecraft_version=1.20.6
minecraft_version_range此模组可用的 Minecraft 版本范围,采用 Maven 版本范围。注意,快照版、预发布版和候选发布版 不保证能正确排序,因为它们不遵循 Maven 版本规则。minecraft_version_range=[1.20.6,1.21)
neo_version你正在开发的 NeoForge 版本。必须与 minecraft_version 保持一致。关于 NeoForge 版本的详细信息,请参阅 NeoForge 版本说明neo_version=20.6.62
neo_version_range此模组可用的 NeoForge 版本范围,采用 Maven 版本范围neo_version_range=[20.6.62,20.7)
loader_version_range此模组可用的模组加载器版本范围,采用 Maven 版本范围。注意,加载器的版本号与 NeoForge 版本号是解耦的。loader_version_range=[1,)
mod_id参见 模组 IDmod_id=examplemod
mod_name你的模组的人类可读显示名称。默认情况下,该名称只会在模组列表中显示,但像 JEI 这样的模组也会在物品提示中突出显示模组名称。mod_name=Example Mod
mod_license你的模组所使用的许可证。建议填写你所用的 SPDX 标识符 和/或许可证链接。你可以访问 https://choosealicense.com/ 来选择合适的许可证。mod_license=MIT
mod_version你的模组版本号,会显示在模组列表中。更多信息请参阅版本管理页面mod_version=1.0
mod_group_id参见 Group IDmod_group_id=com.example.examplemod
mod_authors模组作者,会显示在模组列表中。mod_authors=ExampleModder
mod_description模组描述,作为多行字符串显示在模组列表中。可以使用换行符(\n),会被正确替换为换行。mod_description=Example mod description.

模组 ID(Mod ID)

模组 ID(mod ID)是区分你的模组与其他模组的主要方式。它被广泛用于各种场景,包括作为你的模组注册表(Registry)的命名空间,以及作为你的资源包和数据包的命名空间。如果有两个模组使用相同的 ID,游戏将无法加载它们。

因此,你的模组 ID 应当独特且易于记忆。通常,它会是你的模组显示名称的小写形式,或者是其变体。模组 ID 只能包含小写字母、数字和下划线,长度必须在 2 到 64 个字符之间(含边界值)。

info

gradle.properties 文件中更改此属性会自动同步到其他地方,除了主模组类中的 @Mod 注解。那里的值需要你手动修改,使其与 gradle.properties 文件中的值保持一致。

组 ID(Group ID)

虽然 build.gradle 文件中的 group 属性只有在你计划将模组发布到 maven 时才是必须的,但始终正确设置它是一种良好习惯。你可以通过 gradle.properties 文件中的 mod_group_id 属性来配置这一点。

组 ID 应设置为你的顶级包名。更多信息请参见打包(Packaging)

# 在你的 gradle.properties 文件中
mod_group_id=com.example

你的 Java 源码目录(src/main/java)下的包结构也应遵循这一规范,内部包名代表模组 ID:

com
- example (在 group 属性中指定的顶级包)
- mymod (模组 ID)
- MyMod.java (重命名后的 ExampleMod.java)

neoforge.mods.toml

neoforge.mods.toml 文件位于 src/main/resources/META-INF/neoforge.mods.toml,采用 TOML 格式,用于定义你的模组元数据。它还包含有关模组如何被加载进游戏的附加信息,以及会在“模组”菜单中显示的相关信息。MDK 提供的 neoforge.mods.toml 文件包含了对每一项的注释,本文将更详细地进行说明。

neoforge.mods.toml 文件可分为三部分:与具体模组无关的属性(与模组文件关联)、模组属性(每个模组一个分区)、依赖配置(每个模组或模组组的依赖分区)。neoforge.mods.toml 文件中的某些属性是强制性的;这些必填属性必须指定值,否则会抛出异常。

note

在默认的 MDK 中,Gradle 会将此文件中的各种属性替换为 gradle.properties 文件中指定的值。例如,license="${mod_license}" 这一行表示 license 字段会被 gradle.properties 中的 mod_license 属性替换。像这样被替换的值应在 gradle.properties 中修改,而不是直接在这里更改。

非模组专属属性(Non-Mod-Specific Properties)

非模组专属属性是与 JAR 文件本身关联的属性,用于指示如何加载模组(mod)以及包含其他全局元数据。

属性(Property)类型(Type)默认值(Default)描述(Description)示例(Example)
modLoaderstring必填模组(mod)所使用的语言加载器(loader)。可用于支持其他语言结构,比如将主文件写为 Kotlin 对象,或用不同的方法确定入口点(entrypoint),如接口或方法。NeoForge 提供了 Java 加载器 "javafml" 和低代码/无代码加载器 "lowcodefml"modLoader="javafml"
loaderVersionstring必填语言加载器可接受的版本范围,采用 Maven 版本范围 表达。例如 javafmllowcodefml 目前的版本为 1loaderVersion="[1,)"
licensestring必填本 JAR 内模组所采用的许可证(license)。建议填写你所用的 SPDX 标识,和/或许可证的链接。你可以访问 https://choosealicense.com/ 来帮助选择合适的许可证。license="MIT"
showAsResourcePackbooleanfalse当设为 true 时,模组的资源将在“资源包(Resource Packs)”菜单中作为单独的资源包显示,而不是与“模组资源(Mod Resources)”包合并。showAsResourcePack=true
showAsDataPackbooleanfalse当设为 true 时,模组的数据文件将在“数据包(Data Packs)”菜单中作为单独的数据包显示,而不是与“模组数据(Mod Data)”包合并。showAsDataPack=true
servicesarray[]模组所使用的服务(service)数组。这会被 NeoForge 对 Java 平台模块系统(Java Platform Module System)实现时,作为模块的一部分进行消费。services=["net.neoforged.neoforgespi.language.IModLanguageProvider"]
propertiestable{}替换属性(substitution property)表。StringSubstitutor 会用它将 ${file.<key>} 替换为对应的值。properties={"example"="1.2.3"}(可通过 ${file.example} 引用)
issueTrackerURLstring用于报告和跟踪模组问题的网址(URL)。"https://github.com/neoforged/NeoForge/issues"
note

services 属性在功能上等同于在模块中指定 uses 指令,它允许加载指定类型的服务

另外,你也可以在 src/main/resources/META-INF/services 文件夹下,通过服务文件来定义。服务文件的文件名应为服务的全限定名,文件内容则为要加载的服务名称(参见 AtlasViewer 模组的这个示例)。

模组专用属性(Mod-Specific Properties)

模组专用属性与通过 [[mods]] 标头指定的模组相关联。这是一个表数组;所有的键/值属性都会附加到该模组,直到下一个标头为止。

# examplemod1 的属性
[[mods]]
modId = "examplemod1"

# examplemod2 的属性
[[mods]]
modId = "examplemod2"
属性(Property)类型(Type)默认值(Default)描述(Description)示例(Example)
modIdstring必填参见 模组 IDmodId="examplemod"
namespacestringmodId 的值模组的命名空间(namespace)覆盖。必须也是一个有效的 模组 ID,但可以包含点号或短横线。目前未被使用。namespace="example"
versionstring"1"模组的版本,推荐采用 Maven 版本格式的变体。如果设置为 ${file.jarVersion},则会被 JAR 包 manifest 文件中的 Implementation-Version 属性值替换(在开发环境下显示为 0.0NONE)。version="1.20.2-1.0.0"
displayNamestringmodId 的值模组的显示名称。当需要在界面上展示模组时(如模组列表、模组不匹配时)使用。displayName="Example Mod"
descriptionstring'''MISSING DESCRIPTION'''在模组列表界面显示的模组描述。推荐使用 多行文本字面量。该值支持国际化,详情见 模组元数据翻译description='''This is an example.'''
logoFilestring在模组列表界面使用的图片文件名及扩展名。路径必须是以 JAR 或源码集根目录为起点的绝对路径(如主源码集为 src/main/resources)。有效的文件名字符包括小写字母(a-z)、数字(0-9)、斜杠(/)、下划线(_)、点号(.)和短横线(-)。完整字符集为 [a-z0-9_-.]logoFile="test/example_logo.png"
logoBlurbooleantrue渲染 logoFile 时是否使用 GL_LINEAR*(true)或 GL_NEAREST*(false)。简单来说,就是在缩放 logo 时是否进行模糊处理。logoBlur=false
updateJSONURLstring一个指向 JSON 的 URL,供 更新检查器 使用,以确保当前游玩的模组为最新版本。updateJSONURL="https://example.github.io/update_checker.json"
featurestable{}参见 特性features={java_version="[17,)"}
modpropertiestable{}与该模组关联的键值对表。NeoForge 不使用,主要供模组自身使用。modproperties={example="value"}
modUrlstring指向模组下载页面的 URL。目前未被使用。modUrl="https://neoforged.net/"
creditsstring在模组列表界面显示的致谢和鸣谢信息。credits="The person over here and there."
authorsstring在模组列表界面显示的作者信息。authors="Example Person"
displayURLstring在模组列表界面显示的模组展示页面的 URL。displayURL="https://neoforged.net/"
enumExtensionsstring用于 枚举扩展 的 JSON 文件路径。enumExtensions="META_INF/enumextensions.json"
featureFlagsstring用于 特性标志 的 JSON 文件路径。featureFlags="META-INF/feature_flags.json"

功能(Features)

功能系统允许模组在加载时声明对某些设置、软件或硬件的需求。如果某项功能未被满足,模组加载将会失败,并告知用户相关的需求。目前,NeoForge 提供了以下功能:

功能(Feature)描述(Description)示例(Example)
javaVersion可接受的 Java 版本范围,格式为 Maven 版本范围。应当与 Minecraft 支持的 Java 版本一致。features={javaVersion="[17,)"}
openGLVersion可接受的 OpenGL 版本范围,格式为 Maven 版本范围。Minecraft 需要 OpenGL 3.2 或更高版本。如果你希望要求更高版本的 OpenGL,可以在这里指定。features={openGLVersion="[4.6,)"}

访问转换器专用属性(Access Transformer-Specific Properties)

访问转换器专用属性(Access Transformer-specific properties)通过 [[accessTransformers]] 头部与指定的访问转换器绑定。这是一个 表数组;所有键/值属性会被绑定到该访问转换器,直到下一个头部出现。访问转换器头部是可选的;但一旦指定,内部所有元素都是必需的。

属性(Property)类型(Type)默认值(Default)描述(Description)示例(Example)
filestring必填详见 添加 ATsfile="at.cfg"

Mixin 配置属性(Mixin Configuration Properties)

Mixin 配置属性(Mixin Configuration Properties)通过 [[mixins]] 头部与指定的 mixin 配置绑定。这是一个 表数组;所有键/值属性会被绑定到该 mixin 配置块,直到下一个头部出现。mixin 头部是可选的;但一旦指定,内部所有元素都是必需的。

属性(Property)类型(Type)默认值(Default)描述(Description)示例(Example)
configstring必填mixin 配置文件的位置。config="examplemod.mixins.json"

依赖配置(Dependency Configurations)

模组(Mod)可以指定其依赖项,NeoForge 会在加载模组前检查这些依赖配置。这些配置通过 表数组 [[dependencies.<modid>]] 创建,其中 modid 是使用该依赖的模组标识符。

属性(Property)类型(Type)默认值(Default)描述(Description)示例(Example)
modIdstring必填被添加为依赖项的模组(mod)的标识符。modId="jei"
typestring"required"指定该依赖项的性质:"required"(默认值)表示如果缺少此依赖,则阻止该模组加载;"optional" 表示如果缺少依赖不会阻止模组加载,但仍会验证依赖的兼容性;"incompatible" 表示如果存在该依赖,则阻止模组加载;"discouraged" 表示即使存在该依赖仍允许模组加载,但会向用户发出警告。type="incompatible"
reasonstring可选的用户提示信息,用于说明为何需要此依赖,或为何与其不兼容。reason="integration"
versionRangestring""可接受的语言加载器版本范围,采用 Maven 版本范围 表示。空字符串表示匹配任何版本。versionRange="[1, 2)"
orderingstring"NONE"定义该模组是否必须在此依赖项之前("BEFORE")或之后("AFTER")加载。如果加载顺序无关紧要,则填写 "NONE"ordering="AFTER"
sidestring"BOTH"依赖项必须存在的 物理端"CLIENT""SERVER""BOTH"side="CLIENT"
referralUrlstring指向依赖项下载页面的 URL。目前未被使用。referralUrl="https://library.example.com/"
danger

两个模组(mod)的 ordering(加载顺序)可能因为循环依赖而导致崩溃,例如,如果模组 A 必须在模组 B 之前("BEFORE")加载,同时模组 B 也必须在模组 A 之前("BEFORE")加载,就会出现这种情况。

模组入口点(Mod Entrypoints)

现在 neoforge.mods.toml 文件已经填写完成,我们需要为模组提供一个入口点(entrypoint)。入口点本质上是执行模组的起始位置。具体的入口点由 neoforge.mods.toml 中使用的语言加载器(language loader)决定。

javafml@Mod

javafml 是 NeoForge 为 Java 编程语言提供的语言加载器。入口点通过一个带有 @Mod 注解(annotation)的公共类(public class)来定义。@Mod 的值必须包含在 neoforge.mods.toml 中指定的某个模组 id。从这里开始,所有初始化逻辑(例如 注册事件添加 DeferredRegister)都可以在该类的构造函数中指定。

主模组类(main mod class)只能有一个公共构造函数,否则会抛出 RuntimeException。构造函数可以包含以下 任意 参数,顺序不限;这些参数都不是强制要求的,但不允许有重复参数。

参数类型描述
IEventBus模组专用事件总线(用于注册、事件等)
ModContainer保存该模组元数据的抽象容器
FMLModContainerjavafml 定义的实际容器,保存该模组的元数据,是 ModContainer 的扩展
Dist该模组正在加载的 物理端
@Mod("examplemod") // 必须与 neoforge.mods.toml 中的某个模组 id 匹配
public class ExampleMod {
// 合法的构造函数,仅使用了两个可用的参数类型
public ExampleMod(IEventBus modBus, ModContainer container) {
// 在这里初始化逻辑
}
}

默认情况下,@Mod 注解会在 两端 都加载。可以通过指定 dist 参数来改变这一行为:

// 必须与 neoforge.mods.toml 中的某个模组 id 匹配
// 该模组类只会在物理客户端加载
@Mod(value = "examplemod", dist = Dist.CLIENT)
public class ExampleModClient {
// 合法的构造函数
public ExampleModClient(FMLModContainer container, IEventBus modBus, Dist dist) {
// 在这里初始化仅客户端的逻辑
}
}
note

neoforge.mods.toml 中的一个条目并不需要有对应的 @Mod 注解。同样,neoforge.mods.toml 中的一个条目也可以有多个 @Mod 注解,例如如果你想将通用逻辑和仅客户端逻辑分开。

lowcodefml

lowcodefml 是一种语言加载器(language loader),用于将数据包(datapacks)和资源包(resource packs)作为模组(mods)分发,而无需在代码中编写入口点(entrypoint)。之所以命名为 lowcodefml 而非 nocodefml,是因为未来可能会有一些小的扩展需要极少量的编码。