ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

xcom2-launcher(AML):XCOM 2 与奇美拉小队的替代性 Mod 启动器完整指南

xcom2-launcher(AML):XCOM 2 与奇美拉小队的替代性 Mod 启动器完整指南
  • 桌面应用
  • 游戏开发

【免费下载链接】xcom2-launcher

The 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(即 The Alternative Mod Launcher,简称 AML)展开,系统讲解这款替代 XCOM 2 与 XCOM Chimera Squad 官方启动器的 Mod 管理工具:包括它的定位与运行环境、安装与启动机制、Steam 创意工坊集成、Mod 分类与配置文件体系、内置配置编辑与差异对比、启动参数、兼容性检查与清理工具等核心能力。读完本文,你将掌握 AML 的完整功能地图、关键模块的源码级实现原理,以及配置、排查与日常使用中的实操要点。

一、项目定位:为什么需要替代性启动器

AML 的定位在 readme.md 中表述得非常明确:The Alternative Mod Launcher (AML) is a replacement for the default game launcher from XCOM 2 and XCOM Chimera Squad,即它是官方默认启动器的替代品。官方启动器在管理大量 Mod 时能力有限,而 AML 把以下能力集成到单一桌面程序中:

  • 替换官方游戏启动器,直接从 AML 启动原版 XCOM 2、WotC(天选者之战)与 XCOM Chimera Squad;
  • Steam 创意工坊支持(Mod 详情、标签、更新日志、依赖关系、取消订阅等);
  • Mod 分类与配置方案(Profiles / 分组);
  • 配置编辑器:直接在启动器内修改某个 Mod 的全部配置文件;
  • 配置保存:把修改写入磁盘并直接保存到 settings 文件作为备份;
  • 强大的搜索/过滤功能;
  • 可编辑的 Mod 描述;
  • 基础兼容性检查(重复 ID、类覆盖与 ScreenListener 冲突);
  • 清理 XComEngine.ini 中的旧 ModOverride 条目;
  • 可删除不必要的文件以减小内存占用;
  • 配置方案(Profile)加载器会自动根据配置内容重建分组。

从仓库结构看,这些能力被组织为几大模块:Classes/Mod(Mod 数据模型、分类、过滤、冲突检测)、Classes/Steam(Steamworks 集成)、Classes/XCOM(游戏环境、INI 读写、启动参数)、Forms(WinForms 界面,如 MainForm、ConfigDiff、CleanModsForm、SettingsDialog 等)。

二、运行环境与安装要求

2.1 硬性要求

根据 readme.md 的 Requirements 一节,AML 运行需要:

  • 游戏本体:XCOM 2(含 WotC)或 XCOM Chimera Squad,二选一;
  • Steam:必须已安装并正在运行;
  • .NET Framework:4.7.2 或更高版本;
  • 系统:64 位 Windows。

2.2 启动时的环境校验

从 Program.cs 的入口逻辑可以看到,这些要求并不是纸面声明,而是会在启动时被逐一校验:

  • CheckDotNet4_7_2()(Program.cs)通过检查SortedSet<T>.TryGetValue()方法是否存在来判断 .NET Framework 是否达到 4.7.2,若缺失会弹出提示并询问是否打开下载页;
  • SteamManager.EnsureInitialized()(SteamManager.cs)负责初始化 Steamworks API,失败时会提示检查 Steam 是否运行、steam_appid.txt是否存在于 AML 目录,以及 Steam 与 AML 的权限是否一致(不能一个管理员一个普通权限);
  • 主程序还会检查steam_appid.txt(Workshop.APPID_FILENAME常量,见 Workshop.cs),根据其中的 AppId 决定创建Xcom2Env(XCOM 2,AppId 268500)还是XComChimeraSquadEnv(Chimera Squad,AppId 882100),两个枚举值定义在 XComEnvironment.cs。

2.3 首次启动流程

首次运行时(不存在steam_appid.txt),AML 会显示 WelcomeDialog 让用户选择目标游戏,并把选择的 AppId 写入steam_appid.txt(见 Program.cs)。settings.json会在 AML 安装目录下创建,其中保存游戏路径、Mod 路径、参数列表等用户配置(Settings.cs)。另有一份独立于 settings.json 的全局配置GlobalSettings(GlobalSettings.cs),保存在%LOCALAPPDATA%\AML\AMLSettings.json,用于持久化版本号、Sentry 错误上报开关等不随配置重置的信息。

三、游戏目录与 Mod 目录的自动检测

AML 并不要求用户手动填写游戏路径。XcomEnvironment.DetectGameDir()(XComEnvironment.cs)优先通过SteamApps.GetAppInstallDir()向 Steam 查询安装目录;若失败,则退而求其次,从已识别的 Mod 目录反推steamapps\common\XCOM 2的路径。

Mod 目录的来源是游戏的XComEngine.ini中的Engine.DownloadableContentEnumerator段的ModRootDirs配置。DetectModDirs()(XComEnvironment.cs)会:

  1. 读取该配置项;
  2. 若其中缺少默认的 Steam 创意工坊目录(...\steamapps\workshop\content\<AppId>),自动补上;
  3. 对每个条目做路径规范化(相对路径会按GameDir\bin\Win64解析为绝对路径)并过滤不存在的目录。

在 Program.cs 的InitializeSettings()中,检测到的 Mod 目录会被并入settings.ModPaths,同时自动补齐结尾反斜杠、剔除已不存在的目录。也就是说,Mod 目录的增删主要在XComEngine.ini中管理,而 AML 负责把这份清单读进来并保持同步。

四、Steam 创意工坊集成(源码级解析)

4.1 Steamworks 的接入与生命周期

SteamManager(SteamManager.cs)是 Steamworks API 的封装层:

  • 用一个 50ms 的System.Timers.Timer周期调用SteamAPI.RunCallbacks(),驱动 Steam 回调分发;
  • EnsureInitialized()做线程安全的懒初始化(double-checked locking);
  • Shutdown()先停定时器再SteamAPI.Shutdown(),避免在关闭流程中触发 Steam 异常;
  • QueryResultAsync<TCompleted, TResult>()把 Steam 的CallResult回调模型包装成Task,使上层可以用async/await风格编写异步查询。

4.2 工坊查询、订阅与下载

Workshop静态类(Workshop.cs)提供了一系列对SteamUGC接口的封装:

  • GetSubscribedItems()/Subscribe(id)/Unsubscribe(id):分别对应SteamUGC.GetNumSubscribedItems/GetSubscribedItems/SubscribeItem/UnsubscribeItem,实现"查看已订阅、订阅、取消订阅";
  • GetDetailsAsync(id, getFullDescription):批量查询 UGC 详情。注意MAX_UGC_RESULTS = 50的限制(对应 Steamworks 常量kNumUGCResultsPerPage),单次查询超过 50 个 ID 会直接抛出ArgumentException;查询时设置了SetReturnLongDescription(可选返回全文描述)和SetReturnChildren(true)(返回依赖子项 ID,否则m_unNumChildren恒为 0);
  • GetDownloadStatus(id)/GetInstallInfo(id)/GetDownloadInfo(id):分别查询工坊物品状态(如k_EItemStateNeedsUpdate)、本地安装信息(磁盘占用、安装目录、时间戳)与下载进度(已处理字节/总字节);
  • DownloadItem(id):触发SteamUGC.DownloadItem,并通过OnItemDownloaded事件通知下载完成;
  • GetUsername(steamID):通过SteamFriends.RequestUserInformation+ 等待PersonaStateChange_t回调来异步获取作者昵称(带 5 秒超时保护)。

SteamUGCDetails(SteamUGCDetails.cs)则是 Steamworks 原生结构SteamUGCDetails_t的包装,额外携带Children(依赖子项的工坊 ID 数组)。

4.3 Mod 元数据刷新流程

ModList.UpdateModsAsync()(ModList.cs)是"更新 Mod 信息"的批量流程,启动时或手动触发时执行:

  1. 对每个 Mod 做VerifyModState校验(目录是否存在、是否在已配置的 Mod 路径内、补充 WorkshopID 与 DateAdded 等);
  2. 带 WorkshopID 的 Mod 按每批最多 50 个(Workshop.MAX_UGC_RESULTS)分批发起GetDetailsAsync异步查询,并支持IProgress<ModUpdateProgress>进度上报与CancellationToken取消;
  3. 本地 Mod 则更新目录创建/修改时间、计算目录大小(Tools.CalculateDirectorySize)、解析.XComMod文件与类覆盖信息;
  4. 对工坊 Mod,还会抓取标题、描述、作者昵称、Steam 标签(m_rgchTags逗号分隔解析)、依赖列表,并检测k_EItemStateNeedsUpdate状态来标记"有更新"。

4.4 更新日志抓取

工坊 Mod 的更新日志由ModChangelogCache(ModChangelogCache.cs)负责:通过WebClient抓取 Steam 创意工坊的 changelog 页面,用正则提取changelog headline与正文,剥除 HTML 标签后以标题 + 制表符缩进正文的格式返回,并用ConcurrentDictionary<long, string>做内存缓存,避免重复请求。

五、Mod 数据模型:.XComMod 文件与 ModEntry

5.1 Mod 的识别:XComMod 文件

每个 Mod 的根目录下有一个<ModID>.XComMod元数据文件。ModInfo(ModInfo.cs)负责解析它,支持的键包括:

键含义
publishedfileid工坊发布 ID(long解析失败会被记录为错误并置 -1)
titleMod 标题
category分类名(仅当设置UseSpecifiedCategories为真且非空时生效,否则落到默认分类Unsorted)
description描述
tags标签
contentimage封面图文件名(默认ModPreview.jpg,解析时校验文件确实存在)
requiresxpack是否为 WotC 专属("true"不区分大小写)

解析器对"键值对换行续接"做了容错处理:行尾带\或后续行不含=时,会追加到上一个键的值中,兼容作者手写的不规范格式。

ModEntry(ModEntry.cs)是 AML 中的核心 Mod 数据模型,字段包括Index(加载顺序索引)、ID、Name(含ManualName手动改名标记)、Author(默认"Unknown")、Path、Size、isActive、isHidden、Source(枚举ModSource:Unknown/SteamWorkshop/Manual,见 ModSource.cs)、WorkshopID、三个时间戳(DateAdded/DateCreated/DateUpdated)、Note、Dependencies与IgnoredDependencies、SteamTags、Settings(配置备份列表)、Tags与BuiltForWOTC等。

5.2 Mod 导入流程

ModList.Import()(ModList.cs)负责把目录导入为 Mod 条目:

  • 目录下必须存在唯一的*.XComMod(或*.XComMod-disabled)文件,多个匹配或权限不足会被拒绝并提示;
  • 工坊 Mod 的文件夹名即 WorkshopID(无法解析为 long 会报错并中止);
  • 手动安装的 Mod 从publishedfileid字段读取工坊 ID;
  • 新导入的 Mod 会获得ModState.New标记,并按ModInfo.Category归入对应分类;
  • 工坊目录的判定方式是路径中包含\SteamApps\workshop\(ModList.cs)。

ImportMods()会遍历所有已配置的 Mod 路径批量导入,导入结束后调用MarkDuplicates()做重复 ID 检查。

六、Mod 分类与标签

6.1 分类体系

ModList内部以Dictionary<string, ModCategory>组织 Mod,ModCategory(ModCategory.cs)包含Index(排序序号)、Collapsed(是否折叠)和Entries列表,并通过 Newtonsoft.Json 序列化。InitCategoryIndices()会把分类索引重新编排为从 0 开始的无空洞序列。分类名不区分大小写,访问ModList[string category]时若不存在会自动创建新分类(ModList.cs)。

6.2 标准化分类约定

仓库根目录的 categories.md 给出了面向 Mod 作者的标准化分类建议:Mod 作者在.XComMod中加入category=Category Name即可让 Mod 在首次导入时落入指定分类。官方推荐分类如下:

  • Bugfixes
  • Enemies
  • Gameplay
  • Highlanders
  • Maps
  • Overhauls
  • Quality of Life
  • Soldier Classes
  • Soldier Customization
  • UI
  • Utilities
  • Voicepacks
  • Weapons
  • (Overhaul Name) Addons(大修名不应缩写)

该约定的目的在于防止不同作者各自发明一套分类,导致用户列表碎片化。注意:category只在Settings.UseSpecifiedCategories开启时生效(默认开启),关闭时所有 Mod 落入Unsorted(ModInfo.cs)。

6.3 标签渲染

用户自定义标签由ModTag(ModTag.cs)表示:包含Label、背景色Color(依据亮度自动推导黑色或白色文字)、随机配色生成。TagRenderer(TagRenderer.cs)在 ObjectListView 中把标签绘制成带圆角、阴影与边框的彩色小徽章,并支持点击命中区(HitBox)。启动时 AML 会清理已不存在的标签引用(mod.Tags = mod.Tags.Where(t => settings.Tags.ContainsKey(t.ToLower())),见 Program.cs)。

七、配置文件编辑与差异对比

7.1 INI 读写引擎

IniFile(IniFile.cs)是整个配置能力的地基,内部以Dictionary<string, Dictionary<string, List<string>>>(段 → 键 → 值列表)保存数据,支持:

  • 段头[Section]识别、key=value解析、;开头的注释跳过、%GAME%宏替换为XCom、行尾\\的续行读取;
  • Get/Set/Add/Has/Remove系列方法(Remove(section,key)只清空值不清键,Remove(section,key,value)移除指定值);
  • Save()按"段-键-值"顺序回写文件,每段间留空行。

DefaultConfigFile(DefaultConfigFile.cs)继承自IniFile,对应游戏用户配置%USERPROFILE%\Documents\my games\<游戏>\XComGame\Config\XCom<Name>.ini与默认配置Default<Name>.ini的配对。它实现了 Unreal Engine 风格的"默认配置合并"语义:

  • 加载时若用户文件不存在,则从DefaultXCom<Name>.ini生成并保存;
  • CreateFromDefault()读取默认文件,并根据BasedOn链逐层应用+key(追加)、-key(移除)、!key(清空数组)、;(注释)、普通key(覆盖)五种前缀操作,最终合并出有效配置;
  • 保存时用UpdateTimestamp()依据基准文件DefaultFile的最后写入时间生成IniVersion时间戳(Unix 秒 +.000000),这正是游戏检测配置是否过期所需的信息。

7.2 在启动器内编辑 Mod 配置

对应 README 中"Configuration editor, change all of a mod's configs from right in the launcher"与"Configuration saving"两项能力:ModEntry.GetConfigFiles()(ModEntry.cs)列出 ModConfig目录下所有*.ini文件;ModEntry.AddSetting(path, contents)(ModEntry.cs)把编辑后的内容写回磁盘,并同时登记到Settings列表(ModSettingsEntry,ModSettingsEntry.cs),作为"已备份配置"持久化到 settings.json——这就是 README 所说"save your changes to disk and directly into your settings file for backup"的实现方式。HasBackedUpSettings属性(Settings.Count > 0)用于在界面上标记已备份状态。

7.3 配置差异对比(ConfigDiff)

ConfigDiff(ConfigDiff.cs)是一个双栏对比窗体:左栏为原始配置、右栏为修改后配置。它内置了完整的 LCS(最长公共子序列)算法实现(SimpleDiff<T>,含前后缀跳过优化与动态规划矩阵),把两文件逐行对比并着色:新增行以绿色高亮显示在右栏、删除行以红色高亮显示在左栏。左右两栏的滚动与光标位置会同步联动,且代码编辑区使用 FastColoredTextBox 并接入IniLanguage.Process做 INI 语法高亮。

八、启动参数与启动游戏

8.1 预置参数表

Argument类(Arguments.cs)定义了 AML 预置的 XCOM 命令行参数(DefaultArguments静态表):

名称参数说明默认启用默认快速开关
Review-review显示最终主菜单✅✅
No Red Screens-noRedScreens隐藏错误弹窗✅✅
Show log console-log显示日志控制台——
Crash Dump Watcher-crashDumpWatcher崩溃转储监视器——
Skip startup movies-noStartUpMovies跳过开场动画—✅
Set language-language=强制指定语言——
Enable console-allowConsole启用调试控制台—✅
Autodebug-autoDebug自动调试——
No seek free loading-noSeekFreeLoading禁用 SeekFree 加载——
Regenerate ini files-regenerateinis重新生成 ini 文件—✅

其中"默认启用"的参数会在新建Settings时自动进入ArgumentList;"默认快速开关"的参数会进入QuickToggleArguments(主界面快捷勾选下拉框),两者都可在 Settings.cs 构造函数中看到。Settings.GetArgumentString()用空格拼接全部参数;AddArgument/RemoveArgument会做去重处理。

8.2 启动三条游戏分支

XcomEnvironment.RunGame()有两个实现:

  • Xcom2Env(Xcom2Env.cs):根据UseWotC标志决定启动Binaries\Win64\XCom2.exe(原版,工作目录为游戏根目录)还是XCom2-WarOfTheChosen\Binaries\Win64\XCom2.exe(WotC,工作目录为 WotC 子目录);
  • XComChimeraSquadEnv(XcomChimeraSquadEnv.cs):启动Binaries\Win64\xcom.exe。

启动前都会校验 Steam 是否运行。主界面三条启动入口在 MainForm.cs:RunChimeraSquad()、RunVanilla()、RunWotC()。其中RunVanilla()会特别检查:如果启用了BuiltForWOTC的 Mod,会弹窗警告"极可能导致游戏崩溃",用户确认后才继续。启动前调用Save()把 Mod 启用状态写入游戏配置。

8.3 把启用状态写回游戏

XcomEnvironment.SaveChanges(settings, disableMods)(XComEnvironment.cs)完成两件关键写盘:

  1. 把当前启用(且按Index排序)的 Mod ID 写入用户配置XComModOptions.ini的Engine.XComModOptions段的ActiveMods(若disableMods为真——即挑战模式——则写入空列表);
  2. 重写XComEngine.ini:先删除Engine.Engine段的全部ModClassOverrides条目(对应 README 中 "Cleans old ModOverride entries from XComEngine.ini"),再以当前settings.ModPaths重建Engine.DownloadableContentEnumerator段的ModRootDirs。

此外GetActiveMods()(XComEnvironment.cs)会读取XComModOptions.ini与DefaultModOptions.ini两处ActiveMods并合并去重、剥离引号,用于把游戏当前已启用的 Mod 状态导入 AML(ImportActiveMods)。

九、兼容性检查:冲突、重复与依赖

9.1 类覆盖与 ScreenListener 冲突检测

对应 README 的 "Basic compatibility checks (duplicate ids, class and screenlistener conflicts)"。ModEntry.LoadOverridesAsync()(ModEntry.cs)异步解析两类覆盖信息:

  • Class 覆盖:扫描 ModConfig目录下的XComEngine.ini,用正则^[+]?ModClassOverrides=\(BaseGameClass="...",ModClass="..."\)匹配(ModEntry.cs);
  • UIScreenListener 覆盖:扫描 ModSrc目录下所有*.uc源码文件(并行处理),用正则ScreenClass = ...匹配监听目标,但跳过ScreenClass = none(表示监听所有界面)与Src\XComGame目录(常见误打包的游戏源码)。

冲突判定在ModList.GetActiveConflictsImplementation()(ModList.cs):当多个已启用Mod 覆盖同一个OldClass时,只有同时满足以下条件才报告冲突(ModConflict,ModConflict.cs):

  • 至少有一个是Class类型的覆盖(若全部是 UIScreenListener,则不算冲突);
  • 来自不同 Mod(ID 不完全相同);
  • 覆盖文本行不完全相同(避免误报)。

冲突结果通过UpdateModsConflictState()反映到各 Mod 的ModState.ModConflict标记上。

9.2 Mod 状态机

ModState(ModState.cs)是[Flags]枚举,支持组合标记:

标志值含义
None0无
New1新导入
UpdateAvailable2工坊有更新
Downloading4下载中
ModConflict8存在类覆盖冲突
DuplicateID16重复 ID
NotLoaded32不在已配置 Mod 路径内
NotInstalled64目录/文件缺失
DuplicatePrimary128重复组中的主 Mod
DuplicateDisabled256重复组中被禁用的 Mod
MissingDependencies512依赖缺失

ModEntry.State在每次启动时重新评估,PreviousState则保存上次退出时的快照,用于对比"新缺失"的 Mod(ModEntry.cs)。

9.3 重复 ID 检测与工作区方案

ModList.GetDuplicates()按大小写不敏感的 Mod ID 分组找出重复项;MarkDuplicates()(ModList.cs)在两种模式下工作:

  • 若设置EnableDuplicateModIdWorkaround开启:启用日期最早的 Mod 被标记DuplicatePrimary,其余同名 Mod 通过重命名<ID>.XComMod→<ID>.XComMod-disabled(DisableModFile(),ModEntry.cs)物理禁用,并标记DuplicateDisabled,以此规避游戏引擎对重复 ID 的加载问题;
  • 若关闭:所有重复 Mod 仅标记DuplicateID供界面提示。

Program.InitializeSettings()中若该方案被关闭,会调用EnableModFile()确保所有 Mod 信息文件处于启用状态(Program.cs)。

9.4 依赖检查

依赖关系来自工坊的Children(必选依赖)信息。GetRequiredMods()(ModList.cs)会:

  • 把Dependencies与已安装 Mod 的 WorkshopID 匹配;
  • 若依赖的副本是DuplicateDisabled状态,会替换为主副本;
  • 支持IgnoredDependencies(用户手动忽略的依赖,可用于消除误报);
  • 未安装的依赖通过LoadNotInstalledDependencies()按批次查询工坊详情放入内存缓存_dependencyCache。

UpdatedModDependencyState()据此设置/清除MissingDependencies状态;GetDependentMods()反向查找"依赖某 Mod 的其它 Mod"(可指定按 Mod ID 或工坊 ID 匹配)。

十、过滤、隐藏与清理

10.1 搜索与过滤

ModListFilter(ModListFilter.cs)继承自 ObjectListView 的TextMatchFilter,实现"文本搜索 + 状态过滤 + 隐藏项显示"的组合逻辑:文本匹配结果可与任意ModState标记(如MissingDependencies、ModConflict)做 AND 组合,也可选择显示isHidden的 Mod。设置项ShowStateFilter控制界面上的状态过滤栏是否可见(Settings.cs)。

10.2 删除无用文件减小体积

对应 README 的 "Can delete unnecessary files to reduce memory footprint"。CleanModsForm(CleanModsForm.cs)提供两类清理(操作前有不可撤销确认弹窗,遇到 IO 错误可选择继续):

  • 源码文件(src):可选"删除所有src目录"或"仅删除src\XComGame"(游戏源码被误打包进 Mod 的常见情况)。保护机制是:仅当 Mod没有CookedPCConsole目录(即没有已编译内容)时才允许删除src;
  • 着色器缓存:删除Content\<ModID>_ModShaderCache.upk。可选"全部删除"或"仅删除空缓存"(空缓存判定为文件大小恰好等于 371 字节)。

清理通过Directory.Delete(path, true)/File.Delete实现,并逐个 Mod 遍历执行。

10.3 配置方案(Profiles)与分组

README 提到 "Profile loader will attempt to create groups if the profile contains groups"。ModList的分组模型即ModCategory(分类即分组);导入含分组的 Profile 时,AML 会按ModList[string category]的自动创建逻辑(ModList.cs)重建不存在的分组。ShowModListGroups设置项控制分组视图的显示(Settings.cs)。

十一、更新检查与错误上报

AML 启动时会通过 GitHub Releases API 检查新版本(Program.CheckForUpdate(),Program.cs):

  • CheckForUpdates控制开关(默认开启),CheckForPreReleaseUpdates决定是否拉取预发布版本,IncludeAlphaVersions决定是否接受 alpha 版本;
  • 版本比较基于 GitVersionConfig.yaml 生成的 SemVer 信息(GitVersionInfo.SemVer);
  • 发现新版本时弹出UpdateAvailableDialog(UpdateAvailableDialog.cs)。

错误上报使用 Sentry SDK(InitSentry(),Program.cs),是否启用由GlobalSettings.IsSentryEnabled决定(首次启动的欢迎对话框中询问);未捕获异常会写入error.log并弹出UnhandledExceptionDialog。AML 还通过命名互斥体防止多开(除非设置AllowMultipleInstances,见 Program.cs)。

十二、常用设置项速查

Settings(Settings.cs)中与日常使用直接相关的布尔开关如下(均持久化于settings.json):

设置项默认值作用
CheckForUpdatestrue启动时检查更新
CheckForPreReleaseUpdatesfalse检查预发布版本
IncludeAlphaVersionsfalse接受 alpha 版本
ShowHiddenElementsfalse显示隐藏元素
ShowStateFiltertrue显示状态过滤栏
UseTranslucentModListSelectiontrue列表选中项半透明效果
ShowPrimaryDuplicateAsDependencytrue主重复副本显示为依赖
ShowModListGroupstrue显示分组
CloseAfterLaunchfalse启动游戏后关闭 AML
AutoNumberIndexestrue自动编号索引
UseSpecifiedCategoriestrue采用 Mod 声明的分类
ShowQuickLaunchArgumentsfalse显示快速启动参数面板
NeverImportTagsfalse从不导入 Steam 标签
AllowMultipleInstancesfalse允许多开
EnableDuplicateModIdWorkaroundfalse启用重复 ID 规避方案
UpdateModsOnStartuptrue启动时更新 Mod 信息
OnlyUpdateEnabledOrNewModsOnStartupfalse仅更新启用/新 Mod

十三、常见问题与排查要点

结合 Program.cs 与 XComEnvironment.cs 的容错逻辑,常见问题的排查路径如下:

  • 无法初始化 Steam:确认 Steam 已运行、steam_appid.txt位于 AML 可执行文件目录、Steam 与 AML 权限一致(Program.cs);
  • 检测不到游戏/Mod 目录:优先通过DetectGameDir()向 Steam 查询;失败后从XComEngine.ini的ModRootDirs反推;仍失败则需在设置中手动指定(Program.cs);
  • Mod 目录无法访问:多为误加了系统目录或根目录作为 Mod 路径,AML 会记录"Unauthorized access"并跳过(ModList.cs);
  • settings.json损坏:AML 会提示删除或重命名后重新生成(Settings.cs);如果settings.json与steam_appid.txt指定的游戏不一致,会提示重置其一(Program.cs);
  • 崩溃转储:日志写入AML.log(log4net 配置见 log4net.config),未处理异常另写error.log并显示错误对话框。

十四、结语

作为社区驱动的开源项目(LICENSE 采用 GPLv3),xcom2-launcher 用约十余个职责清晰的模块覆盖了"启动器替代 + 工坊管理 + 配置编辑 + 兼容性检查 + 文件清理"的完整链路。本文以 readme.md 为骨架,结合 ModList.cs、Workshop.cs、XComEnvironment.cs、IniFile.cs、Program.cs 等核心实现,将文档中的每一条功能声明落到了具体的类、方法与调用链上,可作为深入阅读源码或二次开发的索引。若要进一步参与贡献(测试 PR、修复 issue、撰写 Wiki),README 的 Contributing 一节给出了完整指引。

  • 桌面应用
  • 游戏开发

【免费下载链接】xcom2-launcher

The 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
点击查看免费下载
上一篇:【亲测免费】 高效便捷:基于Python的酒店客房管理系统
下一篇:如何永久保存你的微信聊天记录:从数据备份到情感珍藏的完整指南

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进