帧同步_帧同步和状态同步该怎么选(上)

这是一篇拖延了2年多的文章…2017年10月份开始写的,直到这次过年才写完。。。

前言

随着王者荣耀的崛起,使用帧同步(Lockstep)的游戏也越来越多,关于帧同步和状态同步的讨论争论也有不少,那么到底该选哪种同步机制呢?两种机制都使用过,各有优缺点也都踩过不少坑,这里对帧同步和状态同步进行一下总结和讨论。

首先需要说明, 这里的帧同步其实是指LockStep是指服务器按帧转发客户端的操作,客户端进行确定性运算和一致性模拟(同步操作两边客户端通过完全一致的操作计算出完全一致的状态)。每帧同步状态这里也认为是状态同步

这两种同步机制都是为了达到即时同步不同客户端的状态的目的,帧同步需要参与者去管理和维护其自有的那份拷贝,通过施加一致的逻辑来推动所有的状态去同步地更新;状态同步则随着时间的流逝不断地比较和发送最小的状态变化和差异。

我们先看一些使用这两种同步机制的案例:

48b7b13590e65b22f364592f5a25fe49.png

可以看到大部分类型游戏,两种同步方式都可以使用,但绝大部分游戏使用状态同步,大量玩家战斗的游戏只能使用状态同步

网络模型发展历程

下面简单介绍一下网络同步模型的发展。我们可以从DOOM/QUAKE I/II/III的演化来看到同步模型的发展。可以参考DOOM3网络模型的演化与网络架构这篇文章。同步方式的历程大概是帧同步(Lockstep),快照同步(Snapshot synchronization),状态同步(State synchronization),目前绝大部分多人游戏都使用状态同步。

P2P 模型 (DOOM)

DOOM (1994) 的网络模型是基于P2P的帧同步。有着帧同步的各种问题,后面会介绍。并且因为没有主机,每个玩家直连其他所有玩家任何一个人卡所有人都卡,是一个非常古老的同步技术。

Packet Server (包的简单中继)

这个模型在原版 DOOM 的基础上增加了一个 Packet Server,负责转发所有的 tick command。玩家不再直连其他所有玩家,而是连到这个服务器 (某个玩家机器上) 以获取最新的状态。这样改进后,同步量降低了,一个玩家卡只会自己卡,当然如果服务器卡就会卡。体感可以参考魔兽争霸,主机卡了所有人都会卡。同时如果主机是服务器可以避免绝大部分作弊情况,但如果主机是玩家主机作弊就没办法了。帧同步的其他缺陷也没有得到解决。

Client Server (Quake I/II/III)CS架构

Quake I/II/III 实现了比较典型的 C/S 架构 (1996)。这个模型中服务器负责所有的逻辑判断,客户端本质上只是一个渲染终端。玩家把自己的操作和输入发送给服务器,收到一个实体列表用于渲染。服务器把压缩后的快照按照固定频率发送客户端 客户端使用这些快照来插值或推导出平滑连贯的体验 。

这时候同步机制已经变成了服务器同步操作客户端计算逻辑,服务器同步状态的状态同步了,解决了帧同步的大部分问题。但Quake I还做的比较简单,和帧同步不同的是把所有逻辑相关的放在了服务器,客户端在发送操作之后就要等服务器同步状态。延迟问题还是没有得到解决,同时因为要同步所有状态信息带宽占用很高,当游戏越复杂带宽就越高。

Quake III做了进一步的优化。客户端不是等待服务器而是会预测可能的游戏状态,预测状态和服务器端逻辑使用一套代码,如果服务器和客户端确实不一致,则服务器为准强同步。

预测也是降低延迟感的一个重要方式,对延迟要求很高的FPS特别重要。并且状态同步服务器永远所有信息也能允许玩家中途加入和退出了。但同样的开发复杂度也变的更高了,代码需要区分服务器和客户端,需要逻辑和表现分离,需要处理一些联调的问题(服务器和客户端处理时间不一致,预表现差值问题,强同步问题)。

半条命(基于Quake引擎开发)在这个基础上引入了一种延迟补偿 (lag compensation),当玩家向某个目标 (若干毫秒前的状态) 射击时,做实际检测的服务器会采用该目标若干毫秒前的状态来检验是否击中。这么做需要服务器把之前一小段时间的状态持续地保存下来,这样不仅增加了实现复杂度,而且导致了某种程度的不一致性。延时高的玩家反而更容易因为补偿获得更有利的判断,严重影响游戏体验 。这种补偿只能对目标的位置回滚,而所有其他环境状态的改变却已无法倒退,这也会影响实际的体验。

Quake III 里对同步信息做了进一步压缩和优化,只有在 PVS 内的实体才会被同步状态,而且被同步的是压缩后的与上一次同步的差值 (delta compressed relative to the entity states from a previous snapshot,Delta技术) 。

可以看到当玩家比较少的时候,帧同步只需要同步操作,流量会比较小,非常适合同屏大量小兵的情况(小兵不需要同步任何信息),极省带宽。但是当玩家多的时候每个玩家的操作都要互相同步,带宽就会指数增长,无法优化,反而状态同步可以通过分区域的方式同步支持更多的玩家

Quake III 不同,Doom III 的服务器和客户端使用同一份代码来更新/预测实体的状态,这样不用担心服务器和客户端逻辑的互相干扰,同时客户端和服务器也一相同的逻辑帧率运行60fps,每帧客户端上传玩家输入,服务器按固定间隔同步PVS范围内的状态快照,也可以理解为按帧同步的状态同步

Doom III在网络上使用UDP,自己通过冗余包和滑动窗口保证服务器消息不丢失和有序并且允许客户端上行丢包,在弱网情况下比TCP延迟更低,不需要TimeOut机制。

两者的优缺点对比

那么我们再来对比一下帧同步和状态各自的优缺点:

b47a5699f0798cba28b34ac2cb276f6a.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/442308.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

实现连麦_直播课程系统如何实现互动连麦效果?

比起录播课,直播课师生能够更好地互动,因此很多老师利用直播课程系统进行直播教学。直播课程系统的连麦互动往往能让直播课充满生机。在直播教学中使用连麦互动功能,老师可以随时提问学生,学生也可以就不懂的问题询问老师&#xf…

c++ 二次开发 良田高拍仪_在网页中调用摄像头实现拍照上传 - 高拍仪二次开发...

来源于 https://blog.csdn.net/weixin_40659738/article/details/78252562在网页中调用摄像头实现拍照上传高拍仪二次开发在一些公共部门的办事处,比如银行、护照办理中心、税务等,我们可能会注意到办公桌上摆着这样一台机器。办公人员用它拍摄各种证件…

复频域求零输入响应_第十四章 动态电路的复频域分析 习题答案

第十四章 动态电路的复频域分析一、选择题1. 图13—1所示电感元件的电压、电流关系的运算形式是 B 。A .)0()()(-L L L Li s sLI s U ;B .)0()()(--L L L Li s sLI s U ;C .si s sLI s U L L L )0()()(- 2&…

cancase vector_基于Vector总线设备的CAN总线测试方法概述

3.3采样点位置测试测试设备:CANoe、CANStressDR。测试系统架构中需将CANScope旁路处理。测试设备正确接线后(CANStressDR串接在回路中),CANoe发送报文,CANStressDR采用位干扰的方式进行干扰,具体是采用CANStressDR从后往前逐位干扰…

源码mysql5.7安装过程_mysql5.7 源码安装步骤

操作系统:centos 7说明:以下都是root用户操作的。一、数据库安装1、查看系统是否有旧版的mysql# rpm -qa |egrep -i mysql|mariadb如果有的话请先卸载,卸载命令:# rpm -ev 软件包名称2、查看老版本mysql相关的安装目录&#xff1a…

springboot2整合mysql5_SpringBoot2.X (二十五):SpringBoot整合 Mybatis + MySQL CURD 示例

话不多数,直接开始撸代码…工程结构图开始之前先放张工程结构图1、maven 依赖:org.springframework.bootspring-boot-starter-weborg.mybatis.spring.bootmybatis-spring-boot-starter1.3.2com.github.pagehelperpagehelper-spring-boot-starter1.2.9com…

mysql crash 如何导出数据库_mysql 如何做到crash后无损恢复数据的

ps真实的流程没有我说的那么简单,下面的是最基本的情况。预备知识redologbinlogWAL机制redolog简介redolog是个循环日志,其大小固定为4g,存在2个指针来定位其是否已经满了。一个指针是当前写,一个指针是当前checkpoint,其2个指针的…

python turtle画四叶草的步骤_python turtle工具绘制四叶草的实例分享

本篇文章介绍了python使用turtle库绘制四叶草的方法,代码很简单,希望对学习python的朋友有帮助。import turtleimport timeturtle.setup(650.,350,200,200)turtle.pendown()turtle.pensize(10)turtle.pencolor(green)#四叶草def draw_clover(radius,rota…

python解图片迷宫生成路径_用Python代码来解图片迷宫的方法整理

译注:原文是StackOverflow上一个如何用程序读取迷宫图片并求解的问题,几位参与者热烈地讨论并给出了自己的代码,涉及到用python对图片的处理以及广度优先(BFS)算法等。问题by Whymarrh:当给定上面那样一张JPEG图片,如何…

信号模型噪声服从零均值高斯分布_非高斯噪声下基于分数低阶循环谱的调制识别方法...

1 引言当前,绝大多数非高斯噪声的建模形式都为Alpha稳定分布噪声。首先,Alpha稳定分布符合中心极限定理,在理论上适合应用于实际场景中的噪声建模;其次,Alpha稳定分布由于其参数的可变性,包含高斯分布、柯西…

mysql 时间绝对值_datetime和timestamp--时间戳是绝对值,日期是相对值

遇到的问题:系统时间与数据库时间不一致,系统时间是8:20,存到数据库里是0:20。第一直觉是时区不同导致的。先看一段代码:Java代码public static void main(String[] args) {//System.out.println(TimeZone.getDefault());SimpleDa…

python网络编程自学_五分钟搞定Python网络编程实现TCP和UDP连接

Python网络编程实现TCP和UDP连接, 使用socket模块, 所有代码在python3下测试通过。实现TCP#!/usr/bin/env python3# -*- coding: utf-8 -*-import socket# 创建一个socket:s socket.socket(socket.AF_INET, socket.SOCK_STREAM)# 建立连接:s.connect((www.baidu.co…

java自定义线程_Java自定义线程池详解

自定义线程池的核心:ThreadPoolExecutor为了更好的控制多线程,JDK提供了一套线程框架Executor,帮助开发人员有效的进行线程控制,其中在java.util.concurrent包下,是JDK并发包的核心,比如我们熟知的Executor…

java 垃圾回收 null_java方法中把对象置null,到底能不能加速垃圾回收

今天逛脉脉,看见匿名区有人说java中把对做置null,这种做法很菜,不能加速垃圾回收,但是我看到就觉得呵呵了,我是觉得可以加速置null对象回收的。测试的过程中,费劲的是要指定一个合理的测试堆大小&#xff0…

零基础学java web开发pdf_新手学Java Web开发.pdf

作 者 :杨磊等编著出版发行 : 北京:北京希望电子出版社 , 2010.01ISBN号 :978-7-89498-988-8页 数 : 480丛书名 : 新手学编程系列原书定价 : 49.80主题词 : 计算机编程软件,JAVA WEB中图法分类号 : TP3 ( 工业技术->…

java 外卖订餐系统_java外卖订餐系统小项目

本文实例为大家分享了java外卖订餐系统的具体代码,供大家参考,具体内容如下执行结果:通过选择功能序号,执行响应的功能:代码实现:package 外卖订餐系统;/** 代码优点,使用 循环:* 显…

java 字符串包含某个字符_java中判断字符串中是否包含某个特定字符串的方法有哪些...

判断一个字符串是否包含某个子串的n种方法:1、startsWith()方法2、contains()方法3、indexOf方法startsWith()方法这个方法有两个变体,用于检测字符串是否以指定的前缀开始。此方法定义的语法如下:public boolean startsWith(String prefix, int toffset…

java的方法调用中分不清_java中不太清晰的知识点

一、什么包需要导入,什么包不需要导入1.java.lang包的内容是自动导入的,不需要手动导入,其它必须手动导入。2.java.io.OutputStreamWrite已经是完整的类,无需再导入,而printWrite这个类,并不是调用完整的类…

java生命小游戏_Java修炼——飞机生存小游戏

在学习了java入门的课程之后,自己动手跟着老师写的一个小游戏,用的是Frame。总共有七个类。1.飞机游戏的主窗口(MyGameFrame)继承Frame。package com.bjsxt.plane;import java.awt.Color;import java.awt.Font;import java.awt.Frame;import java.awt.Gr…

链队列的基本运算java_链式队列基本操作的实现问题

问题描述:用链式存储方式实现队列的基本操作涉及变量:front:Node型自定义变量,指向队首元素rear:Node型自定义变量,指向队尾元素涉及教材:《数据结构——Java语言描述(第2版)》 清华大学出版社大…