Storvia

小组件

编写可嵌入到深度模式里的辅助小组件

什么是小组件

小组件是一种特殊的沉浸创作模式:它可以嵌入到某个深度模式的游戏(下面称之为主线)里运行。

典型用途:

  • 群聊
  • 私聊
  • 热搜
  • ...

一句话理解边界:

  • 共享主线(读写都作用在主线那一份):角色、物品、关系、世界、玩家、永久记忆、人设。小组件改了它们,等于改了主游戏。
  • 小组件私有沙盒(主线和其他小组件都看不到):剧情设定场景设定自定义(custom)属性存档
  • 消息比较特殊:所有 topic 的消息存在同一张表里,但按 topic 隔离——小组件默认只读到自己 topic 的消息,需要时可显式去读主线(见下文「读取消息历史」)。

「共享」意味着没有回收站:小组件里创建 / 修改 / 删除角色、编辑人设,都是直接写主线,会立刻影响主游戏,且不会自动回滚。真正私有、互不干扰的只有 custom 属性和存档。

创作流程

  1. 在创作台「创作模式」面板选择「沉浸创作
  2. 勾选「可作为小组件」开关
  3. 你可以编辑的区块:
    • 世界观及剧情设定:小组件本身的 LLM 设定(人设、行为规则、回复风格等)
    • 场景设定:小组件自己的场景设定,类似于沉浸模式(不同场景下不同行为)
    • 自定义属性:小组件的私有沙盒字段
    • 封面、标题、标签、简介、开幕小剧场等基础信息

小组件能做什么

资源归属能读能写
消息同表、按 topic 隔离默认仅自己 topic;显式传 storvia_chat_main 可读主线写入自己 topic
永久记忆共享主线✅ 与主线走同一条生成链,同等待遇
人设共享主线写回主线(会改动主游戏)
角色 / 物品 / 关系 / 世界 / 玩家共享主线✅ AI 自动更新,写回主线
自定义(custom) 属性小组件私有沙盒✅ 落自己沙盒,主线 / 其他组件都看不到

关键点

  • 共享主线的属性(角色 / 物品 / 关系 / 世界 / 玩家 / 记忆 / 人设)用的都是主线那一份,小组件里读到的、写回去的都是主线的数据——小组件不能为它们另起一套平行 schema(创作台发布时会自动剔除)。
  • custom 属性是小组件独有的私有沙盒:只有该小组件自己运行时才会注入进 LLM,主线和其他小组件既读不到、也无法覆盖。
  • AI 自动更新指:LLM 生成的正文里夹带的结构化状态变更,会被系统自动解析并落库——共享属性写回主线,custom 写回自己的沙盒。
  • 深度模式主线本身没有 custom(custom 是自由模式专属),所以在深度模式下,custom 就是纯粹属于小组件的字段。

沙盒数据

每次小组件被安装到某主线对话,会给你的小组件开一份私有沙盒,物理位置在 conversations.metadata.widget_sandbox[你的 game_id]。沙盒里存三样东西:

  • custom:自定义属性的当前值
  • custom_inject:各 custom 字段是否注入进 LLM 的开关
  • save_data:小组件的存档数据

沙盒的生命周期:

  • 用户卸载小组件:沙盒数据保留(重新安装即恢复,不会丢失数据,也不会自动清理数据)
  • 多次安装同一小组件:使用同一份沙盒
  • 沙盒按 game_id 隔离:主线看不到它,其他小组件也各有各的沙盒,互不可见

Topic 命名约定

小组件通过 SDK 调用聊天能力时必须传一个 topic,让自己的消息流与主线(storvia_chat_main)以及其他小组件区分开。

强制格式<游戏 id>:<组件内部 topic>

  • 前缀 = 游戏 idgame_id),即你这个小组件被发布后由平台分配的唯一标识。平台保证全局唯一,永远不会与别人的小组件撞。
    • 还没发布拿不到 id?可以先把小组件以私有可见性发布一次,发布成功后即可在游戏详情页拿到 game_id,再回来填到 topic 里使用
  • 后缀 = 你小组件内部自己用的 topic 名(自由命名,用来区分自己内部的多条对话流,如不同房间、不同会话)
// 推荐:用 game_id 作为前缀
const topic = `${gameId}:main`;            // 组件主聊天流
const topic = `${gameId}:room-${roomId}`;  // 多房间场景
const topic = `${gameId}:user-${userId}`;  // 多对一私聊

// 不推荐
const topic = "chat";              // 没前缀,必撞主线 / 其他组件
const topic = "widget:chat";       // 前缀不带游戏 id,多个小组件同名会撞

平台不会强制校验 topic 格式,但不按这个规范走,发生跨组件消息污染时责任自负

读取消息历史(自己 / 主线 / 全部)

小组件通过 chat.messages({ topic, ... }) 拉消息时,topic 参数决定看到的范围:

传值拿到的范围典型用途
${gameId}:xxx(自己的 topic)仅自己这个 topic 的消息小组件正常聊天 / 翻看历史
"storvia_chat_main"主线对话的消息想让小组件「读懂主角现在在干嘛」
其他小组件的 topic该组件的消息一般用不到,不建议跨组件读
不传 / null当前会话下所有 topic 的消息(主线 + 全部组件)极少需要;通常是 bug
// 小组件自己的对话历史
await sdk.chat.messages({ topic: `${gameId}:main`, order: 'asc', limit: 20 });

// 主线对话历史(让群聊 / 私聊 widget 知道主角刚发生了什么)
await sdk.chat.messages({
  topic: 'storvia_chat_main',
  order: 'desc',
  limit: 10,
});

// 全部消息(不传 topic)—— 几乎用不到,注意会拿到所有 widget 的消息流
await sdk.chat.messages({ order: 'desc', limit: 20 });

不传 topic 会把当前 conversation 下所有 topic 的消息混在一起返回(主线 + 你自己 + 其他小组件)。除非确实需要"全景视角",否则永远显式传 topic,避免拿到不该读的内容、上下文错乱。

SDK 调用

聊天、属性(创建、修改、删除)、玩家人设编辑、角色人设(创建、修改、删除)等功能和沉浸模式完全一样调用 SDK 即可。读写 custom 属性会自动落到你自己的沙盒,不需要做任何额外处理。

注意区分写入落点:只有 custom 属性写进小组件私有沙盒。角色、物品、关系、世界、玩家、人设的读写全部作用在主线——在小组件里通过 SDK 建角色 / 改人设 / 删物品,改的是主游戏本身,不是组件私有副本,务必谨慎。

共享设置

以下设置不属于小组件,跟着当前主线对话走:

  • 模型选择
  • 温度
  • 回复长度
  • 回复语言

On this page