ctx.history 提供当前游戏的历史快照,支持追加自定义正文记录,也可以重放历史条目中的语音。

API

方法返回值说明
append(entry)void追加一条 HistoryEntry,通知历史界面刷新
appendBatch(entries)void按数组顺序追加多条 HistoryEntry,只通知一次;接受只读数组,空数组不通知
entries()HistoryEntry[]获取对话历史
choices()Record<string, number>获取选项选择结果
ifResults()Record<string, boolean>获取条件判断结果
inputs()Record<string, string>获取玩家输入结果
replayVoice(uri)void | Promise<void>重放指定语音
useSnapshot()HistorySnapshotReact Hook;订阅完整历史快照

写入条目字段

append 和 appendBatch 使用 SDK 导出的 HistoryEntry 类型,只有 text 必填。
字段类型说明
textstring正文;与内置对白历史一样清理富文本和控制标记后保存
uuidstring可选条目标识;不会自动生成,也不用于自动去重
characterIdstring角色稳定 ID;不会自动填充显示名
namestring显示名;旁白可省略
voiceUristring语音资源 URI;追加时不会自动播放,可用 replayVoice 重放
isReadBeforeboolean条目的已读标记;不会标记剧本块已读
isChoiceboolean标记为选项样式的正文;不会修改 choices() 中的实际选择结果

案例:将扩展消息写入历史

在扩展方法的 run(ctx, params) 或 UI 事件回调中调用:
ctx.history.append({
  text: "获得了旧车站的钥匙。",
  name: "系统",
});

ctx.history.appendBatch([
  { characterId: "alice", name: "爱丽丝", text: "你收到我的消息了吗?" },
  { name: "我", text: "收到了,车站见。", voiceUri: "voice/reply.ogg" },
]);
三条记录依次出现在当前历史列表中,已有记录保留;entries() 立即可读,useSnapshot() 和 history:changed 订阅会收到更新。Engine 执行 seek 时,通知遵循现有批处理规则,在批处理结束时合并发送。 追加只写历史,不显示对白框、不推进剧本,也不修改选项、条件、输入结果。SDK 的语音字段是 voiceUri,宿主会转换为 Engine 内部的 voiceURI。

生命周期与存档

  • 写入的是当前运行中的正文历史,不是独立的持久化日志。重新开始或引擎清理历史后,这些条目也会被清除。
  • 当前存档不会直接保存正文历史数组;读档和回溯会通过剧本重放重建历史。仅在 UI 点击时追加的记录,不会自动在读档后恢复。
  • 需要随剧本恢复的记录,应在扩展方法对应的正常执行、跳过和立即执行路径中重建;若实现了自定义 skip / runImmediately,这些路径也需要追加记录。每次调用都会新增条目,即使 uuid 相同也不会去重,避免同一次执行重复追加。
  • 与剧本无关、需要长期保存的业务日志,应另用扩展存档保存数据,并自行安排恢复时机。
  • 扩展设计态 Preview 中,追加写入当前 Preview 上下文的临时历史,可用于调试订阅和列表;不同上下文互相隔离,不写入游戏运行历史或存档。

案例:渲染最近一条对话

输入: 历史记录中最后一条为爱丽丝的语音台词。
function LatestHistoryLine() {
  const ctx = useExtensionContext();
  const { entries } = ctx.history.useSnapshot();
  const latest = entries.at(-1);

  if (!latest) return <span>暂无历史记录</span>;

  return (
    <button
      disabled={!latest.voiceUri}
      onClick={() => latest.voiceUri && void ctx.history.replayVoice(latest.voiceUri)}
    >
      {latest.name ?? "旁白"}:{latest.text}
    </button>
  );
}
输出:
爱丽丝:明天见。
当条目包含 voiceUri 时按钮可用,点击后重放该条语音;历史为空时输出“暂无历史记录”。