游戏流式传输延迟补偿深入研究
使用本主题确定使用 Xbox Game Streaming 玩游戏时该游戏的延迟补偿。
视频游戏对快速操作的输入处理具有时效性。 设想有这样一个平台游戏:玩家的角色位于移动的传送带上,这条传送带通向悬崖,如图 1 所示。
玩家必须在适当的时间让角色起跳跳太早会错过下一个平台;跳太晚会在起跳前掉下悬崖。 如果游戏在流式处理时遇到网络延迟,这意味着等到玩家看到角色位于合适的起跳位置时,对于 Xbox 服务来说,他们可能已经掉下去了。
当游戏通过网络最终收到按下起跳按钮的通知时,从玩家的角度看,即使他们是在正确的视频帧上按的按钮,结果也会掉下去。
图 1. 显示角色在传送带上的示例平台游戏。
延迟补偿
为了补偿示例中的延迟(如图 1 所示),游戏具有其以前状态的记录。
用户按跳转按钮时,游戏将搜索该点,以确定用户从他们的角度在正确的时间按下该按钮。
更正延迟补偿的关键是知道过去需要搜索多少。 Xbox Game Streaming API 为此提供了一些选项。
平均延迟
在一些场景中,最简单但准确度最低的方法是使用平均延迟。
XGameStreamingGetStreamAddedLatency API 返回由流式传输添加的最近的平均延迟。 该平均值将拆分为输入延迟和输出延迟。
输入延迟表示用户输入服务器接收所花的时间,而输出延迟表示客户端设备接收和处理游戏呈现的视频帧所花的时间。
对于纯粹基于时间的操作,游戏可以将该平均值用作对于操作发生在多久以前的估计值。 但是,网络延迟可能会有所不同,即使框架对框架也不同,因此这种方法不精确。 此外,流添加的延迟度量不包括非流式处理部分延迟,例如游戏运行模拟和呈现所花的时间。
带输入的帧令牌
XGameStreamingGetAssociatedFrame API 解决此问题的方式是:提供玩家在按下按钮(或更改任何其他输入)时看到的关于游戏状态的精确信息。
帧开始时,使用 Microsoft 游戏开发工具包 (GDK) 的游戏会调用 ID3D12Device::WaitFrameEventX
并接收 D3D12XBOX_FRAME_PIPELINE_TOKEN
。 可以使用该 D3D12XBOX_FRAME_PIPELINE_TOKEN
键来将当前状态保存为所选择数据类型(如井号映射)中的稍后位置。 框架完成后,游戏将 PresentX
标记标记上。
PresentX
PresentX 确保令牌以及匹配的视频帧被自动发送到游戏流式传输客户端。
发送到服务器的输入将伴有客户端上当前显示的帧的令牌。 当游戏收到消息 IGameInputReading
,你可以将消息传递到 XGameStreamingGetAssociatedFrame
API 以返回令牌。 你可以使用该令牌查找之前的状态并根据这个存储的状态处理输入。
注意
如果输入未更改 (用户未触摸控制器,或者由于他们只按住按钮),则没有新令牌。
不带输入的帧令牌
在某些情况下,你必须知道用户最近看到过哪些内容,即使其输入未发生变化。 返回到图 1 中显示的示例,角色在达到传送带末端时会掉下去。 部分挑战和规则是在这些时段内回应的。
理想情况下,流式处理用户与非流式处理用户具有完全相同的响应时间。 由于延迟,应更改窗口的结束时间,以便接受在窗口末尾收到的输入。
为此,游戏可以在未按下按钮时使用延迟令牌。 如果输入读取没有操作且与窗口末尾的状态相匹配,则用户反应失败,且结果相当复杂。
XGameStreamingGetLastFrameDisplayed API 返回 D3D12XBOX_FRAME_PIPELINE_TOKEN
客户端最近显示的框架的密钥。 它不断更新,因此你可以在任何时候调用它,并查看玩家是否看到了动画的结束。
注意
使用 XGameStreamingGetLastFrameDisplayed
的方式可以与 XGameStreamingGetAssociatedFrame
相同。 处理输入时 XGameStreamingGetAssociatedFrame
使用令牌,因为它返回进行输入时屏幕上的令牌。 如果已过更多时间 XGameStreamingGetLastFrameDisplayed
可能会从较近期的帧返回令牌。
更多场景
使用上一节中的三个 API,多种情况下可以补偿延迟。 以下各节提供了更多基于常见多用户延迟薪酬方法的示例。
移动
移动角色、相机或瞄准可以分为两类。
具有不同后果的移动
当用户进入碰撞或瞄准并射击时,游戏必须对运动产生的结果做出用户可观察的决定。
在这些案例中,通常将二元决策延迟到游戏收到与需要做出决策的帧关联的输入时。 对于诸如碰撞或从悬崖上掉下来等内容,游戏可能需要在等待时为某些内容设置动画。
例如,在游戏接收实际输入的时间,用户可能会剪辑到对象中,或者浮动或跳转到某个标记上。
常规移动
常规运动是任何导航或瞄准,但是对于像驾驶这样的情况而言,累积运动比给定帧上发生的运动更重要,这可能很重要。
输入投影
游戏可能会根据输入的历史记录,根据用户看到提供输入的框所花的时间,对项目进行未来计划。 例如,如果缩略图的坐标在 0.5,并且延迟令牌为 3 帧时,每帧平均增加 0.1,那么游戏可能会以 0.8 为间隔处理。
当然,当玩家改变速度和方向时,这可能导致错误的预测。 为了结合玩家的实际输入,游戏可以保留先前预测状态的缓冲区。 该状态的实际输入出现时,游戏可以使用真实输入从该状态重新运行模拟并更正可见的状态。
如上所述,应等待规则触发任何结果,直到产生实际输入。 在延迟较高的连接中,这可能会导致可见的“跳动”,游戏可能希望为错误预测提供一些平滑过渡或其他掩饰。
这种策略的一个注意事项是:将呈现的帧传输到客户端的时间更长。 为了使玩家的视图与服务器模拟同步,游戏可能需要通过平均输出延迟进一步向前预测。 对于服务器模拟速度受外部多人游戏服务器控制的多人游戏而言,这一点可能很重要。
特定规则预测
与其预计输入历史记录,游戏可以更好地猜测用户会做什么。 这包括简单的启发式猜测(例如二维平台游戏角色向右移动)以及基于玩家历史记录的机器学习。 和输入预测一样,游戏可以报了预测缓冲区,并在获得实际输入时重新运行模拟。
触控跟踪
使用本机触控输入的游戏可能在玩家的手指下放一个光标或标线。 在延迟较高的情况下,玩家会注意到光标随移动的手指而动。 如本主题的"常规移动"部分所述,游戏可能会预测移动触控输入的方向和速度,使光标通常位于移动手指下。
多用户
依赖于 Xbox Game Streaming 运行的多人游戏的一个优势在于,用户的 Xbox 服务器很可能位于同一 Azure 数据中心。 如果游戏的多人游戏服务器也位于该 Azure 区域中,各台 Xbox 与多人游戏服务器之间的延迟可能低于一毫秒。 不过,玩家的客户端设备的距离会更远。
多人游戏通常已有处理游戏与多人游戏服务器之间的延迟的策略。 这些策略往往涉及来自多人游戏服务器的时间戳或帧计数器。
将这些时间戳和计数器与帧令牌关联,多人游戏就可以将流纳入延迟计算中。 这可帮助多用户对流式处理用户具有合适的体验,并有助于在流式处理和非流式处理用户间建立字段。