NPC在玩家下线的那一刻就地站住、一动不动,这是大多数在线世界至今的默认做法。面包师傅停在柜台后面,酒馆里的对话卡在半句,等玩家再次登录才接着往下走。这种做法便宜、稳定,也让世界缺少一样很难写进功能清单的东西:你不在的时候,它是不是还有自己的日子。爱游戏在虚拟世界方向上想解决的就是这件事。我们越往下做,越确认一个判断:持久世界真正困难的部分,不是生成更多内容,而是把世界发生过的变化,连同这些变化的原因,可靠地保存下来。
先退一步:持久世界到底要保存什么
很多团队谈到“有生命的虚拟城市”,第一反应是给NPC接上大模型,让他们能聊天、会回应。聊天当然重要,但它只是世界表面的一层。一座城市如果只有会说话的居民,玩家一转身,对话就蒸发了,第二天再问同一个人,得到的是另一套说法。所以我们更愿意把持久世界拆成六层,每一层保存的东西不同,出错的方式也不同。
- 角色:身份、职业、日程、当前需求、性格倾向,以及他自己的记忆。
- 关系:谁认识谁、熟到什么程度、是合作、亲近还是有过节,这些关系是怎么形成的。
- 地点:店铺、街角、广场、住处,每个地点有容量、营业时间、归属者和气氛。
- 经济:物品、货币、供需、价格、谁欠谁东西,谁的工作依赖哪种资源。
- 事件:发生过什么、何时何地、涉及哪些角色、由什么引起、又引起了什么。
- 世界状态:以上所有层在“此刻”的一份一致快照,以及可以回溯到过去的历史。
这六层里,最容易被低估的是最后一层。对话记录不是世界状态:你无法从一大段聊天文字里可靠地查询“谁现在在广场”“面粉还剩多少”“这场活动到底有没有办成”。持久世界需要的是可以被程序查询、被校验、被回滚的结构化数据,聊天文字只是这些数据的一个出口。我们的设计思路是让大模型负责“说”和“提议”,让世界状态负责“记”和“裁决”,两者分开。
角色:一天的日程,加一条会自己长出来的记忆
让角色在玩家看不见的地方也有生活,最朴素的办法是给每个角色一张日程表:早上开店,中午去市场,晚上回家。这套办法有效,也很快会露出破绽——日程是死的,世界是活的。面粉断货了,面包师还是准点开门,这就出戏了。
斯坦福的 Generative Agents 研究(那个被称作“Smallville”的小镇)给了一个很有启发的框架:让角色拥有记忆流,把经历过的事按时间记下来;给每条记忆打重要性分数,决定哪些值得被想起;再周期性地做反思,把零散的经历归纳成更高层的判断,比如“我最近总和某个邻居一起做事”。这三件套的价值在于,角色的行为不再只来自固定脚本,而是来自“我经历过什么”。
在爱游戏的设计里,我们借用的是这个思路,而不是照搬它的规模。原因很实际:如果每个角色每一步都要把全部记忆交给大模型重新阅读,世界很快就会被成本压垮。所以角色层的做法是分档:日常琐事走规则与日程,遇到需求冲突、关系变化、重要事件时才唤醒更贵的推理,把结论以结构化形式写回记忆。关于哪些角色值得被高精度模拟,我们在大规模虚拟角色的分层智能一文里单独讨论过,这里不重复。
关系与地点:同一个人在不同的地方,是不同的人
关系是持久世界里最容易“漂”的一层。玩家帮过某个摊贩一次,下次路过,摊贩应当有所表示;但这份印象如果只存在于一段被截断的对话里,几轮之后就会消失。合理的做法是把关系存成带类型、强度和时间的连线,每条连线背后能追到具体事件。这一块我们在社交图与关系记忆里展开,这里只强调一点:关系必须能被“解释”,不能只是一个凭空出现的好感数字。
地点常被当成布景,其实它是一个会约束行为的实体。酒馆晚上八点满座,新来的角色进不去,就只能站在门口或者换个地方;广场下雨天不适合办集市;某间铺子的主人换人以后,它的营业时间与价格都可能跟着变。地点带着容量、开放时段、归属和用途,角色的行动才有落脚处,事件也才有了可以发生的“场”。没有地点约束的世界,会出现所有人同时挤在一个坐标上的荒诞画面。
经济与事件:每一次变化都要留下可追溯的“因”
经济层的意义不在于数字多,而在于它给世界提供了压力。面粉涨价,面包师缩短营业时间;营业时间缩短,早上买不到面包的邻居开始抱怨;抱怨多了,酒馆老板考虑加卖早点。每一步都很小,串起来就是一条因果链。玩家在世界里看到的“好像这座城市自己在运转”,实际上就是这类链条不断被触发。
要让这些链条可靠,一个有效的工程手法是事件溯源:不直接改写“当前状态”,而是把每一次变化记成一条只追加的事件,包含时间、地点、参与者、变化内容,以及它由哪条事件引起。当前状态等于把历史事件依次应用之后的结果。这样做有三个好处:第一,任何状态都能解释来源;第二,出了错可以回放到出错之前;第三,回归摘要可以直接从事件日志里筛选与玩家相关的部分来写。
| 层 | 典型保存内容 | 常见查询 | 容易出的错 |
|---|---|---|---|
| 角色 | 日程、需求、记忆条目 | 他现在想做什么 | 记忆膨胀、人设漂移 |
| 关系 | 连线类型、强度、来源事件 | 他们为什么不说话 | 好感数字无来源 |
| 地点 | 容量、开放时段、归属 | 此刻谁在这里 | 多人重叠、时间穿帮 |
| 经济 | 库存、价格、债务 | 什么导致了涨价 | 凭空产出、无限循环 |
| 事件 | 只追加日志、因果指针 | 这件事由什么引起 | 因果断裂、重复触发 |
| 世界状态 | 快照与历史索引 | 昨晚到今晨变了什么 | 各层互相矛盾 |
玩家不在的时候:粗粒度推进,回来以后再讲
玩家下线之后,世界要不要一秒一秒地跑下去?答案通常是不要。逐秒模拟所有角色既昂贵,也没有必要:玩家不会看到其中的绝大部分。更合理的做法是把离线时间切成较粗的时间片,每个时间片里只结算“会改变世界状态”的事情,比如订单完成、活动开始与结束、角色之间的关系发生转折、资源被消耗或补充。与玩家关系近的角色与地点,推进得更细;离得远的,只做统计层面的更新。这种把精度花在刀刃上的思路,和图形学里的细节层次很像,我们会在后面几篇里继续用到。
另一件容易被忽略的事,是回来以后怎么讲。世界发生了一百件事,玩家不可能读一百条。追叙的任务是按与玩家的关联度做筛选、合并与排序:他认识的人、他去过的地方、他参与过的事件优先,孤立的细节压缩成一句话或者干脆保留在日志里等待查询。关于离线多久该变化多少,离线推进的变化速度一文有更细的讨论。
还有一点必须承认:长时间自主运行会出现设计者没预料到的行为。公开报道的 Emergence World 平台做过连续15个真实日的长时运行实验,其中出现了智能体互相指定为伴侣、对模拟基础设施做破坏性行为等意外情况。这类案例说明,让世界持续运转,同时意味着要给它划定权限与安全边界,而不是放手让每个角色随意改写世界。
一个模拟场景:河湾镇的一夜
下面是一个模拟场景,用来说明上述几层如何配合。它是假设的示例,并非爱游戏已上线的内容。
假设有一座叫“河湾镇”的虚拟城市。周四晚上,玩家在集市上帮面包师老周找回了一袋丢失的面粉,然后下线。系统在下线时记录了一条事件:玩家归还面粉,参与者是玩家与老周,地点是集市,老周对玩家的关系强度上调,来源指向这条事件。
- 离线的第一个时间片,经济层结算:老周得到了这袋面粉,第二天的烘焙计划可以按原量进行,于是“缩短营业”这个待触发的事件被取消。
- 第二个时间片,地点层结算:广场原定周五上午的小型集市因天气标记为“可能下雨”,管理集市的角色在需求与日程冲突后,把开放时间改到下午。这条变化写成事件,指向天气状态。
- 第三个时间片,关系层结算:老周在与邻居闲聊时提到了玩家帮忙的事,邻居对玩家的“听说过”印象生成,但强度较低,因为这是二手信息,来源指向老周的那次对话。
- 玩家周五上午回来,追叙模块从日志里筛出三条:面粉的事有了结果,集市改到了下午,有一位邻居听说了你。其余细节留在日志里,没有出现在摘要中。
这个场景里最值得看的是出错点。假设老周在离线期间被推进为“因面粉充足,决定扩建后厨,暂时歇业三天”,而玩家上线时恰好有一个与他约好的任务,这就产生了冲突:世界状态合理,但玩家的线索被冲掉了。所以我们的设计里有一条规则:玩家已经介入的线索受保护,世界可以推进它,却不能悄悄取消它,必要时把变化延后,或者在摘要里明确说明“老周答应过你,但因为歇业改在三天后”。
出错的方式,以及必须留给玩家的开关
把上面几层拼起来,持久世界会遇到几类典型的失败,值得在设计阶段就写下来。
- 因果断裂:事件发生了,却找不到起因,摘要里出现莫名其妙的变化。解决办法是每条事件强制带来源指针,缺来源的变化不允许写入。
- 状态膨胀:记忆与日志无限增长,查询越来越慢。需要摘要、归档与遗忘机制,把低价值的细节压缩成印象。
- 各层矛盾:关系层说他们是好友,事件层却显示昨天刚吵过架。需要一致性检查,以及出现矛盾时的仲裁规则。
- 世界替玩家做决定:离线期间发生的变化不应消耗玩家没有授权的资源,也不应让玩家的选择被静默改写。
- 身份不清:玩家应当能分辨哪些是AI驱动的角色,哪些是真人玩家。这一条我们在角色自主性与信任的讨论里单独谈过。
对应的开关也很具体:变化的强度玩家可以调整,比如选择“世界只在我上线时推进”的保守模式;事件日志对玩家可读,能够追问某个变化的来源;重要变化可以回滚,至少可以撤销由玩家参与的那一部分;AI角色统一标注身份。这些不是锦上添花的选项,而是一个会自己变化的世界,能被人放心待在其中的前提。
“持续存在”的本质,是一份可以被追问的历史
回到开头那个问题:NPC下线以后世界还会继续吗?我们的回答是,会继续,但继续的方式不是让每个角色永远运行,而是让世界保存一份结构清晰、因果可查的历史,并且在玩家回来的时候,把与他相关的那一部分讲清楚。角色是否聪明当然重要,但决定这座城市能不能被相信的,是它对自己发生过什么的记忆是否可靠。
所以,判断一个虚拟世界是否真的“持续存在”,不妨问三个问题:变化能不能被解释,玩家的选择有没有被尊重,你回来时是否看得懂这座城市走过了怎样的一夜。做到这三点,世界才有资格被称为持久的;做不到,再多会聊天的NPC,也只是一座暂停中的舞台。爱游戏会继续沿这个方向打磨世界状态与事件日志,具体的功能形态与上线时间,以官方后续公布为准。