状态管理
SDK 的 6 个状态模块 —— 世界、玩家、角色、关系、物品、自定义数据
SDK 提供 6 个状态模块,用于读写游戏中的各种数据。前 5 个模块对应创作台中配置的面板字段,数据会在玩家的状态面板中显示,同时以 XML 格式注入 AI 提示词。第 6 个(自定义数据)是纯游戏内部数据,不显示在面板中。
| 模块 | 面板显示 | AI 感知 | 数据结构 |
|---|---|---|---|
sdk.world | 显示 | 注入 XML | 扁平 KV 对象 |
sdk.player.state | 显示 | 注入 XML | 按分组的 KV |
sdk.characters.state | 显示 | 注入 XML | 按角色名的 KV |
sdk.relationships | 显示 | 注入 XML | 关系数组 |
sdk.inventory | 显示 | 注入 XML | 物品数组 |
sdk.custom | 不显示 | 不注入 | 任意 JSON |
前 5 个模块的字段定义需要在创作台中配置(和高级模式一样),配置方法参考 高级模式。这里介绍的是如何通过 SDK 在游戏代码中读写数据。
sdk.world — 世界状态
存储全局环境信息,如时间、地点、天气等。对应创作台中「世界状态」面板启用的字段。
world.get()
获取当前世界状态。
const world = await sdk.world.get();
// { time: "晚上 21:00", location: "秦照野的直播间" }world.update(data)
更新世界状态。传入的字段会与已有数据合并,未传入的字段保持不变。
await sdk.world.update({
time: '深夜 23:30',
location: '回到家中',
});AI 收到的 XML:
<world time="深夜 23:30" location="回到家中"/>sdk.player — 玩家
player.get()
获取玩家基本信息(名称、描述等,来自存档中的 persona 数据)。
const player = await sdk.player.get();
// { name: "小明", description: "冒险者", avatar: "..." }player.state.get()
获取玩家状态。不传参数返回全部分组,传分组名返回该组数据。
// 获取全部分组
const allState = await sdk.player.state.get();
// { "经济": { "花园币": 500, "等级": 3 }, "数据": { "粉丝": 120 } }
// 获取特定分组
const economy = await sdk.player.state.get('经济');
// { "花园币": 500, "等级": 3, "经验": 150 }player.state.update(group, values)
更新指定分组的玩家状态。传入的字段与该组已有数据合并。
await sdk.player.state.update('经济', {
'花园币': 450, // 扣了 50 币
'经验': 180, // 加了 30 经验
});AI 收到的 XML:
<player group="经济" 花园币="450" 等级="3" 经验="180"/>分组名和字段名必须和创作台中配置的完全一致(包括中英文、空格等)。
sdk.characters — 角色
characters.list()
获取所有角色列表。
const chars = await sdk.characters.list();
// [{ name: "秦照野", description: "傲娇毒舌才艺主播" }, ...]characters.get(name)
获取单个角色信息。
const char = await sdk.characters.get('秦照野');
// { name: "秦照野", description: "傲娇毒舌才艺主播", avatar: "..." }characters.add(character)
添加新角色。
await sdk.characters.add({
name: '新角色',
description: '一个神秘的路人',
avatar: 'img/stranger.png', // 可选
});characters.update(name, data)
更新角色信息(描述、头像)。
await sdk.characters.update('秦照野', {
description: '傲娇毒舌才艺主播,最近心情不错',
});characters.remove(name)
删除角色。
await sdk.characters.remove('新角色');characters.detail(name)
获取角色完整信息(基本信息 + 属性状态)。
const detail = await sdk.characters.detail('秦照野');
// {
// name: "秦照野",
// description: "傲娇毒舌才艺主播",
// avatar: "...",
// state: { "心情": "happy", "好感度": 45 }
// }characters.state.get(name)
获取角色的属性状态。
const state = await sdk.characters.state.get('秦照野');
// { "心情": "happy", "好感度": 45, "粉丝牌": "真爱粉" }characters.state.update(name, values)
更新角色的属性状态。合并更新。
await sdk.characters.state.update('秦照野', {
'心情': 'happy',
'好感度': 50,
});AI 收到的 XML:
<character id="秦照野" 心情="happy" 好感度="50" 粉丝牌="真爱粉">
<description>傲娇毒舌才艺主播</description>
</character>角色属性的值只能是字符串或数字(string | number)。如果需要存储复杂数据(数组、嵌套对象),请使用 sdk.custom。
sdk.relationships — 关系
关系是两个实体之间的定向连接,由 from + to 唯一标识。每条关系可以有自定义字段(对应创作台配置的关系字段)。
relationships.list()
获取所有关系。
const rels = await sdk.relationships.list();
// [
// { from: "玩家", to: "秦照野", "好感度": 45, "关系阶段": "朋友" },
// { from: "玩家", to: "宋亦", "好感度": 30, "关系阶段": "认识" },
// ]relationships.get(from, to)
获取两个实体之间的关系。
const rel = await sdk.relationships.get('玩家', '秦照野');
// { from: "玩家", to: "秦照野", "好感度": 45, "关系阶段": "朋友" }relationships.add(relationship)
添加新关系。
await sdk.relationships.add({
from: '玩家',
to: '新角色',
'好感度': 0,
'关系阶段': '陌生',
});relationships.update(from, to, data)
更新关系字段。合并更新。
await sdk.relationships.update('玩家', '秦照野', {
'好感度': 50,
'关系阶段': '朋友',
});relationships.remove(from, to)
删除关系。
await sdk.relationships.remove('玩家', '新角色');AI 收到的 XML:
<relation from="玩家" to="秦照野" 好感度="50" 关系阶段="朋友"/>关系是单向的:from:"玩家" to:"秦照野" 和 from:"秦照野" to:"玩家" 是两条不同的关系。如果需要双向关系,需要分别创建和更新。
sdk.inventory — 物品栏
inventory.list(group?)
获取物品列表。可按分组过滤。
// 获取全部物品
const items = await sdk.inventory.list();
// 按分组过滤
const gifts = await sdk.inventory.list('礼物');
// [{ name: "玫瑰花", count: 3, group: "礼物", desc: "送给主播的礼物" }]inventory.add(item)
添加物品。name 和 group 必填。
await sdk.inventory.add({
name: '玫瑰花',
count: 5,
group: '礼物',
desc: '送给主播的礼物',
iconUrl: '', // 可选
});inventory.update(name, data)
更新物品属性。
await sdk.inventory.update('玫瑰花', { count: 3 }); // 用掉了 2 个inventory.remove(name)
删除物品。
await sdk.inventory.remove('玫瑰花');AI 收到的 XML:
<item name="玫瑰花" count="3" group="礼物"/>sdk.custom — 自定义数据
存储任意 JSON 数据,不受类型限制,不会显示在面板中,也不会注入到 AI 提示词。
适合存储:事件日志、聊天记录缓存、UI 状态、游戏内部逻辑数据等。
custom.get()
获取全部或指定 key 的自定义数据。
// 获取全部
const all = await sdk.custom.get();
// { events: [...], settings: { theme: "dark" } }
// 获取指定 key
const events = await sdk.custom.get('events');
// [{ type: "gift", detail: "送了玫瑰花", time: 1711234567890 }]custom.set(data)
写入自定义数据。传入的 key 与已有数据合并,未传入的 key 保持不变。
await sdk.custom.set({
events: [...existingEvents, { type: 'gift', detail: '送了玫瑰花', time: Date.now() }],
last_login: Date.now(),
});custom 模块的值可以是任何 JSON 类型(字符串、数字、数组、嵌套对象),不像 characters.state 和 player.state 限制为 string | number。
面板数据 vs 自定义数据
选择存储位置的原则:
| 需要面板显示? | 需要 AI 感知? | 数据类型 | 推荐模块 |
|---|---|---|---|
| 是 | 是 | 简单 KV | world / player.state / characters.state / relationships / inventory |
| 否 | 否 | 任意 JSON | custom |
| 否 | 是 | 任意 | 通过 context 参数传给 AI |
如果你的数据结构复杂(数组、嵌套对象),但又需要 AI 感知,可以存在 custom 里,然后在调用 sdk.chat.send() 或 sdk.chat.generate() 时通过 context 参数手动传给 AI。