“幽灵回放”式对手为什么撑不过第三局

最省事的滑雪AI对手是这样做出来的:让开发者或者离线求解器在赛道上跑出一条最快路线,录下每一帧的位置和速度,比赛时让AI沿着这条录像滑,再按难度把整体速度乘上一个系数。简单难度乘0.9,困难难度乘1.0,“专家”难度乘1.03。

玩家第一局会觉得对手很强。第二局开始注意到,对手每次都在同一个旗门前同一个位置压刃,在同一个跳台上同样的高度起跳。到第三局,玩家已经能预测对手每一段的动作,剩下的事情只是追上一条会动的线。更糟的是,当赛道因为降温结冰、因为下雪变慢时,这条录像不会改变——对手在冰面上依然稳稳过弯,玩家却在打滑。

im体育不希望对手是一段回放。我们希望它是一个在赛道上做决策的选手:它读雪况、看前面的人、按自己的性格承担风险、会犯错,也会从错误和对手身上学习。下面按我们内部设计AI滑雪选手的五个步骤来讲,每一步都会说明这个选手“能知道什么”和“不能知道什么”。

步骤一:把赛道切成可以决策的段

一条完整赛道对决策来说太长了。AI需要把它切成一系列段,每段有明确的入口和出口条件,然后在段与段之间做连接。我们的切分依据不是等距,而是地形和旗门:

  • 加速段:坡度稳定、没有强制转向,目标是减少阻力、保持低姿态。
  • 弯道段:从刹车/减速点开始,到出弯后重新获得稳定加速为止。
  • 技术段:连续旗门或反向弯,节奏比单个弯的速度更重要。
  • 地形段:跳台、波浪道、陡坡变缓的折点,关键是起跳和落地时机。

每一段内部,AI在若干条候选线之间做选择。候选线不是凭空随机的,它们由几何约束生成:外线、中线、内线,以及在它们之间的过渡。每条候选线都有一组属性:理论速度、所需立刃角度、对雪面的依赖程度、出口位置和出口速度。

这里最重要的一点是“段与段之间的耦合”。一个弯如果为了抢出弯速度走了外线,出口会偏向赛道外侧,下一个反向弯就只能走一条被迫的线。所以AI的选择不是每段独立的最优解,而是一个短距离的前瞻:当前段加后面一到两段,整体代价最低的那个组合。

步骤二:读雪况,而不是读录像

候选线的“理论速度”并不是固定值。同一条外线,在压实雪上可能是最快的,在冰面上可能是最慢的,因为选手必须在弯前大幅减速才能过去。这个问题在动态雪况一文里有完整的链条:温度、降雪、风和前面选手的滑行不断改写雪面网格,抓地随之变化。

AI选手在比赛前和比赛中都会读取雪况,但读取方式受到限制。我们把它能拿到的信息分成三类:

  1. 赛前公开信息:气温曲线、夜间降雪量、风向风速、赛道分段雪况概览。这些是玩家同样能看到的。
  2. 赛前观察:如果它在比赛前滑过预览、或者看过前面选手的滑行,它会对部分段落有更准确的判断。
  3. 实时感知:比赛中它“看到”的前方雪面。这部分受能见度影响,大雾和平光下它看到的距离和清晰度都会下降。

AI不能直接读取网格里的真实数值。它拿到的是带误差的估计,误差大小取决于它的经验、信息来源和能见度。一名在这座山上比过很多次的老将,对冰面位置的估计更准;一名第一次来的新人可能会低估外线的冰。这种“知道得不完全”本身就是选手之间差异的来源。

换句话说,AI的优势不能来自上帝视角。它强,是因为它更会读雪、更早注意到那片冰,而不是因为它能看见地图里的数字。

步骤三:赛道上不止一个人

单人计时赛里,路线只受环境影响。但在同场竞速、追逐赛或者多人出发的越野滑雪赛里,其他选手本身就是约束。

位置决定可选的线

如果玩家正好在前面两个身位、占着内线,AI想走内线就只能跟在后面吃减速,或者冒险从外线超越。这时它的选择就不再只是“哪条线最快”,而是“以当前的位置和速度差,哪条线能让我在出弯时领先”。我们在代价函数里加入了碰撞风险和被阻挡的时间损失,让AI在拥挤段落会主动避开别人的线。

前面的人会改变雪面

在同一轮里,前面选手的滑行会刮出更硬的轨迹、推出新的雪包。AI如果能看到前面选手在某个弯打滑,它会调低对那条线的估计。玩家也可以利用这一点:观察对手在哪里失误,然后避开。

它不知道你下一秒要做什么

AI能看到玩家当前的位置、速度和朝向,就像比赛中一个真实选手能用眼睛看到对手一样。它不能读取玩家的手柄输入,也不能预知玩家下一秒要往哪边压刃。它对玩家行为的预测只能基于观察到的运动趋势和它记住的玩家习惯。

步骤四:同一个赛道,不同性格走出不同的线

如果所有AI都在做同一个代价最小化,它们仍然会收敛到同一条线,只是出发时间不同。这就是为什么我们要引入选手性格。性格在技术上是代价函数里的一组权重和阈值,它决定了选手愿意为多少速度承担多少风险。

选手类型 风险阈值 典型选择 容易出问题的地方
激进型 冰面上也敢走外线,跳台尽量少减速 雪况估计偏差时更容易摔
稳健型 优先走抓地好的线,弯前留足余量 直线较长的赛道上吃亏
技术型 在技术段抢节奏,直线段保守 体力消耗集中在后半程
地形型中高把时间押在跳台和波浪道 侧风天的落点控制
跟随型 观察领先者,选择前面人验证过的线领先者失误时被带偏

性格不只影响选择,还影响对环境的反应方式。比如同样看到大雾,激进型可能只把风险阈值略微下调,稳健型则可能直接改走全程最保守的线。这使得同一场雾天比赛里,对手之间的差距会被拉开或者重新洗牌,玩家能感受到“今天这个天气对谁有利”。

我们也让性格随比赛情境变化。领先时,大多数选手会变得更保守;落后且剩余段落不多时,稳健型也可能冒一次险。这是真实比赛里常见的心理,而且它让对手的行为有迹可循——玩家能看出对手“急了”。

步骤五:失误要真实,学习要有边界

失误从哪来

一个从不失误的AI,即使路线选择得再合理,也会让人觉得是机器。我们的做法不是在固定时间点随机插入失误,而是让失误从三个具体原因产生:

  • 估计误差:它以为那段是压实雪,其实是薄新雪盖着冰。
  • 执行误差:在接近抓地极限时,控刃精度有一个与技术水平相关的波动。
  • 疲劳:长距离、湿重雪、连续技术段都会消耗体力,体力下降后执行误差增大。AI没有无限体力。

因为失误有原因,玩家可以理解它,甚至利用它:在对手体力下降的后半程发起追击,或者在冰面较多的比赛日期待激进型对手出错。

学习什么,不学习什么

AI会在多场比赛之间积累经验。它会记住这座山哪些段落容易结冰、哪个跳台侧风大、某个弯在下午会变快。它也会记住玩家:这名玩家习惯在第二段抢内线、在最后一个弯总是冒险。下一次比赛时,它可能提前占住内线,或者在最后一个弯前留出空间避免碰撞。

但学习有明确的边界:它学的是可观察的行为模式,而不是玩家的输入数据;它提升的是路线判断和稳定性,而不是物理参数。它不能因为输了几次就获得更高的最高速度,也不能因为玩家领先就在看不见的地方悄悄加速。

这一点和难度设计直接相关。很多游戏用“橡皮筋”来维持比赛紧张感:落后的AI自动加速,领先的AI自动放慢。在im体育里我们反对这种做法,更倾向于调整对手阵容、天气窗口和AI的路线质量,具体思路在滑雪动态难度里写得更细。

我们给AI对手定下的几条禁令

把上面的内容反过来说,就是一份明确的禁止清单。这些是im体育AI滑雪对手在设计上不允许做的事情:

  1. 不读取玩家的手柄或键盘输入。
  2. 不在比赛中修改自己的物理参数,包括最高速度、摩擦系数和抓地。
  3. 不无视天气:冰面、新雪、风、能见度对它的影响与对玩家相同。
  4. 不拥有无限体力。
  5. 不在玩家视野外暗中加速或减速来维持差距。
  6. 不读取雪面网格的真实数值,只能基于观察和经验做估计。

这份清单的意义在于:当玩家输给AI时,他应该能在回放里找到原因——对手在第二段选了更好的线,或者在第四段没有犯我犯过的错。当玩家赢了AI时,他也知道是自己读懂了雪况,而不是系统放了水。

一场模拟比赛里的四种线

用一个设计示例收尾。一条五段的大回转赛道,比赛日早上气温零下六度,夜里降雪五厘米,第二段长弯外线结冰,第四段跳台有中等侧风。

激进型选手读到了外线的冰,但它的估计偏乐观,认为冰面只有十来米。它走外线,减速不足,出弯时轻微侧滑,损失约0.3秒。稳健型选手直接走内线新雪,出弯速度低,但第三段稳定。技术型选手在第二段走中线,在第三段连续小弯里抢回时间,但第五段体力下降,直线上被稳健型反超。跟随型选手看到激进型在外线侧滑,第二段果断改走中线,结果是全场最稳的一轮。

玩家第一轮走外线摔了。第二轮他参照跟随型的线路走中线,同时注意到激进型在第四段跳台被侧风推偏,于是提前把落点往左修正,这一轮他赢了。

这个结果不是事先写好的,它来自赛道分段、雪况估计、位置交通、性格权重和失误模型的共同作用。换一天、换一种天气,它们的排序就会变。这也是im体育大模型在体育开放世界大模型里想要承担的角色之一:给每个AI选手一套像真人一样“看、想、做、错、学”的决策过程,而不是一条永远不变的最优路线。