Skip to Content

变量管理1.0

旧版本。推荐大家使用2.0版本

功能概览

  1. 在消息中变更状态 <plot-log>

    • 在 AI 回复中嵌入 <plot-log> 区块,记录/更新变量
    • 支持设置、追加、数值增减、删除四种操作
    • 支持编辑/删除/滑动消息时自动回滚正确变量状态
  2. 变量保护指令

    • 使用 xbsetvar 进行初始变量指令设置
    • 默认行为:只允许”改值”,不允许新增
  3. 世界书条件事件 <varevent>

    • 在世界书中设置变量条件,满足时自动显示文本或执行动作
    • 可视化编辑器:点点选选就能生成规则,不用写代码
  4. 数值映射(自然语言→数值)

    • 将”开心”、“害羞”等词汇自动转换为数值变化
  5. 变量占位符与斜杠命令

    • {{xbgetvar::变量名}} 显示 JSON 格式的值
    • {{xbgetvar_yaml::变量名}} 显示 YAML 格式的值(推荐给 AI 看)
    • /xbgetvar 变量名 快速查看变量

一、理解数据结构

在开始之前,你需要理解变量里的两种容器。

数组 = 排队

像排队一样,一条条往下加,用 - 开头:

战斗日志: - "第1回合:命中" - "第2回合:闪避" - "第3回合:暴击" 角色特性: - "力量型" - "怕痒"

特点:只管顺序,没有名字。第1个、第2个、第3个…

初始化"$list 战斗日志": []

AI 加东西:用 追加

对象 = 抽屉柜

像抽屉柜一样,每样东西有名字,按名字找:

背包: 苹果: 数量: 3 描述: "回血用" : 数量: 1 描述: "攻击用" 状态效果: 中毒: 剩余: 2 描述: "每回合掉血" 狂暴: 剩余: 1 描述: "攻击+5"

特点:每个东西都有标签(名字),用名字来找。

初始化"$free 背包": {}

AI 加东西:用 录入

怎么选?

问自己一个问题:“这东西以后怎么加?“

回答用哪个初始化写法AI 怎么加
不用加,就改改数字/文字普通值"体力": 0录入 / 变更
一条条往下加(像聊天记录)数组"$list 日志": []追加
每个有名字,要能单独找到对象"$free 背包": {}录入

一句话总结

数组存流水账,对象存有名字的东西。 $list 告诉系统这是数组,$free 告诉系统这是对象。


二、在消息中变更状态

让 AI 在回复中包含一个特殊区块 <plot-log>,用来记录剧情变化。

四个操作关键词

操作别名用途适用于
录入set / 记下 / 记录 / record设置/覆盖值普通值、对象
变更bump / 调整 / 推移 / adjust数值加减(可负)数字
追加push / 添入 / 增录 / append往列表加一条仅数组
删除del / 遗忘 / 抹去 / erase删除路径都可以

基本用法

<plot-log> 录入: 好感度: 65 心情: "害羞" 变更: 约会次数: 1 追加: 重要事件: - "第一次看电影" 删除: - 临时标记 </plot-log>

录入:设置/覆盖值

用于设置文字、数字、或整个对象:

录入: # 设置普通值 日常.时间: "15:30" 日常.地点: "学院区" # 设置嵌套值 战斗.对手.服装.上身: "背心(撕破)" 战斗.对手.生理.胸部: "右乳暴露" # 往对象里加一个新东西(注意:不是追加!) 背包.治疗药: 数量: 3 描述: "恢复50HP" # 往对象里加状态效果 战斗.对手.状态效果.羞耻: 剩余: 2 描述: "性技DC-2"

变更:数值加减

只用于数字,可以是正数(加)或负数(减):

变更: 战斗.回合: 1 # +1 玩家.体力: -30 # -30 战斗.对手.体力: -20 # -20 战斗.对手.快感: 25 # +25 背包.治疗药.数量: -1 # 用掉一个

追加:往数组加

⚠️ 重要:追加只能用于数组($list)!

追加: # 往战斗日志加记录 战斗.日志: - "R3: 对手锁技→玩家 -30HP" - "R3: 玩家撕衣→对手 +25快感" # 往事件记录加 事件: - "14:52 - 战斗白热化" # 往特性列表加 玩家.特性: - "力量型"

错误示范

# ❌ 错误:背包是对象($free),不能用追加 追加: 背包: 苹果: 数量: 3 # ✅ 正确:往对象加东西用录入 录入: 背包.苹果: 数量: 3

删除:移除路径

推荐用列表形式:

删除: - 背包.苹果 # 删除对象里的一项 - 状态效果.中毒 # 删除状态效果 - 战斗.日志[0] # 删除数组第一条(索引从0开始)

也可以用嵌套形式(末端用数组列出要删的):

删除: 背包: - 苹果 - 过期药水 战斗.对手.状态效果: - 格斗强化

完整示例

<plot-log> 录入: 战斗.阶段: "激烈交战" 日常.时间: "14:52" 战斗.对手.服装.上身: "背心(撕破,右乳暴露)" 战斗.对手.生理.胸部: "右乳暴露,乳头挺立" 战斗.对手.状态效果.羞耻: 剩余: 2 描述: "性技DC-2" 玩家.状态效果.手臂疼痛: 剩余: 1 描述: "格斗DC-1" 变更: 战斗.回合: 1 玩家.体力: -30 玩家.快感: 5 战斗.对手.体力: -20 战斗.对手.快感: 25 背包.治疗药.数量: -1 追加: 战斗.日志: - "R3: 对手【腕十字固】→玩家 -30HP" - "R3: 玩家撕破对手上衣 +25快感" 事件: - "14:52 - 观众开始起哄" 删除: - 战斗.对手.状态效果.格斗强化 - 背包.过期药水 </plot-log>

状态一致性与回滚

系统会自动处理消息编辑的问题:

  • 编辑消息:先回滚到该消息生效前的状态,再按新内容重新计算
  • 滑动替换:先回滚,再应用新的回复内容
  • 删除消息:回滚到被删消息之前的变量状态

这确保了无论怎么修改对话,变量状态都能保持一致。


三、变量守护和规则集

基本控制

总体原则

  • 默认行为:只允许”改值”,不允许新增/删除对象键,不允许新增/删除数组项
  • 需要修改规则时:把 /setvar 换成 /xbsetvar
  • 想放开操作:在键名前加规则前缀($ 开头)

可用规则前缀

前缀作用
$ro只读,任何人都不能改
$ext对象允许新增键(不可删)
$prune对象允许删键(不可增)
$free对象可增可删
$grow数组允许添加(不可删)
$shrink数组允许删除(不可增)
$list数组可增可删
$min=数 / $max=数数值最小/最大限制
$range=[a,b]数值范围限制
$enum={A;B;C}字符串必须是这几个之一
$match=/regex/flags字符串必须匹配正则

初始化示例

/xbsetvar key="$free bf" { "日常": { "日期": null, "时间": null, "地点": null }, "金钱": 0, "$list 事件": [], "战斗": { "状态": "未开始", "回合": 0, "回合上限": 0, "阶段": null, "$list 日志": [], "$free 对手": { "名称": null, "体力": 0, "体力上限": 0, "快感": 0, "快感上限": 0, "$free 状态效果": {}, "$free 服装": { "上身": null, "下身": null }, "$list 特性": [], "$list 弱点": [] } }, "$free 玩家": { "名称": null, "$range=[0,999] 体力": 0, "$range=[0,999] 体力上限": 0, "$range=[0,999] 快感": 0, "$free 状态效果": {}, "$free 服装": {}, "$list 特性": [], "$list 弱点": [] }, "$free 背包": {}, "$free 图 的": {} }

规则就三条

  • $list = 数组(一条条加的)→ 用 追加
  • $free = 对象(按名字存的)→ 用 录入
  • 普通值 → 用 录入变更

使用效果

设置规则后:

  • AI 尝试把体力改成 1500?自动拉回 999(设了 $range=[0,999]
  • AI 想删除角色真名?拒绝操作(设了 $ro
  • AI 要往背包加新道具?允许(设了 $free
  • AI 想往日志加记录?允许(设了 $list

四、变量宏

在角色卡、世界书、消息中显示变量值。

两种格式

输出格式用途
{{xbgetvar::路径}}JSON给代码用、精确取值
{{xbgetvar_yaml::路径}}YAML给 AI 看(推荐)

为什么要用 YAML 版本?

假设变量 bf.背包 的值是:

{"苹果":{"数量":3},"刀":{"数量":1}}

两种宏的输出对比:

{{xbgetvar::bf.背包}} 输出:

{"苹果":{"数量":3},"刀":{"数量":1}}

{{xbgetvar_yaml::bf.背包}} 输出:

苹果: 数量: 3 : 数量: 1

AI 看 YAML 更清晰,输出也用 YAML,格式统一不混乱。

使用示例

<bf-state> bf.日常.时间: "{{xbgetvar::bf.日常.时间}}" bf.日常.地点: "{{xbgetvar::bf.日常.地点}}" bf.战斗.回合: {{xbgetvar::bf.战斗.回合}} bf.背包: {{xbgetvar_yaml::bf.背包}} bf.玩家.状态效果: {{xbgetvar_yaml::bf.玩家.状态效果}} bf.战斗.对手.状态效果: {{xbgetvar_yaml::bf.战斗.对手.状态效果}} </bf-state>

注意事项

xbgetvar_yaml 输出多行,不要在外面套引号:

<!-- ❌ 错误:引号会破坏格式 --> bf.背包: "{{xbgetvar_yaml::bf.背包}}" <!-- ✅ 正确:换行后直接写 --> bf.背包: {{xbgetvar_yaml::bf.背包}}

五、斜杠命令

命令用途示例
/xbgetvar 路径读取变量/xbgetvar bf.玩家.体力 | /echo
/xbsetvar 路径 值设置变量/xbsetvar bf.玩家.体力 100
/xbaddvar 路径 增量数值加减/xbaddvar bf.玩家.体力 -20
/xbpushvar 路径 值数组追加/xbpushvar bf.日志 "新记录"
/xbdelvar 路径删除变量/xbdelvar bf.临时标记

带规则前缀的设置

/xbsetvar key="$list bf.新数组" ["item1", "item2"] /xbsetvar key="$free bf.新对象" {"key": "value"} /xbsetvar key="$range=[0,100] bf.玩家.体力" 50

六、世界书条件事件

在世界书中设置 <varevent>,当变量满足条件时自动触发。

可视化编辑器

不用写代码!点击世界书条目上的”条件规则编辑器”按钮(尺子+笔图标),就能打开图形化界面。

在这个界面里:

  1. 设置条件:选择变量名、比较方式(大于、等于、包含等)、目标值
  2. 设置显示内容:条件满足时要插入的文字
  3. 设置动作(可选):回复生成后要执行的命令
  4. 点击确认:自动生成代码并写入世界书

手写示例

<varevent> [event.低血量警告] condition: var(`bf.玩家.体力`) < val(`30`) display: "【系统】血量过低,请注意!" [event.高好感触发] condition: var(`bf.好感度`) >= val(`80`) display: "【系统】好感度已达到高级阶段" js_execute: "console.log('好感度达标')" </varevent>

事件优先级

  • 同一个 <varevent>:多条事件同时满足时,只触发最后一条
  • 想要多个都生效:创建多个 <varevent> 区块

七、数值映射

将自然语言自动转换为数值变化。

设置入口

在世界书的”条件规则编辑器”中,点击”bump 数值映射设置”按钮。

配置格式

每行一条规则:变量名(可空) | 词组或/正则/ | 数值

好感度 | /她(很)?害羞/i | 1 好感度 | 生气 | -2 心情值 | 很开心 | 2 | 略显疲惫 | -1

最后一行变量名为空,表示对所有变量生效。

使用效果

配置后,AI 可以这样写:

<plot-log> 变更: 好感度: 她很害羞 # 自动转换为 +1 心情值: 很开心 # 自动转换为 +2 </plot-log>

八、常见问题

Q:追加报错或没效果?

A:追加只能用于数组($list)。如果目标是对象($free),应该用录入。

# ❌ 错误:背包是对象 追加: 背包.苹果: ... # ✅ 正确:对象用录入 录入: 背包.苹果: 数量: 3

Q:删除没效果?

A:推荐用列表形式。如果用嵌套写法,末端必须有值。

# ✅ 推荐 删除: - 背包.苹果 # ✅ 也可以 删除: 背包: - 苹果 # ❌ 错误:末端没值 删除: 背包: 苹果:

Q:xbgetvar 和 xbgetvar_yaml 有什么区别?

A:输出格式不同。xbgetvar 输出 JSON,xbgetvar_yaml 输出 YAML。给 AI 看推荐用 YAML 版本,格式更清晰。两者替换时机完全一致。

Q:编辑消息后变量会乱吗?

A:不会。系统会自动回滚到编辑前的状态,再按新内容重新计算。

Q:一个 varevent 能触发多个事件吗?

A:不能。同一个 <varevent> 内多条事件同时满足时,只触发最后一条。要多个都触发,需要写多个 <varevent> 区块。