扩展可以用 scheduleStrategy() 声明项目级章节调度策略。在蓝图的「扩展策略」节点中选择策略,不会出现在普通的「调用扩展方法」Block 里。
v1.8.0 新增

声明策略

import {
  Extension,
  extension,
  scheduleStrategy,
} from "@avg-studio/sdk";

@extension({ id: "story-map", label: "故事地图" })
export class StoryMap extends Extension {
  static chooseNextChapter = scheduleStrategy({
    id: "choose-next-chapter",
    title: "故事地图调度",
    description: "根据地图选择和剧情状态决定下一章",
    async resolve(ctx, input) {
      const nextId = await openMapAndWaitForSelection(ctx, input.chapters);

      if (!nextId) {
        return { kind: "end", reason: "玩家结束本轮流程" };
      }

      return {
        kind: "chapter",
        chapterId: nextId,
      };
    },
  });
}
策略必须声明为扩展类的静态属性。显式 id 只能包含小写字母、数字和连字符;省略时会由静态属性名转换,例如 chooseNextChapter 会生成 choose-next-chapter。

输入参数

resolve(ctx, input) 的 input 包含:
字段说明
schedulerId当前调度器的稳定标识
chapters在当前蓝图策略节点中选择、且可用的候选章节
activeChapterId当前正在运行的章节;没有时为 null
lastCompletedChapterId上一个完成的章节;没有时为 null
cycle当前调度器已经做出决策的轮次
每个候选章节包含 id、name 和 index。返回章节时必须使用当前 chapters 中存在的 id。

返回结果

继续运行某章:
return {
  kind: "chapter",
  chapterId: input.chapters[0].id,
  diagnostics: { source: "fallback" },
};
结束当前策略(蓝图中沿完成出口继续):
return {
  kind: "end",
  reason: "所有可用章节已经完成",
};
diagnostics 可用于调试展示,Studio 不会解释其中的业务结构。

异步选择

resolve 可以返回 Promise,因此可以打开扩展 UI,等待玩家完成地图或日程选择后再返回结果。不要把未完成的 Promise、DOM 节点或 UI 临时状态写进存档;存档只需要保留扩展自己的持久业务数据。

在 Studio 中启用

  1. 构建扩展并在当前项目中启用。
  2. 在「剧本运行设置」启用蓝图调度,阅读并确认运行规则变化。
  3. 在叙事地图中添加「扩展策略」节点。
  4. 选择扩展策略与候选章节,并连接进入路线和完成出口。
  5. 从项目入口运行,检查第一轮、候选章结束返回策略、重复轮次和策略完成后的路线。
策略抛出错误、返回不存在的章节,或始终返回同一章而没有结束条件,都可能让项目无法继续。至少测试无候选章节、目标章节被禁用、读档恢复和玩家关闭选择界面等情况。