Skip to content

设计游戏状态 ​

好玩的世界都会记点什么。Battle Royale 记着 40 个学生,谁还活着。Sakura Season 记着三条各自独立的感情线。Wandering Diary 同时记着同伴的态度、背包和所在地点。

变量类型、行为规则和精准追踪的基础,见 变量。


先想清楚:该记什么? ​

加变量之前,先问自己:玩家需要感觉到什么是真的?

生存游戏里是资源:生命、饥饿、弹药,玩家得感觉到东西不够用。恋爱游戏里是关系的深浅,玩家得感觉到自己的选择在一点点累积成什么。推理游戏里是掌握了哪些线索,玩家得感觉到调查范围在缩小。

不用什么都建变量。叙事上的细节 AI 自己就处理得很好,除非天气在机制上有用,不然不需要 current_weather 变量。要记的是 会影响决定和后果 的东西。

一个简单的判断办法:如果这个值应该影响 AI 接下来写什么,就做成变量。如果只是点缀,让 AI 自己发挥。


变量的一生 ​

你在画布上 定义 一个变量(类型、初始值、范围)。玩家开新的一局时,它被 初始化 成初始值。游玩过程中有几种方式会改它:每次回复后的 精准追踪 小助手、AI 写的方括号 指令(针对没开精准追踪的变量)、行为、玩家界面上的按钮,以及根据别的变量重新计算的 公式。每回合结束时,整个游戏状态会被 保存 下来。

如果你给一个已经有人在玩的世界加了新变量,已有的存档下次加载时会自动拿到它的初始值。删掉一个变量,它会被悄悄过滤掉。你可以放心地反复调整变量设计,不会弄坏任何人的存档。


选对类型 ​

四种变量类型在 变量 里介绍过。画布上叫数值、文字、开关、列表/表格(卡的数据里是 number、string、boolean、json)。要考虑的是 什么时候用哪种,因为这会影响 AI 怎么跟你的世界打交道。

数值:值是一点点变化的,需要用阈值触发事件,或者变化的幅度有意义。数值的最小/最大值由引擎强制卡住,不用浪费提示词去告诉 AI「别让生命低于零」。

文字:值是一个标签而不是一个量,比如地点、心情、故事阶段。如果可选的就那么几个(阶段、心情),填上 可选值,精准追踪就只会在这几个里面挑。只有两种状态的(锁着/开着)别用文字,用开关。

开关:某件事要么发生了,要么没发生。最简单的类型,AI 最好管,拿来当条件设定和行为的门槛最合适。

列表/表格:一个变量需要存结构化数据的时候,比如带物品属性的背包、有好几层关系的阵营图、带嵌套进度的任务日志。简单的值别用它,[health: -10] 比 [stats.health: -10] 稳。这种类型用不了精准追踪,所以 AI 用指令来改它。


写行为规则:四个问题 ​

同一段行为规则,写故事的 AI 会读;打开了精准追踪的话,就是精准追踪的小助手来读。不管谁读,好的行为规则都回答了四个问题:

1. 这些值代表什么? 给 AI 一张对照表。数值就写每个区间在故事里是什么样;文字就列出有哪些状态;开关就说清楚开和关在故事里各代表什么。

2. 什么会让它变? 把情况写具体。关系变量写「友好的互动会加好感」就可以;生命写「受到物理伤害会掉血」也行。例子给得越多,AI 越前后一致。

3. 变多少? 大多数创作者在这里下的功夫都不够。给出幅度范围:小事小变,大事大变。没有这个,AI 要么反应过头(每次互动都 +20 好感),要么反应不够(差点死了生命只掉 2)。

4. 上限是多少? 限制每回合最多变多少,避免数值乱跳、破坏沉浸感。打开了精准追踪的话,填 每回合最多涨 和 每回合最多降,由引擎来卡。没开的话,就把上限写进行为规则:「单回合变化不超过 15」。

TIP

通常两到四句话就够了。行为规则比一小段还长的话,就该精简。告诉 AI 概念和边界,不用给它一本规则书。


几件值得知道的事 ​

delete 操作 用来从 JSON 对象里删掉一个键,或者从 JSON 数组里删掉一个元素。用普通的方括号写法就行:[npcs: delete "aria"](对象的键用带引号的字符串)或 [inventory: delete 0](数组下标用数字)。唯一的坑:delete 后面必须跟一个值,光写 [var: delete] 会变成一次隐式 set,把字符串 "delete" 写进变量,这几乎不会是你想要的。要批量删除或者按 id 删数组元素,也可以用 <UpdateVariable> 的 JSON Patch 块(见 AI 指令与宏)。


已发布世界里的真实做法 ​

记录关系 ​

Sakura Season 给每位女主角一个单独的数值变量,在行为规则里写好幅度范围。这是最简单的做法,2-5 个角色时很好用。

另一种做法:用一个 JSON 对象装下所有关系。

json
{
  "aria": { "trust": 50, "romance": 0, "met": true },
  "kael": { "trust": 30, "romance": 0, "met": false }
}

角色多的时候这样更清爽,因为 AI 可以用点路径改任何一个角色([relationships.aria.trust: +10]),加新角色也只要 merge 一个新键进去。代价是:单独的数值变量对 AI 来说更好懂,更不容易出错,还能用精准追踪。

角色只有 2-5 个、想要最稳的话,用单独的变量。角色很多、或者需要中途动态加角色的话,用 JSON 对象。

背包系统 ​

最简单的背包是一个文字变量,AI 用 append 往里加东西,Battle Royale 的死亡名单就是这么记的。要做带物品属性的正经背包,用 JSON 数组:

json
[
  {"id": "torch", "name": "火把", "qty": 1},
  {"id": "bread", "name": "面包", "qty": 2}
]

加东西用 push,删东西用 delete 加下标。行为规则里要告诉 AI 用哪种写法:

加物品时用 push,带上完整的物品对象。删物品时用 delete 加数组下标。背包上限 10 件,满了以后角色得先扔掉一件。

地点和场景状态 ​

一个叫 location 的文字变量(初始值:「起始村庄」)通常就够了。玩家走到哪,地点就跟着变(AI 写 [location: set "dark forest"],或者精准追踪从可选值里挑一个),再用挂在 location 上的 条件设定 把对应的场景描写发给 AI。

更复杂的世界,一个场景要记好几个方面,就用 JSON 对象:

json
{
  "area": "castle",
  "room": "throne-room",
  "time": "night",
  "alert-level": "high"
}

AI 可以只改其中一项:偷偷溜过守卫之后写 [scene.alert-level: set "low"]。


完整的指令语法,包括全部 9 种操作、简写的坑和 JSON 变量的点路径写法,见 AI 指令与宏。


常见错误 ​

记得太多。 不用什么都建变量。如果一件事 AI 在叙事里就能处理,不需要背后有个数字,那就别建。每多一个变量,AI 就多一份要读、要保持一致的状态。大多数好的世界记 5-15 样东西,很少有需要 50 个的。

行为规则写得太含糊。 「记录生命」对 AI 来说等于没说。「轻伤掉 5-15,重伤掉 15-25,0 = 死亡场景」就把 AI 需要的都说清楚了。变量能用还是被无视,差别就在行为规则。

简单类型就够却用了 JSON。 只需要一个数字,就用数值。[health: -10] 比 [stats.health: -10] 简单也更稳。JSON 留给真正有结构的数据。

数值忘了设最小/最大值。 没有边界的话,AI 可能把生命推到 -47,或者把金币推到 999,999。每个数值变量都设一下 范围,引擎会自动卡住。

不测试幅度。 把你的世界玩 10 个回合,看看数字感觉对不对。如果好感三次互动就从 15 跳到 80,幅度给得太大了;如果 20 回合后几乎没动,又太小了。试玩 时右边的 这回合 会写出每个数为什么变了、为什么没变。

ID 让 AI 难认。 用简单好读的 ID,比如 health、player-gold、aria-trust(变量的 ID 在它设置里的 高级 下面)。别用空格、特殊字符,也别用可能和内置宏撞名的名字(user、char、time、date)。如果想在设定里用 {{宏}} 写出它的值,用下划线别用减号(player_gold):带减号的 ID,包括新变量自动生成的随机 ID,都不能当宏用。


另见 ​

完整的变量 schema → World Spec: Variables