网络游戏之帧同步物理模拟

原创 2017年07月25日 19:36:09

笔者介绍:姜雪伟,IT公司技术合伙人,IT高级讲师,CSDN社区专家,特邀编辑,畅销书作者,已出版书籍:《手把手教你架构3D游戏引擎》电子工业出版社和《Unity3D实战核心技术详解》电子工业出版社等。

CSDN视频网址:http://edu.csdn.net/lecturer/144

本篇博客我们将用网络中的帧同步技术进行物理模拟,帧同步是通过仅发送控制该系统的输入而不是该系统的状态将系统从一台计算机连接到另一台计算机的方法。 在网络物理模拟中,这意味着我们发送少量的输入,同时避免发送状态像位置,方向,线速度和每个对象的角速度。

它的好处是带宽与输入的大小成比例,而不是模拟中的对象数量。 是的,凭借帧同步技术,您可以将一百万个物体的物理模拟网络与只有一个相同的带宽进行网络连接。

虽然这在理论上听起来很棒,但在实践中很难实现帧同步,因为大多数物理模拟不是确定性的。 编译器,OS和甚至指令集之

间的浮点行为差异使得几乎不可能保证浮点计算的确定性。帧同步技术模拟物理是比较困难的。

帧意味着给定相同的初始条件和相同的输入集合,您的模拟给出完全相同的结果,我的意思是完全相同的结果。那么确切的说,你可以在每一帧结束时对整个物理状态进行校验它将是一样的。

在上面你可以看到几乎是帧同步的模拟 左边的模拟由玩家控制 从相同的初始条件开始,右侧的模拟具有与两秒延迟相同的

输入。 两个模拟都以相同的增量时间向前推进(确保完全相同结果的必要前提条件),并且两个模拟都应用相同

的输入。 请注意,在最小的差异之后,模拟将进一步失去同步 这个模拟是非帧同步

正在发生的事情是,我使用的物理引擎(Open Dynamics Engine)使用随机数生成器来随机化约束处理的顺序以

提高稳定性。 这是开源的! 不幸的是,因为左边的模拟器以不同的顺序对右边的模拟进行了限制,导

致了略微不同的结果。

幸运的是,在同一台机器上,使用相同的二进制文件和相同的操作系统将ODE所需的所有内容都

是通过dSetRandomSeed运行模拟之前将其内部随机种子设置为当前帧。 一旦这样做,ODE给出完全相同的结果,

左右模拟保持同步。

需要注意的是, 即使上述模拟在同一台机器上是帧同步,但并不一定意味着它也将在不同的编译器,不同的

操作系统或不同的机器架构之间帧同步。 事实上,由于浮点优化,调试和发布版本之间的差异可能不是帧同步的。

接下来看看具体实现,我们的示例物理模拟由键盘输入驱动:箭头键施加力量使玩家立方体移动,保持空间

提升立方体并吹动其他立方体,并保持“z”启用运动模式。

我们如何处处理联网入?我们必须发送键盘的整个状态吗? 不需要发送整个键盘状态,仅需要影响模拟的键的状态。 这也不是一个

好策略。 我们需要确保在右侧完全相同的输入,完全相同的时间,所以我们不能通过TCP发送“按键”和“关键释

放”事件。我们所做的是代表一个结构体的输入,从键盘中输入这个结构:

  struct Input
    {
        bool left;
        bool right;
        bool up;
        bool down;
        bool space;
        bool z;
    };
接下来,我们将这个输入从左边的模拟发送出去,让右边的模拟知道输入属于帧n。

这里是关键部分:右边的模拟只能在帧n的输入时模拟帧n。 如果没有输入,则必须等待。

举个例子,如果您正在使用TCP发送,您可以简单地发送输入,没有其他信息,另一方面您可

以读取进入的数据包,并且接收到的每个输入都对应于一个帧,用于模拟向前推进。 如果给定的渲

染帧没有输入到达,则右侧不能前进,它必须等待下一个输入到达。

所以让我们继续使用TCP,你每帧发送一次(每秒60次)从左到右的模拟输入。这里有点复杂 

由于我们无法模拟前进,除非我们有下一个的输入,仅仅通过网络到达任何输入,然后在输入端运行模拟是不够的,因为结果会非常不稳定。

在60HZ网络发送的数据通常不会在每个数据包之间达到很好的间隔,即1/60秒。

如果你想要这种行为,你必须自己实现。

你在这里做的是类似于Netflix在流式传输视频时所做的工作。 你最初暂停一下,所以你有一个

缓冲区,以防一些数据包迟到,然后一旦延迟已经过去,视频帧间隔正确的时间间隔。 如果你的缓

冲区不够大,那么视频播放将是交错的。 使用帧同步,您的模拟行为与完全相同的方式:当缓冲区

不够大以平滑抖动时显示挂起, 当然,增加缓冲区大小的成本是额外的延迟,所以你不能只是缓解

你的办法摆脱所有问题。玩家不会用1秒的额外延迟玩你的游戏。

解决的目标是在平均条件下,播出延迟缓冲器为帧n,n + 1,n + 2等提供稳定的输入流,很好地

隔开1/60秒, 在最坏的况下,时间到达帧n并且输入尚未到达,但它返回null,并且模拟被迫等待。

如果数据包已经聚合并传送迟到,则可能有多个输入准备就绪到每帧出库。 在这种情况下,我限制

在每个渲染框架的4个模拟帧,所以模拟有机会赶上,但不会模拟这么长时间,它进一步落后,“死亡

之螺旋”。

使用这种播放缓冲策略并通过TCP发送输入,我们确保所有输入可靠和按顺序到达。 这是方便的,

毕竟,TCP是为这种情况设计的:可靠的有序数据。

但是这种想法是有问题的:

以上您可以看到模拟网络使用TCP上的帧同步在100ms延迟和1%数据包丢失 如果您仔细观察右侧,

您可以每隔几秒看到一次。 这里发生的是每次数据包丢失时,TCP都必须等待RTT * 2(实际上可能会更糟)。

发生碰撞是因为帧同步正确的模拟,但是不能模拟没有输入n的帧n,所以它必须暂停等待输入n被重新发送!

这不是所有的, 它随着延迟和数据包丢失的增加而明显变差。 这是在250ms延迟和5%数据包丢失的情况

下使用TCP上的帧同步的相同模拟网络:

如果你没有丢包和/或非常小的延迟时间,那么你很可能会用TCP获得可以接受的结果。 但请注意,如果您

使用TCP,则它在恶劣的网络条件下表现得非常糟糕。

我们要代替TCP, 我们需要确保所有输入的可靠和顺序到达。 但是,如果我们在UDP数据包中发送输入,那

些数据包将丢失。 如果不是在事件发生后丢失数据包,并重新发送丢失的数据包,那么我们会冗余地包含每个UDP

数据包中的所有输入,直到我们知道另一方已经收到它们为止?

假如输入非常小(6位), 假设我们每秒发送60个输入(60fps模拟)和往返时间,我们知道它们将在30-250ms

范围内。 最多可能是2秒的最坏情况,在这一点上,我们会超时连接。 这意味着平均而言,我们只需要包含2-15帧

输入和最坏情况,我们需要120个输入,最差的情况是120 * 6 = 720位, 这只有90个字节的输入! 这是完全合理的。

当然,从右边的模拟到左边还需要另外一个数据包,所以左侧知道哪个输入已被接收。 每个帧正确的模拟从网

络中读取输入数据包,然后将它们添加到播放延迟缓冲区,并跟踪其接收到的最新输入,并将其作为“ack”或输入确

认发送回左边。

当左侧接收到该确认信号时,丢弃比最近接收的输入更早的输入。 这样,我们只有少量的输入与两次模拟之间

的往返时间成比例。

我们通过改变游戏的规则来替换TCP。

我们已经实现了完全不同的,更符合我们要求的,而不是“在UDP上实现TCP的95%”。
对于一个协议,由于我们知道它们很小,

冗余地发送输入,所以我们不必等待重新传输。

那么这种方法比通过TCP发送输入好多了?

让我们来看看…

上面的图片显示了使用这种技术在UDP上同步的帧同步,具有2秒的延迟和25%的分组丢失。 想象一下TCP在这些条件下

可能会有多糟糕。

因此,总而言之,即使在TCP应该具有最大优势的情况下,在唯一依赖可靠序列数据的网络模型中,

我们仍然可以轻松地用UDP构建的简单协议来解决问题

希望对读者有所帮助。。。。。。。。。。。。。。。。。






版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

《ImageEffects(屏幕特效)官方文档翻译》——编写屏幕特效【Writing Image Effects】

译注:鉴于翻译的混乱情况,将Texture译为纹理(实际上也应该如此),因为纹理和贴图还是有一些区别的。Image Effects是Unity3D中一种进行图像后期渲染的方式。...
  • kevlis
  • kevlis
  • 2016年11月01日 11:27
  • 514

Unity3D 海水多线程渲染算法实现

笔者介绍:姜雪伟,IT公司技术合伙人,IT高级讲师,CSDN社区专家,特邀编辑,畅销书作者,已出版书籍:《手把手教你架构3D游戏引擎》电子工业出版社和《Unity3D实战核心技术详解》电子工业出版社等...
  • jxw167
  • jxw167
  • 2017年07月21日 17:27
  • 548

帧同步在竞技类网络游戏中的应用

原文链接:http://blog.sina.com.cn/s/blog_674f1bd20101omv7.html 帧同步在网上可以搜的资料比较少,关于游戏的更是没有,不过,实现的原...
  • gzzheyi
  • gzzheyi
  • 2015年08月04日 10:01
  • 3071

帧同步--竞技类网络游戏设计方案

一、        前言  帧同步,根据wiki百科的定义是,一种对同步源进行像素级同步显示的处理技术,对于网络上的多个接入者,一个信号将会通过主机同步发送给其他人,并同步显示在各个终端上。同步...

帧同步在竞技类网络游戏中的应用

帧同步在网上可以搜的资料比较少,关于游戏的更是没有,不过,实现的原理也比较简单,最近几天就写了份关于帧同步的文档,当作给同事扫扫盲,顺便也在这里发发,可以给其他人参考参考            ...

网络物理模拟(三):具有确定性的帧同步

翻译:张乾光(星际迷航) 审校:陈敬凤(nunu) 大家好,我是格伦·菲德勒。欢迎大家阅读系列教程《网络物理仿真》,这个系列教程的目的是将物理仿真的状态通过网络进行广播。 在之前的文章中,我们...

网络游戏的客户端同步问题 .

有关位置同步的方案实际上已经比较成熟,网上也有比较多的资料可供参考。在《带宽限制下的视觉实体属性传播》一文中,作者也简单提到了位置同步方案的构造过程,但涉及到细节的地方没有深入,这里专门针对这一主题做...

聊聊网络游戏同步那点事

http://www.cnblogs.com/murongxiaopifu/p/6376234.html c#语言规范 阅读目录 0x00 前言0x01 游戏同步中的...

网络游戏中的(低精度)时间同步

对于网络游戏来说,从物体的移动、攻击到最基础的计时等等,都需要客户端与服务器保持时间的相对一致,那么服务器与客户端同步便是一个必须要解决的问题。通常,网络游戏都会利用心跳来进行同步,那么当客户端并不需...

网络游戏同步

原文地址:http://dev.gameres.com/Program/Abstract/DeadReckoning.htm 同步在网络游戏中是非常重要的,它保证了每个玩家在屏幕上看到的东西大体是一样...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:网络游戏之帧同步物理模拟
举报原因:
原因补充:

(最多只允许输入30个字)