LDLib2 UI — Agent 指南
本文档面向 AI agent。 它提供了使用 LDLib2 构建 UI 的结构化工作流程。 请遵循决策树,使用最小模板,然后根据需要导航到详细页面。
步骤 1:确定语言 / 格式
询问用户他们想要的格式。这决定了所有后续代码的语法。
| 格式 | 何时使用 | 语言专属文档 |
|---|---|---|
| Kotlin | 使用 Kotlin DSL 进行模组开发(最简洁) | kotlin_support.md |
| Java | 使用 Java 进行模组开发 | getting_start.md |
| KubeJS | 整合包脚本,无需编译 | kjs_support.md |
| XML | 声明式 UI 结构,可视化编辑 | xml.md + XSD 模式 |
XML 注意: XML 仅定义 UI 树和样式。你仍然需要 Java/Kotlin/KubeJS 代码来加载 XML、进行数据绑定,并将其包装在
ModularUI中。请引导 agent 阅读 XSD 文件以了解可用的标签和属性。
步骤 2:确定 UI 类型
关键规则: 如果 UI 需要 Player 数据或服务端状态,它必须是基于 Menu 的 UI 并使用 ModularUI.of(ui, player)。
步骤 3:最小模板
每个模板都是一个完整的、可运行的起点。选择匹配步骤 2 的一个。
仅客户端 Screen
ModularUI createUI() {
var root = new UIElement().addClass("panel_bg").addChildren(
new Label().setText("Hello")
);
return ModularUI.of(UI.of(root, StylesheetManager.INSTANCE.getStylesheetSafe(StylesheetManager.GDP)));
}
// 打开:Minecraft.getInstance().setScreen(new ModularUIScreen(createUI(), Component.empty()));基于 Menu 的 UI(服务端同步)
对于 Menu UI,请使用内置工厂。详见 factory.md。
public class MyBlock extends Block implements BlockUIMenuType.BlockUI {
@Override
public ModularUI createUI(BlockUIMenuType.BlockUIHolder holder) {
var root = new UIElement().addClass("panel_bg").addChildren(
new Label().setText("Block UI"),
new InventorySlots()
);
return ModularUI.of(
UI.of(root, StylesheetManager.INSTANCE.getStylesheetSafe(StylesheetManager.GDP)),
holder.player
);
}
// 打开:BlockUIMenuType.openUI((ServerPlayer) player, pos);
}其他触发器: 将
BlockUIMenuType替换为HeldItemUIMenuType(物品)或PlayerUIMenuType(任意)。详见 factory.md。
HUD Overlay
// 仅客户端。在 RegisterGuiLayersEvent 中注册。
var muiCache = Suppliers.memoize(() -> ModularUI.of(UI.of(
new UIElement().layout(l -> l.widthPercent(100).heightPercent(100).paddingAll(10))
)));
event.registerAboveAll(MyMod.id("my_hud"), (ModularHudLayer) muiCache::get);详见 hud.md。
基于 XML 的 UI
<?xml version="1.0" encoding="UTF-8" ?>
<ldlib2-ui xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="https://raw.githubusercontent.com/Low-Drag-MC/LDLib2/refs/heads/1.21/ldlib2-ui.xsd">
<stylesheet location="ldlib2:lss/mc.lss"/>
<root class="panel_bg">
<label text="Hello from XML"/>
<button text="Click me"/>
</root>
</ldlib2-ui>// 加载并使用
var xml = XmlUtils.loadXml(ResourceLocation.parse("mymod:my_ui.xml"));
var ui = UI.of(xml);
// 查询元素:ui.select("#my_id"), ui.select(".my_class > button")
return ModularUI.of(ui, player); // 仅客户端用 ModularUI.of(ui)关于 XML 自动补全和验证,请阅读 XSD 模式 以了解所有可用的标签、属性和结构。
步骤 4:数据绑定模式
这是生成正确 UI 代码最关键的知识。共有 3 种模式:
模式 A:仅客户端(无服务端同步)
使用 bindDataSource / bindObserver 或 Kotlin 的 dataSource / observer。不涉及网络。
// 消费者:显示动态数据
new Label().bindDataSource(SupplierDataSource.of(() -> Component.literal("Value: " + myVar)));
// 生产者:响应用户输入
new TextField().bindObserver(value -> myVar = value);模式 B:双向同步(Menu UI)
使用 DataBindingBuilder + .bind()。仅服务端 getter/setter —— 客户端自动处理。
new Switch().bind(DataBindingBuilder.bool(() -> serverBool, v -> serverBool = v).build());
new TextField().bind(DataBindingBuilder.string(() -> serverStr, v -> serverStr = v).build());
new ItemSlot().bind(itemHandler, 0); // 物品栏简写
new FluidSlot().bind(fluidTank, 0); // 流体简写Kotlin 简写:switch { bind(::serverBool) },textField { bind(::serverStr) }
模式 C:服务端到客户端只读
使用 S2C 变体。客户端无法修改该值。
new Label().bind(DataBindingBuilder.componentS2C(() -> Component.literal(serverData)).build());Kotlin:label { bindS2C({ Component.literal(serverData) }) }
对于复杂绑定(自定义类型、RPCEvent、列表同步、远程 getter/setter):请阅读 data_bindings.md。
步骤 5:导航地图
使用此表按需求查找详细文档。
核心概念
| 需求 | 阅读 | 路径 |
|---|---|---|
| ModularUI 的工作原理 | ModularUI | docs/ldlib2/ui/preliminary/modularui.md |
| Screen 与 Menu 的区别 | Screen & Menu | docs/ldlib2/ui/preliminary/screen_and_menu.md |
| UI 工厂(方块/物品/玩家) | Factory | docs/ldlib2/ui/factory.md |
| 布局(flexbox、grid、size、padding) | Layout | docs/ldlib2/ui/preliminary/layout.md |
| 样式表 / LSS | Stylesheet | docs/ldlib2/ui/preliminary/stylesheet.md |
| 事件(鼠标、键盘、生命周期) | Events | docs/ldlib2/ui/preliminary/event.md |
| 数据绑定与 RPC | Data Bindings | docs/ldlib2/ui/preliminary/data_bindings.md |
| 样式动画 | Style Animation | docs/ldlib2/ui/preliminary/style_animation.md |
| HUD 覆盖层 | HUD | docs/ldlib2/ui/hud.md |
| XEI(JEI/REI/EMI) | XEI | docs/ldlib2/ui/xei_support.md |
| XML UI | XML | docs/ldlib2/ui/xml.md |
| Kotlin DSL | Kotlin | docs/ldlib2/ui/kotlin_support.md |
| KubeJS 绑定 | KubeJS | docs/ldlib2/ui/kjs_support.md |
组件速查表
| 组件 | 类 | 关键方法 | 文档 |
|---|---|---|---|
| 基础元素 | UIElement | .layout(), .style(), .addClass() | element.md |
| 标签 | Label | .setText(), .bind() | label.md |
| 按钮 | Button | .setText(), .setOnClick(), .setOnServerClick() | button.md |
| 文本框 | TextField | .setText(), .bind(), .setNumbersOnlyInt() | text-field.md |
| 文本域 | TextArea | .setText(), .bind() | text-area.md |
| 开关 | Toggle | .setText(), .bind() | toggle.md |
| 切换开关 | Switch | .bind() | switch.md |
| 选择器 | Selector | .setCandidates(), .bind() | selector.md |
| 进度条 | ProgressBar | .setProgress(), .bind(), .label() | progress-bar.md |
| 滚动条 | Scroller / Scroller.Horizontal | .bind() | scroller.md |
| 物品槽位 | ItemSlot | .bind(handler, slot), .setItem() | item-slot.md |
| 流体槽位 | FluidSlot | .bind(tank, slot), .setFluid() | fluid-slot.md |
| 物品栏槽位 | InventorySlots | (自动玩家物品栏) | inventory-slots.md |
| 标签页 / 标签视图 | Tab, TabView | .addTab() | tab.md, tab-view.md |
| 开关组 | ToggleGroup | .addToggle() | toggle-group.md |
| 滚动视图 | ScrollerView | (可滚动容器) | scroller-view.md |
| 分割视图 | SplitView | (可调整大小的分割) | split-view.md |
| 颜色选择器 | ColorSelector | .bind() | color-selector.md |
| 标签字段 | TagField | .bind() | tag-field.md |
| 搜索 | SearchComponent | .bind() | search-component.md |
| 树形列表 | TreeList | — | tree-list.md |
| 场景(3D) | Scene | — | scene.md |
| 图形视图 | GraphView | — | graph-view.md |
| 代码编辑器 | CodeEditor | — | code-editor.md |
| 检查器 | Inspector | — | inspector.md |
| 模板 | Template | (从 XML 加载) | template.md |
| 可绑定值 | BindableValue<T> | .bind()(隐藏同步辅助) | bindable-value.md |
| 富文本 | Text | .setText() | text.md |
纹理速查表
| 纹理 | 类 | 文档 |
|---|---|---|
| 精灵图(图像) | SpriteTexture | sprite.md |
| 颜色矩形 | ColorRectTexture | color-rect.md |
| 颜色边框 | ColorBorderTexture | color-border.md |
| SDF 矩形 | SDFRectTexture | sdf-rect.md |
| 资源矩形 | RectTexture | rect.md |
| 物品堆叠 | ItemStackTexture | item-stack.md |
| 流体堆叠 | FluidStackTexture | fluid-stack.md |
| 文本 | TextTexture | text.md |
| 动画 | AnimationTexture | animation.md |
| 组 | GroupTexture | group.md |
| Shader | ShaderTexture | shader.md |
| UI 资源 | UIResourceTexture | ui-resource.md |
| LSS 纹理语法 | — | lss.md |
步骤 6:完成前检查清单
在将代码返回给用户之前,请验证:
- [ ] UI 类型匹配需求:仅客户端 Screen 没有
player参数;Menu UI 有player参数 - [ ] 数据绑定正确:服务端数据使用
DataBindingBuilder.xxx().build()+.bind();仅客户端数据使用bindDataSource/bindObserver - [ ] 工厂已注册:Menu UI 需要工厂注册(方块/物品/玩家)或手动 MenuType
- [ ] KubeJS 脚本放置位置:
LDLib2UI.*处理器必须在两侧运行 —— 建议放在startup_scripts/ - [ ] XML 文件 放在
assets/<modid>/ui/下并通过ResourceLocation加载 - [ ] 样式表已应用:使用
StylesheetManager.GDP、.MC或.MODERN作为内置主题,或提供自定义 LSS - [ ] 输出格式匹配请求:完整 UI 返回
ModularUI,可复用组件返回UIElement