彻底搞懂Mod冲突:xcom2-launcher如何检测类覆盖与ScreenListener重复
【免费下载链接】xcom2-launcherThe Alternative Mod Launcher (AML) is a replacement for the default game launchers from XCOM 2 and XCOM Chimera Squad.项目地址: https://gitcode.com/gh_mirrors/xc/xcom2-launcher
xcom2-launcher 是 XCOM 2 与 XCOM Chimera Squad 的第三方 Mod 启动器(AML),它能自动检测Mod 冲突:通过解析每个 Mod 的XComEngine.ini中的类覆盖(Class Override)声明,以及扫描源码中UIScreenListener(ScreenListener)钩子,快速定位互相打架的 Mod,并以红色高亮和冲突日志直观呈现。
1️⃣ Mod 冲突是什么,为什么新手常踩坑
当两个 Mod 都想修改同一个游戏类(比如都替换某个 UI 屏幕类)时,游戏引擎只能"二选一"——后加载的会覆盖先加载的,另一个 Mod 的功能随之失效,甚至导致崩溃。
xcom2-launcher(AML)内置了类覆盖与 ScreenListener 冲突检测,在你启动游戏之前就把问题暴露出来。它的检测逻辑集中在 Classes/Mod/ 目录下的几个类里,下面一步步拆解。
2️⃣ 两种"覆盖":AML 检测的两类冲突源头
| 类型 | 声明位置 | 含义 | 是否必然互斥 |
|---|---|---|---|
| 类覆盖(ModClassOverrides) | Mod 的Config/XComEngine.ini | 用自定义类替换游戏原类 | 是,多个 Mod 覆盖同一类必冲突 |
| UIScreenListener | Mod 的Src/*.uc源码 | 挂在某屏幕上的 UI 监听器,屏幕显示时执行逻辑 | 否,多个监听器可同时挂载 |
这两种覆盖记录统一存放在 ModClassOverride.cs 中,其OverrideType枚举只有Class与UIScreenListener两个值(见 ModClassOverride.cs#L23-L27)。
检测类覆盖:正则解析 XComEngine.ini
ModEntry.cs 定义了编译好的正则(#L29),匹配形如:
ModClassOverrides=(BaseGameClass="XComGame.XComGameState_Critter",ModClass="MyMod.MyCritter")
GetClassOverrides()(#L278-L298)会遍历 Mod 的Config目录下所有XComEngine.ini,把每一处"原类 → 新类"的替换登记下来。
检测 ScreenListener 重复:扫描 .uc 源码
GetUIScreenListenerOverrides()(#L225-L276)会并行扫描 ModSrc目录下的所有.uc文件,用正则匹配ScreenClass = xxx声明(#L31),记录"新监听类"挂在"哪个原屏幕类"上。两个细节值得注意:
ScreenClass = none表示监听器对所有 UI 屏幕生效,会被直接跳过(#L263-L267),避免误报;- 路径包含
Src\XComGame的文件会被排除(#L251-L255)——把游戏自带源码整个塞进 Mod 是新手常见错误,不算 Mod 自己的声明。
3️⃣ 判定逻辑:4 条规则过滤误报
收集到全部覆盖记录后,ModList.cs 的GetActiveConflictsImplementation()(#L74-L92)按"被覆盖的原类名"分组,并套上 4 条过滤规则:
- 同一原类必须有 2 个以上覆盖,否则谈不上冲突;
- 组内至少存在一个"类覆盖"——如果所有 Mod 都只是挂 UIScreenListener,源码注释明确写着 "If every mod uses a UIScreenListener, there is no conflict"(#L85-L86);
- 必须来自不同的 Mod——同一个 Mod 内部重复登记不算冲突;
- 声明文本必须不完全相同(#L89-L90)——
TextLine字段保留原始行文本,正是为了避免格式归一化造成的假阳性(对应上游 issue #102)。
四条规则同时满足,才会生成一条 ModConflict 记录(含冲突类名 + 全部相关覆盖)。
4️⃣ 状态更新与界面呈现
UpdateModsConflictState()(ModList.cs#L94-L118)分三步:先清空所有旧冲突标记,再给每个卷入冲突的 Mod 打上ModConflict状态位(定义在 ModState.cs#L12),最后只刷新发生变化的条目。
主界面(MainForm.cs)随后把这些结果可视化:
- 列表高亮:冲突 Mod 行背景变为珊瑚色,状态列显示
Conflict(MainForm.ModList.cs#L351-L355),悬停提示 "This mod makes changes that conflict with another mod."(#L392-L393); - Overrides 网格:逐行列出每个 Mod 覆盖了哪个原类、替换成什么类,UIScreenListener 条目会额外标注
(UIScreenListener)(MainForm.cs#L507-L510); - 冲突日志:按类名分组列出全部参与 Mod(
GetOverridesString,#L614-L660);若同一类的冲突全是监听器,还会补一句 "meaning they do not conflict with each other" 加以解释; - 筛选器计数:左侧
Conflicts (n)过滤器实时显示冲突 Mod 数量(#L479)。
💡 另外,AML 在生成游戏配置时会自动清理XComEngine.ini里过期的ModClassOverrides残留(XComEnvironment.cs#L222-L223),减少旧数据带来的干扰。
5️⃣ 实用排障指南:发现冲突后怎么办
- 打开Conflicts页签,在 Overrides 网格中找到冲突的类名,确认是哪两个 Mod 在争抢;
- 阅读两个 Mod 的说明,判断是否功能互斥;
- 最常见的解法:禁用其中一个 Mod;若日志中带有 "(UIScreenListener)" 标注,说明它们只是共用监听钩子,通常可以共存,若仍异常再逐个排查;
- 处理完重新勾选 Mod,AML 会即时重算冲突状态。
小结:xcom2-launcher 用"正则解析 ini 类覆盖 + 扫描 .uc 源码监听器 + 4 条分组过滤规则"这套组合拳,把"Mod 冲突"从玄学变成了可定位、可过滤、可解决的具体条目。相关核心文件:ModEntry.cs、ModList.cs、ModConflict.cs、ModClassOverride.cs。
【免费下载链接】xcom2-launcherThe Alternative Mod Launcher (AML) is a replacement for the default game launchers from XCOM 2 and XCOM Chimera Squad.项目地址: https://gitcode.com/gh_mirrors/xc/xcom2-launcher
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考