编写自己的运行时
绘制运行时需要满足的模块契约,以及 Studio 如何发现、校验并打包它
Studio 的模型角色不限定于 Live2D 或 Spine。任何能够向容器内绘制的渲染器均可作为运行时使用,例如已有的渲染器、粒子系统、精灵表播放器或 WebGL 场景。以 自定义运行时 安装后,其行为与两个具名产品完全一致
模块要求
runtimes/puppet/ 下的一个目录,内含一个 index.js,该文件须为浏览器可加载的 ES 模块,并产出满足引擎 PuppetBackend 的对象:
export default function createPuppetBackends({ game, resolveFile, log }) {
log("info", "my-renderer registered");
return {
name: "my-renderer",
mount(container, ctx) {
// 在 `container` 内绘制,返回由引擎驱动的实例。
return {
ready: () => loadedPromise,
apply: (state) => { /* 完整状态,不是增量 */ },
command: (name, payload) => { /* 一次性效果 */ },
describe: () => ({ motions: [], expressions: [], skins: [], params: [] }),
resize: (size) => { /* 盒子尺寸变化 */ },
dispose: () => { /* 容器由 Studio 清空 */ },
};
},
};
}必需项只有 name 与 mount。name 不能为空,角色引用的即为该名称,另见下文关于命名的说明
引擎的木偶 (Puppet) 页面是完整契约,其中说明各方法接收的参数与调用时机、apply 接收完整状态而非变化量的原因,以及读档为何以一次 apply 完成而非回放
支持的导出形式
Studio 接受多种导出形式,便于模块同时导出其他内容:
| 导出 | 视作 |
|---|---|
export default function (ctx) | 工厂。以宿主上下文调用,可返回一个后端、一个数组,或一个 promise |
export default backend | 后端对象本身 |
export default [a, b] | 单个模块提供多个后端 |
export const createPuppetBackends / puppetBackends / puppetBackend | 以上任意形式的具名导出,保留 default 导出位 |
工厂返回空不视为错误
宿主上下文
工厂接收以下字段:
| 字段 | 含义 |
|---|---|
game | 这些后端将注册进的 Game |
resolveFile(path) | 位于模块自身目录内某个文件的 URL,供带有附属文件的运行时使用,例如 wasm core、shader 或查找表。访问范围限于该模块所在目录 |
log(level, message) | 向宿主控制台输出,自动带上模块名前缀 |
resolveFile 解析的是模块自身旁边的文件,挂载上下文中的 ctx.resolveSibling 解析的是模型旁边的文件。两者并存,因为运行时与它绘制的模型是两个独立的包
安装
选择 项目 → 运行时 → 自定义运行时,填写名称,然后指定单个打包产物 index.js,或指定一个整体复制的目录
Studio 随后会以游戏运行时的相同方式加载该模块,确认其产出了后端。未注册任何后端的模块会被拒绝,复制操作一并回滚
目录名取自模块注册的 backend 名,而非安装时填写的名称。引擎按注册名解析角色的运行时,而编辑器列出的是目录名,名称不一致会导致角色在舞台上不显示。Studio 会将目录重命名为一致,并报告所选用的名称
构建时的处理
runtimes/puppet/ 下每个含 index.js 的目录都会被复制进构建产物,游戏在第一个场景挂载前加载它。缺少 index.js 的目录会被跳过并给出警告,不会导致构建失败
后端始终未就位的 puppet 不会导致游戏崩溃。引擎保留该区域及其位置、变换与存档状态,仅不绘制内部内容
实现建议
- 尽量打包为单个文件。 单个自包含的 ES 模块不涉及模块解析问题。仅当运行时确实在运行期加载附属文件时才使用目录形式
- 模块在每个 game 中只加载一次,无需在实现中区分当前所属的 game
- 尽量实现
describe()。 它使 Studio 的动作与表情字段由文本框变为列表,并使角色编辑器绘制预览。该方法可选,编辑器在缺少它时仍可工作 dispose()无需清空容器。 该操作由 Studio 完成,包括 mount 抛出异常的情况- 选项由运行时自行解释。 Studio 原样传递角色的选项映射,不读取其中任何键。运行时所需而不属于引擎三个状态通道的内容均可放入其中