配置框架

基本信息

属性 值
根文件 config/salisarcana.cfg
分组文件目录 config/salisarcana/
分组数 7
设置总数 204
根源文件 config/SalisConfig.java(90 行)
组基类 config/ConfigGroup.java
设置基类 config/settings/Setting.java

功能

Salis Arcana 的配置系统是它唯一的主体内容——本模组自己只注册 1 个方块、2 个物品与 4 条研究,其余全部是对 Thaumcraft 4 的行为改写。理解这套框架是理解本模组的前提。

配置分两层:

  • config/salisarcana.cfg 是根配置,只放两个东西:一个全局开关 enableversionChecking,以及 modules 分类下 7 个「整组开关」 (键名形如 Enable enhancements group)。
  • config/salisarcana/<分组名>.cfg 是分组配置,每组一个文件,真正的 204 项设置都在这里。

分组被关闭时,其配置文件根本不会被读取——SalisConfig.synchronizeConfiguration() 在 SalisConfig.java:50-52 处直接 continue,既不加载也不写出该文件。因此一个被整组 关闭的分组,其 .cfg 会在下次启动时被保留原样而不会同步。

分组注册机制

分组不是通过枚举或循环注册的,而是靠构造函数自注册:

public ConfigGroup() {
    SalisConfig.groups.add(this);
}

——ConfigGroup.java:23-25。

七个分组则在 SalisConfig 中以 static final 字段实例化(SalisConfig.java:25-31)。 Java 的类初始化保证了这些字段在任何 Setting 被访问前就已构造完毕,因此 groups 列表在使用时必定已经填满 7 项。

Java 字段 分组类 分组名(= 文件名) 设置数 根配置中的整组开关键
addons ConfigAddons addons 1 Enable addons group
bugfixes ConfigBugfixes bugfixes 79 Enable bugfixes group
commands ConfigCommands commands 10 Enable commands group
features ConfigFeatures enhancements 75 Enable enhancements group
modCompat ConfigModCompat mod_integrations 6 Enable mod_integrations group
thaum ConfigThaumcraft thaumcraft_configuration 32 Enable thaumcraft_configuration group
debug ConfigDebug debug 1 Enable debug group

⚠️ 分组名与类名系统性不一致:ConfigFeatures → enhancements、 ConfigModCompat → mod_integrations、ConfigThaumcraft → thaumcraft_configuration。 文件名取自 ConfigGroup.getGroupName()(SalisConfig.java:68),不是类名。找配置文件时 必须用分组名。

设置类型体系

所有设置继承自 Setting,按取值方式分出若干子类:

类型 源文件 写入的 Forge 键类型 说明
ToggleSetting config/settings/ToggleSetting.java getBoolean 布尔开关,最常用
IntSetting config/settings/IntSetting.java getInt 整数,可带上下限
FloatSetting config/settings/FloatSetting.java getFloat 浮点数
StringSetting config/settings/StringSetting.java getString 字符串
StringArraySetting config/settings/StringArraySetting.java getStringList 字符串列表
IntArraySetting config/settings/IntArraySetting.java getIntList 整数列表,可固定长度
EnumSetting<E> config/settings/EnumSetting.java getString + 校验 枚举,可指定「禁用值」
CustomResearchSetting config/settings/CustomResearchSetting.java 多个键 自定义研究,详见 自定义研究
ReplaceWandComponentSettings config/settings/ReplaceWandComponentSettings.java 多个键 上一行的子类,键名加 Research 后缀
BeaconBlockFixSetting config/settings/BeaconBlockFixSetting.java getIntList 额外维护一个 16 位布尔表
CommandSettings config/settings/CommandSettings.java 多个键 命令,详见 命令
BaseCompatSetting config/settings/compat/BaseCompatSetting.java 多个键 兼容块,可挂子设置

IntSetting 与 FloatSetting 的上下限通过链式 .setMinValue(...) / .setMaxValue(...) 声明,写入 .cfg 时由 Forge 强制约束——读入越界值会被夹回边界。

依赖(IEnabler)机制

每项设置的第一个构造参数都是它的依赖。Setting.isEnabled() 的语义是 「自身为真 且 依赖为真」。因此存在两层开关:

  • 整组开关(根配置)→ 分组 isEnabled()
  • 父设置 → 子设置

典型例子是 salisarcana.enhancements.cfg 里的 _enabledreplaceWandCapsResearch:它的父依赖是 replaceWandCapsSettings, 所以即使显式写入 true,只要父设置被关掉,它仍然不生效。

Setting.setCategory(...) 决定键在 .cfg 中落入哪个分类。绝大多数设置用 general,但复合设置会重设分类——例如 BaseCompatSetting 在 BaseCompatSetting.java:27 把子设置的分类强制改写成所属 modid, 这是 mod_integrations.cfg 里能看到 angelica、gtnhtcwands 等分类的原因。

关闭的设置不写入文件

凡调用了 .setEnabled(false) 的设置,其默认值即为关闭。这类设置在 .cfg 中 不会出现对应条目(getBoolean 只在值与默认不同时才落盘)。全仓共 17 项如此:

分组 数量 键(注意:部分键名与 Java 字段名不同)
缺陷修复组 2 unOredictGoldCoin、wardingDontStoreNBTMeta
调试组 1 logWarpSources
功能增强组 8 nodeModifierWeights、nodeTypeWeights、Inverse Scrolling、Save Thaumonomicon Page、researchDuplicationFree、useStabilizerRewrite、mobVisDropWhitelist、bannerFreePatterns
神秘时代配置组 6 hungryDynamicReach、pureDynamicReach、sinisterDynamicReach、taintedDynamicReach、_uncapped_potion_ids、disableAspectTint

键名取自构造函数的第 2 个参数,不是 public final 的字段名。差异示例: 字段 nomiconInvertedScrolling 的配置键是 Inverse Scrolling, 字段 stabilizerRewrite 的配置键是 useStabilizerRewrite, 字段 mobVisWhitelist 的配置键是 mobVisDropWhitelist, 字段 potionIdLimitRaised 的配置键是 _uncapped_potion_ids。

数值

全部 204 项设置由程序化解析 config/group/*.java 中 7 个文件的 public final ... = new ...Setting( 声明得到,并用两种独立表述交叉校验:

  • 表述 A:正则匹配 = new [A-Za-z]+(Setting|Settings)\( → 1+79+10+1+75+6+32 = 204
  • 表述 B:Python 解析构造调用并做括号配平 → 204

两种表述结果一致。第三种表述(^ public final [A-Za-z]+ [a-zA-Z]+ = new )得出 203, 差额已定位:该正则的 [a-zA-Z]+ 不接受数字,漏掉了字段名含数字的 tc4tweakScrollPages(ConfigModCompat.java:22)。这是校验脚本的缺陷,不是内容缺陷。

「外部读取者」检查:204 项设置中有 203 项能在 config/group/ 以外的源码里找到引用。 唯一「查无读者」的 allowSingleWandReplacement(ConfigFeatures.java:60)经人工复核 并非死代码:它在本类内被 singleWandReplacementEnabled()(ConfigFeatures.java:497) 读取,而该方法作为 setApplyIf 条件被 Mixins.java:537 使用,属同包引用导致的 初筛误报。

交互

配置文件不在 preInit 阶段加载,而是在核心模组的构造函数中加载: SalisArcanaCore() 直接调用 SalisConfig.synchronizeConfiguration() (SalisArcanaCore.java:25-27)。这早于任何模组的 preInit, 正是补丁条件能在 Mixins 枚举求值时被安全查询的前提。

根配置路径由 SalisConfig.java:36-37 拼出(config + modid + .cfg), 分组配置路径由 SalisConfig.java:68 拼出(config + modid + 目录 + 分组名 + .cfg)。

相关条目