一个总在滑板公园门口等你的NPC

很多开放世界里的体育NPC都有同一个问题:他们的全部存在感来自玩家。滑板公园门口的那个人,永远在那里,永远在做同一个kickflip,玩家走过去他就说“要不要比一场”。玩家输了他还在,赢了他也还在,三个月后他还是那句话。他没有想去的地方,没有想赢的比赛,也不会因为下雨就不来。

我们想让NPC变成另一种样子:一个叫小周的NPC,这个季度的目标是进入城市滑板巡回赛的前二十;为此他每周练四天,周末去不同的街区找新Spot;某次练习扭了脚踝,巡回赛只能缺席一站;下个季度他开始转向碗池,因为那边竞争没那么激烈。玩家可能在某个下午遇到他,也可能一个月都没碰上,但他的生活在继续。下面按“目标、日程、行动、结果、目标修正”这条循环来拆。

目标:每个NPC先有自己想要的东西

在im体育里,我们的设计是给每个体育NPC分配一组分层目标:

  • 长期目标:以季度或年为单位,例如“成为区域冲浪赛前十”“完成雪山三条黑道”“组建自己的骑行俱乐部”。
  • 中期目标:以周为单位,服务于长期目标,例如“本周练熟一个新扶手动作”“参加周六的山区限时赛”。
  • 短期意图:以小时为单位,例如“去海边看看今天的浪”“找人练三对三”。

目标的来源不是随机抽取,而是NPC自身的属性:擅长的项目、性格(好胜、谨慎、爱社交)、当前能力、所在城市有哪些设施。一个住在海边、擅长划水的NPC,更可能把“成为冲浪选手”作为长期目标;一个在滑板上屡屡受挫、却在骑行上进步很快的NPC,可能会慢慢换项目。

日程:资源有限,才需要取舍

目标需要落到日程上。NPC的日程受三类资源限制:

  1. 体力:高强度训练后需要恢复,连续比赛会累积疲劳,状态会下降。
  2. 时间:一天只有那么多小时,去雪山和去海边在地图上有距离,路上的时间也算。
  3. 伤病:受伤后部分项目暂停,恢复期内只能做低强度训练或换项目。

以一个模拟示例来说,小周本周想练新动作,又想参加周六的比赛。如果周三练得太猛导致疲劳,他可能主动把周五的训练改为休息,以保证周六的状态。这类取舍让NPC的行为变得可以理解:他今天没出现在老地方,不是系统出错,而是他有别的安排。天气也会改变日程,暴雨天户外滑板取消,他可能改去室内公园,或者干脆在家休息。

行动:在世界里真正做事

日程安排好以后,NPC要在世界里真的执行:移动到训练地点、在Spot上反复尝试、报名赛事、和其他NPC组队。玩家在场时,这些行动用完整的物理和动画表现;玩家不在附近时,改用粗粒度的统计推进,只算“练了多久、成功率变化多少、有没有受伤”。离线推进如何控制成本、保持一致,可以参考持续变化的体育世界

行动中最重要的是NPC之间的互动。两个目标相同的NPC会在同一个Spot相遇,成为训练伙伴或竞争对手;一个想组俱乐部的NPC会主动邀请风格相近的人。这些关系不需要玩家参与就能形成,玩家后来看到的是一个已经有人际网络的城市。

结果:成绩和经历都要留下来

每一次行动都会产生结果:能力的小幅变化、比赛名次、伤病、新的关系。这些结果写进NPC的长期记忆,包括比赛结果、遇到过的对手、宿敌关系、所属俱乐部、排名变化。与玩家的交集也记在里面:玩家曾在某场比赛中超过他,或者曾在他缺人时补位。这些记忆存放在im体育大模型的长期记忆层里,只保存关键事件和摘要,不保存每一帧动作。NPC职业层面的积累怎样呈现为一条完整的生涯曲线,NPC运动员职业生涯一文有专门讨论。

目标修正:失败了会换方向,成功了会定更高

循环的最后一步是修正目标。季度末,系统根据结果评估每个NPC的目标完成度:完成了,就设定更高一层的目标;接近完成,就延续;差得很远或伤病严重,就可能调整方向。小周如果连续两站巡回赛排在五十名以外,同时在碗池练习中进步明显,他可能把长期目标改成碗池项目。这种转变会在玩家面前自然出现:某天他出现在碗池边,说自己最近在练这个。

避免所有NPC都围着玩家转

最后一条设计约束是克制。与玩家相关的目标(比如“打败那个新来的人”)只能是NPC目标池里的一小部分,并且只在真正与玩家有交集后才会出现。大多数NPC的生活与玩家无关,他们有自己的比赛、朋友和挫折。im体育AI在生成NPC反应时也遵循这一点:NPC可以记得玩家,但不会把一天的安排都围绕玩家展开。正是因为他们不总是在等你,偶然遇到时的那句“上次那场你赢得不容易”才显得有分量。