关于游戏的网络同步探索

找了些资料,以后慢慢更新

著名游戏网络同步方案汇总

下表为本人汇总的各著名游戏的网络同步方案,已尽力添加引用来源。
通过该表,读者可尝试思考:为什么他们会采取这样的方案?找找看有否什么规律?相信看完下文,应该可以找出答案。
注,本文的锁步同步(Lockstep)特指只同步操作的确定性锁步同步(Deterministic
Lockstep)。本文不讨论快照同步(Snapshot Synchronization、Snapshot
Interpolation),认为其等同于状态同步(State Synchronization)。

网络传输协议(Network Transport Protocol)

本文中的网络传输协议(Network Transport Protocol),主要是指UDP协议和TCP协议。
在TCP/IP协议族(互联网协议套件,Internet
Protocol Suite)中,UDP和TCP位于传输层(Transport
Layer),它俩都独立依赖于更底一层网络互连层(Internet Layer)中的IP协议(网际协议,Internet Protocol)。

Berkeley套接字(Berkeley Sockets)是进行UDP或TCP通信的标准API,属于POSIX标准,所以Socket、Berkeley Socket、POSIX Socket、BSD Socket,都指同一个东西。
通过Socket这个类及其方法,很简单就能进行UDP或TCP通信。

UDP在IP之上,增加了端口(Port)的概念,收发双方从而能通过约定好的几个端口来进行不同功能的通信;增加了校验和以增加了一定的校验能力。
所以也能看到UDP其对于网络游戏来说,和IP几乎有很相似的特性:

    • 不可靠不保序传输(Unsequenced Unreliable Transmission),即传输不保序,也不确保可达,某个具体数据包在传输的过程中,是可能丢失的;也可能数据包到达了,但数据出错从而校验失败,也被Socket丢弃掉,
    • 传输快,多亏了不可靠,所以Socket不会浪费时间和带宽,对丢失的数据包进行重传
    • 应用通过Socket成功拿到的UDP数据包保证是正确的
    • 连接快,因为根本就无连接。多亏了不可靠,所以收发双方每次通信都是无状态的,所以通信前不需建立连接
    • 简单,上层应用能按需实现额外的传输特性(QoS),比如保序不可靠、可靠不保序、可靠保序、最新状态传输(Most Recent State)、快速冗余传输(Quickest Possible Delivery),等,
    • 报头小,节省带宽

       
  • 除了也有端口、校验外,TCP主要额外提供了:
    • 保序可靠传输(Sequenced Reliable Transmission),通过报头Sequence number、Acknowledgement Number、Window Size等字段来实现,
    • 流量控制(Flow Control),通过报头的Window Size实现,接受者把自己的期待流量提示给发送者,防止发送方以过快的速度发送数据给接收方
    • 拥塞控制(Congestion
      Control),通过报头的Sequence number、Acknowledgement
      number等字段,以及通过Timer机制实现,据此收发双方可判断数据包丢包,而推断出当前网络是否拥塞,并采取一些措施来减缓数据发送。

    TCP本身足够复杂,本文并不能细究他们的具体原理,仅简述和网络游戏同步相关的特性:

    • 本身提供保序可靠传输,不需游戏作额外工作,很适用于回合制游戏、RPG等通信频率不高的游戏类型
    • 传输慢,正因TCP本身对所有发出的数据包,都考虑保序可靠、流量控制、拥塞控制(包含了慢启动(Slow-Start),而这些功能对于大部分游戏类型,特别是快节奏(Fast

      Paced)游戏是不适用的,因为这类游戏通信频率高,要求低通信时延,新发的数据包可能比已发送的数据包更重要(比如游戏状态数据包,游戏状态经常改变,与其重传旧状态数据包,倒不如将其抛弃,赶快传输新的状态数据包),
    • 连接慢,首次通信需要进行著名的三次握手连接,
    • 复杂且黑盒,难扩展,
    • 报头大,不适用于数据包数量多的情况

    综上所述,大多网络游戏采用UDP。
    TCP更加适用于回合制等慢节奏游戏,如炉石传说等。
    另魔兽世界使用了TCP,且取得了辉煌的商业成功,故也有不少MMORPG也使用TCP,尽管如此,未见得TCP是最好的选择。[9]

网络同步模型(Network Model)

最主要的网络模型是:锁步同步(Lockstep)状态同步(State Synchronization)
本文针对“帧”有以下两种术语定义:
逻辑帧,在本文会被称为Tick,游戏在逻辑层面是离散的过程,即可以认为是一个逻辑帧一个逻辑帧地进行逻辑运算,逻辑帧号是指游戏逻辑层面当前处于第几帧;
渲染帧,在本文会被称为Frame,游戏在画面呈现层面也是离散的过程,即可以认为是一幅画面一幅画面地呈现给玩家的,渲染帧号是指游戏当前呈现的是第几幅画面;
游戏的逻辑帧率和渲染帧率是互相独立的,比如一个游戏可以是20帧每秒的逻辑帧率、60帧每秒的渲染帧率。

游戏逻辑是一个逻辑帧一个逻辑帧地持续离散进行的,可以抽象为:

游戏在第 个逻辑帧时,根据玩家信息 和游戏配置 ,进行初始化运算 ,得出初始化状态集合

游戏在第 个逻辑帧时,根据前一个状态集合 和游戏配置 ,根据第 帧收到的外部变化原因集合 ,进行逻辑 运算,得出第 个逻辑帧新的游戏状态集合

是游戏状态变化的根本原因的集合,往往是各个玩家操作。
是游戏状态的集合,由众多状态子集组成,其中有以下2个重要子集定义,

,其中 是一些能被玩家所明显观察到的对象的状态集合, 为一些可用于推导最终状态的中间状态集。

在网络同步时,称从客户端发出信息进行网络传输的过程为上行,称客户端经过网络传输收到信息的过程为下行,则,

一般锁步同步的本质是,上下行都仅包含游戏外部变化原因集合
一般状态同步的本质是,下行仅包含游戏运算得出的结果状态集合 (更精确地说是状态子集 ),上行包含和/或状态子集

注,本文的锁步同步特指只同步操作的确定性锁步同步(Deterministic Lockstep)。本文不讨论快照同步(Snapshot Synchronization、Snapshot Interpolation),认为其等同于状态同步。

网络同步模型简史

1990年代便已有针对每一步(step、turn)进行停止等待(stop-and-wait-type)的网络同步方式,即客户端一步一步地把自己的信息发给其他客户端,这些信息可以是客户端的本地网络对象的状态,也可以是玩家操作[13][14]。
同期,P2P(见下网络拓扑结构一节)是更为盛行的网络连接拓扑结构。但P2P的停止等待同步方案有lookahead-cheating类型的外挂,比如使用外挂的客户端A在第k步时故意等到别人的第k步信息都到达了之后,才进行逻辑运算并发送自己的第k步信息,等于客户端A总是偷窥别人的游戏决策之后才作出自己的决策,从中获取到不公平的先手利益。
所以,2001年,Nathaniel
Baughman和Brian Neil
Levine在此基础上,提出锁步同步(Lockstep)[14]以对抗该外挂。每个客户端在发送第k步的明文信息之前,先针对明文信息进行加密计算生成“预提交哈希值(commitment

hash)”并发送给其他客户端,待客户端接收到第k步的所有客户端的预提交哈希值之后,才发送自己第k步的明文信息给其他客户端,等到收到所有其他客户端的第k步明文信息后,本客户端为这些明文信息逐一生成明文哈希值并和预提交哈希值对比,如果发现客户端B的明文哈希值和预提交哈希值不等,则代表客户端B是外挂。
至此,锁步同步是既可以同步客户端玩家操作、也可以同步客户端权威网络对象的状态。所以也并不要求确定性。
然后,同样也是2001年,Mark
Terrano和Paul Bettner在帝国时代(Age of
Empire)游戏中为了解决游戏中海量网络实体的问题,基于锁步同步,方提出了确定性锁步同步(Deterministic
Lockstep)[15],即每一步同步的,仅仅只有玩家操作数据,而不包含网络对象数据。

另外,1999年,Christophe
Diot和Laurent Gautier提出了Bucket
Synchronization[13],即把时间按固定时长(约40ms)划分为Bucket,该时长内的数据归属于该Bucket。在一开始时有一个较长的播放时延(Playout

Delay,约100ms),用于等待其他客户端的Bucket数据传输到达。没及时到达的数据不会被直接应用,但也可以保存起来用于可能发生的外插(Extrapolation)比如航位推测(Dead
Reckoning)。
其Bucket,事实上即逻辑帧(Tick)的概念。

最后,2003年,Ho Lee等人针对上述锁步同步的每一步的时延都较大的缺点进行优化,借鉴Bucket Synchronization,提出了Pipelined Lockstep[16]。
至此,现在为大家所理解的:操作同步、不等待超时玩家的操作的确定性锁步同步,终于成型。

总而言之,每一步都停止等待的网络同步很早就有,却缺个简短的名字。为了安全性提出的“Lockstep”方案使用广泛,逐渐成为停止等待同步的代名词。翻译成中文时,引入了时间帧的概念Bucket

Synchronization也和Lockstep已经结合起来使用,便将“step”译为帧,称为“帧同步”。然后更狭义的确定性锁步同步用得越来越多,大家也逐渐把“Deterministic
Lockstep”简称为“Lockstep”,所以,确定性锁步同步口头交流中更常被简称为“帧同步”,有时也会被称为“操作同步”。
所以,本文也把确定性锁步同步简称为锁步同步。

锁步同步(Lockstep)

因为锁步同步只同步变化的原因 ,所以要求各个客户端的运算逻辑 是严格确定性(Deterministic)的,所有客户端才能算出严格一致的结果 。如果在计算过程中包含了一丝不确定的因素,即会导致各个客户端运算时有一丝的误差,那么接下来的逻辑帧误差会越来越大,导致蝴蝶效应,从而最终各个客户端看到的结果状态完全不一样了。
以著名锁步游戏王者荣耀为例,假设你的客户端和其他正确客户端已经发生不一致,其他玩家在正确客户端作出的合理操作,到达你已经状态不一致的客户端做逻辑演算时,却变得不一样的状态结果,这个结果很可能是不合理的,所以你很可能会看到其他玩家英雄都奇怪地乱跑,甚至跑到塔下送死,或者对着空气放技能,等。
游戏要做到严格确定性,须做好一些事情:

  • 不使用浮点数而使用定点数,或限定各客户端所运行的硬件及操作系统从而浮点数的运算是一致的,
  • 确定性的随机数机制,
  • 确定性的容器及算法(增加、移除、排序等),
  • 隔离和封装逻辑层,以防止其他不确定性的调用,
  • 如需,则也须做到确定性的物理机制、导航机制、动画骨骼机制等,
  • 排查所有引起异常(exception)的逻辑

对锁步同步游戏来说,不同步造成的游戏体验是极差的,偶现的不同步问题是极为头痛的, 因此制定检测不同步的管线流程对锁步同步游戏来说是至关重要的,比如帧状态哈希对比、静态代码扫描分析、帧级别甚至函数级别的高性能日志、外网不同步率统计,等。

状态同步(State Synchronization)

因为状态同步只同步游戏运算得出的结果状态,所以需要有机器来进行权威(Authoritative)的状态计算,并传输给其他机器,其他机器都将采纳接收到的状态。
本文只讨论权威机器只有一部的情况。视乎具体网络拓扑结构,这部权威机器会被称为服务器(Server)或主机(Host),其他没有权威的机器称为客户端(Client)。
所以,状态同步,口头交流中也常不太精确地被称为“CS同步(Client-Server)”。

包括Halo、Unreal、Unity、Overwatch等,几乎所有著名状态同步的技术实现,都最终参考了Mark Frohnmayer和Tim Gift于1998年发布的The TRIBES Engine Networking Model[1]一文进行实现。

状态同步开发过程中最基础也最重要的是,不管客户端网络对象当前处于什么状态,它都要做到能正确地完全退出旧状态,退出后不能残留旧状态的逻辑层效果,并正确地进入服务器告知的新权威状态,从而带来新状态的逻辑层效果。
也要避免以非状态同步的方式同步权威状态,比如服务器只传输 给客户端(而不传输 ),让客户端在本地计算出网络对象的新状态。这可能会带来服务器客户端之间状态不一致。比如某个网络对象在第k个逻辑帧发生了从而进入,且之后 都不再改变,那么服务器只会在第 帧才会发送;之后若客户端因断线重连或实时死亡重播等原因导致该网络对象状态在客户端被重置为 ,但当前服务器逻辑帧已大于 ,服务器不会再传输Ik给客户端,那么该网络对象在客户端里就错误地一直停留在了。

之前在锁步同步讨论到的确定性指的是“严格的”确定性。在讨论状态同步时,偶尔也会提及“不严格的”确定性(比如[4]的Q/A阶段最后一个问题),此类确定性只要求客户端服务器之间满足“足够的”确定性,以便客户端能够比较准确地进行预表现即可,因为客户端最终会采纳服务器的状态,修正累计的误差。

原文  https://zhuanlan.zhihu.com/p/56923109

原文地址:https://www.cnblogs.com/dragon2012/p/11903515.html

时间: 2024-11-09 13:48:16

关于游戏的网络同步探索的相关文章

游戏中的网络同步机制——Lockstep(帧同步)

本文来自: https://bindog.github.io/blog/2015/03/10/synchronization-in-multiplayer-networked-game-lockstep/#top 值得参考文章:https://blog.codingnow.com/2018/08/lockstep.html 可参考的项目工程:https://github.com/CraneInForest/LockStepSimpleFramework-Shared 0x00 前言 每个人或多或

《守望先锋》架构设计与网络同步

原文链接 Overwatch Gameplay Architecture and Netcode Timothy Ford Lead Gameplay Engineer Blizzard Entertainment 翻译:kevinan 在GDC2017[Overwatch Gameplay Architecture andNetcode ]的分享会上,来自暴雪的Tim Ford介绍了<守望先锋>游戏架构和网络同步的设计.一起来看看吧. 哈喽,大家好,这次的分享是关于<守望先锋>(

游戏化 网络文学开启版权变现模式

起点中文网和腾讯文学在网络文学变现上殊途同归,都在利用网络文学的游戏形态,缔造一个传统文学所没有的互动参与的大融合,让读者和作者之间的界限越发模糊. 文/张书乐 刊载于<法人>杂志2014年9月刊 8月中旬开幕的上海书展上新增了"网络文学会客厅",上海网络作家协会.盛大文学.腾讯文学分别举行专场活动,血红.蝴蝶蓝.猫腻.洛水.忘语等众多网络"大神"亮相书展,众多读者纷纷前往一窥"大神"们的风采. 而在8月1日,同在上海举办的China

游戏引擎网络开发者的 64 做与不做 | Part 1 | 客户端方面

摘要:纵观过去 10 年的游戏领域,单机向网络发展已成为一个非常大的趋势.然而,为游戏添加网络支持的过程中往往存在着大量挑战,这里将为大家揭示游戏引擎网络开发者的 64 个做与不做. [编者按]时下,游戏网络化已势不可逆,因此,对于游戏开发者来说,掌握网络引擎的打造技巧同样不可避免.近日,Research Industrial Systems Engineering GmbH 安全研究员 Sergey Ignatchenko「拥有 20 年以上的工程经验」在 IT Hare 上撰文,深入分享了游

Unity3D RTS游戏中帧同步实现

帧同步技术是早期RTS游戏常用的一种同步技术,本篇文章要给大家介绍的是RTX游戏中帧同步实现,帧同步是一种前后端数据同步的方式,一般应用于对实时性要求很高的网络游戏,想要了解更多帧同步的知识,继续往下看. 一.背景 帧同步技术是早期RTS游戏常用的一种同步技术.与状态同步不同的是,帧同步只同步操作,其大部分游戏逻辑都在客户端上实现,服务器主要负责广播和验证操作,有着逻辑直观易实现.数据量少.可重播等优点. 部分PC游戏如帝国时代.魔兽争霸3.星际争霸等,Host(服务器或某客户端)只当接收到所有

实时pvp(皇室战争)网络同步研究

实时pvp的关键在于对抗延迟和网络同步. 这里先分享几篇非常经典的文章 http://www.skywind.me/blog/archives/131 https://www.zhihu.com/question/36258781 http://www.skywind.me/blog/archives/1048 之前我也分享过一篇关于帧同步的思考,这篇文章最后也分享了几篇非常不错的英文文章. http://blog.csdn.net/langresser_king/article/details

ue4网络同步笔记

网络同步主要的概念是 复制.  不是以前的S,C逻辑分离.  是S复制到C通过 Switch Has Authority  将S与C的逻辑在程序内分离. 所属权:每个连接到S的C都有自己的 控制权.从PlayerController开始,PlayerController属于 连接,PlayerController控制的Pawn属于PlayerController,Pawn内的组件属于Pawn,最终都属于 连接. 都拥有 所属权.所属权涉及 Actor 的变量,RPC 复制条件.相关文档 条件性复

IEEE1588精密网络同步协议(PTP)

1  引言 以太网技术由于其开放性好.价格低廉和使用方便等特点,已经广泛应用于电信级别的网络中,以太网的数据传输速度也从早期的10M提高到100M,GE,10GE.40GE,100GE正式产品也于2009年推出. 以太网技术是"即插即用"的,也就是将以太网终端接到IP网络上就可以随时使用其提供的业务.但是,只有"同步的"的IP网络才是一个真正的电信级网络,才能够为IP网络传送各种实时业务与数据业务的多重播放业务提供保障.目前,电信级网络对时间同步要求十分严格,对于一

实现一个简单的Unity网络同步引擎——netgo

实现一个简单的Unity网络同步引擎Netgo 目前GOLANG有大行其道的趋势,尤其是在网络编程方面.因为和c/c++比较起来,虽然GC占用了一部分机器性能,但是出错概率小了,开发效率大大提升,而且应用其原生支持的协程很容易就能开发出高并发的服务端程序.笔者接触VR行业两年有余,接触了一些商业unity网络引擎,总觉的用的东西都落伍了,于是自己写了一个简单的引擎.目前实现了的基本功能: 支持房间概念. 支持灵活的数据同步方式,包括帧同步和RPC. 支持自定义事件的发送. 也实现了一个简单的de