跳到主要内容

界面、HUD 与本地化

通知 HUD 位置编辑​

直接使用 Saturn 自带的 HUD 编辑入口:默认在游戏中按右 Shift 打开 HudEditScreen,也可以用 /saturn hud open。系统不另加设置页入口或按键。SystemHudEntries.NOTIFICATIONS 在物理客户端初始化时登记为 system.notification,由 NotificationHudEntry 连接 Saturn 放置逻辑与 AUI 通知。拖动外框移动,拖过窗口边缘锚点可更换参照点;选中后用方向键微调,Shift + 方向键移动 10 像素,右上角勾选框控制显隐。完成返回游戏。通过 /saturn hud system.notification reset 恢复默认锚点及偏移。

位置、锚点和显隐由 Saturn 写入本机 config/saturn/hud.json,不在 config/system 重复保存。默认保持水平居中、距离底部 6% 的位置;内容变化时底部锚点保持不变,高度向上增长。宽度和最大高度仍由共享 CSS 控制,编辑器只移动位置,不缩放通知。其他锚点使用 Saturn 的定位及窗口边界钳制,GUI 缩放和 AUI 文档缩放通过 GUI ↔ 文档坐标转换处理。

编辑器用 Saturn 原生绘制接口显示简化的被动预览框,不创建通知、不处理业务按钮、不触发提示音或 TTS;没有活动通知时也能编辑。标题统一由 Saturn 在框外绘制,框内不重复显示;常驻卡片预览仅保留简短占位文案。尺寸使用最近一条通知的已提交布局,尚无通知时使用默认示意高度。真实通知仍走原有 AUI 文档及共享 CSS,按钮只在聊天栏交互,展开/淡入动画和消息队列逻辑保持原样。隐藏通知暂停显示并取消当前语音,不清空队列;重新开启后恢复当前消息。

共享的 AuiHudEntry.apply 只读取根面板已提交的原始尺寸,不使用 scaleX 动画后的视觉边界,也不发起递归几何测量。只在面板实例或放置结果变化时写入 left/top/bottom,不改 transform、不平移 AUI 视口。注册入口仅由 SystemModClient 引用,专用服务端不加载 HUD 编辑器或 AUI 类型。

通知和常驻卡片在 body 上声明 system_hud,共享 CSS 将 HUD 的背景色、背景图、阴影和背景滤镜清空,并隐藏根装饰伪元素。AUI 1.2.9 的 HTML.normalizeDocumentMarkup 会丢弃原始 html 标签属性,不能依赖模板中的 html class:AssistantThemes 在实际文档根节点补上同一标记,body 的透明规则则在首次加载共享 CSS 时直接生效。只保留通知面板和任务卡片自身的背景,普通页面继续保留原有遮罩。

常驻卡片 HUD​

SystemHudEntries.DISPLAY_CARDS 登记为 system.cards,与通知分别定位、分别控制显隐。默认左侧 4 GUI 像素、距顶部 22% 高度;共享 CSS 限宽 min(360px, 38vw),高度不设上限,卡片按内容向下排列,不生成滚动条。Saturn 定位同步使用实际内容高度。使用 Saturn 编辑器拖动“常驻卡片”,或 /saturn hud system.cards reset 重置位置;布局仍写入 Saturn 的 hud.json,没有新的编辑入口或本模组位置配置。

固定任务由服务端核心 DataStorage 持久化并刷新进度,客户端只保存镜像。完整任务列表、详情和常驻卡片的图钉共享状态。按聊天键后可以查看 tooltip 和取消固定;打开其他界面时立即清除交互,默认保留被动绘制到退出动画完成后再卸载,避免挡住背包按钮。可在设置中启用其他界面显示。F1 或登出时仍立即卸载。编辑器仅绘制被动预览,不创建真实卡片或请求任务数据。该 HUD 没有确认按钮、自动跳转或播报,通知队列继续独立工作。数据流与扩展入口见常驻卡片。

启用动画时,常驻卡片按 Saturn 锚点决定出入方向:左侧左进左出,右侧右进右出,上下居中时按所在屏幕半边选择。包装层使用 280ms 的 transform 过渡和 180ms 的 opacity 过渡,不修改宽高或定位;原生首次布局完成后才显示。取消固定、需要隐藏的界面切换、隐藏 HUD 或数据不可读时等待退出结束再删除,退出过程中返回游戏或恢复数据则反向进入;进度更新保持包装层,不重播动画。ScreenEvent.Opening 立即更新显示目标和交互状态,鼠标输入前也复核可交互状态;需要隐藏时文档以 AUI persistent overlay 在新界面上完成退出,退出期间不创建新卡片。

“设置 → 常规 → 常驻卡片”提供两个客户端开关,修改后立即生效并保存到 config/system/system-client.json:cardAnimations 默认 true,关闭后出入直接切到最终状态,运行中的动画也会取消;cardsOnOtherScreens 默认 false,开启后在背包、箱子等游戏内页面继续显示、刷新卡片,便于对照物品,设置和暂停菜单等页面仍隐藏。正常游戏和聊天栏始终允许显示;其他页面只接受 Screen.isInGameUi() 返回 true 的界面,不以 isPauseScreen() 或游戏是否实际暂停分类。聊天栏需单独允许,因为原版没有覆盖其 isInGameUi()。其他游戏内页面只展示,不启用卡片鼠标命中;HUD 编辑器始终使用自身预览,F1、登出和 Saturn 显隐仍优先。切换模式或主题会保留这两个配置。

界面结构与交互​

各功能的本地指令、控件、页面与本地动作由 ClientModule 贡献;业务卡片的文字、按钮和播报由对应 CardData.buildCard 一次描述,不再登记客户端卡片行为表。完整模式始终显示对话,侧栏直接排列模块入口,不再显示分组标题或“对话”按钮;用量统计和设置位于右上角。导航仍来自 workspace 声明,可用性由服务端同步的模块 ID 控制。扩展入口见功能模块化。

JSON 模板在 assets/system/cards 中,通过 CardNode 的 dispatch Codec 解析;CardPresentation 统一构建本地展示。Context 的状态、参数和回调三表平铺,CardBuilder/组件会复制不可变快照。仅单个纯文本节点且没有按钮和额外内容时显示为普通消息;文字带按钮仍是卡片。简约模式使用文字编号选择,HUD 正文显示 BODY 按钮,FOOTER 由代码生成;资源包只控制布局。格式见客户端 JSON 卡片。

任务格子、商店、奖池与奖品预览共用 CardGrid / CardPagination,最大三行,按当前模式的列数自动计算每页容量:完整模式 18 项、通知 9 项。只创建当前页节点,避免长货架一次构建过多 DOM 和原生图标;结果少或到了最后一页仍保留三行区域与分页栏,不能翻页的方向置灰。分页与通知底部确定按钮分开,不发送请求、不切换通知或重播语音;具体字段和扩展方式见共用分页网格。

任务格子的格式化标题通过居中的 flex 包装层排列颜色片段,片段使用受宽度限制的 block 文本框,兼顾单行与换行居中。AUI 1.2.9 对嵌套 inline 片段不应用整行 text-align,仅给外层设置 center 无效;这里的覆盖只作用于任务格子标题,不改变普通正文和其他卡片的格式化文本。

所有界面共用 assets/apricityui/apricity/system/assistant.css 的布局与组件样式,并加载当前选择的 AUI 主题。完整界面使用同目录下的 assistant.html,由 AssistantScreen 承载。默认使用青蓝半透明面板、细边框和暖金色重点色;模块工具栏位于对话记录下方、输入框上方,点击当前模块入口可收起,关闭时不重复触发查询。

设置“常规”页嵌入 AUI 原生 <theme-switcher>,接收其 aui-theme-change 事件;AssistantThemes 将主题 ID 写入 ClientConfig 并立即保存到 config/system/system-client.json。AUI 本身只切换当前文档,本模组在页面初始化及资源重载后应用已保存主题,并同步现有的 system/ 活动文档,覆盖完整、简约、设置、用量页面和 HUD。主题样式加载成功后才替换旧主题,过期的异步结果不能覆盖新选择;通知交互状态只增删自身状态类,保留主题作用域。HUD 根背景及装饰伪元素固定透明或隐藏,主题只绘制通知面板。其他模组的页面不受影响。

固定文案直接写在模板里,用 AUI 的 <translation>键</translation> 承载,由文档在布局和绘制时按当前语言解析,不再由 Java 逐个元素写入;模块工具栏按钮、标题和说明因此随模板走,自定义模板只需替换标记就能自带上这些文案。只有随状态变化的文本(status、send、asr_toggle、设置页状态、usage_scope、usage_page、区域名、识别后端名)、输入框占位符(placeholder)、aria-label 以及语种下拉选项仍由 Java 提供,因为这些是属性或运行时取值,节点文本无法表达。子节点文本就是完整键,不能带首尾空白;键缺失时与原版一致直接显示原键。AUI 的 text-align 只作用于元素自身的直接文本,内容区被拉伸又需要居中的按钮(.settings_tab、.settings_modes button)改为 display:flex + justify-content:center,与已有的 .shop_controls button 一致。

每日签到工具栏采用紧凑的日历标记、小标题、奖励去向说明和右侧签到按钮;窄窗口允许换行。标题和说明使用元素 ID 限定字号与间距,避免主题的大标题样式把底部操作区撑高。文案不预先断言今日是否已签到,重复签到仍由服务端返回已有记录。

对话滚动区使用单列 grid 和 safe end 对齐,内部普通文档流容器承载消息,让短对话靠近输入区、长对话仍可从顶部滚动。内容或工具栏变化前记录已提交的滚动位置,统一渲染边界完成新布局后再恢复;原本位于底部时跟随新消息,向上阅读历史或仍在向上滚动时保留当前及目标位置,不把偏移直接设成内容总高度。

完整模式的新消息以 240ms、18px 的上移配合淡入出现,只使用 transform / opacity,不逐帧改变卡片高度。底部跟随复用 AUI 的目标滚动缓动,连续到达的消息更新目标位置,向上翻阅时不强制拉回底部。首次打开、窗口重建与模板重载不重播历史入场动画;仅忙碌状态变化时保留已有消息节点,卡片更新按 UUID 识别,不视为新消息。

新行先以无过渡的 message_new 完成首次布局,再切换为 message_entering 播放动画,结束后清除动画类。普通按钮仅过渡背景、文字和阴影,覆盖原生主题附带的 transform / border-color 过渡;边框颜色仍随状态即时变化,避免 AUI 将边框颜色插值误判为布局变化。图钉保留倾斜 / 竖直状态但不做旋转插值,避免新任务列表逐按钮触发尺寸测量。采样依据见页面布局审计。

滚动范围通过 AssistantGeometry 读取已提交的 scrollHeight、Rect 和盒模型边距,不调用 Box.innerSize / Size.of 或滚动范围探测 API 重测子树。prepareRender 仅由原生 AUI 绘制调用;AssistantPageScreen 在提取阶段观察布局是否已完成,输入框、补全与 HUD 定位只读取有效几何,未就绪时等待后续帧。滚动恢复单独开启 GeometryQueryScope,保留 setScrollTop 注册缓动的行为。翻页、折叠、切换章节及图钉更新只排队失效,不在事件内同步重排。完整与简约页面保留未变的卡片,常驻 HUD 只替换内容变化的卡片;空闲轮询不重复写入相同的文字、display 或交互 class。依据和未验收范围见页面布局审计。

客户端“系统”按键映射默认未绑定;玩家可在控制设置中自行分配。游戏内按下打开当前选择的完整或简约界面,任一助手系统页面内再次按下即可返回游戏;其他游戏页面不受影响。

页面初始化保留 AssistantPages.prepare,在创建文档前按实际视口预热模板引用的本地 CSS;仅等待 DOM 的 readyState 不足以等待外部样式。完整、简约、设置与用量界面共用 AssistantPageScreen,在文档上下文中申请主题、绑定监听器和填充内容,后续布局由原生 AUI 处理。空草稿不设置光标范围;非空草稿等待原生布局完成后再定位,防止 AUI 的光标滚动计算提前触发整页测量。完整页面外壳使用定位边界划分侧栏与主区域,body 不参与 flex 测量;聊天区内部保留原有弹性布局。补全弹层的变动排队交给下一次原生提交,不在提取阶段额外驱动布局、动画或滚动。HUD 通知复用样式预热,保留隐藏状态的样式起点及原有展开、淡入动画。

HUD 通知使用视口固定定位,宽度保持 min(840px,94vw),默认底边为 6vh,位置由 Saturn HUD 布局管理;正文换行,正文、任务行和物品统一在滚动区内查看,滚动区高度最多约为 10 行正文,面板本身最高为视口的 64%,超出内容滚动且保留底部操作。横向缩放动画只负责展开与收起。鼠标内部监听挂在通知面板上,仅聊天栏打开且当前通知完全可见时主动消费事件;AUI 普通监听器即使回调未执行操作也会将事件标为已消费,因此不能用普通监听器承担这层条件判断。每次刷新交互状态清除 HUD 键盘焦点,不可交互时清除按下状态,队列收起完成后移除文档。

AUI 的全局鼠标释放键由依赖自身管理,系统不再通过 Mixin 过滤或扫描其他 AUI 文档。通知与常驻卡片仍通过原版聊天栏交互。语音按键的保持状态与输入所有权分开:只有当前录音 session 尚未完成、仍活动且属于当前界面时才抑制字符,失焦或离开世界会清理保持状态。以上依据源码及静态检查,未启动游戏验收。

助手名称和介绍来自当前连接同步的 system:system 注册表,完整界面的标题/欢迎区、简约界面的说话人/空闲介绍和 HUD 通知共用 AssistantClient.system()。两个字段都是翻译键,在客户端解析;绑定文案的参数依次为宿主名、系统名称和介绍,播报只读取宿主名及系统名称。数据包不会下发语言文件,自定义翻译需配套资源包,格式见系统定义。

共享样式将文字、面板、边框、按钮、强调色、圆角与字体接到 AUI 主题变量;完整界面、简约模式、HUD 消息和用量账本使用同一套映射,布局差异通过 body.simple、body.notification 和 body.usage 调整,不使用独立样式文件。默认 t09-arwes-transparent 同时启用 t08-arwes 基础作用域,保留原先较深的主面板与暖金色重点,其他主题按自己的色板显示。样式不依赖外部工程路径。

字体优先使用所选 AUI 主题的 --font-body;主题没有提供时,回退到客户端已安装的微软雅黑 UI、微软雅黑、思源黑体/Noto Sans、苹方及通用无衬线字体。共享样式的结果正文为 14px,辅助说明至少 12px,标题和按钮使用 600 字重;主题也可提供自己的排版规则。本模组没有附带字体文件,不同操作系统的实际字形可能不同。

完整界面与简约模式通过 AssistantInputScreen 同步 AUI 输入框焦点和 Minecraft 26.1 的文本输入状态,避免游戏在每 tick 将输入法关闭。消息、物品搜索和商城搜索框都接入同一逻辑;失焦、关闭界面、切换模式或重建文档时释放文本输入状态,不强制切换系统语言。输入法预编辑文本使用 Minecraft 原生浮层,候选区域按 AUI 文档坐标转换到 GUI 坐标后定位在当前输入框附近;已确认的文字继续交给 AUI 的原有字符事件处理。

组合输入期间只由原生预编辑浮层设置候选区域,避免界面与浮层每帧提交不同矩形造成闪烁。未组合输入时只在输入框位置或 GUI 缩放变化后更新区域。AUI 的 blur 发生在焦点切换提交之前,因此等待切换完成后同步;不同可编辑输入框之间移动时保持输入法会话开启。

完整界面与简约界面的消息框均为单行 <input type="text">,打开时自动聚焦,Enter 或小键盘 Enter 与发送按钮共用一条提交路径;物品与商城搜索框的 Enter 分别触发对应搜索。按住 Enter 不会重复发送,等待响应或空白输入不清除草稿。原生输入法组合期间及结束后 150ms 内不执行发送、补全或方向键选项切换,确认候选时不失焦;补全弹层在组合期间隐藏。

AssistantCommandSuggestions 在客户端按前缀提供英文字指令、中文别名、/system 前缀、开关参数以及当前回复中的选项编号和任务名称,不调用网络或模型;未接入 FTB 时隐藏任务类固定指令。AssistantInputScreen 只在消息框聚焦、光标位于末尾且没有文本选区时显示补全,每次展示最多 6 行;上下键切换,Tab 或点击只填写草稿,Enter 才执行,Esc 收起列表。补全节点是 body 的直接子节点,使用独立 fixed 弹层,不参与输入区或面板的尺寸计算。候选重建时先隐藏,渲染阶段按输入框边界定位在其上方,使用所属文档的 CSS 像素并限制可用高度;位置未变化时不重复写样式。布局查询、物品 tooltip 与输入法热区计算都在 Document.withContext 作用域内完成,避免混用其他文档或窗口的视口尺寸。弹层沿用唯一的 assistant.css;候选内容通过纯文本设置,点击补全恢复原输入焦点,不重启输入法会话。

简约界面使用 assistant-simple.html,由 AssistantSimpleScreen 承载:底部说话框、当前请求、当前回复和输入区;颜色与字体跟随共享主题。面板使用 fixed 定位,水平居中、底边固定在 6vh,不依赖 body 的 flex 末端对齐,补全出现、收起或候选变化不会推动面板。只读取客户端单独的 current 快照,不遍历对话列表,不加载历史;所有业务选项展平为连续编号,以 选择 1 或 /select 1 执行同一服务端动作。它只有发送按钮,其余功能使用文字或指令。

绑定提示、事件、服务端通知和界面关闭后的回复统一由 AssistantMessages 管理,使用 assistant-message.html 和同一份 assistant.css。通过 Document.create 注册普通 AUI 文档,由 AUI 自带的 HUD 层渲染;消息本身没有 Screen、输入框或额外渲染层,也不申请鼠标释放、输入焦点或输入法会话。页面背景全透明,通知宽度保持 min(840px,94vw),默认底边为 6vh,编辑后采用 Saturn 锚点与偏移;正文与附加列表超长时在通知框内滚动,滚动区最多约 10 行正文高。

正常游玩时整棵 DOM 禁用指针命中,按钮可见但不接受操作;进入原版 ChatScreen 后,使用 body.notification.interactive 仅开启面板及其后代的命中。模板使用 aui-mouse-events=passthrough,不按文档命中自动拦截原版事件,由面板内部监听器按交互状态显式调用 consumeNative()。指针命中规则使用 !important,避免主题重新启用被动 HUD 的命中。打开背包等非聊天界面立即移除通知文档;鼠标按下、释放和界面滚轮事件在 AUI 全局输入分发前再次检查实际界面,移除不该存在的 HUD,避免残留文档挡住 FTB 侧栏等原生控件。点击时清除 AUI 焦点,避免后续空格/Enter 被按钮吞掉;关闭聊天立即关闭指针命中并禁用按钮,保留同一文档和动画进度。提示从 options.keyChat 读取聊天键名,默认 T,用户重绑后自动更新。

启用语音输入后,可在通知完全展开时按住语音键(默认 F8)操作当前按钮,无需进入聊天栏;提示同时显示实际绑定键名。按钮使用固定本地化文案键,例句与缓存向量按当前按钮集合匹配,支持“确定”“关闭”“查看任务详情”“领取奖励”等;鼠标与语音共用同一执行入口。录音与等待识别时保留当前通知,并在 notification_voice 显示状态及中间文字;不申请输入焦点。匹配不足或按钮歧义时打开主聊天并复用正常路由;动作忙碌时在通知内提示。隐藏、切换、确认和登出都会取消原通知的识别,详见语音输入。

面板通过共享 CSS 的 transform: scaleX(...),以水平中心为原点在 240ms 内向左右展开或收缩,不改变布局宽度和文字换行。标题、正文、按钮和提示统一放在 notification_content,以 160ms 的 opacity 过渡淡入淡出。AssistantMessages 以六个阶段管理顺序:隐藏、展开、淡入、可见、淡出、收缩,每步通过 AUI Transition.isActive 等待上一动画结束。首次打开先展开,再淡入;确认、关闭或明确操作触发替换时先淡出,内容全透明后才替换为下一条并淡入,连续通知保持面板展开。可见阶段没有倒计时,播报结束不切换通知。队列清空时,淡出后再收缩并卸载;淡出期间收到的新消息直接接续,收缩期间收到新消息则反向展开后淡入。动画阶段不接受按钮交互。鼠标事件每次文档 refresh generation 只注册一次,切换消息不重复挂载监听器。其他界面、F1、登出和显式清理仍即时隐藏或卸载,保留原有焦点及生命周期边界。

每条消息总有“确定”,绑定另有“打开系统”;业务通知从服务端结果提取可信动作,并可提供“查看详情”。确认会移除当前项,服务端按钮默认等待直接回复后原位替换当前通知,其他排队项保持顺序;礼包领取保留当前列表,由回包静默刷新,全部领取后才移除。业务动作保留原模块与输入,仍由服务端授权校验,助手忙碌时禁用。本地按钮按声明关闭或保留通知。没有模型生成的 HTML 或可执行脚本。

任务列表的详情动作单独渲染在 notification_choices,逐行显示完整列表的连续编号、名称、章节和进度,不占用底部两个业务按钮名额;底部保留“查看详情”和“确定”,任务列表不再提供“下一页”。列表沿用共享 CSS,按 T 后可滚动并点击任意一行,忙碌与动画阶段禁用;行操作仍引用对应的服务端可信动作,语音遇到同名详情动作时走原有歧义回退。消息去重同时比较行文案与动作,避免不同任务列表因正文说明相同而被合并;切换通知时重置列表滚动位置。

通知框首次由隐藏进入展开阶段时播放原版注册音效 system:notification,结束后才开始正文播报;合成在提示音期间并行准备。连续通知只切换正文,收缩中途反向展开也不重复提示音,完全收起后下一轮才重新提示。提示音为播报音量的 75%,共用 Voice 分类与当前消息 session,关闭、隐藏或切换通知时同时停止。提示音不要求开启自动朗读或配置云端密钥;恢复通知和刷新文档不重复播放,详见 语音合成与音色设计。

只有服务端成功持久化新绑定后才入队“叮!恭喜宿主,系统绑定成功”的固定通知,正文使用实际系统名称、宿主名称与系统介绍;左上角黄色标题始终为本地化的“系统”。播报保留“叮!”及实际系统名称和介绍,不读固定标题。不额外推理、不虚构初次绑定奖励,重复授予显示已绑定提示。队列依次显示,按卡片 ID 去重,最多等待 32 条,满载丢弃最早等待项。绑定与普通通知均持续保留,直到明确操作或服务端更新;其他界面或 F1 时卸载文档,恢复后重建同一通知,避免与简约界面重叠。资源重载后按文档 refresh generation 重新填充文本与按钮。若模板损坏,则回退到聊天消息并释放该项,避免逐 tick 重试。

正文保留完整内容,长文本、任务列表与物品列表在限定高度内分别滚动,不再按 360 码点或 6 行截断。事件与管理通知记入工作台会话,但不覆盖当前交互结果或其编号。客户端消息队列没有独立持久化或历史界面,登出、成功撤销时清理活动文档及等待项,撤销提示随后单独入队。

FTB 任务完成与新任务解锁复用同一 event 路径,使用 system.result.quest_completed / system.result.quest_unlocked 双语模板,卡片带任务标题、章节及既有 system:quest_detail 动作。完成通知按各玩家当前可领奖励增加固定“领取奖励”按钮:唯一普通奖励直接领取,多项或自选奖励显示选择详情。一个任务一条消息,完成项先入队、随后解锁项依次入队;不覆盖简约界面当前回复。详情及领取均可通过按钮或通知语音明确操作,沿用原有授权与引用校验。

已解锁且未完成、剩余目标全为原生勾选目标的任务,在解锁通知和详情卡片增加固定“完成此任务”动作,简约模式同样列入编号选项。通知语音例句按 system.action.complete_quest 注册;点击与语音共用 system:quest_submit 的仅勾选模式,由服务端重新检查当前条件,不消费物品或经验,不跳过真正锁定的前置任务,完成后只显示原有完成通知。

仅在新绑定成功后,按“绑定消息 → 可领取的新手礼包 → 当前可推进任务概览”的顺序加入通知队列;全部匹配礼包汇总为一条通知,缺少礼包或任务时跳过。概览显示普通可推进任务的总数及前三项,用“查看任务”重新读取完整滚动列表,不把已有任务逐条当作新解锁。重新登录、重复授予、换队或重载不重复触发引导,撤销后重新绑定可以再次触发。介绍任务从所有系统读取入口过滤;符合条件的勾选物品任务按来源分组呈现全部奖励,不展示或播报来源任务名、章节或 ID,沿用物品渲染、tooltip、滚动和语音 session。“查看礼包”读取同一完整列表,“领取礼包”按可信引用批量处理;成功后静默更新,移除已领取项,失败保留在列表中,不追加成功提示或普通任务完成通知。新解锁礼包按每批每玩家汇总一次。

用量账本使用 assistant-usage.html 与 TokenUsageScreen,继续只加载 assistant.css。AI 汇总和玩家明细通过独立网络载荷读取,普通玩家仅查看自己,管理员可查看全服,服务端每次查询重新校验权限。TTS / ASR 面板始终显示当前账号的本地记录,实时更新,不上传服务端,不混入其他玩家行或全服汇总。查看不依赖绑定、不进入对话、不占用模型;统计口径与存储路径见用量统计。

保留的是视觉风格。旧的绑定页、数据驱动功能列表、旧 HUD、世界窗口与旧完成弹窗没有继续使用。/system 打开后同步个人偏好;自动通知统一使用上述 HUD 消息,不抢占游戏焦点。

玩家、FTB 和物品文本继续通过 AssistantView.text/element 写入纯文本节点,FTBQ 的 § / & 格式由 text 节点处理。AI 知识问答与联网答案改用独立的 system:markdown 节点:复用 AUI 内置解析器,再由 AssistantMarkdown 的被动读取器仅重建预设展示元素、纯文本与原版 URL 点击动作,不把模型 HTML、属性或脚本直接插入 AUI。外部图片只保留 alt 文字,不下载;共享 CSS 统一 Markdown 的标题、列表、引用和代码样式。动作按钮和文字编号仍由 Java 根据业务结果创建,携带固定模块和输入;服务器继续重新校验。详见Markdown 正文。

FTBQ 标题、章节、说明、目标及奖励中的原版 § 格式和 FTB 常用的 & 格式由共享 AssistantText 处理,完整界面、简约模式、HUD 正文及任务按钮共用一条路径。FTBQ 服务端标题保留原始文字,未进行客户端富文本解析;LegacyText 先把有效的 &0~&f、&k~&o、&r 转成原版格式码(大小写均支持),保留未知码和转义的普通与号,再复用原版 StringDecomposer.iterateFormatted。显式换行后从空样式重新解析,颜色和粗体等只影响当前行;同一行因宽度自动折行时继续保留格式。任务列表的标题、章节以及目标、奖励名称等独立字段通过 LegacyText.scoped 在拼接边界追加重置码,分隔符、编号、进度与状态恢复界面默认样式。按连续样式创建固定 span 节点并设置颜色、粗体、斜体、下划线及删除线;§r / &r 恢复当前界面的默认样式,不强制黑色。混淆样式不生成随机乱码,其他无效或末尾不完整的 § 格式码按原版解析规则处理。正文、换行和 Unicode 字符仍通过 setTextContent 写入,任务文本中的 HTML 标签只作为文字显示。格式节点保持行内布局和原按钮点击目标,不新增样式文件。TTS 使用同一转换入口提取纯文本,不朗读这两类控制码。

对话、待响应请求、服务端偏好与能力、当前结果统一保存在不可变的 AssistantClientState 中,界面通过 AssistantClient.state() 读取;客户端登出或成功撤销时直接替换为 EMPTY,刷新版本号继续递增。AssistantClient 保留网络、导航和语音副作用,响应只投递给原连接代次。服务端历史和偏好按玩家读取;关闭窗口不回滚已经入账的奖励。输入区限制长度,等待期间不重复提交,但服务端仍独立限流。

完整界面的历史面板最多返回 24 条完整消息,超大结果仅保留装得下的完整卡片,整次响应另有限长;不会截断序列化 JSON。对话滚动容器和每条消息使用普通块布局,长卡片按完整内容占位;消息间距由外边距控制,避免嵌套纵向 flex 测量导致后续消息进入上一张卡片。物品、任务详情中的奖励和自选项保留分页动作,任务列表及名称候选列表改为完整滚动列表,普通奖励按钮显示对应奖励名称。任务列表使用紧凑的编号行,只显示名称、章节与百分比;完整界面可点击行,简约界面可用“查看 1”或“查看 名称”。列表与候选列表不显示嵌套目标和奖励,详情的说明、目标、奖励分别分页;有界详情不再受通用卡片 6000 字符截断影响。

完整界面的商城有侧栏入口、搜索工具栏、商品货架卡片和独立确认卡片;简约模式以文字和编号完成相同流程。货架最多列出 128 个商品,超出时提示只显示前一部分。价格使用服务端求值后的 Saturn Cost 快照,单物品费用显示图标,资源、标签与其他费用使用文字;无法生成账单时隐藏购买动作。报价令牌不展示在卡片正文里,不显示虚构余额。

抽奖页与商城共用伸展搜索栏:输入框占满剩余宽度,搜索与全部奖池按钮等高且不被压缩;窄窗口时输入框单独占一行,按钮在下方均分宽度。辅助说明使用 12px 字号。奖池卡片与商城兑换卡片统一使用物品表格:同一个 system:items 节点通过 columns(列数,0 为行内流式)、cell(槽位宽度)和 icon(图标尺寸)描述货架式网格,槽位等高、按列对齐,空位保留网格宽度;只展示结果物品,不再单独列出单次消耗或所需支付,消耗改为悬停结果物品时的原版 tooltip 行。确认兑换卡(报价)仍在正文显示所需支付与支付材料分组。ID 降为次要文字;抽奖详情的奖品货架显示奖品名与物品图标,概率和完整物品清单在 tooltip 里,不再堆叠权重和嵌套数据字段。完整界面按 CardView.template 选择卡片正文,简约模式和 HUD 共用对应的紧凑文字与物品预览;所有操作仍携带原来的可信动作,报价和独立确认流程不变。

各 CardData 在 buildCard 中提供物品预览参数,AssistantItems 统一渲染,完整卡片、简约模式当前回复和 HUD 通知共用 AUI 原生 <item>。物品查询按注册表 ID 显示默认物品;签到候选、奖励与收件箱、商城商品和支付材料、抽奖消耗与奖品使用实际 ItemStackTemplate,保留自定义名称、附魔、耐久及其他组件。卡片按组显示图标、名称和数量,通知使用紧凑图标与数量角标,较多物品可以在按 T 进入聊天后滚动查看;空预览区域隐藏。图标跟随原文档布局、裁剪和淡入淡出,不增加独立绘制层或新样式文件。

物品模型通过共享 CSS 放大至原来的 1.75 倍,外层预留 40px 空间;单独增大 <item> 宽高不会改变 AUI 默认 16px 模型,因此对原生节点应用缩放。任务详情将普通物品奖励合并在“奖励:”标题的下一行,直接排列小卡片,物品名与数量不再在上方重复出现;领取状态移入各小卡片的次要文字。新手礼包通知只显示物品图标与数量角标,不附加“可领取”或“暂不可领取”状态文字;领取失败时仍显示对应错误。非物品奖励继续保留文字,自选奖励仍按候选分组。简约模式和通知的正文同样省去已由小卡片显示的普通奖励行;纯文本格式仍可单独获取完整摘要。

奖池浏览与商城共用同一张货架卡片(system:offer_grid):每个奖池一个单元格,显示最多 2 件最稀有奖品的图标和奖池名,点击格子才请求该奖池的详情,报价仍在服务端按需求值。悬停格子里任意物品显示的是整个奖池的清单:按概率从低到高取最多 10 个奖品,再按概率从高到低排列,每项带奖品名、概率和物品,超出 10 个时首行注明只列最稀有的部分。详情卡片用同一个货架节点列出该奖池的奖品;这时悬停只显示当前物品——原版物品提示(名称、附魔、说明等,取自 ItemStack)加该奖品的概率,整池清单不再重复。单次消耗独立成卡片正文上方一行(priced 状态),免费奖池不显示该行。签到候选统一放在候选奖励区,物品卡片附带所属奖励包名称;签到结果、抽奖结果及收件箱沿用奖励小卡片,商城兑换卡片只展示商品,所需支付移到 tooltip 与确认卡。简约模式与通知同样使用图标区域,奖品名称与物品列表不会在正文重复展开。

悬停图标通过 GuiGraphicsExtractor.setTooltipForNextFrame 提交原版物品提示,保留高级提示及 NeoForge tooltip 扩展。输入界面与 HUD 均使用原版延迟 tooltip 阶段;HUD 在聊天界面的 Render.Foreground 提前提交 AUI 界面状态,使随后提取的提示位于通知之上。AUI 自身按同一帧的 extractor 去重提交,不增加第二份界面绘制,也不重复处理输入法预编辑浮层。通知只有处于可交互的完整可见阶段才响应悬停,确认、切换或收起后不继续显示上一条物品提示;游戏操作期间不抢占鼠标。

FTB 详情和完成/解锁通知通过 Codec 同步普通物品奖励预览,沿用不可见及被阻止奖励过滤;详情中的自选项使用 QuestChoiceOutput 携带各候选名称与物品,保持分页、选项顺序和领取引用对应。ItemPreviewOutput 将显示数量与物品模板分开,FTB 基础模板取数量 1,数量角标直接使用 FTB 的固定值或随机范围,避免超大数量超过模板 Codec 的单栈范围。预览不触发发奖,不展开其他模组特有的非物品奖励,也不在通知中遍历整个自选奖池。

双语文件为 assets/system/lang/en_us.json 与 zh_cn.json,键集合必须完全相同。新增状态、字段或按钮需要同时维护两份文件。来自注册表的物品名仍受服务端语言影响,FTB 原始本地化组件尚无专门客户端翻译协议。

统一设置使用 assistant-settings.html,常规、语音播报和语音输入在同一文档内切换标签,仍只加载 assistant.css,复用 AssistantInputScreen 的原生 IME 生命周期;不带聊天输入框的页面不会注册消息补全或 Enter 发送。密钥使用 AUI 的 password 输入框,仅存本机。固定文本先在客户端翻译,再送入 TTS;语种默认跟随游戏语言,也支持自动或显式选择,Qwen3 使用 language_type,Qwen-Audio 使用 language_hints。播报页另有默认关闭的整句音频缓存开关。界面和当前通知各自持有语音 session:新回复替换旧朗读,关闭或切换界面即取消;通知确认、操作或隐藏同样立即取消。播报结束不自动切换通知,手动切换不等语音播完。通知恢复和历史不重播,播放状态区分原版和 OpenAL 后备。中英文语言文件的键集合保持一致。具体参数、音色兼容与工具用法见 语音合成与音色设计。

语音播报页的“合成语种”使用 AUI 原生下拉选择框,列出跟随游戏语言、自动识别及全部支持语种,选项名称使用客户端本地化。选择后立即自动保存到原有语言字段;未填写 API Key 时沿用禁用逻辑。下拉框沿用唯一的共享 CSS 的字体、边框和焦点样式,弹出选项使用 AUI 原生弹层。

同页的“播报任务详情”“播报任务奖励”“播报任务背景”复用共享 assistant_switch,修改后立即自动保存,默认开启详情与奖励、关闭背景。详情关闭只读名称和奖励;开启后追加要求,背景还需单独开启且通过服务端叙事筛选。空说明、纯操作解释或不确定内容不作为背景播报,按任务唯一 ID 与语言持久化筛选结果。轮到当前语音 session 时按可信任务 ID 请求只读文案,模型回包不写入对话或替换卡片,不重置通知动画。物品名通过原版 Component 在客户端展开;可选目标与数量范围独立格式化,原有物品小卡片和 tooltip 不变。

系统文语气、提示词与公开参考来源见 文案与提示词。UI 固定模板负责结算通知,模型只填写受限的签到选择理由;不会为语气额外增加模型轮次。

搜索卡片只先展示精简回答和“来源与摘要”折叠标题。通用 details 节点默认收起,点击后显示来源标题与摘要;link 节点将来源标题变为可点击的链接,复用 Minecraft 原版 URL 校验、链接开关和确认流程。两者共用 assistant.css,完整与简约模式均可点击,HUD 仅在聊天栏打开且通知可交互时响应。展开不会重复请求或播报,返回或重建页面后按 JSON 的 open 值初始化。

折叠和链接按钮使用单独的文字子元素,箭头固定占位,展开时立即重排内容子树。搜索来源改为独立块纵向排列,以分隔线区分;摘要最多显示三行预览,长文本省略,点击标题可查看原网页。服务端会压缩摘要中的连续空白,不把网页原始段落直接铺满卡片。

设置页的历史、自动朗读、通知音效、音频缓存、语音输入和识别后立即发送统一使用共享 assistant_switch 拨动开关样式,包含滑块位移、开关配色、焦点和禁用状态。“通知音效”位于语音播报页顶部,默认开启且无需密钥,与自动朗读独立;关闭后正文直接播报,连续通知仍不重复提示音。切换后立即写入 SpeechConfig.notificationSoundEnabled 并保存,旧配置缺少该字段时默认开启。底层使用 button type=button role=switch,避免 AUI 原生 checkbox 绘制与轨道叠加;不再使用透明 checkbox 覆盖。AssistantView.bindSwitch 统一处理点击、禁用检查和状态切换,switchChecked 以 aria-checked 同时驱动样式、辅助语义和表单读取。按钮支持 Enter / Space 激活,轨道与文字不接收指针,整行按钮可点击。所有标签修改后自动保存,TTS 仅保留试听和停止按钮。其他界面可复用同一结构与 CSS,不另加样式表。完整/简约模式仍使用分段按钮。

设置页内容区、标签页和设置分组采用普通块流,滚动区由固定尺寸外壳分配空间,长内容在内部滚动;原生主题选择器在分组右上角定位,不参与内容高度的 flex 测量。开关使用块状按钮和绝对定位的固定轨道,滑块通过 left 过渡,避免 AUI 在解析 transform 过渡时提前调用 Size.of。标签切换和控件刷新仅提交变化的 class、aria-selected、display 和 disabled,保存逻辑保持不变。依据、日志和未验收范围见页面布局审计。

本轮仅检查模板结构、ID 绑定、资源路径与语言键,未运行游戏渲染。实际尺寸、滚动、输入焦点及不同 GUI 缩放仍需用户指定范围后进行客户端验收。

助手输入框通过 Brigadier 的 replacement range 应用补全,保留 /、/system 前缀以及参数原文。本地候选先显示,再异步合并连接已同步的服务端命令树建议,不等待网络才弹出。回包需匹配当前页面文档、连接、命令树、草稿、光标、状态版本和输入法状态,避免过期建议覆盖新输入;按键仍沿用 Tab 采用、上下选择、Escape 收起、Enter 发送。MC 自己取消上一笔远端补全时,本地任务/按钮候选继续可用,不会因此清空。

对话模式菜单​

完整 / 简约发送框左侧共用 ConversationModeSelector,大字名称、小字描述,默认标准。弹层向上绝对定位,不参与消息区布局;只在状态 revision 改变时更新选中和权限,禁用项用颜色置灰,不使用 opacity 合成或主动测量。支持点击外部关闭、Esc 收起、上下键选择和 Enter / Space 激活。管理员设置随 AiStatus 下发,服务端再次检查偏好修改和执行授权。详见 执行模式。