Carbon UI - 星空界面框架

Carbon UI - 星空界面框架

首个面向《星空》的网页技术 UI 框架。一个 SFSE 插件,通过 Ultralight 渲染游戏内 HTML/CSS/JS 菜单,合成到 D3D12 帧中,并为 DLSS 帧生成构建。其他模组的依赖项。

[center]

[i]首个面向《星空》的 Web 技术 UI 框架[/i]
[/center]

[line]

[center][size=5][b]什么是 Carbon UI?
[/b][/size]受 [url=https://www.nexusmods.com/profile/Doombringer88/#][b]Doombringer88 [/b][/url]艺术构想启发的游戏内 UI 重制[/center]

[quote]Carbon UI 是一个 [b]SFSE 插件[/b],让《星空》模组能够使用与驱动网页相同的技术——[b]HTML、CSS 和 JavaScript[/b]——来构建它们的界面,并实时渲染在游戏内。

它内嵌了 [url=https://ultralig.ht/]Ultralight[/url] 引擎(一个 WebKit 级浏览器内核),并将其输出直接合成到《星空》的 D3D12 帧中。模组作者由此获得现代化、GPU 加速的菜单——flexbox 布局、CSS 动画、透明度、真正的下拉菜单和弹出面板、文本输入——而不必再与遗留的 UI 工具链作斗争。

它是[b]“《星空》版的 PrismaUI”[/b]:一个独立的、净室实现的框架,基于公开的 Ultralight SDK 从零构建。未使用或包含任何 PrismaUI 代码。[/quote][quote][size=4][b]AI 垃圾警告[/b][/size]

[b]测试较浅——部分功能可能无法开箱即用。[/b]
我分享它是因为我觉得其他人会想用它。如果你讨厌 AI,你不必使用它。[/quote] 终于修复了 FSR3+FG 问题——现在应适用于所有超分辨率技术(V0.9.0)
[line]

[center][size=5][b]这是一个框架——你安装它是为了另一个模组[/b][/size][/center]

[b]Carbon UI 自身几乎不产生任何效果。[/b]它附带一个演示叠加层,让你确认它正在工作——在游戏中按 [b]F7[/b] 切换它。你安装 Carbon UI 是因为[b]另一个模组将其列为前置需求[/b],正如其他 SFSE 插件框架一样。如果某个模组页面在其需求中列出了 Carbon UI,那么这就是你需要的下载。

[line]

[center][size=5][b]功能[/b][/size][/center]

[b]▸ 游戏内的真正 Web UI[/b]
由 Ultralight 1.3(WebKit 级)渲染的完整 HTML/CSS/JS 菜单。支持 flexbox 和网格布局、CSS 过渡和动画、透明度、自定义字体、原生质感的下拉菜单和弹出面板。凡是在现代浏览器中能工作的,在你的模组 UI 中都能工作。

[b]▸ D3D12 present-hook 合成[/b]
视图每帧作为预乘 alpha 叠加层直接绘制到《星空》自己的交换链中——没有第二个窗口,没有全屏闪烁。绘制周围的故障保护机制意味着 UI 故障会跳过一帧并记录日志,而不会让游戏崩溃。

[b]▸ 为 DLSS 帧生成而设计[/b]
present hook 使用[b]按交换链的渲染上下文[/b],并在 NVIDIA Streamline 背后的真实原生交换链上绘制,因此即使启用 DLSS 帧生成,UI 也能保持干净并以原生节奏呈现。这是从设计之初就纳入的,而非事后添加。

[b]▸ 可重新绑定的打开按键[/b]
演示叠加层默认通过 [b]F7[/b] 打开,该按键[b]可在菜单内重新绑定[/b]——按下 [b]Rebind[/b] 按钮,然后按下你想要的键。你的选择会持久保存到 DLL 旁边的 [font=Courier New]CarbonUI.ini[/font]。按 [b]Esc[/b] 关闭。

[b]▸ 完整的输入捕获[/b]
当菜单持有焦点时,Carbon UI 将鼠标、键盘和滚动作为正常的 DOM 事件路由到页面,并从游戏中拦截它们——因此你在点击按钮时绝不会开火。包括一个[b]原始鼠标虚拟光标[/b],不受《星空》鼠标视角控制的影响,具备完整编辑键的键盘文本输入,以及滚轮滚动。

[b]▸ 为模组作者导出的 C API[/b]
其他 SFSE 插件通过稳定、运行时解析的 [b]C-ABI[/b] 来使用 Carbon UI——通过 SFSE 消息握手获取,无链接时依赖。创建和分层视图,驱动 JS↔C++ 桥接,捕获输入,并(可选地)冻结世界。由于它是在运行时请求的,即使 Carbon UI 不存在,你的模组也能正常加载——你可以软依赖它。

[line]

[center][size=5][b]面向模组作者[/b][/size][/center]

将你的 UI 作为纯 HTML/CSS/JS 构建,作为松散文件放在你自己的模组中分发,并通过 Carbon UI API 来驱动它。所有跨越 DLL 边界的内容都是 C——不透明句柄和 UTF-8 [font=Courier New]const char*[/font]——因此接口在不同编译器和版本间保持稳定。

[b]在 [font=Courier New]kPostLoad[/font] 时请求 API:[/b]
[code]#include "CarbonUI_API.h"

static const CarbonUI::IAPI* g_ui = nullptr;

void OnSFSEMessage(SFSE::MessagingInterface::Message* msg) {
if (msg->type == SFSE::MessagingInterface::kPostLoad) {
g_ui = CarbonUI::RequestCarbonUIAPI(SFSE::GetMessagingInterface());
if (!g_ui) { /* Carbon UI 未安装 / 版本过旧——优雅降级 / }
}
}[/code]
[b]从你的 HTML 创建视图,并双向接通桥接:[/b]
[code]// C++ -> 创建一个全屏、可聚焦、透明的视图
CarbonUI::ViewDesc d{};
d.structSize = sizeof(d);
d.url = "file:///Data/CarbonUI/MyMod/index.html";
d.transparent = 1; d.focusable = 1; d.z = 10;
CarbonUI::ViewHandle v = g_ui->CreateView(g_ui->ctx, &d);

// JS -> C++ : 页面调用 window.carbonui.call("firePower", "0x1234")
g_ui->RegisterListener(g_ui->ctx, v, "firePower", &OnFirePower, nullptr);

// C++ -> JS : 在页面中即发即忘的 eval
g_ui->Invoke(g_ui->ctx, v, "renderPowers([{\"name\":\"Anti-Gravity Field\"}])");

// 打开:显示 + 聚焦(输入现在流向页面)
g_ui->ShowView (g_ui->ctx, v, true);
g_ui->FocusView(g_ui->ctx, v, true);[/code]
[b]在 JS 侧,一个全局桥接对象:[/b]
[code]// 从页面调用 C++(window.stardeck 保留为兼容别名)
window.carbonui.call("firePower", "0x1234");

// 宣告就绪,以便 C++ 能推送初始状态——绝不要与页面加载竞争
window.addEventListener("DOMContentLoaded", () => carbonui.call("uiReady"));

// 掌控你自己的关闭键:视图聚焦时游戏看不到 Esc
window.addEventListener("keydown", e => {
if (e.key === "Escape") carbonui.call("close");
});[/code]
从 [b]Files[/b] 标签页获取 [b]CarbonUI_API.h[/b] 和开发者指南(可选的“Developer Kit”下载),或阅读源码。一个完整的示例——将星裔能力绑定到按键的“Power Deck”——随指南一起提供。

[i]注意:[font=Courier New]SetFreeze[/font](菜单打开时暂停游戏世界)已包含但标记为[b]实验性[/b]——《星空》引擎的暂停语义很不友好,因此它[b]默认关闭[/b]。大多数菜单想要焦点而不需要冻结。[/i]

[line]

[center][size=5][b]需求[/b][/size][/center]

[list]
[
][b]Starfield 1.16.244[/b](Steam/PC)——此构建所针对的游戏版本。[/]
[
][url=https://sfse.silverlock.org/][b]SFSE[/b](Starfield Script Extender)[/url]——与你确切游戏版本匹配的构建。[b]SFSE 与游戏版本绑定[/b]:《星空》更新后,请等待匹配的 SFSE 更新,之后任何 SFSE 插件才能加载。[/]
[
][b]Address Library for SFSE Plugins[/b]——覆盖你游戏版本的发行版。[/]
[/list]
渲染器:[b]D3D12[/b](《星空》唯一的渲染器——无需配置)。在启用 [b]DLSS 帧生成[/b] 时也能工作。

[line]

[center][size=5][b]安装[/b][/size][/center]

[size=4][b]面向用户[/b][/size]
[list=1]
[
]像任何 SFSE 插件一样,用 [b]MO2 或 Vortex[/b] 安装该压缩包并启用。这会将 [font=Courier New]CarbonUI.dll[/font]、演示视图和 Ultralight 引擎资源放置到 [font=Courier New]Data/SFSE/Plugins/[/font] 下。[/]
[
][b]一个手动步骤:[/b]将四个 Ultralight 运行时 DLL——[font=Courier New]Ultralight.dll[/font]、[font=Courier New]UltralightCore.dll[/font]、[font=Courier New]WebCore.dll[/font]、[font=Courier New]AppCore.dll[/font](在压缩包的 [font=Courier New]GameRoot/[/font] 文件夹中)——复制到[b]游戏根目录,与 Starfield.exe 相邻[/b]。Windows 从可执行文件所在文件夹加载它们;它们不能放在模组文件夹内。(MO2 用户总是手动操作;可选的 FOMOD 可为 Vortex 放置它们。)[/]
[
]通过 [b]sfse_loader.exe[/b] 启动游戏,一如既往地通过你的模组管理器。[/]
[/list]
[size=4][b]面向开发者[/b][/size]
[list=1]
[
]安装该模组(见上)。[/]
[
]从 Files 标签页下载 [b]Carbon UI Developer Kit[/b]——[font=Courier New]CarbonUI_API.h[/font] + 开发者指南 + 一个最小示例视图——并遵循“面向模组作者”的配方。[/]
[/list]
[b]验证它已加载:[/b]检查 [font=Courier New]Documents\My Games\Starfield\SFSE\Logs\CarbonUI.log[/font] 中类似 “present hook installed” 和 “overlay Ultralight view ready” 的行,然后按 [b]F7[/b] 显示演示叠加层。

[line]

[center][size=5][b]故障排除[/b][/size][/center]

[list]
[
][b]完全没有日志文件[/b] → SFSE 没有在运行该插件。通过 [font=Courier New]sfse_loader.exe[/font] 启动,并确保你的 SFSE(和 Address Library)与你确切的游戏版本匹配。《星空》更新后,两者都必须更新,之后任何 SFSE 插件——包括 Carbon UI——才能加载。[/]
[
][b]已加载但没有叠加层 / 日志中出现 Ultralight 错误[/b] → 四个 Ultralight DLL 不在游戏根目录、与 [font=Courier New]Starfield.exe[/font] 相邻。它们不能放在模组文件夹内。[/]
[
][b]某个依赖模组提示“未找到 Carbon UI”[/b] → 确认 [font=Courier New]CarbonUI.dll[/font] 位于 [font=Courier New]Data/SFSE/Plugins/[/font] 中,并出现在 [font=Courier New]CarbonUI.log[/font] 中。[/]
[
]请在任何 bug 报告中附上 [font=Courier New]CarbonUI.log[/font]。[/]
[/list]
[line]

[center][size=5][b]致谢[/b][/size][/center]

[list]
[
][b]Ultralight, Inc.[/b]——[url=https://ultralig.ht/]Ultralight[/url] HTML 渲染引擎(Carbon UI 内嵌的 WebKit 级内核)。[/]
[
][b]CommonLibSF / libxse 贡献者[/b]——此插件所基于的反向工程《星空》C++ 库。[/]
[
][b]Ian Patterson 和 SFSE 团队[/b]——[url=https://sfse.silverlock.org/]Starfield Script Extender[/url]。[/]
[
][b]StarkMP[/b]——[url=https://github.com/PrismaUI-SKSE/framework]PrismaUI[/url],证明了此概念并启发了它的《天际》Ultralight 框架。Carbon UI 是面向《星空》的独立净室实现,[b]不包含任何 PrismaUI 代码[/b]。[/]
[
][b]Bethesda[/b]——感谢《星空》。[/*]
[/list]
[line]

[center][size=5][b]许可证与源码[/b][/size][/center]

Carbon UI 的代码为 [b]GPL-3.0-or-later[/b](附 Ultralight 链接例外)——源码开放,欢迎在相同许可证下分支和衍生。

[b]源码:[/b] [url=https://github.com/CarbonNode/CarbonUI]github.com/CarbonNode/CarbonUI[/url]

Ultralight 运行时 DLL 根据 Ultralight 自己的免费层级许可证再分发,[b]不受[/b] GPL 约束;其最终用户条款包含在压缩包的 [font=Courier New]ultralight-license/[/font] 下。

[center][i]Carbon UI 由 CarbonNode 制作。[/i][/center]