跳到主要内容

UiCore

使用着色器在 GUI 空间中绘制菜单、HUD、对话、小地图和名牌,无需客户端模组。

私有v0.1.0-alpha菜单与视觉
依赖TypeWriter0.9.0-beta-177 (BTC build)CraftEnginePacketEventsEntityQuestBTCMobsGUI可选Codex可选BattlePass可选TinyEssentials可选Cosmetics可选Party可选

专为 BornToCraft 服务器网络打造。此扩展仅作参考文档,不对外分发。

概览​

UiCore 在原版客户端的 GUI 空间中绘制菜单、卡片、HUD、对话、小地图和世界地图,无需任何客户端模组。它依靠资源包携带的核心着色器(text.vsh)来实现:绘制的所有内容都是字体字形,着色器会读取字形的 ascent 和颜色,以得知应将其放在固定的 15 乘 15 网格的哪个位置。无论 GUI 缩放、视野或窗口大小如何,结果对每位玩家都完全一致,并且它可以出现在屏幕上的任何位置,而不仅仅是物品栏打开的地方。

UiCore 取代了两个较旧的工具:AdvancedMenus(箱子菜单)和 BetterHud。菜单不再是箱子物品栏:它是一个视图,由你在网页面板中编写的组件图层堆叠而成,玩家用头部瞄准它。同一个网格还用来绘制 HUD 模块、对话行和选项。

该扩展的源码文件夹以旧的 HUD 扩展命名;扩展名称是 UiCore。它运行于 TypeWriter 的 BTC 构建版本,需要 CraftEngine 来托管资源包,并且被标记为 alpha(0.1.0-alpha)。

功能​

  • 视图 — 带有面板、按钮、列表、标签页、子界面、提示、仪表和文本输入的全屏界面。
  • 状态与动画 — 组件会随事实或权限而变化,视图可以以擦除、绽放或淡入的方式出现。
  • HUD 模块 — 锚定在角落或中央的常驻元素,在玩家阅读其他界面时隐藏。
  • 对话 — 用滚轮或光标回应的说话行和选项,共用一个样式条目。
  • 过场动画对话 — 同样的说话行位于过场动画时间轴上。
  • 小地图与世界地图 — 带有兴趣点、路径点和勘测模式的地形图。
  • 名牌 — 用于怪物和玩家的 3D 名牌,带有横幅、等级徽章和 NPC 状态指示器。
  • 横幅与聊天控制 — 屏幕顶部的单行公告,以及在某个地点静音聊天的动作。
  • 物品触发器 — 右键点击某种材质即可打开视图。
  • 集成 — 当存在这些扩展时,显示来自任务、codex、战斗通行证、装饰品、宠物、社交、wiki 和 RPG Core 的数据。

安装​

  1. 安装 CraftEngine:它托管着携带着色器、字体和图片的资源包。如果你的构建版本尚未提供 PacketEvents,请安装它;它用于聊天抑制以及滚轮和移动按键。
  2. 安装 TypeWriter 的 Entity 和 Quest 扩展以及 BTCMobs 扩展:它们是声明的依赖项。
  3. 可选地安装 UiCore 可以读取的扩展:Ghost、Codex、BattlePass、TinyEssentials、Cosmetics、NumericalStorage、Permissions、Pets、Friend、Party 和 Guild。GUI 扩展同样是可选的:当它存在时,UiCore 会读取它发布的菜单状态。
  4. 将 UiCore 的 JAR 放入 plugins/Typewriter/extensions/ 并重启服务器。
  5. 将 UiCore 的资源包片段部署到 CraftEngine 包中。该包由扩展自带的工具生成(generate-gui-pack,然后是 validate-gui-pack),并且必须在与之匹配的 JAR 之前部署,否则每个物品图标都会在没有任何错误提示的情况下偏移一个位置。
资源包标识符

Minecraft 资源标识符只接受 [a-z0-9._-/]。包含任何其他字符的字体提供器会被客户端静默拒绝,并且字形会在屏幕顶部显示为一个黑色矩形。包生成器会拒绝写入这样的路径。

快速上手​

通过指南针打开一个小菜单。

  1. 在 TypeWriter 网页面板中,打开一个**静态(static)**页面,添加一个 UI View 条目。将 viewId 设为 hello_menu。
  2. 添加一个图层(layerId 为 main)和第一个组件:placement.kind 为 CELL,column 为 4,row 为 6,width 为 7,height 为 3,palette 为 SURFACE,hoverPalette 为 BLUE_LIGHT,text 为 Hello,tooltip 为 Click me。
  3. 在 onLeftClick 中,链接一个动作,例如命令或消息。添加第二个组件,使用 navigateTo 或 Close UI View 来离开。
  4. 添加一个 viewId 为 hello_menu 的 Open UI View 动作,或绑定一个物品:添加一个 material 为 COMPASS、viewId 为 hello_menu 的 UI Item Trigger。
  5. 发布。右键点击指南针:界面会出现,用头部瞄准按钮并点击。

工作原理​

视图是一个由图层组成的列表(从后到前);一个图层包含组件;组件说明它位于何处、如何绘制、显示什么,以及点击会触发什么。有三个限制来自编码方式,而不是代码:

  • 着色是一个索引。 一个单元格的颜色携带其列、行和调色板索引,因此着色来自一个固定的具名调色板(SURFACE、BLUE_LIGHT、GOLD……),而不是自由的十六进制值。
  • 图片廉价,字体稀缺。 组件可以用面板图片绘制;任意数量的图片共用一个字体。文字着色来自字体,而资源包自带 16 种文字着色,因此第 17 种会回退为白色。
  • 没有滑动,文字也不会淡出。 动画会按某种顺序显示单元格。文字随其面板一同出现。

当玩家正在坠落时,打开视图的请求会被拒绝(玩家会收到一条消息)。渲染器链(UI Configuration 的 rendererOrder)决定由哪个渲染器来提供视图:GUI(此着色器)、DIALOG、SPATIAL 或 CHEST。

菜单​

打开​

视图可以通过以下方式打开:

  • Open UI View 动作(viewId);
  • 来自 UI View Commands 条目的 /ui open <viewId> 命令;
  • UI Item Trigger,当玩家手持给定材质右键点击时打开一个视图(两个视图认领同一种材质时会被记录为警告,并且只有最后一个会打开);
  • 小地图的 openMaterial,用于打开世界地图。

Close UI View 或 /ui close 会关闭它。

布局与组件​

菜单的网格为 15 列乘 15 行。placement.kind 为 CELL(网格上的一个单元格:column、row、width、height)、MARKER(在视口中从 0 到 1 的位置,x 和 y,会被限制范围)或 SCRIM(全屏遮罩)。按钮需要多个单元格才便于瞄准。

组件字段效果
palette、hoverPalette、disabledPalette静止时、光标下,以及 criteria 不匹配时的着色。
background来自资源包的面板图片(九宫格),取代单一的着色;backgroundBinding 根据占位符选择图片。
text、textPalette、textAlign、textEffect绘制在组件上的文字。
icon、lineIcon绘制在文字之前,或位于行尾的材质图片。
image、imageBinding在组件内按保持纵横比的方式放置的资源包图片。
label、tooltip当光标停留在组件上时,显示在界面旁边或提示锚点处的文字。
gauge根据保存 0 到 100 的占位符绘制一个条(例如 btcui_health_percent)。
binding组件取值所用的占位符。
criteria、onLeftClick、onRightClick点击的条件以及被触发的条目。
navigateTo打开同一视图的另一个界面。
input要求玩家输入一个值;onInputCommands 从控制台运行,其中 {input} 和 %player% 会被替换。

界面、列表与状态​

  • 节点(nodes、rootNodeId)声明标签页和子界面,每个节点选择哪个图层填充哪个命名区域。标题用于面包屑导航。
  • 重复项(图层上的 repeats)在带编号的数据源上绘制一个窗口:第 n 项读取绑定 <source>.<n>。stepMode 为 PAGE 时,每次手势翻转整个窗口,ITEM 则每次移动一项。
  • 状态(states)在条件成立期间更改组件:着色、文字、提示、图标、面板或可见性。条件成立的最高优先级状态就是当前生效的状态,状态可以细化 parentId,组件通过 id 或 column:row 来定位。状态会在每次重绘时重新评估。
  • 进入效果(opening、openingMillis、openingFade):WIPE_DOWN、WIPE_UP、WIPE_RIGHT、WIPE_LEFT、BLOOM 或 FADE。它只在进入界面时播放,而不是在两个界面之间切换时。

调色板​

FRAME、SURFACE、SURFACE_LIGHT、MUTED、BLUE、BLUE_LIGHT、CYAN、TEAL、GREEN、GREEN_LIGHT、YELLOW、ORANGE、RED_DARK、RED、PURPLE、WHITE、BLACK、INK、SLATE、STEEL、STEEL_LIGHT、MIST、PAPER、FOREST、MINT、GOLD、AMBER、WINE、CORAL、VIOLET。NONE 表示不绘制任何内容。

交互​

光标跟随玩家的头部:偏航角和俯仰角被投影到网格上,并吸附到某个单元格。玩家可以通过 /ui sensitivity <degrees> 更改其速度:角度越大,光标越慢。

  • 左键和右键点击会触发 onLeftClick 和 onRightClick;滚轮用于滚动列表和标签页;潜行是关闭视图的快捷方式(研究树列表获得焦点时除外)。
  • 视图会让位于世界:走开、传送、受到伤害或打开物品栏都会将其关闭。
  • 视图打开期间,其他玩家的聊天不会显示在屏幕上,服务器消息会由 UI 聊天而不是原版聊天重新绘制。

HUD 模块​

UI HUD 条目使用与视图相同的图层和组件,锚定在某个 corner(TOP_LEFT、TOP_RIGHT、BOTTOM_LEFT、BOTTOM_RIGHT、CENTRE);偏移量从该角向内计算。priority 决定两个重叠的组中哪个绘制在上方,visibility 则控制该组的显示。当视图、对话、过场动画或世界地图占据屏幕时,HUD 模块会自动暂停。

对话​

UI Spoken Dialogue 显示一行带有说话者名称、可选 portrait、打字 duration(为零则一次性显示)和 sound 的文本。UI Option Dialogue 添加选项(options):navigation 为 KEYS(滚轮和确认键)、CURSOR 或两者兼有(默认);timer 会取消对话并触发 cancelTriggers;每个选项都有 criteria(它会被绘制为锁定状态,或在设置 hideWhenLocked 时隐藏)、锁定期间显示在其提示位置上的 lockedReason、modifiers 和 triggers。两者都接受一个 style 条目;留空则使用服务器自己的样式。

UI Dialogue Style 以网格单元格为单位定义外观:speech(边框、文字区域、说话者横幅、头像)、options(窗口、面板、所选和锁定选项的着色、插入符和滚动箭头、可选的第二列)以及 chrome(确认键图片、倒计时行、黑边行)。UI Spoken Cinematic 通过 startFrame 和 endFrame 片段将文本行放入过场动画页面。

地图与名牌​

常驻的小地图由 Minimap Settings 配置(worlds 和 excludeListedWorlds、size、blocksPerCell、borderThickness、openMaterial、maxWaypoints、worldMapAreas),其兴趣点由 Minimap Points of Interest 配置。它在屏幕上的位置是在资源包中设置的,而不是在这里,因为服务器既不知道分辨率,也不知道 GUI 缩放。世界地图通过右键点击 openMaterial 或使用 /worldmap 打开;日常游玩时,它会根据小地图读取的内容填充,而勘测模式则会有意地绘制更大的半径。

名牌是三维的,并且按观看者区分。Global Nameplate 在怪物上方绘制文本行(entityTypes、btcMobsOnly、lines、viewDistance、requireLineOfSight……)。Player Nameplate Banner 定义可选择的横幅背景(带有 _left、_middle 和 _right 切片的 CraftEngine 图片前缀),玩家的选择存储在选择构件中。Nameplate Settings 设置距离、预算和生命值单位;Level Badge Settings 设置写在等级之前的词(默认前缀,可以是翻译占位符)。NPC Status Override 会在 NPC 上方放置一个指示器模型(可接取、进行中、交互……)。

命令​

命令说明
/ui open <viewId>打开一个视图。
/ui close关闭已打开的视图。
/ui sensitivity [degrees]显示或设置你的光标扫动角度(度)。
/ui icons [materials]在聊天中输出物品图标,以检查精灵字体。
/ui chat vanilla仅限管理员:让你使用原版聊天,直到你断开连接或再次运行它。
/worldmap打开或关闭世界地图。
/worldmap survey、forget、stats、minimap、waypoint <name>、waypoint clear、save、debug勘测模式、忘记你的地图、显示其大小、切换小地图、重命名或清除路径点、保存,以及输出诊断信息。
/nameplates(别名 /nameplate、/btcnameplates)equip <id>、unequip、preview [id]、list、toggle [on|off],以及管理员形式 force-equip、force-unequip、force-preview、admin-toggle。

/ui 和 /worldmap 的名称来自其条目的 commandName 字段。它们的 permission 字段是你选择的权限节点:为空表示所有人。/worldmap survey、forget、save 以及勘测开关使用 surveyPermission。

权限​

权限授予
UI View Commands 的 permission/ui 子命令(为空:所有人)。
World Map Command 的 permission 和 surveyPermission/worldmap,以及勘测和忘记(为空:所有人)。
btcnameplates.command.equip、.unequip、.preview、.list、.toggle面向玩家的对应 /nameplates 子命令。
btcnameplates.command.admin.force_equip、.force_unequip、.force_preview、.toggle管理员的 /nameplates 子命令。
组件和组上的 visibility.permission为没有该节点的玩家显示或隐藏某个元素。

占位符​

MiniPlaceholders 扩展 btcui,用于组件、仪表和文本。

占位符返回
<btcui_level_glyph:37>以资源包的彩色等级数字写出的任意数字。
<btcui_global_level_glyph>、<btcui_global_level>、<btcui_global_level_badge>以字形、数字,或带有配置前缀的形式显示的全局等级。
<btcui_global_percent>、<btcui_global_detail>、<btcui_xp_detail>朝向下一个全局等级的进度及其数值。
<btcui_health>、<btcui_health_max>、<btcui_health_percent>、<btcui_absorption>生命值和伤害吸收。
<btcui_food>、<btcui_food_max>、<btcui_food_percent>、<btcui_saturation>饥饿值。
<btcui_air>、<btcui_air_max>、<btcui_air_percent>、<btcui_air_gauge>氧气供应;当玩家不缺氧时,仪表为空。
<btcui_xp_level>、<btcui_xp_progress>、<btcui_xp_percent>原版经验条(用于附魔)。
<btcui_riding>、<btcui_mount_name>、<btcui_mount_health>、<btcui_mount_health_max>、<btcui_mount_health_percent>、<btcui_mount_gauge>坐骑。
<btcui_underwater>、<btcui_swimming>、<btcui_burning>、<btcui_freezing>玩家状态。
<btcui_x>、<btcui_y>、<btcui_z>、<btcui_world_time>、<btcui_world_day>位置和时间。
<btcui_banner>、<btcui_actionbar>、<btcui_chat:...>由 UI 绘制的当前横幅、动作栏和聊天行。

条目​

26 个条目,由扩展源码生成。

动作5
受众2
对话2
过场动画1
实体数据1
命令2
构件1
清单12

故障排查​

在应当显示文字和单元格的地方出现黑色矩形或方块。 资源包片段缺失、已过期或在 JAR 之后才部署,或者字体路径包含 [a-z0-9._-/] 之外的字符。请先重新部署资源包,再部署匹配的 JAR,并检查 CraftEngine 是否已重新加载它。

物品图标显示了错误的物品。 资源包与 JAR 不匹配:图标的字符就是它在表中的序号,因此在 JAR 之后才生成的资源包会使每个图标发生偏移。请重新生成并验证资源包,然后重新部署两者。

物品打开了一个空菜单。 两个 UI Item Trigger 绑定认领了同一种材质;日志会显示 est reclame par ... 以及各自的组件数量。请移除多余的绑定。

names view '<id>', which no page defines. 传给动作、命令或物品的 viewId 与任何已发布的 UI View 都不匹配。处于 declared but incomplete 状态的视图没有任何可被解析的图层或组件。

菜单无法在半空中打开。 当玩家正在坠落时,UiCore 会拒绝打开界面。请在地面上重试。

聊天消失了。 UiCore 自己绘制聊天:有视图处于打开状态、Mute UI Chat 处于生效状态,或玩家将其关闭了。离开你静音的地点时,请使用 Unmute UI Chat;管理员可以使用 /ui chat vanilla 来检查原版聊天。

手势停止工作。 日志中的 Gesture decoding unavailable 表示 PacketEvents 无法启动:滚轮和移动按键会失效,但点击仍然有效。

相关扩展​