事实证明,加入多人模式后,开发时间和问题数量至少是我预想中不做多人版 Sunderstar 的三倍。即使是相对简单的太空射击游戏,只要客户端和服务器对飞船或弹丸的位置产生分歧,事情就会变复杂。

问题在最基本的操作中就能看出来。等待服务器更新会延迟移动输入的响应。发生碰撞时,客户端与服务器之间的偏差可能把飞船拉回修正后的位置。迟到的更新则让远程物体的运动难以保持平滑。

射击也有类似问题。武器存在散布时,即时本地射击与服务器弹丸难以可靠匹配。向较旧的服务器位置修正,可能让弹丸向后跳,或看起来突然变速。命中特效也必须及时出现,并且不能在服务器确认到达时再次闪烁。

我修改了本地飞船,使它使用与服务器相同的计算立即预测运动,再在服务器更新到达时修正偏差。其他飞船在收到的位置之间平滑移动;更新延迟时,则进行有限度的运动估算。

碰撞也需要预测。客户端现在使用服务器的碰撞数据,计算玩家飞船对小行星或其他飞船的碰撞反应。只有玩家自己的飞船在本地移动。小幅位置修正会被平滑处理,传送等大幅变化则立即发生。

可视弹丸现在会采用服务器给出的方向,但不会向后跳,并保持恒定速度。命中特效在本地出现,对应的服务器特效会被抑制,避免同一次命中闪烁两遍。命中和伤害依然由服务器决定。

我还统一了弹丸生成、炮口闪光、声音和重放所使用的炮口位置。修改运动预测时,甚至暴露了 Host 模式下的一个机器人归属问题,也一并进行了修复。

自动检查已通过,Unity 网络模拟中的指标也已经改善。不过,这些改善仍需要在使用独立服务器的真实互联网对局中验证。

如果你做过多人游戏,哪个看似简单的功能花了你最多时间才真正做好?