您的位置:首页 > 理论基础 > 计算机网络

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

2018-03-08 21:08 726 查看
【参考博文】GAD-网络游戏同步技术

引言

  帧同步的形式很泛,根据不同游戏,使用的技术范围又不一样,所以大家都在讲方法论,要全面覆盖可能需要较大的篇幅,所以,我简单描述下。  假定大家对帧同步和状态同步有一定的认识,理论上的问题,我就不作过多解释了。  大家都知道,帧同步的核心是一致性,通过一致性的算法,使得各端输入一致的情形下,输出也是一致的,以此,可以解决同步的根本问题——仲裁的结果是一致的。  严格的帧同步,实现起来,解决算法一致性、输入一致性的问题基本就能实现了,然而实践过程中,由于网络延时、抖动、用户实时体验带来了一些其他的问题,使得问题解决起来变得更复杂,为了把问题聚焦,这部分内容我们就不重点讨论,后面的篇幅,主要聚焦在如何保证算法一致性和输入一致性。

1.算法一致性(或者确定性)

  算法不一致的主要原因是数值计算不一致和算法流程不一致。数值计算。 
浮点数的运算精度,在不同机器上有不同的表现,由此,导致了浮点数的精度可能导致计算结果不一致。 
所以,首要问题是把游戏逻辑部分(后续会有关于逻辑和表现分离的说明)所使用的浮点数运算全部改成具有一致性的数值运算。那么,怎么实现一种数值运算,既具有小数的表达能力,又有一致性的运算结果呢? 
常规方法中,尽管形态多样,但理论来讲,基本都是定点数(关于定点数的实现,可以翻看其他资料)。工程上,还要考虑定点数的精度,不同的精度,性能可能不一样,如何在精度和性能之间做平衡,需要结合自己的数值范围来确定。综上所述,我们导出需要实现的代码。 
实现1:定点数 
包含浮点数计算的常规算法,包含加、减、乘、除、绝对值、负运算等基本运算,另外,还要根据自己的使用实现开平方、指数函数、对数函数,三角函数等。 
其中定义域较大的函数,一般使用解方程的方法,比如牛顿法,定义域较小或者可以限制到一个周期以内的函数,比如三角函数,定义域在0-2pi,可以使用泰勒级数,具体用几阶,要根据自身对精度的要求,同时,由于有限项的泰勒级数只在某些定义域区间较好的拟合度,所以需要在通过数值分析来论证精度。最后,其实三角函数可以通过查表法来实现,性能快,精度与所需要存储的表格大小有关系。至此,我们拥有了一致性的定点数,我们用它来替换浮点数,然后在有些应用场景,逻辑层也会使用到更多的数学工具,比如向量、矩阵、欧拉角、四元数等,所以我们得实现这部分数学工具。实现2:一致性数学工具 
1. 向量、矩阵、欧拉角、四元数 
2.几何工具:点、线、面、体,各种几何元素的关系,相交性检测(做一个射击游戏,需要射线检测来判定是否命中),不是所有的都要写,用多少实现多少。除了上述的内容,还有逻辑层可能用了物理,物理部分主要包含碰撞检测和动力学 
比如抛出一个篮球,带抛物线的,需要一致性的物理运算,篮球碰到框则需要一致性的碰撞检测,碰到框之后的反馈也可能需要动力学表现(这部分可以是表现层)。实现3:一致性物理系统 
包含逻辑层需要使用的动力学和碰撞检测有些游戏逻辑需要动画系统支持,比如动作游戏,一个技能触发一个动作,动作除了表现层的动画(比如2D游戏的图片序列),还有一些影响逻辑的部分,比如动画控制了攻击判定框在时间轴的变化,这个时候需要实现逻辑层上的动画,主要需要解决的问题是,时间要改成整数或者定点数,另外,插值数据的类型也得使用一致性得数据类型,比如位置向量等。实现4:一致性动画系统 
与常规得表现层动画类似,可以根据需要简化。(比如不需要骨骼或者不需要融合)数值一致性的常规问题大致说这么多,还有些其他的内容,比如寻路,AI判定等凡是有浮点数的地方,全部换成定点数,最终还是需要根据项目需求,选择需要实现的内容。注意:定点数的运算性能比浮点数差很远,数量级在10-100以上,需要评估性能,好规划策划设定的问题规模。前面讲到,算法不一致的另外一个原因是:流程不一致。 
流程不一致的主要原因,可能是输入导致的,也可能是架构导致的。输入导致的算法流程不一致,这个问题,我们把它归到输入一致性,后面讨论。 
主要讨论架构导致的流程不一致。首先,帧同步需要在架构上做逻辑和表现分离,那么,什么是逻辑,什么是表现,其实没有绝对的定论,一般来说,对游戏结果有影响的部分为逻辑,对游戏结果没影响,只影响视觉、听觉、和其他与游戏结果无关的用户交互的部分为表现。整个帧同步的运行体系,简单的模型历程流程大致为: 
游戏框架跟从网络收取同步包->上传用户输入->分发同步包给逻辑内核(用户输入)->逻辑内核更新->逻辑内核发送消息给表现层->表现层更新需要注意的几点: 
1.逻辑更新频度和表现更新频度不一致 
2.逻辑内核更新的时间片是等间隔的,表现不一定 
3.同步包的内容是所有用户在某个时间片以内的输入容易出错的地方是,逻辑层和表现层交织在一起,表现层影响逻辑层,导致算法流程不一致。所以,帧同步实施的第一要务是明确分离逻辑层和表现层。

输入一致性

  完了算法计算一致性,接下来,我们要讨论,输入一致性的问题。 
这里所说的输入比较笼统,整理讲的是逻辑层的输入,包含一些全局变量、随机数的种子等等,最重要的一个问题是,逻辑层每帧的时间间隔是固定的,没有特殊需求的话,建议用整数表示,精确为毫秒。一致性的细节问题还有很多,先大概讲这么多吧。解决了一致性问题,一个严格的帧同步模型,后续实施就相对轻松了。强调下,为什么反复提“严格”的帧同步模型,因为实际运行过程中,很可能出现不严格的模型,当网络延时较大、抖动、以及游戏对输入响应有更高要求的时候,需要做一些预先的表现(表现层的预测),当结果预测不一致的时候,需要回滚,这个跟状态同步差不多,当然也有逻辑层的预测,算帧同步的高级应用,目前少有游戏使用。最后,说下回放、断线、反外挂、注意事项帧同步实现回放有天生的技术优势,因为有了一致性的保证,存储初始数据和用户输入,逻辑内核启动播放模式,将时间轴的用户输入,按照时间轴消耗即可。断线其实是回放的变种,应用形态不一样,技术差不多,可以不驱动表现。反外挂,帧同步的游戏结果是所有客户端一起说了算,算法一致性保证了大家的结果是一致的,可以简单使用少数服从多数的方式来判定谁用外挂,两方数量一致(或者差不多)的情形,可以使用部署在仲裁服务器上的逻辑内核来计算结果,以服务器为准。注意事项 
帧同步适用的情形:参与玩家数量不多(人数影响单个同步包的大小) 
有利情形:各端需要同步的NPC数量众多、游戏逻辑运算量很大大概就这么多,表达能力有限,感觉也没讲清楚,只是希望对你有所帮助。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  帧同步