Mod 文件
Mod 文件决定 JAR 中包含哪些 Mod、在“Mod”菜单中显示哪些信息,以及游戏如何加载 Mod。
gradle.properties
gradle.properties 保存 Mod ID、版本等常用属性。构建时,Gradle 读取这些值并替换到 neoforge.mods.toml 等位置。这样只需修改一处,就能在所有相关位置应用。
MDK 的 gradle.properties 也通过注释解释了多数值。
| 属性 | 描述 | 示例 |
|---|---|---|
org.gradle.jvmargs |
向 Gradle 传入额外 JVM 参数,通常用于调整内存。它影响 Gradle 本身,而非 Minecraft。 | org.gradle.jvmargs=-Xmx3G |
org.gradle.daemon |
构建时是否使用 Gradle 守护进程。 | org.gradle.daemon=false |
org.gradle.parallel |
是否派生 JVM,以并行执行项目。 | org.gradle.parallel=false |
org.gradle.caching |
是否复用之前构建的任务输出。 | org.gradle.caching=false |
org.gradle.configuration-cache |
是否复用之前构建的构建配置。 | 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 |
Mod 可使用的 Minecraft 版本范围,以 Maven 版本范围表示。快照、预发布版和候选发布版不遵循 Maven 版本规则,因此不保证正确排序。 | minecraft_version_range=[1.20.6,1.21) |
neo_version |
开发使用的 NeoForge 版本,必须与 minecraft_version 匹配。参阅 NeoForge 版本规范。 |
neo_version=20.6.62 |
mod_id |
参阅 Mod ID。 | mod_id=examplemod |
mod_name |
便于阅读的 Mod 显示名称。默认只在 Mod 列表显示,JEI 等 Mod 也会在物品提示框中显著显示名称。 | mod_name=Example Mod |
mod_license |
Mod 的许可。建议填写 SPDX 标识符及/或许可链接,可参考 https://choosealicense.com/ 选择许可。 | mod_license=MIT |
mod_version |
Mod 列表中显示的版本,参阅版本规范。 | mod_version=1.0 |
mod_group_id |
参阅 Group ID。 | mod_group_id=com.example.examplemod |
Mod ID
Mod ID 是区分不同 Mod 的主要标识,广泛用于注册表命名空间,以及资源包和数据包命名空间。两个 Mod 使用相同 ID 会阻止游戏加载。
应选择独特、易记的 ID,通常为显示名称的小写形式或某种变体。ID 只能包含小写字母、数字和下划线,长度为 2 至 64 个字符,包含端点。
说明 在
gradle.properties中修改 ID 会自动应用到其他位置,但主 Mod 类中的@Mod注解除外。该处必须手动修改,与属性文件保持一致。
Group ID
build.gradle 的 group 属性仅在计划将 Mod 发布到 Maven 仓库时必需,但始终正确设置它是良好习惯。MDK 通过 gradle.properties 的 mod_group_id 设置。
Group ID 应为顶层包名,更多信息见包结构。
# In your gradle.properties file
mod_group_id=com.example
Java 源代码(src/main/java)的包也应遵循此结构,并以内部包表示 Mod ID:
com
- example (top-level package specified in group property)
- mymod (the mod id)
- MyMod.java (renamed ExampleMod.java)
neoforge.mods.toml
此文件位于 src/main/resources/META-INF/neoforge.mods.toml,采用 TOML 格式,定义一个或多个 Mod 的元数据、加载方式及“Mod”菜单中的显示信息。MDK 提供的文件通过注释解释每个条目,下文作进一步说明。
文件可分三部分:关联整个 Mod 文件的非 Mod 专属属性、每个 Mod 各自一节的属性,以及各 Mod 依赖项的配置。某些属性必填,缺失值会抛出异常。
提示 默认 MDK 中,Gradle 会用
gradle.properties的值替换多个属性。例如,license="${mod_license}"表示用属性文件中的mod_license替换license。这类值应在gradle.properties修改,而不是直接在此修改。
非 Mod 专属属性
这些属性关联 JAR 本身,表示加载方式和额外的全局元数据。
| 属性 | 类型 | 默认值 | 描述 | 示例 |
|---|---|---|---|---|
modLoader |
string | javafml |
Mod 使用的语言加载器,可支持 Kotlin 对象等替代语言结构,或通过接口、方法等方式确定入口点。NeoForge 提供 Java 加载器 "javafml"。 |
modLoader="javafml" |
loaderVersion |
string | "" |
可接受的语言加载器版本,以 Maven 版本范围表示。该原文快照中 javafml 的版本为 1。未指定版本时,可以使用任何加载器版本。 |
loaderVersion="[1,)" |
license |
string | 必填 | JAR 内 Mod 的许可,建议填写 SPDX 标识符及/或许可链接。可参考 https://choosealicense.com/ 选择。 | license="MIT" |
showAsResourcePack |
boolean | false |
为 true 时,资源在“资源包”菜单中作为独立资源包显示,不合并到“Mod Resources”。 |
showAsResourcePack=true |
showAsDataPack |
boolean | false |
为 true 时,数据文件在“数据包”菜单中作为独立数据包显示,不合并到“Mod Data”。 |
showAsDataPack=true |
services |
array | [] |
Mod 使用的服务数组,由 NeoForge 的 Java 平台模块系统实现用于创建 Mod 模块。 | services=["net.neoforged.neoforgespi.language.IModLanguageProvider"] |
properties |
table | {} |
替换属性表。StringSubstitutor 用它将 ${file.<key>} 替换为对应值。 |
properties={"example"="1.2.3"},随后以 ${file.example} 引用 |
issueTrackerURL |
string | 无 | 报告与跟踪 Mod 问题的 URL。 | "https://github.com/neoforged/NeoForge/issues" |
提示
services的功能等同于模块的uses指令,允许加载指定类型的服务。也可以在
src/main/resources/META-INF/services中创建服务文件:文件名为服务的完全限定名称,内容为待加载的服务名称。参见 AtlasViewer 示例。
Mod 专属属性
通过 [[mods]] 将属性关联到指定 Mod。这是表数组,下一个表头之前的所有键值属性都属于该 Mod。
# Properties for examplemod1
[[mods]]
modId = "examplemod1"
# Properties for examplemod2
[[mods]]
modId = "examplemod2"
| 属性 | 类型 | 默认值 | 描述 | 示例 |
|---|---|---|---|---|
modId |
string | 必填 | 参阅 Mod ID。 | modId="examplemod" |
namespace |
string | modId 的值 |
覆盖 Mod 命名空间。必须是有效 Mod ID,但还允许点或连字符。目前未使用。 | namespace="example" |
version |
string | "1" |
Mod 版本,建议使用 Maven 版本规范的变体。设为 ${file.jarVersion} 时,会替换为 JAR manifest 的 Implementation-Version 属性,开发环境显示为 0.0NONE。 |
version="1.20.2-1.0.0" |
displayName |
string | modId 的值 |
在 Mod 列表、Mod 不匹配界面等位置显示的名称。 | displayName="Example Mod" |
description |
string | '''MISSING DESCRIPTION''' |
Mod 列表中的描述,建议使用多行字面字符串。也支持翻译,参阅翻译 Mod 元数据。 | description='''This is an example.''' |
logoFile |
string | 无 | Mod 列表中使用的图像文件名和扩展名。位置必须是从 JAR 或源集根目录(主源集例如 src/main/resources)开始的绝对路径。有效字符包括小写字母(a-z)、数字(0-9)、斜杠(/)、下划线(_)、点(.)和连字符(-)。原文另给出的完整字符集写作 [a-z0-9_-.]。 |
logoFile="test/example_logo.png" |
logoBlur |
boolean | true |
使用 GL_LINEAR*(true)还是 GL_NEAREST*(false)渲染图标,也就是缩放时是否模糊处理。 |
logoBlur=false |
updateJSONURL |
string | 无 | 更新检查器使用的 JSON URL,用于判断当前 Mod 是否为最新版本。 | updateJSONURL="https://example.github.io/update_checker.json" |
modUrl |
string | 无 | Mod 下载页面 URL,目前未使用。 | modUrl="https://neoforged.net/" |
credits |
string | 无 | Mod 列表中显示的鸣谢。 | credits="The person over here and there." |
authors |
string | 无 | Mod 列表中显示的作者。 | authors="Example Person" |
displayURL |
string | 无 | Mod 列表中显示的展示页面 URL。 | displayURL="https://neoforged.net/" |
enumExtensions |
string | 无 | 枚举扩展所用 JSON 文件路径。 | enumExtensions="META_INF/enumextensions.json" |
featureFlags |
string | 无 | 功能标志所用 JSON 文件路径。 | featureFlags="META-INF/feature_flags.json" |
功能要求
功能系统让 Mod 可以要求加载时具备特定设置、软件或硬件。条件不满足时,加载失败,并向用户说明要求。使用表 [features.<modid>] 创建配置,其中 modid 为使用这些要求的 Mod ID。NeoForge 当前提供:
| 功能 | 描述 | 示例 |
|---|---|---|
javaVersion |
可接受的 Java 版本范围,以 Maven 版本范围表示,应符合 Minecraft 支持的版本。 | javaVersion="[17,)" |
Mod 属性
Mod 属性系统将任意键值与特定 Mod 关联。当多个 Mod 文件定义相同键、但提供不同元数据时,这很有用。可通过 IModInfo#getModProperties 获取映射,再取得指定键的对象值。使用表 [modproperties.<modid>] 创建配置,其中 modid 为使用这些属性的 Mod ID。
// Assume we have two mods `mod1` and `mod2` with the following property configuration in separate files
// [modproperties.mod1]
// key="value1"
// [modproperties.mod2]
// key="value2"
@Mod("mod1")
public class ModOne {
private final String key;
public ModOne(ModContainer container) {
// Will store 'value1' in key
this.key = (String) container.getModInfo().getModProperties().get("key");
}
}
@Mod("mod2")
public class ModTwo {
private final String key;
public ModTwo(ModContainer container) {
// Will store 'value2' in key
this.key = (String) container.getModInfo().getModProperties().get("key");
}
}
访问转换器专属属性
通过 [[accessTransformers]] 将访问转换器专属属性关联到指定访问转换器。这是表数组,下个表头之前的键值均属于该转换器。表头可省略,但一旦指定,所有元素均必填。
| 属性 | 类型 | 默认值 | 描述 | 示例 |
|---|---|---|---|---|
file |
string | 必填 | 参阅添加 AT。 | file="at.cfg" |
Mixin 配置属性
通过 [[mixins]] 将 Mixin 配置属性关联到指定配置。这是表数组,下个表头之前的键值均属于该 Mixin 区块。表头可省略,但指定后所有元素均必填。
| 属性 | 类型 | 默认值 | 描述 | 示例 |
|---|---|---|---|---|
config |
string | 必填 | Mixin 配置文件位置。 | config="examplemod.mixins.json" |
requiredMods |
array | [] |
必须存在这些 Mod ID 对应的 Mod,才应用这些 Mixin。 | requiredMods=["sodium"] |
behaviorVersion |
string | 无 | 要匹配行为的 Fabric Mixin 版本。必须介于默认行为版本(每次 NeoForge 结束破坏性变更窗口时固定)与运行时实际 Fabric Mixin 版本之间。 | behaviorVersion="0.17.1" |
依赖配置
Mod 可以声明依赖,NeoForge 会在加载前检查。使用表数组 [[dependencies.<modid>]] 创建配置,其中 modid 为使用该依赖的 Mod ID。
| 属性 | 类型 | 默认值 | 描述 | 示例 |
|---|---|---|---|---|
modId |
string | 必填 | 依赖 Mod 的标识符。 | modId="jei" |
type |
string | "required" |
依赖性质:"required" 为默认,缺失时阻止加载;"optional" 允许缺失,但存在时仍检查兼容性;"incompatible" 在依赖存在时阻止加载;"discouraged" 允许依赖存在,但向用户警告。 |
type="incompatible" |
reason |
string | 无 | 可选的用户可见消息,说明为何需要或为何不兼容该依赖。 | reason="integration" |
versionRange |
string | "*" |
原文描述为可接受的语言加载器版本范围,以 Maven 版本范围表示。"*" 匹配任意版本。 |
versionRange="[1, 2)" |
ordering |
string | "NONE" |
Mod 应在依赖之前("BEFORE")还是之后("AFTER")加载。无顺序要求时使用 "NONE"。 |
ordering="AFTER" |
side |
string | "BOTH" |
依赖必须存在的物理端:"CLIENT"、"SERVER" 或 "BOTH"。 |
side="CLIENT" |
referralUrl |
string | 无 | 依赖下载页面 URL,目前未使用。 | referralUrl="https://library.example.com/" |
重要警告 两个 Mod 的
ordering可能形成循环依赖而崩溃,例如 A 必须在 B 之前加载,同时 B 又必须在 A 之前加载。
Mod 入口点
填写 neoforge.mods.toml 后,还需要提供执行 Mod 的起点,即入口点。具体形式取决于文件中指定的语言加载器。
javafml 与 @Mod
javafml 是 NeoForge 为 Java 提供的语言加载器。入口点为带 @Mod 注解的 public 类,注解值必须是 neoforge.mods.toml 中声明的某个 Mod ID。之后可在构造函数中实现全部初始化逻辑,例如注册事件或添加 DeferredRegister。
主 Mod 类只能有一个 public 构造函数,否则会抛出 RuntimeException。构造函数可以按任意顺序接收以下任意参数,没有必填参数,但不允许重复。
| 参数类型 | 描述 |
|---|---|
IEventBus |
Mod 专属事件总线,用于注册、事件等。 |
ModContainer |
保存 Mod 元数据的抽象容器。 |
FMLModContainer |
javafml 定义的实际元数据容器,继承 ModContainer。 |
Dist |
Mod 正在加载的物理端。 |
@Mod("examplemod") // Must match a mod id in the neoforge.mods.toml
public class ExampleMod {
// Valid constructor, only uses two of the available argument types
public ExampleMod(IEventBus modBus, ModContainer container) {
// Initialize logic here
}
}
默认情况下,@Mod 注解在两端都加载。可通过 dist 参数改变:
// Must match a mod id in the neoforge.mods.toml
// This mod class will only be loaded on the physical client
@Mod(value = "examplemod", dist = Dist.CLIENT)
public class ExampleModClient {
// Valid constructor
public ExampleModClient(FMLModContainer container, IEventBus modBus, Dist dist) {
// Initialize client-only logic here
}
}
提示
neoforge.mods.toml条目不一定需要对应@Mod注解。反过来,一个条目也可以有多个@Mod注解,例如分别组织通用逻辑和仅客户端逻辑。
来源: NeoForged/Documentation(26.1)。中文翻译依据提交
4a680cdd4d15。