@forgeax-extension/wb-game-video
v0.26.0
Published
ForgeaX workbench plugin — Video Game (gameplay-on-video) editor & player. 视频游戏(玩法优先)编辑器:Boss 战 / 血条 / QTE 闯关 / 限时·暂停选择 / 可点热点 + 视频分支(fork of wb-reel)
Maintainers
Readme
@forgeax-extension/wb-game-video
玩法优先的视频游戏蓝图编辑器与运行时。它把视频演出、血条、QTE、限时选择和热点交互组合成可序列化的 GraphLibraryDocument,由纯 TypeScript 状态机确定性执行。
当前契约
- 图文档权威文件是宿主绑定游戏工作区内的逻辑路径
blueprint.json;首次保存同时补齐project.json。物理目录布局由宿主 workspace adapter 决定。 - 未保存草稿留在浏览器 localStorage。未初始化项目由
GameBootstrap引导宿主initialize; 首次 initialize 默认写入 empty library(单entry节点空壳,非 Nodia demo)。Nodia 仅用于 用户显式 demo 重置(createNodiaSeed)。已初始化 package 读取失败会进入可重试错误页,不会自动 写入空蓝图覆盖原文件。 - 游戏身份只来自宿主:后端读取
WorkbenchExtensionContext.gameId,浏览器等待 nonce-bound handshake 后读取ExtensionClient.ready()返回的gameId。AI 工具都不接受调用者提供的gameSlug。 - AI 使用
wb-game-video:patch-graph原子增量改图;任一 op 或整本校验失败时不写盘。wb-game-video:save-graph保留给编辑器 UI 覆盖保存整份文档,不向 AI 暴露。 - 可序列化运行内核位于
src/runtime/core,React 渲染层位于src/runtime/react;图中只保存组件 id 与可序列化输入。 - 扩展提供 manifest 驱动的 host 工具:增量改图、规则目录、图读取、项目基础控件生成、内置视频列表、
镜头脚本/关键帧/视频生成、素材查询和角色/场景引用导入。完整调用契约见
SKILL.md。
本地开发
本仓是独立仓库,使用 Bun:
git clone https://github.com/ForgeaXGame/forgeax-ex-game-video.git
cd forgeax-ex-game-video
bun install --frozen-lockfile
bun run dev
bun run test
bun run lint
bun run build要脱离 Studio 单独运行完整编辑器,使用开发 host shell:
bun run dev:standalone
# http://localhost:15185/dev.html该入口仅在 Vite 开发服务中存在。它使用官方 WorkbenchFrame 提供同样的 nonce-bound
handshake,并将所选游戏的数据写入 .workbench-dev/games/<gameId>/。它不修改生产
index.html、扩展 manifest 或 Studio iframe 入口;Studio 仍使用宿主注入的真实游戏工作区
和服务能力。命令会先构建一次 Node 可加载的扩展后端,再启动前端与后端 watcher;开发
host 的版本记录与媒体存储是进程内实现,模型生成能力不可用。
bun run build 依次跑 frontend、backend、build:standalone 与 check:release。
Player 播放页源码位于 src/player/,产物统一写入根目录 dist/player/;单独构建或预览:
bun run build:standalone
bun run start:standalonebun run dev 启动 Vite 开发适配器(独立运行时默认 15185;Studio launcher 可通过
VITE_DEV_PORT 注入端口)和后端 watch。适配器只挂载
/__workbench__/v1 的标准 Workbench HTTP 契约;用宿主 iframe 的 nonce-bound
handshake 注入 game id、runtime id 和端点后再打开编辑器。它不提供旧的兼容业务路由。
本地游戏包保存在被忽略的 .workbench-dev/games/<gameId>/,首次 initialize 时由
扩展的 empty library seed 创建 project.json、blueprint.json 与 assets/manifest.json。
Nodia demo 需显式调用 createNodiaSeed。
bun test 是无 DOM 的 server/release-contract gate;浏览器、React 与 Vite 覆盖使用
完整的 bun run test(Vitest)。
@forgeax/[email protected] 通过 registry 安装。开发和 CI 使用
bun install --frozen-lockfile,以 bun.lock 固定已发布的 Host 契约;不需要也不应配置本地
tarball、路径 override 或 vendored provenance。
Media contract release dependency
浏览器素材库使用 Host 的 /games/:gameId/media 可恢复上传和元数据 API;扩展不再提供
assets/wb-game-video-media.json 或 media/resources 生命周期。该契约由
@forgeax/[email protected] 发布并以 registry tarball + integrity pin 固定。
宿主集成
发布包要求精确 peer:@forgeax/[email protected] 与
@forgeax/[email protected]。包导出:
@forgeax-extension/wb-game-video/./host— Workbench 扩展 host(seed、工具、router)@forgeax-extension/wb-game-video/standalone— player 播放页 HTML(dist/player/index.html)@forgeax-extension/wb-game-video/styles.css— 编辑器样式
游戏组件模块契约
游戏专属组件由 gameComponents.moduleUrl('index.js') 提供的模块注册。模块导出
register(host)(也接受默认导出的函数或带 register 的对象),其中 host 只提供:
- 共享的
React实例; registerComponent(id, manifest);registerOverlayRenderer(id, component, manifest?)。
export function register(host) {
host.registerComponent(manifest.id, manifest)
host.registerOverlayRenderer(manifest.id, Component, manifest)
}可序列化 manifest 位于
src/runtime/core/component-catalog,React 叶子组件位于
src/runtime/react/component-host/components。二者使用
LocalComponentManifest 描述包内契约;转为平台
ComponentDef / ComponentManifest 的类型边界只位于
component-host/index.ts。叶子组件不应直接依赖 editor、
engine/session 状态或平台 schema 来解释作者输入。
PR #141 后不再存在 registerInteractionSkin、registerHpBar,也不再提供
interactionSkins()、hpBarComponents()、skinPositioning()、skinDefaultAnchor() 这类并行元数据
访问器;组件发现以 manifest 与 renderer 注册为唯一入口。src/runtime/react/index.ts 导出
bootComponents、createCoreSkinRegistry 与 createDefaultComponentRegistry;
src/runtime/core/component-catalog/index.ts 只提供无 React 的 manifest 列表与安装器。不再提供
registerCoreSkins、newComponents 或 installNewComponents。
该组件目录是仓内内建 catalog,不是受支持的 npm 子路径。公开包入口仅以上述根入口、./host、
./styles.css、./standalone 为准。
其中的 host 提供游戏包 seed、33 个工具和扩展 HTTP router。生产宿主负责加载它,并为每个已解析的游戏
创建唯一的 WorkbenchExtensionContext:
import { host as videoGameWorkbenchExtension } from '@forgeax-extension/wb-game-video/host'
import { createWorkbenchExtensionContext } from '@forgeax/workbench-host/node'
const response = await workspace.withGameRoot(
resolvedGame.id,
{ create: false, versioning },
async (scope) => {
const context = createWorkbenchExtensionContext({
gameId: resolvedGame.id,
gameRoot: scope.gameRoot,
files: scope.files,
media: hostMedia,
models: hostModels,
videoGeneration: hostVideoGeneration,
services: hostServices,
})
const router = videoGameWorkbenchExtension.createRouter?.(context)
if (!router) throw new Error('wb-game-video router is unavailable')
const routed = await router.handle(request)
return {
...routed,
...(routed.body ? { body: new Uint8Array(routed.body) } : {}),
}
},
)上面的 context 构造必须发生在
workspace.withGameRoot(resolvedGame.id, { create: false, versioning }, async (scope) => …)
回调内;router 构造、请求处理与响应字节复制也必须在该回调返回前完成。不得根据
gameRoot 路径临时构造 files,也不得在 scope 关闭后保留 context。
gameId 与 scope.gameRoot 在进入扩展前就由宿主解析完成。扩展后端只使用 context 注入的能力:
files提供限定在游戏根内的读写、目录枚举和跨进程withLocks;media提供素材读写、幂等落盘与回收;models提供文本、图片和视频生成;videoGeneration是宿主的视频生成 job facade;services是宿主限定范围的服务访问 facade;gameId是工具调用和 HTTP router 的唯一游戏身份。
扩展不会再适配任何宿主产品专用的请求形状,也不会读取进程环境、全局 active-game 文件或
请求中的 gameSlug 来选择游戏。
浏览器端在初始化前必须等待 createExtensionClient().ready()。这次 nonce-bound handshake
返回精确的 gameId、runtimeId、capability 列表和宿主端点;浏览器不得从 URL query、
location 或默认 slug 推导这些值。包读写和扩展请求分别使用 gamePackage 与
extension.fetch()。版本入口仅在 versions.supported() 为 true 时显示,组件模块仅使用
gameComponents.moduleUrl() 返回的 handshake 端点;缺少相应 capability 时按“不支持”处理,
不得拼接备用 URL。
发布顺序
发布必须按以下顺序:
- 先发布已经过评审的
@forgeax/[email protected]; - 从 registry 验证其类型与能力契约,并更新
bun.lock; - 完成 frozen install、测试、构建和 pack 检查后,最后发布当前 manifest 中声明的扩展版本。
代码导航
| 关注点 | 位置 |
|---|---|
| 图 schema 与校验 | src/runtime/core/schema/graph-schema.ts · src/runtime/core/validate/validate.ts |
| 状态机与 session | src/runtime/core/engine |
| manifest catalog | src/runtime/core/component-catalog |
| React 覆盖组件与播放适配 | src/runtime/react |
| 蓝图、规则与场景纯创作逻辑 | src/authoring |
| 编辑器壳、画布与持久化 | src/editor |
| 顶层独立播放器 | src/player |
| Player 本地开发样例游戏包 | game-package |
| AI 工具后端 | src/server/tool-handlers.ts |
| 扩展声明 | forgeax-extension.json |
仓库只有一个源码根 src/ 和一个发布产物根 dist/。src/ 按业务领域分层,editor、backend 与
player 的构建结果分别进入 dist/、dist/server/ 与 dist/player/;源码树内不保存构建产物。
历史设计记录位于 docs/superpowers;代码、manifest、schema 与本页是当前发布契约。
License
MIT
