CFXControl Flex Wiki
English中文

模组兼容

Control Flex 是为中大型整合包设计的:默认零配置,只有当某个模组的输入不按常理出牌时才逐级加码。这一页讲清五种手段各自能做什么、什么时候该升级到下一层,以及产物最终落在哪。

一、适配阶梯:五种手段的关系

从零成本到写代码,这是一个「能用就不往上走」的阶梯:越往下越精确,维护成本也越高。

手段 需要什么 能覆盖什么 产物在哪 成本
自动发现 什么都不用 用 KeyMapping 正常注册键位的模组 无(运行时注册) 零
游戏内模组适配 一个手柄,几分钟 按键分层、界面 / 叠层的摇杆与光标行为 compat/user/<mod_id>.json 低
兼容配置 联网,或一个现成文件 上面两层的可分享版本,外加派发通道、按键抑制、提示文案 compat/{default,mods,user}/ 低
手写 compat JSON 文本编辑器 + 字段表 精细规则:每键派发通道、按物品抑制、相位保持、每页摇杆参数 compat/user/<mod_id>.json 中
桥接模组 Java + Gradle 绕开 KeyMapping 的自绘输入、运行时状态、自绘 UI 独立 JAR + compat/mods/*.json 高

大多数整合包停在 1–3 层就够了。真正需要桥接的模组不多,通常是「自带一套输入系统」的那几个:EMI、Create 的列车控制台、沉浸车辆、Epic Fight。

二、什么时候该升级到下一层

  1. 先看「按键映射」里有没有它 —— 有 key,说明是标准的 KeyMapping 模组,第 2 / 3 层就能解决。
  2. 有 key,但界面里没反应 —— 多半是「在哪里生效」或「怎么派发」不对:先用第 2 层加界面 / 叠层规则,再用第 3 层换派发通道。
  3. 按了没反应,或按一下触发两次 —— 派发通道选错了(eventBus / keyMapping 重复触发),用第 4 层精确指定。
  4. 连 key 都不出现 —— 模组把键位存在自己的配置里、直接读原始键态、或直接读手柄,只有第 5 层桥接能接。
  5. 模组有「战斗模式」这类运行时状态 —— 桥接推状态(IPlayerStateRegistry),JSON 用 itemSuppressKeys 的 playerState 条件去消费它。

三、五种手段共用一套数据模型

不管用哪一层,落到磁盘上都是同一份 compat JSON,核心只有三个按键分区,加上一个「派发」概念:

分区 什么时候生效 典型用法
inGameKeys 没有界面、也没有叠层时 战斗键、技能键、变身键
screenKeys 有界面(Screen / GUI)打开时 背包、合成、查看配方
overlayKeys 有叠层打开时(画在 HUD 之上的轮盘、法阵等) 法术轮盘、径向菜单、拍照 HUD

按键最终怎么送进模组,由派发通道决定:keyMapping、eventBus、glfwPoll、screenInput、virtualKbm。同一份 JSON 可以给不同按键配不同通道,这也是「同一个键按一下触发两次」这类问题的解法。

四、产物落在哪:三层目录

compat 配置按三层加载,优先级 user > mods > default,同一个 mod_id 整份覆盖、不做字段合并。改哪一层、会不会被后续操作覆盖,在手动修改配置里讲清楚。

五、按你的身份继续读

还是不正常?按这个顺序查

  1. 看「按键映射」—— 这个动作绑到正确的层了吗(Main / Screen / Overlay)?
  2. 打开该模组的模组适配 —— 加一条界面 / 叠层规则,或应用一份社区配置。
  3. 如果模组只监听物理键,用虚拟键鼠绑定。
  4. 日志里搜 [ModCompat],看这份配置到底加载了没有、被什么门槛拦住了。