Mod配置菜单

Mod配置菜单

一个集中配置已安装模组的地方。

MOD配置菜单

一个界面,兼容所有受支持的框架。

框架 // 预设 // 合辑

简介

MCM 将多个模组框架的设置整合到一个统一的游戏内界面中,提供统一的导航、控制、预设、合辑、描述和视觉设计。

◆ ◆ ◆

01 // 为什么需要 MCM

我必须承认,我对游戏当前的状况并不是特别满意,但对它的模组社区状况却再满意不过了。其背后所展现的才华、创造力以及付出的巨大努力,确实令人难以置信,并且毫无疑问,令人叹为观止 🤗

然而,有一件事一直困扰着我,那就是不同模组使用的大量独立配置界面。

《赛博朋克2077》 拥有几个出色的设置框架,但一旦安装了足够多的模组,它们的选项就不可避免地分散在 Native Settings UIMod Settings、专用的 CET ImGui 窗口、自定义覆盖层、单独的快捷键以及其他界面中。

事情已经发展到安装十个模组可能意味着还要安装一大堆支持框架,并记住每个单独设置菜单隐藏在哪里的地步。

这就是更传统的 模组配置菜单 想法的由来:

**一个集中配置已安装模组的地方。**◆ ◆ ◆

02 // 框架支持

当前可用

计划支持

  • ◐ 开发中 独立的 CET ImGui 设置

依赖说明

目前,MCM 仍然需要原始的设置框架作为后端 API 保持安装状态。

例如,如果一个模组依赖于 Mod Settings,那么 Mod Settings 仍然必须安装。实际上,这目前只是一个技术上的要求,未来可能不再需要。

一旦安装了 MCM,现有的 MODSMOD SETTINGS 条目将被一个单一的 MCM 条目取代。

来自所有受支持框架的模组随后将通过相同的布局、导航系统、控制、描述和视觉风格呈现。

◆ ◆ ◆

03 // 功能

统一界面

  • 所有受支持的设置框架共用一个一致的游戏内界面
  • 标准化的模组列表、控件、描述和导航
  • 完整的鼠标、键盘和手柄支持
  • 可选的框架标签和模组列表过滤
  • 可配置按字母顺序或原始设置顺序排列
  • 支持收藏夹,并可配置通过星标、名称高亮或两者兼用来指示
  • 懒加载:设置仅在选中其模组时加载
  • 可选的首次运行设置,用于核心界面偏好和设置行为

设置工作流

  • 明确的 应用还原 工作流
  • 可选的 自动应用 模式,实现更改后立即应用的行为
  • 每个设置和每个模组均可恢复可靠的框架默认值 (MCM 自身偏好)
  • 可选的视觉指示器,用于标识与默认值不同的设置
  • 改进的滑块列表选择器,适用于大型选项集
  • 可配置的界面颜色,基于《赛博朋克2077》的原生调色板

预设与合辑

  • 为单个模组命名预设
  • 当前默认值 虚拟预设
  • 应用更改前的预设比较预览
  • 用于保存和恢复完整设置组的多模组合辑
  • 快速基线捕获和支持更新现有合辑
  • 操作进度跟踪和尽力而为的回滚
  • 便携式合辑备份,用于在重装游戏或共享设置后恢复
  • 优雅处理缺失或暂时不可用的模组

兼容性与完善

  • 包含 19 种界面本地化,匹配游戏支持的所有语言
  • 隔离的框架桥接器,一个不可用或损坏的提供者不会阻止其他提供者工作
  • 跨不同框架来源的设置实现统一视觉行为
  • 当框架更新更改模组或设置标识符格式时,安全地进行旧版身份迁移
  • 设计用于进一步的框架扩展和独立提供者支持
◆ ◆ ◆

04 // 需求

使用最新版本

你安装中的每个依赖项都必须更新到其最新可用版本。 这既适用于核心需求,如 Cyber Engine Tweaks、redscript 和 Codeware,也适用于你已安装模组使用的每个设置框架,包括 Native Settings UI、Mod Settings 和 Redscript Configuration Framework

安装依赖项是不够的:过时的框架可能会被成功检测到,但仍然缺乏当前 MCM 版本所需的 API,这可能导致 redscript 编译错误。

请勿移除源框架

MCM 不会取代 Native Settings UI、Mod Settings 或 RCF。 如果已安装的模组需要这些框架之一,则必须保持其安装状态。

◆ ◆ ◆

05 // 安装

  1. 安装最新版本的 Cyber Engine TweaksredscriptCodeware
  2. 安装你的模组所需的 设置框架 的最新版本。
  3. 安装单一的 Mod Configuration Menu 压缩包。它已包含所需的 API 组件。
  4. 正常启动游戏。

手动安装

MCM 压缩包解压到《赛博朋克2077》主目录。模组管理器用户可将其作为常规模组安装;UI 和 API 在压缩包内仍是独立的运行时组件。

◆ ◆ ◆

06 // 更新

Mod Organizer 2 或 Vortex

将新压缩包作为更新安装,并允许模组管理器替换以前的版本。在大多数情况下,管理器会为你移除或覆盖旧文件。

手动更新

为了获得最干净和最可靠的更新:

  1. 关闭游戏。
  2. 如果你希望保留,请备份下面列出的 MCM 用户数据。
  3. 移除当前的 MCM 目录 (见下文)。
  4. 移除旧版 MCM 目录 (亦见下文)。
  5. 将完整的新压缩包解压到《赛博朋克2077》主目录。
  6. 仅恢复步骤 2 中保存的用户数据。保留新压缩包的 storage.version,不要恢复旧的 Lua 或 redscript 文件。
  7. 正常启动游戏。

需要保留的用户数据

  • bin/x64/plugins/cyber_engine_tweaks/mods/ModConfigurationMenu/config.json - MCM 界面偏好
  • bin/x64/plugins/cyber_engine_tweaks/mods/ModConfigurationMenuAPI/data 目录的内容,除了 storage.version - 预设、合辑和便携式备份

需要移除的当前目录

  • bin/x64/plugins/cyber_engine_tweaks/mods/ModConfigurationMenu
  • bin/x64/plugins/cyber_engine_tweaks/mods/ModConfigurationMenuAPI
  • bin/x64/plugins/cyber_engine_tweaks/mods/00_MCMNativeSettingsLifecycle
  • r6/scripts/ModConfigurationMenu
  • r6/scripts/ModConfigurationMenuAPI

需要移除的旧版目录

  • bin/x64/plugins/cyber_engine_tweaks/mods/!MCM_Bootstrap

如果列出的任何目录不存在,请跳过它。不要删除属于其他模组的类似名称文件夹。

不要合并手动更新

简单地将一个新版本解压到旧的手动安装之上可能会留下已重命名或已停用的文件。这些文件可能会与当前版本一起加载并导致错误。请先移除旧安装,然后将新压缩包解压到一个干净的位置。

◆ ◆ ◆

07 // 使用方法

  1. 打开主菜单或暂停菜单。
  2. 在常规的 设置 条目附近选择 MCM
  3. 从左侧列表中选择一个模组。
  4. 更改所需的设置。
  5. 选择 应用 以保存待定的更改,或 还原 以恢复上次应用的状态。

待定更改

一次只有一个模组可以拥有待定更改。在切换到另一个模组之前,请先应用或还原这些更改。

在受支持的设置上使用 Backspace 键可恢复其框架定义的默认值。

使用 默认值 可为选定的模组暂存所有可用的默认值。除非启用了 自动应用,否则这些更改仍遵循正常的 应用/还原 工作流。

预设 页面存储所选模组的命名配置。合辑 页面存储多个模组的配置,并可通过 快速基线 捕获当前受支持的设置。预设和合辑预览会在应用任何更改之前显示将要更改的内容。

合辑可以导出为独立的 .mcmcollection 备份,并在重装游戏或模组后再次导入。导入的备份会作为本地合辑添加以供查看,不会自动更改当前设置。缺失的模组会一直存储,直到它们再次可用。

保留外部副本

便携式备份存储在 <CET>/mods/ModConfigurationMenuAPI/data/portable 下。在卸载游戏或完整的模组管理器实例之前,请将重要文件复制到游戏外部或你的完整模组管理器实例之外。

当框架或模组在 MCM 已经打开后才注册其设置时,请使用 刷新

应用/还原工作流

MCM 最初的设计围绕基于应用-还原的工作流。对一个或多个设置所做的更改不会立即生效,必须按“应用”按钮确认。

这也适用于相关的预览,在所选设置被应用之前,预览可能无法渲染或更新。

这是有意为之的行为,而非错误。 如果你更喜欢旧设置框架使用的更改即应用行为,请在 MCM 设置中启用“自动应用”。启用此选项后,每次更改都会立即应用。

◆ ◆ ◆

08 // 卸载

移除已安装的 Mod Configuration Menu 压缩包。这将同时移除其 UI 和 API 组件。

MCM 不会向存档文件添加游戏记录或持久化对象。已通过 MCM 应用的设置仍由它们原始的模组或框架存储。

UI 包也可以移除,同时为其他渲染器或工具保留 MCM API 的安装。

依赖安全

当其他已安装的模组仍然依赖某个原始设置框架时,请勿将其移除。

◆ ◆ ◆

09 // 故障排除

MCM 条目缺失

  • 确认 MCMCyber Engine Tweaks 已启用。
  • 确认 MCM、你的设置框架以及使用这些框架的模组所要求的每个依赖项都已正确安装并更新到最新可用版本。
  • 安装或更新 MCM 后重启游戏。
  • 检查 redscriptCET 日志,查找编译或初始化错误。

如果选择 MCM 打开的是类似普通游戏设置界面的东西,而不是 MCM,请将其视为初始化失败,并检查相同的依赖项和日志。例如,在禁用 RCF 本身的同时保留基于 RCF 的模组启用,可能会阻止这些模组正确编译。

模组从列表中缺失

  • 确认该模组、其原始设置框架及其所有依赖项都已启用、正确安装并更新到最新可用版本。
  • MCM 内部选择 刷新
  • 如果框架仅在启动期间注册设置,请重启游戏。

设置只读或不受支持

源模组可能使用了 MCM 尚无法安全表示的框架控件。这通常是暂时的兼容性限制,而不是永久决定让该设置不受支持。请报告受影响的模组和设置,以便调查缺失的控件;一旦有清晰的可重现示例,小的兼容性补充通常可以快速实现。

报告问题时

请包括:

  • 游戏版本
  • MCM UI 和 API 版本
  • CET、redscript 和 Codeware 的确切版本
  • 所有已安装设置框架的确切版本
  • 受影响模组的名称和版本
  • 安装是由 MO2/Vortex 管理还是手动执行
  • CET 和 redscript 日志
  • 问题截图
◆ ◆ ◆

10 // 常见问题解答

为什么我在安装或更新 MCM 后出现 redscript 编译错误?

首先,将所有相关依赖项更新到其最新可用版本。不仅要检查 Cyber Engine Tweaks、redscript 和 Codeware,还要检查你的模组使用的每个设置框架 - Native Settings UI、Mod Settings 和 Redscript Configuration Framework,以及这些框架或使用它们的模组所需的任何附加依赖项。较旧的框架可能仍然安装并被检测到,但缺少当前 MCM 桥接器所需的 API 元素。

如果错误仍然存在,请对 MCM 和受影响的依赖项执行全新重装,而不是将新文件复制到旧安装之上。然后报告问题时附上 r6/logs/redscript_rCURRENT.log、你的确切依赖项版本和错误截图。

另一个模组的 redscript 错误会阻止 MCM 工作吗?

会的。Redscript 会一起编译已安装的模组脚本,而不是将每个模组构建为完全隔离的包。一个未解决的导入、缺失的依赖项或不兼容的脚本都可能导致整个模组 redscript 编译失败。发生这种情况时,MCM 的原生 UI 脚本和许多其他无关模组的 redscript 组件也可能无法加载。

这并非 MCM 特有。如果游戏报告 redscript 编译错误 (即使未提及 MCM),请从错误窗口中列出的模组名称开始排查。访问每个模组的页面,查看其完整需求,并确保模组及每个所需依赖项都已正确安装并更新到最新可用版本。详细的编译器报告可在 r6/logs/redscript_rCURRENT.log 中找到。

为什么 MCM 警告我有过时的文件或目录?

MCM 识别到了旧安装留下的文件。如果它指出了过时的目录,请移除该目录。如果它建议进行干净重装,请关闭游戏,移除当前安装的 MCM 文件和目录,然后再次安装完整的当前压缩包。

该警告并不意味着你的存档已损坏。它意味着已停用的 Lua 或 redscript 文件可能仍会与当前版本一起加载,并导致难以诊断的重复行为、编译错误或故障。上面的 更新 部分包含了干净的手动更新步骤。

为什么我的设置或其预览没有立即更改?

默认情况下,MCM 会暂存更改,直到你选择 应用。这包括控制实时预览的设置:更改滑块、选择器、开关或其他值后,预览可能保持原样,直到应用新值。这是预期行为,并且可能会影响带有视觉预览的模组,包括广告或显示控制器。

选择 应用 以提交待定的值,或者如果你希望每次更改都立即提交,请在 MCM 的自身设置中启用 自动应用还原 会丢弃暂存的更改并返回上次应用的值。

为什么控件显示不同、只读或不支持?

源框架可能公开了 MCM 尚不知道如何安全表示的、自定义的或新引入的控件。MCM 可能会暂时使用更简单的表示,或者保持该值只读,而不是猜测其应有的行为。

请报告模组、设置、源框架,并附上截图。这通常只是一个缺少的兼容性映射,小的控件补充通常可以快速实现 - 有时在获得可重现示例的当天就能完成。

为什么建议手动安装进行干净更新?

将新压缩包复制到旧安装之上会覆盖当前文件,但无法移除已重命名或已停用的文件。这些遗留物会保持活跃,并可能与新版本一起加载。

此问题并非 MCM 特有。重复的手动更新可能会在整个游戏安装中逐渐留下来自许多不同模组的陈旧脚本和目录。一切可能看似工作正常,而这些遗留物却在悄悄导致冲突、重复代码、编译失败或后来出现看似无关的问题。

强烈建议使用模组管理器,最好是 Mod Organizer 2Vortex 也比手动反复合并压缩包安全得多。模组管理器使包的所有权可见,并使干净的替换、冲突检查、禁用和移除变得更加可靠。

MCM 会取代 Native Settings UI、Mod Settings 或 RCF 吗?

不会。那些框架仍然拥有它们的注册表、回调、验证和配置文件。MCM 在它们的 API 之上提供了一个统一的界面。

MCM 支持普通的 CET ImGui 设置吗?

暂时不支持。直接的 ImGui 集成正在开发中。

MCM 会修改我的存档文件吗?

不会。MCM 不将游戏数据存储在存档中。

预设和合辑存储在哪里?

它们由 MCM API 存储在单独的配置文件中。它们不会被写入《赛博朋克2077》的存档文件,也不会改变 MO2 的加载顺序。便携式 .mcmcollection 备份存储在 <CET>/mods/ModConfigurationMenuAPI/data/portable 中,应在移除游戏或完整的模组管理器实例之前复制到外部存储。

预设和合辑有什么区别?

预设属于单个模组。合辑将多个模组的设置快照或链接的预设分组到一个可以一起预览和应用的设置中。

导入合辑会立即更改我的设置吗?

不会。导入会首先创建一个新的本地合辑。你可以查看它,并稍后明确选择 应用。缺失或暂时不可用的模组仍会存储在合辑中以备将来恢复。

主菜单条目可以命名为 MODS 而不是 MCM 吗?

可以。菜单标签可以在 MCM 的自身设置中更改,而无需恢复原始框架条目。

我可以在没有附带 UI 的情况下使用 MCM API 吗?

可以。API 是渲染器无关的,可以被其他界面和工具使用。

为什么模组只在按刷新后才出现?

某些框架和模组在游戏生命周期的后期才注册设置。MCM 支持延迟注册,而 刷新 请求立即进行提供者重新扫描。

◆ ◆ ◆

11 // 鸣谢

受支持的设置框架

衷心感谢这些作者创建并维护 MCM 所支持的原始设置框架:

原始框架仍然是依赖它们的模组的独立需求。这是有意为之:MCM 与他们的工作集成并尊重他们的工作,而不是重新分发或取代他们的实现。

核心模组工具

感谢构建 MCM 所依赖的工具、API、文档和基础。

灵感与参考

还要感谢更广泛的《赛博朋克2077》模组社区分享知识、测试、反馈和支持,这些持续推动着这个项目的改进。

◆ ◆ ◆

12 // 面向模组开发者

渲染器无关的 API

MCM API 可以为其他界面和工具提供支持,而无需依赖附带的 UI。

MCM 构建在一个独立的、渲染器无关的 API 之上。其他 CET 模组可以使用它来发现受支持的模组、懒加载标准化设置、暂存和应用值、检查框架默认值、管理预设和多模组合辑、订阅更改,或者构建一个完全不同的界面。

框架集成作为桥接模块被隔离。可以在不修改核心 API 或现有桥接器的情况下添加新的设置框架。

获取 API

MCM API 由一个名为 ModConfigurationMenuAPICET 模组导出。它不是一个 redscript 命名空间,不需要通过 require() 包含或复制到另一个模组中。将 MCM API 添加为你的模组的需求,然后在 onInit 期间通过 CET 的 GetMod() 函数获取其公共 Lua 表:

local MCM

registerForEvent("onInit", function()
  -- MCM API 作为一个独立的 CET 模组导出。
  -- GetMod() 应在 CET 初始化所有已安装的模组之后调用。
  local api = GetMod("ModConfigurationMenuAPI")

  -- 当 MCM API 未安装或初始化失败时,干净地停止。
  if api == nil then
    print("MCM API is not installed.")
    return
  end

  -- apiVersion 描述的是公共 API“契约”,而非 MCM 包版本。
  -- 不同的协议版本可能包含破坏性更改。
  if api.apiVersion ~= 2 then
    print("This mod requires MCM API v2.")
    return
  end

  MCM = api
end)

初始化后,返回的表就是 API。MCM 只是这些示例中使用的局部变量名,不是必需的全局命名空间;你可以用任何名称存储此表。例如,使用 MCM:refreshIndex()MCM:listMods()MCM:openMod(modKey)。这些方法支持两种 Lua 调用风格,但下面的示例统一使用冒号形式。

公共 API

发现与架构

  • MCM:refreshIndex() - 刷新所有已注册的提供者并重建模组索引。
  • MCM:refreshProvider(providerId) - 刷新单个提供者,不触及其他人。
  • MCM:listProviders() - 返回当前提供者状态。
  • MCM:listMods(filter?) - 返回已索引的模组,可选择过滤。
  • MCM:openMod(modKey) - 懒加载并打开一个模组的设置架构。
  • MCM:closeMod() - 关闭当前模组并丢弃其待定的草稿。
  • MCM:listCategories(modKey) - 返回已打开模组的类别。
  • MCM:listSettings(modKey, categoryKey?) - 返回所有设置或一个类别的设置。
  • MCM:getValue(settingId) - 返回暂存值,如果不存在草稿则返回已提交值。

默认值与草稿

  • MCM:hasDefault(settingId) - 检查框架是否暴露了可靠的默认值。
  • MCM:getDefault(settingId) - 返回标准化的框架默认值。
  • MCM:isDefault(settingId, value?) - 将有效值或提供的值与默认值进行比较。
  • MCM:getDefaultDiff(modKey?) - 返回有效值与可靠默认值不同的设置。
  • MCM:getDefaultCoverage(modKey?) - 总结模组的默认值和重置支持情况。
  • MCM:setDraft(settingId, value) - 验证并暂存新值,但暂不应用。
  • MCM:clearDraft(settingId) - 移除一个暂存值。
  • MCM:resetDraft(settingId) - 暂存设置的框架定义默认值。
  • MCM:setDraftToDefault(settingId) - 显式暂存一个可靠的默认值。
  • MCM:setModDraftsToDefaults(modKey?) - 为一个模组暂存所有可重置的默认值。
  • MCM:hasDrafts(modKey?) - 检查模组是否有待定的更改。
  • MCM:apply(modKey?) - 应用一个模组的完整草稿批次。
  • MCM:revert(modKey?) - 丢弃待定更改并恢复上次提交的状态。
  • MCM:reloadMod(modKey?) - 在没有待定草稿时重新加载模组架构。

预设

  • MCM:listModPresets(modKey) - 返回存储的预设以及虚拟的 CURRENT 和 DEFAULTS 预设。
  • MCM:getModPreset(presetId) - 解析一个存储的或虚拟的预设。
  • MCM:createModPreset(modKey, options) - 将一个模组的有效值捕获到一个命名预设中。
  • MCM:updateModPreset(presetId, options) - 重命名、描述或重新捕获存储的预设。
  • MCM:duplicateModPreset(presetId, options) - 复制存储的或虚拟的预设。
  • MCM:getPresetReferences(presetId) - 返回链接到预设的合辑条目。
  • MCM:deleteModPreset(presetId, options?) - 删除预设并可显式分离链接条目。
  • MCM:previewModPreset(presetId) - 在不暂存的情况下将预设与当前值进行比较。
  • MCM:stageModPreset(presetId) - 暂存预设中的所有兼容值。
  • MCM:applyModPreset(presetId) - 暂存并应用一个完整的预设。

合辑与操作

  • MCM:listCollections() - 返回合辑元数据。
  • MCM:getCollection(collectionId) - 加载一个合辑及其条目。
  • MCM:createCollection(options) - 创建一个空的命名合辑。
  • MCM:updateCollection(collectionId, options) - 重命名或描述合辑。
  • MCM:deleteCollection(collectionId) - 删除一个合辑及其存储的条目。
  • MCM:putCollectionEntry(collectionId, modKey, options?) - 添加或替换一个快照或链接的预设条目。
  • MCM:removeCollectionEntry(collectionId, entryId) - 移除一个模组条目。
  • MCM:previewCollectionEntry(collectionId, entryId) - 将一个合辑条目与当前值进行比较。
  • MCM:captureCurrentSetup(options) - 调度一个多模组基线捕获。
  • MCM:updateCollectionFromCurrent(collectionId) - 从所有当前可用的受支持模组更新合辑。
  • MCM:listMissingCollectionEntries(collectionId) - 列出当前不可用的条目。
  • MCM:cleanMissingCollectionEntries(collectionId) - 调度移除不可用的条目。
  • MCM:applyCollection(collectionId) - 预检并调度合辑应用。
  • MCM:rollbackCollection(operationId) - 在合辑应用后调度尽力而为的恢复。
  • MCM:getPortableCollectionDirectory() - 返回向玩家显示的便携式备份目录。
  • MCM:listPortableCollections() - 列出并验证便携式合辑文件。
  • MCM:inspectPortableCollection(fileName) - 返回备份元数据和每个模组的兼容性信息。
  • MCM:exportCollection(collectionId) - 写入一个独立的便携式合辑备份。
  • MCM:importPortableCollection(fileName) - 将便携式备份作为新的本地合辑导入。
  • MCM:deletePortableCollection(fileName) - 永久移除一个已验证的便携式备份目标。
  • MCM:getOperation(operationId) - 返回已调度操作的进度和结果。
  • MCM:cancelOperation(operationId) - 取消排队中或正在运行的操作。

操作、诊断与事件

  • MCM:invokeAction(settingId, interaction?) - 执行一个受支持的操作行并返回标准化的效果。
  • MCM:mountCustom(settingId, host) - 请求所属提供者将受支持的自定义内容挂载到渲染器宿主中。
  • MCM:getStatus() - 返回当前可读的 API 状态。
  • MCM:getDiagnostics() - 返回提供者诊断和最近错误。
  • MCM:subscribe(eventName, callback) - 订阅一个 MCM 生命周期事件。
  • MCM:unsubscribe(token) - 移除一个现有的事件订阅。

桥接器作者可以通过 MCM.providers:registerProvider(provider) 注册另一个设置提供者。完整的提供者契约将单独记录。

以下示例刷新提供者索引并列出每个发现的模组:

registerForEvent("onInit", function()
  if MCM == nil then
    return
  end

  local snapshot, refreshWarning = MCM:refreshIndex()
  if snapshot == nil then
    print("MCM refresh failed: " .. tostring(refreshWarning))
    return
  end

  local mods, listWarning = MCM:listMods()
  if listWarning ~= nil then
    print("MCM mod list warning: " .. tostring(listWarning))
  end

  for _, mod in ipairs(mods or {}) do
    print(string.format("%s [%s]", mod.name, mod.providerName))
  end
end)

设置是在打开模组后懒加载的。更改会作为草稿暂存,并仅在 apply() 后写入原始框架:

local function applySetting(modKey, settingId, newValue)
  local opened, openError = MCM:openMod(modKey)
  if opened == nil then
    print("MCM could not open the mod: " .. tostring(openError))
    return false
  end

  local staged, stageError = MCM:setDraft(settingId, newValue)
  if not staged then
    print("MCM rejected the value: " .. tostring(stageError))
    MCM:closeMod()
    return false
  end

  local applied, applyError = MCM:apply(modKey)
  MCM:closeMod()

  if not applied then
    print("MCM could not apply the value: " .. tostring(applyError))
    return false
  end

  return true
end

该 API 还公开了提供者诊断、生命周期事件、调度的批量操作、操作和自定义内容控件,以及额外框架桥接器的注册契约。完整的参考、DTO 契约、事件和集成示例包含在 API 包内的 API.md 文件中。

◆ ◆ ◆

我的其他模组