配置

配置

配置定义可应用于某个 Mod 实例的设置和用户偏好。NeoForge 的配置系统使用 TOML 文件,并通过 NightConfig 读取。

创建配置

配置可以通过 IConfigSpec 的子类型创建。NeoForge 使用 ModConfigSpec 实现它,并提供 ModConfigSpec.Builder 构造配置。构建器通过 Builder#push 创建并进入区段,通过 Builder#pop 离开区段,从而将配置值分组。之后可以用以下两种方法之一构建配置:

方法 说明
build 创建 ModConfigSpec。
configure 创建一个 pair,包含持有配置值的类与 ModConfigSpec。

提示 ModConfigSpec.Builder#configure 通常与静态代码块配合使用,并让持有配置值的类通过构造函数接受 ModConfigSpec.Builder,以定义和保存这些值:

//Define a field to keep the config and spec for later
public static final ExampleConfig CONFIG;
public static final ModConfigSpec CONFIG_SPEC;

private ExampleConfig(ModConfigSpec.Builder builder) {
    // Define properties used by the configuration
    // ...
}

//CONFIG and CONFIG_SPEC are both built from the same builder, so we use a static block to seperate the properties
static {
    Pair<ExampleConfig, ModConfigSpec> pair =
            new ModConfigSpec.Builder().configure(ExampleConfig::new);
        
    //Store the resulting values
    CONFIG = pair.getLeft();
    CONFIG_SPEC = pair.getRight();
}

每个配置值都可以提供额外上下文以增加行为。上下文必须在配置值完全构建之前定义:

方法 说明
comment 描述配置值的用途。可提供多个字符串形成多行注释。
translation 为配置值名称提供翻译键。
worldRestart 修改配置值前必须重启世界。
gameRestart 修改配置值前必须重启游戏。

ConfigValue

可以使用任意 #define 方法,结合已定义的上下文创建配置值。

所有配置值方法至少接受两个组成部分:

  • 表示变量名称的路径:使用点分隔的字符串,表示配置值所属区段。
  • 没有有效配置时使用的默认值。

专门用于 ConfigValue 的方法还接受:

  • 验证器:确保反序列化得到的对象有效。
  • 表示配置值数据类型的类。
//Store the config properties as public finals
public final ModConfigSpec.ConfigValue<String> welcomeMessage;

private ExampleConfig(ModConfigSpec.Builder builder) {
    //Define each property
    //One property could be a message to log to the console when the game is initialised
    welcomeMessage = builder.define("welcome_message", "Hello from the config!");
}

可通过 ConfigValue#get 获取实际值。值还会被缓存,以免重复读取文件。

其他配置值类型

  • 范围值:必须位于指定边界之间。
    • 类类型:Comparable<T>;方法:#defineInRange。
    • 额外参数:允许的最小值、最大值,以及表示数据类型的类。

提示 DoubleValue、IntValue、LongValue 是分别将类指定为 Double、Integer、Long 的范围值。

  • 白名单值:必须包含在给定集合中。
    • 类类型:T;方法:#defineInList。
    • 额外参数:允许值的集合。
  • 列表值:值是一组条目组成的列表。
    • 类类型:List<T>;方法:#defineList,若允许空列表则使用 #defineListAllowEmpty。
    • 额外参数:在配置界面添加新条目时提供默认值的 supplier;确保反序列化后的列表元素有效的验证器;可选的列表条目数量验证器,防止条目过少或过多。
  • 枚举值:给定集合中的枚举值。
    • 类类型:Enum<T>;方法:#defineEnum。
    • 额外参数:将字符串或整数转换为枚举的 getter,以及允许值的集合。
  • 布尔值:boolean 值。
    • 类类型:Boolean;方法:#define。

注册配置

构建 ModConfigSpec 后必须注册,以便 NeoForge 按需加载、跟踪和同步配置。应在 Mod 构造函数中通过 ModContainer#registerConfig 注册,参数包括表示配置所属端的配置类型、ModConfigSpec,以及可选的配置文件名。

// In the main mod file with a ModConfigSpec CONFIG_SPEC
public ExampleMod(ModContainer container) {
    ...
    //Register the config
    container.registerConfig(ModConfig.Type.COMMON, ExampleConfig.CONFIG_SPEC);
    ...
}

配置类型

配置类型决定文件位置、加载时机以及是否通过网络同步。默认情况下,物理客户端从 .minecraft/config 加载,物理服务端从 <server_folder>/config 加载。各类型的区别如下。

建议 NeoForge 在代码库中提供了配置类型的说明。

  • STARTUP
    • 物理客户端和物理服务端均从 config 文件夹加载。
    • 注册时立即读取。
    • 不会通过网络同步。
    • 默认文件后缀为 -startup。

警告 STARTUP 配置可能造成客户端与服务端不同步,例如用配置禁用内容注册。因此,强烈建议不要用此类配置启用或禁用会改变 Mod 内容的功能。

  • CLIENT
    • 仅在物理客户端从 config 文件夹加载,服务端没有此类配置的位置。
    • 在 FMLCommonSetupEvent 触发前立即读取。
    • 不会通过网络同步。
    • 默认文件后缀为 -client。
  • COMMON
    • 物理客户端和物理服务端均从 config 文件夹加载。
    • 在 FMLCommonSetupEvent 触发前立即读取。
    • 不会通过网络同步。
    • 默认文件后缀为 -common。
  • SERVER
    • 物理客户端和物理服务端均从 config 文件夹加载。
    • 可在每个世界中覆盖:客户端路径为 .minecraft/saves/<world_name>/serverconfig,服务端路径为 <server_folder>/world/serverconfig。
    • 在 ServerAboutToStartEvent 触发前立即读取。
    • 通过网络同步到客户端。
    • 默认文件后缀为 -server。

配置事件

可以通过 ModConfigEvent.Loading、ModConfigEvent.Reloading 和 ModConfigEvent.Unloading,处理每次配置加载、重载或卸载时的操作。事件必须注册到 Mod 事件总线。

注意 这些事件会为 Mod 的所有配置触发。应使用提供的 ModConfig 对象判断正在加载或重载哪份配置。

配置界面

配置界面允许用户在游戏中修改 Mod 配置值,无需打开文件。界面会自动解析已注册的配置文件并填充内容。

Mod 可以使用 NeoForge 的内置配置界面,也可以继承 ConfigurationScreen 修改默认行为或制作自己的界面。还可以从零创建界面,并通过下述扩展点交给 NeoForge。

在客户端的 Mod 构造过程中注册 IConfigScreenFactory 扩展点,即可注册配置界面:

// In the main client mod file
public ExampleModClient(ModContainer container) {
    ...
    // This will use NeoForge's ConfigurationScreen to display this mod's configs
    container.registerExtensionPoint(IConfigScreenFactory.class, ConfigurationScreen::new);
    ...
}

进入游戏的“Mods”页面,在侧栏选择 Mod,再点击“Config”按钮即可打开。Startup、Common、Client 配置选项始终可编辑。Server 配置仅在本地世界中游玩时可编辑;连接服务器或其他人的局域网世界时,界面会禁用 Server 配置。该 Mod 的配置首页会显示全部已注册文件,供玩家选择。

警告 制作界面时,应为所有配置条目添加翻译键,并在语言 JSON 中提供译文。

可通过 ModConfigSpec$Builder#translation 指定翻译键,例如扩展前面的代码:

ConfigValue<T> value = builder.comment("This value is called 'config_value_name', and is set to defaultValue if no existing config is present")
    .translation("modid.config.config_value_name")
    .define("config_value_name", defaultValue);

为了便于翻译,可以打开配置界面并访问所有配置及子区段,再返回 Mod 列表界面。此时,遇到的所有未翻译条目都会打印到控制台,方便确认要翻译的内容及翻译键。


来源: NeoForged/Documentation(26.1)。中文翻译依据提交 4a680cdd4d15。