- 桌面应用
- 游戏开发
【免费下载链接】xcom2-launcher
The Alternative Mod Launcher (AML) is a replacement for the default game launchers from XCOM 2 and XCOM Chimera Squad.
导读
本指南围绕开源项目 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)会:
- 读取该配置项;
- 若其中缺少默认的 Steam 创意工坊目录(
...\steamapps\workshop\content\<AppId>),自动补上; - 对每个条目做路径规范化(相对路径会按
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 信息"的批量流程,启动时或手动触发时执行:
- 对每个 Mod 做
VerifyModState校验(目录是否存在、是否在已配置的 Mod 路径内、补充 WorkshopID 与 DateAdded 等); - 带 WorkshopID 的 Mod 按每批最多 50 个(
Workshop.MAX_UGC_RESULTS)分批发起GetDetailsAsync异步查询,并支持IProgress<ModUpdateProgress>进度上报与CancellationToken取消; - 本地 Mod 则更新目录创建/修改时间、计算目录大小(
Tools.CalculateDirectorySize)、解析.XComMod文件与类覆盖信息; - 对工坊 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) |
title | Mod 标题 |
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)完成两件关键写盘:
- 把当前启用(且按
Index排序)的 Mod ID 写入用户配置XComModOptions.ini的Engine.XComModOptions段的ActiveMods(若disableMods为真——即挑战模式——则写入空列表); - 重写
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 覆盖:扫描 Mod
Config目录下的XComEngine.ini,用正则^[+]?ModClassOverrides=\(BaseGameClass="...",ModClass="..."\)匹配(ModEntry.cs); - UIScreenListener 覆盖:扫描 Mod
Src目录下所有*.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]枚举,支持组合标记:
| 标志 | 值 | 含义 |
|---|---|---|
| None | 0 | 无 |
| New | 1 | 新导入 |
| UpdateAvailable | 2 | 工坊有更新 |
| Downloading | 4 | 下载中 |
| ModConflict | 8 | 存在类覆盖冲突 |
| DuplicateID | 16 | 重复 ID |
| NotLoaded | 32 | 不在已配置 Mod 路径内 |
| NotInstalled | 64 | 目录/文件缺失 |
| DuplicatePrimary | 128 | 重复组中的主 Mod |
| DuplicateDisabled | 256 | 重复组中被禁用的 Mod |
| MissingDependencies | 512 | 依赖缺失 |
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):
| 设置项 | 默认值 | 作用 |
|---|---|---|
CheckForUpdates | true | 启动时检查更新 |
CheckForPreReleaseUpdates | false | 检查预发布版本 |
IncludeAlphaVersions | false | 接受 alpha 版本 |
ShowHiddenElements | false | 显示隐藏元素 |
ShowStateFilter | true | 显示状态过滤栏 |
UseTranslucentModListSelection | true | 列表选中项半透明效果 |
ShowPrimaryDuplicateAsDependency | true | 主重复副本显示为依赖 |
ShowModListGroups | true | 显示分组 |
CloseAfterLaunch | false | 启动游戏后关闭 AML |
AutoNumberIndexes | true | 自动编号索引 |
UseSpecifiedCategories | true | 采用 Mod 声明的分类 |
ShowQuickLaunchArguments | false | 显示快速启动参数面板 |
NeverImportTags | false | 从不导入 Steam 标签 |
AllowMultipleInstances | false | 允许多开 |
EnableDuplicateModIdWorkaround | false | 启用重复 ID 规避方案 |
UpdateModsOnStartup | true | 启动时更新 Mod 信息 |
OnlyUpdateEnabledOrNewModsOnStartup | false | 仅更新启用/新 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.
相关推荐
AssetStudioMod:Unity资源逆向工程的架构设计与技术实现深度解析
AssetStudioMod:Unity资源逆向工程的架构设计与技术实现深度解析 AssetStudioMod作为Perfare原版AssetStudio的增强
开发工具游戏开发逆向工程XCOM 2替代模组启动器AML:3大核心优势与完整使用指南
XCOM 2替代模组启动器AML:3大核心优势与完整使用指南 XCOM 2替代模组启动器AML是一款专为XCOM 2和XCOM Chimera Squad游戏设
桌面应用游戏开发Tavily Python SDK错误处理与调试技巧:10个常见问题解决方案
Tavily Python SDK错误处理与调试技巧:10个常见问题解决方案 Tavily Python SDK是一款强大的工具,让开发者能够轻松与Tavily
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考