V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Game Engines
Unreal Engine
MyCryENGINE
yazoox
V2EX  ›  游戏开发

请教一下,类似 LOL,王者荣耀, Diablo3 这样的网络游戏,如何同步多机实时的数据?

  •  
  •   yazoox · 2021-03-22 09:44:16 +08:00 · 7868 次点击
    这是一个创建于 1093 天前的主题,其中的信息可能已经有所发展或是发生改变。

    比如:
    一局游戏,
    LOL 10 人
    王者荣耀 10 人
    暗黑 8 人 \

    几个人的操作,显示,这些数据,都是要在 10 台机器 /客户端“同步“ 更新的!

    类似这样的服务器&客户端架构,数据结构,数据同步,是如何设计实现的?有没有相关的文章详细讲解这个的?

    p.s. 因为最近在看 Microsoft 的 Fluid 技术,用于多人协作的。但微软的这个,我个人理解,对于“实时”性要求不高,有点延时关系不大。只要数据准确,正确,不出错。

    但是网络游戏不一样,对于实时性应该要求挺高的。好奇是如何设计和实现的。

    45 条回复    2021-03-24 12:32:00 +08:00
    vus520
        1
    vus520  
       2021-03-22 09:49:39 +08:00
    都是走服务器中转,一般延迟能控制在 80~30ms 以内,你说的实时,怕是没见过 460 哦
    yunhui
        2
    yunhui  
       2021-03-22 09:51:17 +08:00
    Vegetable
        3
    Vegetable  
       2021-03-22 09:56:57 +08:00   ❤️ 4
    服务器有一个逻辑帧概念,也就是一个时间点的状态快照。客户端去和逻辑帧同步就行了,涉及到两个指标,一个是服务器本身有多少帧,一个是客户端同步的频率是多少 tickrate 。
    timethinker
        4
    timethinker  
       2021-03-22 09:58:08 +08:00
    帧同步需要客户端计算结果严格一致,不然就会走偏,服务端在一局的游戏中只扮演数据转发的角色。
    chinvo
        5
    chinvo  
       2021-03-22 09:59:03 +08:00 via iPhone
    帧同步 和 状态同步
    yeqizhang
        6
    yeqizhang  
       2021-03-22 10:01:36 +08:00
    之前看主播解释攻速阈值时,说过帧这概念..
    ReferenceE
        7
    ReferenceE  
       2021-03-22 10:16:03 +08:00 via Android
    建议可以去康康 SignalR ?好像也是微软的
    eason1874
        8
    eason1874  
       2021-03-22 10:27:19 +08:00
    游戏有大厅服务器和专门的对战服,玩家匹配的时候就是客户端在确认用哪个对战服,然后客户端用 WebSocket 或者 UDP 直连对战服。

    想知道客户端和服务端怎么交互数据,可以去腾讯云看一下游戏云解决方案,比如游戏联机对战引擎 SDK 文档的 API 介绍。
    wasd6267016
        9
    wasd6267016  
       2021-03-22 10:34:18 +08:00   ❤️ 5
    帧同步、状态同步
    一句话给你介绍:
    帧同步,所有客户端根据服务器下发的逻辑帧(包含的信息是十台设备的操作输入),在客户端演算一遍,输入一致算法一致 所以每个人看到的结果一致,谁延迟高谁吃亏

    状态同步:
    服务器以一定的频率下发各个玩家角色的状态给各个客户端,客户端以服务器信息为绝对真理,努力往这个结果上靠
    Macv1994
        10
    Macv1994  
       2021-03-22 10:42:53 +08:00
    同问,我也一直想问这个问题
    Still4
        11
    Still4  
       2021-03-22 10:43:21 +08:00   ❤️ 4
    wow 是状态同步,客户端下发操作命令,服务器运算操作结果,产生的结果推送到同屏的客户端,如果所有人都在不停的动,服务器负载是人数的平方,70 级的时候屠城只要 7 个团在一个房间内就会宕机,大概 300 人

    war3 是帧同步,客户端下发操作命令,服务器直接推送操作指令给同屏客户端,接收的客户端负责运算结果,要求所有客户端版本相同,不允许跨版本连接。录像文件可以很小,因为只需要记录操作行为,实际结果是录像+客户端共同完成的
    dbpe
        12
    dbpe  
       2021-03-22 11:02:06 +08:00
    @Still4 有些游戏有延时补偿的..那是状态同步呢还是帧同步呢?
    polo3584
        13
    polo3584  
       2021-03-22 11:03:39 +08:00
    自己写过一个简单帧同步的格斗游戏,简单来说,服务器用一个固定频率发送客户端数据,有两个流派,一个是服务器计算之后再发送显示的内容,另一种是服务器发送固定数据到客户端再运算显示。
    joesonw
        14
    joesonw  
       2021-03-22 11:22:47 +08:00
    实时竞技都是帧同步, 每个客户端把当前帧(例如过去 1/60 秒)的动作, 用 UDP 发出去. 而且包得很小, 为了避免做排序重发. 一般都把当前帧和之前的 2(或多)帧放到一起发出去, 还得在一个 MTU 大小内, 避免被拆包.
    ETiV
        15
    ETiV  
       2021-03-22 11:27:31 +08:00 via iPhone
    服务器同时跑一个同样的场景、地图的主要(验证)逻辑
    然后把各个客户端传上来的数据依次 patch 当前状态
    再把这一帧的状态下发下去
    HytonightYX
        16
    HytonightYX  
       2021-03-22 11:27:46 +08:00   ❤️ 1
    第一次听到这两个概念感觉蛮有意思的,知乎上搜了下,这篇文章还不错
    https://zhuanlan.zhihu.com/p/104932624
    luoqeng
        17
    luoqeng  
       2021-03-22 11:36:26 +08:00
    完全不是一个技术类别,没啥可类比的。

    microsoft Fluid 类似于 CRDT 分布式框架,CRDT 主要无中心服务器,p2p 情况下可以最终一致结果。CRDT p2p 具体应用 聊天 文字协同编辑

    游戏服务器是一台中心服务器,中心服务器决定客户端请求先后顺序,广播给其他客户端,没有一致性问题。
    gBurnX
        18
    gBurnX  
       2021-03-22 12:26:04 +08:00   ❤️ 7
    简单来说,王者荣耀这类游戏不是 p2p 游戏,而是严格的 客户端 - 服务器 模式( C-S )。
    简单说一下流程:

    1.玩家的客户端, 负责把玩家的操控指令,发到服务端。

    2.服务端负责接收所有玩家客户端的操控指令,并负责计算,最后把计算结果反馈给所有的玩家客户端。

    3.玩家客户端负责接受服务端的运算结果,并显示出来。

    4.以上的过程,是会有延迟的。但有些技能是立即释放。立即释放技能的流程是:
    第一阶段,玩家在客户端点击这类立即释放的技能按钮,客户端把释放指令发送到服务端,客户端同时立即显示技能释放画面。

    第二阶段,服务端把技能释放后的结果,传回到客户端,客户端此时显示技能释放后的效果,比如有没有打中或对方英雄、中招的物体状态的变化(比如 HP 、行动速度等等)。

    所以:
    A.当客户端网络卡顿时,你会发现你无法操作角色,比如控制角色行走、拐弯、释放技能,此时会变得卡顿或无法操作。

    B.当客户端网络卡顿时,你会发现技能释放后,虽然画面会显示技能释放动画,但被击中的对象,却没有及时反馈被击中后状态的改变,比如扣血、被控住,等等。

    5.因为延迟的存在,并且很多技能是立即释放的。所以,如何把立即释放的技能进行阶段分解,减少玩家因延迟的卡顿感,这就是游戏设计者需要考虑的用户体验问题。

    WOW 在这个问题上是花了大量心思的,当年网络延迟波动有可能高达一两秒,但游戏画面与操作却没有太大的卡顿。不像现在的 LOL 和王者荣耀,延迟大于 100ms 就会有明显感觉。这就是游戏体验在设计上的差距。
    gBurnX
        19
    gBurnX  
       2021-03-22 12:30:20 +08:00
    另外楼上有些小伙伴说了帧同步,实际上没有纯粹的帧同步游戏,不然只要有网络延迟,游戏的不同步率只会越来越大。

    帧同步率的游戏,其实是帧同步 + 每隔一段时间( 1s )的全局状态同步。当年 war3 和 starcraft 的联机挂就是针对全局同步的漏洞来实现联机时资源修改的功能。
    Keyes
        20
    Keyes  
       2021-03-22 13:09:32 +08:00 via iPhone
    @gBurnX 关键帧[捂脸哭]
    bbao
        21
    bbao  
       2021-03-22 13:18:36 +08:00
    王者荣耀是 16ms 一次帧同步,服务器负责收集和推送客户端进行重放,卡顿时候,那种快进快打的效果,就是客户端播放过往同步的帧
    fighte97
        22
    fighte97  
       2021-03-22 13:47:02 +08:00
    看你到底要做什么,除了 FPS 和 FTG 其他的根本不需要低延迟
    xishijt
        23
    xishijt  
       2021-03-22 14:01:07 +08:00
    歪个楼,所以戴森球什么时候出联机?
    dbpe
        24
    dbpe  
       2021-03-22 16:32:54 +08:00
    @gBurnX 所以这里我很好奇.WOW,战地这些有延时补偿的游戏是怎么做的呢..
    wasd6267016
        25
    wasd6267016  
       2021-03-22 16:53:09 +08:00
    @gBurnX 哈?完全帧同步的游戏玩家数都上 3 亿了 …… 你了解下原理,1s 级别的状态同步完全没必要
    wasd6267016
        26
    wasd6267016  
       2021-03-22 17:00:31 +08:00
    @gBurnX
    “WOW 在这个问题上是花了大量心思的,当年网络延迟波动有可能高达一两秒,但游戏画面与操作却没有太大的卡顿。不像现在的 LOL 和王者荣耀,延迟大于 100ms 就会有明显感觉。这就是游戏体验在设计上的差距。”
    lol 和 wow 完全是两种模式
    当你延迟超过 1s 的时候 你玩什么游戏体验都不可能好,装作“体验好”只是安慰你罢了
    这有什么吹的啊 多少人被低 ping 战士乱杀的时候也没少骂啊
    高延迟情况下,状态同步的 wow 之所以你觉得“不卡” 是客户端在假装模拟罢了,但是真正战斗起来你就会发现看上去你打到了总是不扣血( FPS 也经常会这样),因为你客户端模拟的打到了,在服务器根本没大到,最终以服务器结果为准

    帧同步的游戏这几年能火就是完全因为网络条件好了啊,你玩 lol 的时候能接受技能看着打到了结果不扣血?
    这还能硬吹一波 wow……服了
    wasd6267016
        27
    wasd6267016  
       2021-03-22 17:04:52 +08:00
    @gBurnX
    错误太明显了吧
    “简单来说,王者荣耀这类游戏不是 p2p 游戏,而是严格的 客户端 - 服务器 模式( C-S )。
    简单说一下流程:

    1.玩家的客户端, 负责把玩家的操控指令,发到服务端。

    2.服务端负责接收所有玩家客户端的操控指令,并负责计算,最后把计算结果反馈给所有的玩家客户端。

    3.玩家客户端负责接受服务端的运算结果,并显示出来。”

    来来来 http://youxiputao.com/articles/12939?qqdrsign=06f3d
    看看这篇文章
    第二点就是完全错的 服务器只接受指令转发指令 所有的计算客户端来进行

    你上面说的这种 算是一种状态
    fenghengzhi
        28
    fenghengzhi  
       2021-03-22 17:09:40 +08:00
    多人游戏同步无非就是帧同步和状态同步
    但这和多人协作还是有一些不一样的,你 LOL 王者荣耀每个人都是控制各自的英雄,你控制不了别人的英雄,
    而多人协作是可能会有多人同时控制相同内容的情况的
    gBurnX
        29
    gBurnX  
       2021-03-22 20:24:43 +08:00
    @wasd6267016

    1. 括号里的 1s 只是给个例子,并不是说一定要 1s 啊。

    2.并不是硬吹 wow,而是 WOW 在延迟高达 1s 甚至更高的情况下,人物行走控制与技能释放也是很流畅。而王者荣耀延迟只要超过 100ms 甚至 500ms 时,仅仅行走控制就会变得很艰难。

    3.建议您留意一下,您发的那篇文章,时间是什么时候的。如果您近期还在玩王者荣耀高端局,您会发现最近锁血挂消失了,封神榜也很久没有锁血挂了。另外,你发的那篇文章,里面也存在常识性的错误。
    secondwtq
        30
    secondwtq  
       2021-03-22 20:32:54 +08:00
    看到提到帧同步,可以参考一下这个文章
    https://zhuanlan.zhihu.com/p/165293116 关于 “帧同步”说法的历史由来

    另外还有一些整活的: https://www.forrestthewoods.com/blog/tech_of_planetary_annihilation_chrono_cam The Tech of Planetary Annihilation: ChronoCam
    secondwtq
        31
    secondwtq  
       2021-03-22 20:49:54 +08:00
    @gBurnX
    > 另外楼上有些小伙伴说了帧同步,实际上没有纯粹的帧同步游戏,不然只要有网络延迟,游戏的不同步率只会越来越大。
    > 帧同步率的游戏,其实是帧同步 + 每隔一段时间( 1s )的全局状态同步。当年 war3 和 starcraft 的联机挂就是针对全局同步的漏洞来实现联机时资源修改的功能。

    来源请求
    cs8425
        32
    cs8425  
       2021-03-23 10:55:42 +08:00
    @gBurnX #29
    2. "流畅"只是客户端设计成不等伺服回应 直接呈现画面造成的假象而已
    3. @wasd6267016 是说实际上血量因為延遲 "还没有"扣到 以至于看起来像锁血 跟挂没有关系 不要瞎扯....
    gBurnX
        33
    gBurnX  
       2021-03-23 11:22:39 +08:00
    @cs8425

    你说的第 2 点,我已经在最开始的 18 楼详细解释过了。建议您以后在回复前,先仔细看评论,别遗漏,以免造成没必要的误会。

    至于你说的第三点,我觉得你对同步原理还欠缺深入,并且你对这款游戏也没怎么关注,同时你也没怎么用过外挂。

    首先服务器只接受指令转发指令这种模式,就一定能做锁血挂这种东西。很多年前,QQ 游戏大厅里一些 P2P + 服务器中转混合模式的小游戏,都存在这个问题,甚至直接出现无敌挂。以前很多国服选手已经证实过了锁血挂,而且还上过封神榜。

    你不关注这些事情,请不要随意说别人瞎扯,谢谢。多学习,多沟通。
    cs8425
        34
    cs8425  
       2021-03-23 13:06:56 +08:00
    @gBurnX #33
    行 你就当我漏看吧
    #18 跟 #29 的回覆完全不像同一个人= =
    如果可以的话
    我想请教一下"SD 敢达 Online"这种同时有 P2P 又同时是 C-S 的游戏要怎看...?
    wasd6267016
        35
    wasd6267016  
       2021-03-23 13:59:32 +08:00
    @gBurnX 大哥…… 王者荣耀开发者自己写的 到你这里就是常识性错误了
    wasd6267016
        36
    wasd6267016  
       2021-03-23 14:08:26 +08:00
    @secondwtq 游戏的不同步率只会越来越大 这句话就已经表明他根本不懂 帧同步了
    gBurnX
        37
    gBurnX  
       2021-03-23 17:21:32 +08:00
    @wasd6267016

    1.我的意思是,你发的资料,是很久以前的了。那种结构,出现锁血挂很正常。

    2.常识性错误指的是星际。星际因为早期这种架构,出现了联机下的资源修改挂,后来的版本通过使用混合模式,修复了这个问题。截止到你发的文章的日期,星际已经不是一个纯粹的指令同步了。
    gBurnX
        38
    gBurnX  
       2021-03-23 17:23:12 +08:00
    @wasd6267016

    纯粹的指令同步,延迟越高,随着时间增长,一定会出现不同步率越来越大。

    年轻人,不要随意说别人不懂。你觉得别人不懂,那你直接上技术细节。
    gBurnX
        39
    gBurnX  
       2021-03-23 17:35:54 +08:00
    @cs8425
    实在抱歉,你说的 [SD 敢达 Online] 这游戏,我没玩过,也没研究过...

    游戏的同步模型,现在发展的比较成熟,很少有只使用单一同步模式的游戏了。

    从大方向上来看两个极端:
    1.延迟越要低,服务端就越不应该参与计算。但劣势是,同步率越容易出错,掉线重连成本越大,同时外挂越容易做。

    2.与上面相反的另一个极端是,同步率要高,掉线重连成本要低,外挂要难做,服务端就应该参与数值计算,甚至要对各客户端的数据进行验证。比如吃鸡的 1km 透视外挂,从技术层面来说,一种很简单的解决方法,就是服务端对玩家数值做验证。我不是吹 WOW,WOW 在玩家可行进的范围,是服务端做了验证的,不然 WOW 还会有穿墙挂。回到吃鸡,如果加入验证,玩家是没办法做到简单的透视的。但问题是,如果加入验证,蓝洞的服务器成本会成倍提高,他们从财务上并不愿意去做这事。

    如果开发一款新游戏,应该针对玩家的用户体验、游戏逻辑,在不同场景、不同游戏模式中,混合使用这两种不同的同步策略。比如现在王者荣耀的掉线恢复功能,客户端代价很大且恢复速度慢。如果要提高用户体验,该功能其实应该改用混合两种同步策略,主第二种同步方式,同时用数据库联机同步技术来用第一种,但王者没做,主要是这种混合策略会很复杂,他们目前没能力做好,其次服务器与带宽资源的投入会加大,财务上也不一定顶得住。
    wasd6267016
        40
    wasd6267016  
       2021-03-23 19:11:36 +08:00
    @gBurnX 谁主张谁说明 你不说技术细节反而让别人来证明
    纯粹的技术问题争论都要用“年轻人”这种称呼来摆架子了么……
    那你赢了
    wasd6267016
        41
    wasd6267016  
       2021-03-23 19:12:56 +08:00
    @gBurnX
    也是 当你说王者荣耀这种游戏“服务端负责接收所有玩家客户端的操控指令,并负责计算”这句话时候 已经没和你讨论的必要了
    wasd6267016
        42
    wasd6267016  
       2021-03-23 19:17:29 +08:00
    @gBurnX
    “请问 Java 方向的软工大一的学生”
    …… 哦 小屁孩啊 我笑了
    secondwtq
        43
    secondwtq  
       2021-03-23 19:17:40 +08:00
    @gBurnX
    > 星际因为早期这种架构,出现了联机下的资源修改挂,后来的版本通过使用混合模式,修复了这个问题。

    来源请求
    gBurnX
        44
    gBurnX  
       2021-03-23 19:30:48 +08:00
    @wasd6267016

    1.从 [谁主张谁说明] 这个角度来看,你第一次质疑我,用的那篇文章,根本就没成功质疑到位,原因是那篇文章,无论时间、内容都有问题。你至少得去找一篇接近最近的,以及内容靠谱的文章,来作为你的佐证。然后如果我有空,可以给你讲讲到底是怎么回事。


    2.你说,从我说的 xxx,就觉得没必要和我讨论。这个情况中,你既没说我说过的那句话,到底哪里有问题,你也没给出你认为的正确的方案。从我的角度来看,我觉得这种情况,你是为了杠而杠。

    如果你不是为了杠而杠,你可以明确地讨论一下,我说的那句话,到底哪里有问题,或者你认为的正确的算法流程是什么。


    3.软工大一学生那个帖子,是我帮别人发的。我在之前的回复里提到过好几次。作为你的讨论对象,你只看了我的提问,却没有耐心去翻翻我的回复,就急着来杠,说明你不仅不够细心,也没讨论问题的经验,心态还很急躁。所以,你会犯上面第 2 点这种基础错误,也就不奇怪了。同时,对于一个做技术的人来说,这些缺点都是大忌,很容易压低你的技术上限。就同步这简单的小问题,你会在这里翻船,也就不奇怪了。
    timethinker
        45
    timethinker  
       2021-03-24 12:32:00 +08:00
    使用帧同步的这种游戏一般来讲实时性和运算复杂性要求都比较高,服务端不大可能参与运算。对于外挂,每一家公司都有不同的策略,有的是通过举报,即不公平性导致其他玩家察觉出外挂的存在,作弊玩家顾忌账号的注册成本,或者通过技术性的检测(即在服务端模拟一个轻量级的客户端接收事件序列,模拟当前的状态是否有异常,不过开发成本也会比较高)。

    假设当状态都由服务端来进行计算,客户端的每一个细节都需要考虑到,计算量就会特别大,而且将这些计算完毕的状态再同步下发给客户端的网络带宽也很高(例如某一个物品的位置、状态),而且对于物理引擎也要跟客户端同步,比如计算碰撞、物理惯性各种细节,因为逻辑帧相对来说都比渲染帧要低,客户端也不能够完全按照服务端下发的状态进行立即同步,不然画面显示就会有卡顿,客户端必然要在本地进行平滑过渡处理,处理不好可能会导致画面漂移等一系列问题,就需要一个取舍。

    所以在服务器进行状态运算产生的问题就是网络带宽和运算性能。

    现在有一种叫做云游戏的东西,客户端只是当做一个“视频播放器”,把触摸或按下键盘的操作发给服务器,服务器完成操作渲染后传输流数据给客户端,客户端安装包可以做到很小,只有几 MB 。对于高实时的游戏来说明显会感觉到延迟,就像手机通过 2.4G 无线 WIFI 投屏到电视一样,手机画面同步到电视上总会慢一拍。

    也有说网络延迟会越来越高,这个问题其实有时候我们玩游戏也能够感觉出来,一种做法是快进播放,网络的延迟只是暂时的,当它跟上来了,就需要把之前的逻辑帧补上去,所有有时候会觉得画面突然的快进,其他的玩家不会等你,在其他玩家看来你只是停留在那里,谁叫你网络不好呢对吧?

    假设服务端只负责事件转发,就需要确保客户端的运算结果是一致的,包括不同设备 CPU 的浮点计算结果一致(有自己的底层计算库),游戏引擎也要做适配,不然就会产生不同步的现象,要保证这一点就需要大量的测试,尽可能覆盖多一点的设备。但是开发成本显然更低,只需要侧重于客户端,并且减少了与服务端的联调,开发效率就会提高。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   3748 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 32ms · UTC 10:37 · PVG 18:37 · LAX 03:37 · JFK 06:37
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.