跳转至

原创教程 · KubeJS 6.x (1.20.1) · 联动模组:Modern UI(ModernUI-MC,作者 BloCamLimb)· 资料核实于 2026-08-23(官方源码 / changelog / KubeJS 官方仓库)

Modern UI 联动:界面与文本增强

Modern UI(模组 ID modernui)是一个纯客户端的现代化 UI 引擎 + 文本渲染引擎模组。很多人以为它和 KubeJS 有脚本级联动——先给结论:目前没有任何官方 KubeJS 绑定。本文基于对 ModernUI-MC 官方源码(master 分支)、全部 changelogs(2019~2026)和 KubeJS 官方仓库的核查:Modern UI 从未提供过 KubeJS 事件桥、bindings 或脚本 API,它的 Modding API 是面向 Java 模组开发者的。

但这不代表两者没关系。Modern UI 作为客户端增强层,会静默改善所有基于原版 GUI 渲染的内容——包括 KubeJS 做的界面和文本。这篇讲清楚:

  • 它能做到什么(哪些能力自动作用到 KubeJS 相关界面上);
  • 边界在哪(哪些东西它管不着);
  • 怎么做(KubeJS 侧能用的三种联动姿势);
  • 事例(可复制的脚本 + 桥接模组骨架)。

目录

  1. Modern UI 是什么
  2. 它能做到什么
  3. 与 KubeJS 的边界
  4. 怎么做:三种联动姿势
  5. 事例 A:检测安装并差异化提示
  6. 事例 B:桥接模组(Java 插件)骨架
  7. 事例 C:落英服枪战全家桶架构
  8. 常见问题

1. Modern UI 是什么

项目 内容
模组名称 Modern UI(ModernUI-MC)
Mod ID modernui
Minecraft 1.20.1(EOL 分支,对应版本 3.12.0.1 / 3.11.x 系)
加载器 Forge / NeoForge / Fabric
定位 客户端 UI 框架 + 文本布局渲染引擎 + 性能优化
作者 BloCamLimb
许可 LGPL-3.0-or-later
下载 https://modrinth.com/mod/modern-ui · https://www.curseforge.com/minecraft/mc-mods/modern-ui
源码 https://github.com/BloCamLimb/ModernUI-MC

⚠️ 注意:GitHub 上的 BloCamLimb/ModernUI 是 3.13+ 重写后的跨平台桌面 UI 框架(面向桌面应用),Minecraft 模组用的是它的衍生产物 ModernUI-MC。查资料时别拿错仓库。


2. 它能做到什么

2.1 文本渲染引擎(自动生效)

Modern UI 内置一套独立于原版的文本布局与渲染引擎,任何走 Minecraft 原版字体管线的文字都会自动受益(官方 README 原话:让「Minecraft and Mods based on Vanilla GUI system」无改动享受现代文本系统)。具体包括:

  • SDF 文字渲染:任意缩放下文字都清晰锐利,抗锯齿 + FreeType 字体 hinting;
  • 更强的字体回退(fallback):生僻字、特殊符号不会变「豆腐块」;
  • 全 Unicode 16.0 Emoji:内置 Google Noto Color Emoji,彩色 emoji 直接渲染;
  • 精确字体尺寸计算:按设备空间计算原生字形大小;
  • Unicode 断行:支持 CSS line-break / word-break 规则,中日韩文本排版更好;
  • 异步文本布局:快速且精确,主线程卡顿更少;
  • 性能优化:真实 1 字节 alpha 遮罩纹理(原版是 4 bpp),文本渲染快数倍,GC 压力显著降低。

2.2 原版 GUI 体验增强

  • 平滑滚动(原版列表、Forge 滚动面板);
  • 高级 tooltip 样式:圆角/普通边框(带抗锯齿)、渐变色、动画、像素级平滑定位;
  • 文本输入框撤销/重做、Unicode 分词迭代;
  • 聊天支持 Discord/Slack/GitHub/JoyPixels emoji 短代码(:smile: 之类);
  • 标题居中、控制行距、支持 RTL 布局;
  • 屏幕背景高斯模糊、淡入动画、背景色自定义;
  • 更多窗口模式(无边框全屏/最大化)、失焦自动限帧、打开背包自动暂停单机等。

2.3 对 KubeJS 用户的实际意义

KubeJS 做的内容 Modern UI 是否增强
原版风格 GUI(Screen 类、GuiGraphics 绘制) ✅ 文字渲染自动增强(更清晰、支持 emoji)
聊天消息、标题、ActionBar、物品提示框(KubeJS 改过的) ✅ 自动增强
KubeJS 6.1+ Interactive UI 组件里的文本 ✅ 走原版字体管线的部分增强(布局/组件本身是 KubeJS 自研,不受影响)
KubeJS 自定义纹理/模型绘制 ❌ 与文本引擎无关
KubeJS 服务端逻辑、事件、配方 ❌ 完全无关(Modern UI 是纯客户端)

3. 与 KubeJS 的边界

搞清楚边界,才不会白折腾:

  • 没有 ModernUIEvents、没有脚本 bindings、没有 KubeJS 事件桥——KubeJS 脚本里不存在任何 modernui 开头的全局对象或事件组(这是查证结论,不是没找到文档);
  • Modern UI 的 Modding API 面向 JavaMuiScreenMuiModApiUIManager 等类都在 icyllis.modernui.mc.* 包下,需要 Java 模组才能完整使用;
  • UI 线程约束:Modern UI 的 UI 操作必须在客户端渲染线程(主线程)执行,服务端脚本/异步环境里调用会崩;
  • 服务器上装 Modern UI 无意义:它没有任何服务端逻辑,纯客户端模组(服务器装了也不报错,但什么都不干)。

4. 怎么做:三种联动姿势

4.1 姿势一:脚本检测(最常用,最安全)

用 KubeJS 内置的 Platform.isModLoaded() 检测客户端/服务端是否装了 Modern UI,然后差异化执行逻辑:

// server_scripts/modernui_detect.js
ServerEvents.loaded(event => {
    if (Platform.isModLoaded('modernui')) {
        console.log('[联动] 检测到 Modern UI,启用高级文本相关功能')
        global.modernUI = true
    } else {
        console.log('[联动] 未安装 Modern UI')
        global.modernUI = false
    }
})

4.2 姿势二:Java.loadClass 实验性访问(不推荐生产用)

KubeJS 允许用 Java.loadClass() 加载任意类(受 class filter 限制)。理论上可以访问 icyllis.modernui.*

// ⚠️ 实验性!仅演示类加载能力,不要用于正式功能
let MuiModApi
try {
    MuiModApi = Java.loadClass('icyllis.modernui.mc.MuiModApi')
    console.log('[联动] Modern UI API 类加载成功')
    // 列出公开方法(只读反射,不执行任何 UI 操作)
    MuiModApi.getDeclaredMethods().forEach(m => console.log('  - ' + m.getName()))
} catch (e) {
    console.log('[联动] Modern UI API 不可用: ' + e)
}

为什么说不要用于生产

  • Modern UI 的 UI 操作强制要求客户端渲染线程,KubeJS 服务端脚本的 tick/事件大多不在该线程;
  • 反射拼 View 树(LinearLayout、TextView、点击回调……)在 JS 里写,可读性和可维护性极差;
  • Modern UI 的类在服务端不存在(客户端专用类),服务端脚本直接引用会 ClassNotFound。

4.3 姿势三:写桥接模组(官方推荐的正路)

KubeJS 官方推荐的集成方式就是 KubeJS 插件(KubeJSPlugin):任何模组都可以注册自己的事件组、bindings、类型包装,暴露给 KubeJS 脚本。想要「KubeJS 脚本能打开 Modern UI 界面」,正确做法是写一个十几行的小插件模组(Java),把 Modern UI 的界面打开能力封装成一个 KubeJS 事件,脚本侧就变成一行调用。骨架见 事例 B


5. 事例 A:检测安装并差异化提示

完整可用的服务端脚本:根据玩家是否装了 Modern UI,在聊天里提示不同内容(比如推荐装 Modern UI 以获得更好的文字渲染)。

// server_scripts/modernui_welcome.js
PlayerEvents.loggedIn(event => {
    const { player } = event
    const hasModernUI = Platform.isModLoaded('modernui')

    player.tell([
        Text.green('欢迎回来,' + player.username + '!'),
        hasModernUI
            ? Text.gold('✨ 检测到 Modern UI:文字渲染已增强,emoji 全彩显示')
            : Text.gray('(提示:安装 Modern UI 可提升文字渲染与 emoji 显示,纯客户端可选)')
    ])
})

// 用法示例:给装了 Modern UI 的玩家发特殊福利
PlayerEvents.loggedIn(event => {
    if (Platform.isModLoaded('modernui')) {
        // 例如:送一个彩蛋物品(示意)
        event.player.give('minecraft:emerald')
    }
})

要点:

  • Platform.isModLoaded() 是 KubeJS 内置,客户端/服务端脚本都能用;
  • 服务端脚本检测的是服务端 mod 列表——Modern UI 是客户端模组,服务端检测会返回 false!要检测「玩家客户端装没装」,用 player.isModLoaded 之类客户端侧判断,或让客户端脚本(client_scripts)上报。

📌 更准确的客户端检测:把检测逻辑放 client_scripts,用 Platform.isModLoaded('modernui') 在客户端判断,然后通过 KubeJS 的自定义数据/网络(或 FPSMatch 等联动模组的通道)同步给服务端。


6. 事例 B:桥接模组(Java 插件)骨架

目标:让 KubeJS 脚本能监听「Modern UI 打开界面」的请求。这是一个最小 KubeJS 插件(KubeJS 6.x / 1.20.1,API 以你实际引入的 KubeJS 版本为准)。

6.1 插件入口

// src/main/java/com/example/modernuibridge/ModernUIBridgePlugin.java
package com.example.modernuibridge;

import dev.latvian.mods.kubejs.plugin.KubeJSPlugin;
import dev.latvian.mods.kubejs.script.BindingRegistry;
import dev.latvian.mods.kubejs.event.EventGroup;
import dev.latvian.mods.kubejs.event.EventHandler;

public class ModernUIBridgePlugin extends KubeJSPlugin {
    // 事件组:脚本里用 ModernUIBridge.openScreen 监听
    public static final EventGroup GROUP = EventGroup.of("ModernUIBridge");

    public static final EventHandler OPEN_SCREEN = GROUP.client(
        "openScreen", () -> OpenScreenEvent.class
    );

    @Override
    public void registerEvents(EventsWrapper events) {
        events.register(GROUP);
    }
}

6.2 事件类

// src/main/java/com/example/modernuibridge/OpenScreenEvent.java
package com.example.modernuibridge;

import dev.latvian.mods.kubejs.event.KubeEvent;
import net.minecraft.client.player.LocalPlayer;

public class OpenScreenEvent implements KubeEvent {
    private final LocalPlayer player;

    public OpenScreenEvent(LocalPlayer player) {
        this.player = player;
    }

    public LocalPlayer getPlayer() {
        return player;
    }
}

6.3 资源注册文件

# src/main/resources/kubejs.plugins.txt
com.example.modernuibridge.ModernUIBridgePlugin modernuibridge

6.4 脚本侧调用(客户端脚本)

// client_scripts/modernui_bridge.js
ModernUIBridge.openScreen(event => {
    const { player } = event
    console.log('玩家请求打开 Modern UI 界面: ' + player.username)
    // 在这里调用你的 Modern UI 界面(Java 侧封装好的方法)
    // 例如:ModernUIUtils.showMyScreen(player)
})

📌 这只是一个结构正确的骨架。真正把 Modern UI 的某个界面类(如继承 MuiScreen 的自定义 Screen)接到 showMyScreen() 上,属于 Java 模组开发范畴——界面本身的代码写在你自己的模组里,插件只负责把「打开界面」这个动作暴露给脚本。这样脚本侧保持简单,复杂 UI 逻辑留在 Java 侧。


7. 事例 C:落英服枪战全家桶架构

结合本服务器实际使用的组合(FPSMatch + TaCZ + Modern UI + KubeJS),讲清楚四者分工——这也是「联动」最常见的真实形态:各司其职,互不干扰

模组 职责 与 KubeJS 的关系
FPSMatch 服务端+客户端 对局框架:地图/队伍/商店/事件/统计 提供官方 KubeJS 事件桥 FPSMatchEvents(mapStart/playerKill/teamJoin…),脚本可直接监听
TaCZ 服务端+客户端 枪械本体(武器、弹药、手感) KubeJS 可通过事件/命令间接配合
Modern UI 纯客户端 文字渲染增强、emoji、tooltip、性能优化 无脚本 API;自动增强 KubeJS 相关界面的文字显示
KubeJS 服务端为主 玩法规则、奖励、统计、公告、UI(6.1+) ——

典型联动场景:

// 服务端脚本:FPSMatch 击杀事件 + 检测 Modern UI 的提示文本
FPSMatchEvents.playerKill(event => {
    const { player } = event
    // 击杀奖励(KubeJS 职责)
    player.give('minecraft:emerald', 1)
    // 提示文本(Modern UI 会自动把它渲染得更清晰)
    player.tell(Text.gold('击杀 +1!'))
})

架构结论

  • KubeJS 和 Modern UI 不需要也不存在直接的脚本联动——前者管规则,后者管观感;
  • 想让玩家文字体验更好:装 Modern UI(客户端)就完事了,KubeJS 侧什么都不用改;
  • 想做 Modern UI 风格的高级自定义界面:写 Java 模组(或桥接插件),别指望纯脚本。

8. 常见问题

Q:KubeJS 脚本里为什么找不到 ModernUIEvents / modernui 相关对象? A:Modern UI 从未提供 KubeJS 绑定(已查证官方源码与 changelog)。没有任何全局对象或事件组是正常的。

Q:服务端脚本 Platform.isModLoaded('modernui') 为什么返回 false? A:因为 Modern UI 是纯客户端模组,服务端 mod 列表里没有它。要检测玩家客户端是否安装,请在 client_scripts 里检测并通过网络/存档数据同步。

Q:装了 Modern UI 后,KubeJS 做的界面会变好看吗? A:文字部分会(更清晰、emoji 彩色、断行更好);界面布局、纹理、组件渲染不变。

Q:能用 KubeJS 脚本直接打开 Modern UI 界面吗? A:不能优雅地做。Modern UI 的 UI 是 retained 模型 + 客户端线程约束,脚本硬调(Java.loadClass)只适合实验,正式功能请写桥接模组(见事例 B)。

Q:KubeJS 6.1 的 Interactive UI 和 Modern UI 是什么关系? A:没有关系。Interactive UI 是 KubeJS 自研的 UI 系统(见 26/27 篇),Modern UI 是独立的第三方 UI 引擎。两者可以共存,但互不调用。

Q:Modern UI 和 OptiFine / Sodium / Iris 冲突吗? A:官方宣称兼容 OptiFine、Sodium (Rubidium)、Iris (Oculus) 及许多模组。遇到渲染问题先查 Modern UI 配置里的渲染后端设置。


小结

  • Modern UI = 纯客户端文本引擎 + UI 框架 + 性能优化没有 KubeJS 官方绑定;
  • 它自动增强所有原版字体管线渲染的内容,KubeJS 界面文字免费受益;
  • 三种联动姿势:脚本检测(Platform.isModLoaded)→ Java.loadClass 实验 → 桥接模组(正路);
  • 在落英服枪战架构里:KubeJS 管规则、FPSMatch 管框架、Modern UI 管观感,各司其职。

相关资源:ModernUI-MC 源码 https://github.com/BloCamLimb/ModernUI-MC · Modrinth https://modrinth.com/mod/modern-ui · Modern UI 核心框架 https://github.com/BloCamLimb/ModernUI · KubeJS 插件开发(KubeJSPlugin)https://github.com/KubeJS-Mods/KubeJS