笔者介绍:姜雪伟,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构建的简单协议来解决问题。

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

网络游戏之帧同步物理模拟相关推荐

  1. mtk 帧同步_【小松教你手游开发】【面试必读(编程基础)】网络游戏同步方式(帧同步和状态同步)...

    在做网络游戏的时候首先要做的是选择一种同步方式来使用,网上的文章都是说帧同步与状态同步的选择,但是又经常讲的模糊不清,我大概整理了一下,并且有一种我们现在项目用的网络同步方式 状态同步 状态同步就有好 ...

  2. 多人网络游戏服务器开发基础学习笔记 II: 帧同步 | 游戏客户端预测原理分析 | FPS 游戏状态同步

    这篇是对书本 网络多人游戏架构与编程 的学习第二篇(第一篇:多人网络游戏服务器开发基础学习笔记 I:基本知识 | 游戏设计模式 | 网游服务器层次结构 | 游戏对象序列化 | 游戏 RPC 框架 | ...

  3. 网络游戏数据同步的实现 一:状态同步、帧同步的基本原理概述

    什么是游戏的数据同步 数据同步是指使用某种方式让同在一局游戏中的多个客户端保持游戏进程同步. 什么游戏需要数据同步? 联机游戏(cs.饥荒.dead4ife2等) 网游(魔兽.天堂.传奇) 需要快照. ...

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

    本文为转载文,转自 https://www.cnblogs.com/cxihu/p/5836747.html 打野家认为这个文章写的很清晰明确,合理的阐述了帧同步的原因原理,从理论上弥补了打野家对帧同 ...

  5. 浅谈《帧同步网络游戏》之“框架”实现思路

    版权申明: 本文为"优梦创客"原创文章,您可以自由转载,但必须加入完整的版权声明 更多学习资源请加QQ:1517069595获取(企业级性能优化/热更新/Shader特效/服务器/ ...

  6. 网络游戏同步方式(帧同步和状态同步)

    在做网络游戏的时候首先要做的是选择一种同步方式来使用,网上的文章都是说帧同步与状态同步的选择,但是又经常讲的模糊不清,我大概整理了一下,并且有一种我们现在项目用的网络同步方式 状态同步 状态同步就有好 ...

  7. 多人网络游戏服务器开发基础学习笔记 I:基本知识 | 游戏设计模式 | 网游服务器层次结构 | 游戏对象序列化 | 游戏 RPC 框架 | 帧同步和状态同步

    今天继续开新坑,尽管过了很多 Unix 套接字编程的坑,但是实际还是有很多不同场景和性能的需求,以及最服务器架构的内容也就接触过 preforking 和 master 带 worker 而已. 所以 ...

  8. 【网络游戏同步技术】帧同步的一致性

    [参考博文]GAD-网络游戏同步技术 引言 帧同步的形式很泛,根据不同游戏,使用的技术范围又不一样,所以大家都在讲方法论,要全面覆盖可能需要较大的篇幅,所以,我简单描述下. 假定大家对帧同步和状态同步 ...

  9. 网络游戏中的帧同步与状态同步

    帧同步的基础概念 相同的输入 + 相同的时机 = 相同的输出. 客户端发送操作信息到服务器,服务器收到后转播给所有的客户端,客户端接收服务器的操作信息后计算游戏行为的结果, 然后通过广播下发游戏中各种 ...

最新文章

  1. iOS访问系统日历 添加提醒事件
  2. java实现验证码功能
  3. PySCF :基于Python的化学模拟框架
  4. poj1321 DFS
  5. 请求getServiceTime出错
  6. hdu4099(斐波那契数+字典树)
  7. php 通用购物车,PHP实现购物车代码[可重复使用]
  8. 7-113 堆栈操作合法性 (20 分)
  9. 消息称Uber正洽谈出售旗下自动驾驶部门ATG给Aurora
  10. ViewPager——PagerTitleStrip和PagerTabStrip
  11. vue中动画效果的实现
  12. fences(桌面整理软件)与eDiary3.3.3下载链接
  13. 经济学中的100个基本概念
  14. 胃溃疡 ---- 四药同治(丽珠得乐、奥美拉唑、阿莫西林 + 克林霉素)
  15. python报错:UnicodeDecodeError: ‘gbk‘ codec can‘t decode byte 0xa3 in position 48
  16. CentOS7系统管理-庄博-专题视频课程
  17. Python网络爬虫--项目实战--scrapy爬取人人车
  18. PHP爬取汽车品牌数据《三》
  19. 作为硬件工程师,常用设计资源合集
  20. 百炼-1664-放苹果-C语言-递归算法入门

热门文章

  1. 支付宝上线直播功能,网友怒赞:YunOS成了
  2. jitsiMeet与Callkit的对接心得
  3. 计算机基础知识教程打印a4纸,学会这9个Word打印方法,不浪费任何一张A4纸,涨知识了...
  4. 在世界上搜词采用计算机,计算机二级Word,Excel真题及答案
  5. wiki中文语料下载及繁体转简体的处理。
  6. 2022中国地理信息产业大会 荣誉背后国产GIS的自主创新力量
  7. MySql安装手册(二进制安装)
  8. Java多线程之线程安全问题
  9. codeigniter mysql主键_codeigniter mysql视图与查询
  10. 离散数据与连续数据区别