文档章节

物理游戏的同步模型

梦想游戏人
 梦想游戏人
发布于 2017/11/02 08:16
字数 2368
阅读 143
收藏 0

该篇分析的环境是:服务器不接入物理引擎,纯物理游戏(偏向于强操作)开房间。

分析点主要是:同步模型,服务器框架,防作弊,主客户端热切换(保证游戏任何玩家掉线都不会影响游戏)

该篇记录更多的是个人思考的记录。

同步模型:

服务器不接入物理引擎的话,那么只有依赖于选举一个客户端(主客户端)来做物理处理,然后把状态同步到其他客户端,其他客户端做插值处理。(服务器也可以接入逻辑来控制取代主客户端的部分功能,甚至取消主客户端这个角色,服务器记录来自客户端的状态快照然后逻辑处理)。

    因此其他客户端的“物理效果”表现力和插值算法和同步频率有关:

     客户端物理表现方案1:主客户端全物理,每个玩家都是物理控制下,其他玩家吧操作发送给主客户端,然后接收来自主客户端的状态信息,然后做插值。好处是游戏控制权都在主客户端,降低了同步模型设计的难度,主客户端只需要接收其他玩家的操作信息即可,因此,其他玩家的操作,主客户端就要处理为操作状态的改变,而不是收到一个操作就处理一个操作,因为同步频率远低于游戏帧数,因此会出现操作不连贯,发生的现象比如移动一走一停,因此主客户端应该处理为输入状态的改变,比如某客户端的移动移动发送给主客户端的数据应该是开始左移动,停止左移动,而不是左移动,左移动。

 

    客户端物理表现方案2:每个客户端的玩家自身的物理效果可以实时物理(自身是一系列的刚体的力的组合,玩家的移动操作等直接作用于自身刚体,得到更好的物理表现实时效果), 让玩家看到自己的表现很完美(有点像常规网络的客户端预处理,表现先行的思想), 然后定时把自己的状态(BodyPart的position rotation )发送给主客户端,主客户端对该玩家的信息插值后,做逻辑判定。这种方案对于所有客户端,玩家自身的物理状态都是独立控制的,自己看自己的角色物理表现,比如动作动画,很完美,只不过主客户端扮演的角色是逻辑仲裁,比如伤血,捡武器,道具产生。相对的代码实现复杂度也不高,

可以考虑服务器接入部分逻辑,来修正客户端的同步错误

对抗网络抖动& 延迟:

先用TCP快速实现功能(这种实际上是属于优化层面了,费时费力因此先实现功能为主),再用可靠UDP加速传输,在接入可靠UDP时,使用了UDT,但是发现效果不好(看了文档没发现有什么调优的方法,没继续研究下去),Android真机WIFI下,整体延时的确下降了,但是游戏体验也不是很大提高。

 

思路1:采用更适合的可靠UDP方案,KCP似乎是一个比UDT更好的选择,

思路2:灵感突来,发现在同步模型2下,position rotation这种同步频率很高,而且很频繁的消息时,如果发生了丢包,为了保证可靠性而带来的一个tick内收到多个包,导致一次性更新下来角色明显出现抖动之类的不平滑效果,因此考虑逻辑层选择性的丢掉一些包,用最新的包即可,在这个思路下,萌发了另外一个思路,对于这种消息可以考虑用纯UDP,丢包了无所谓,反正我也是不需要的,保证了可靠,为了不表现出抖动我也要丢掉,既然这样那为什么要保证可靠?因此出现了思路3。

思路3:消息分为3类(chanel),1保证到达,2保证按顺序到达,3无需保证可靠性,,,第三种可以完全用纯UDP实现(允许时间在tick内即可),甚至在可靠UDP上做极限优化,比如只重发一次等,,,第二种可以考虑TCP或者可靠UDP,第一种也可以是可靠UDP的不保证顺序模式,,,因此一次游戏,会有多个socket,各自负责自己的消息Chanel,甚至第三种消息可以用客户端P2P来直发(减少服务器中转后丢包的可能性)。。第一种消息可以是(掉血,道具生成,子弹发射),第二种消息可以是(逻辑前后有强顺序性的消息,),第三种消息可以是(位置,旋转)等。在深入思考,其实这种方案就类似于raknet发送的模式,有好几个选项,。一开始就想接这个方案,无奈Android IOS接入到C#遇到一些问题,绕了一大圈,好像又回到这种方案了。

 

个人最理想的方案是(asio+kcp)or(go+kcp)(协程很好用啊)组合,加入消息分类策略,如果效果还是不够好,在考虑P2P,毕竟P2P也有一定的问题,打洞(NAT穿透)不一定能100% OK,因此需要服务器中转,为那些不能打洞的客户端服务。可能会丧失服务器验证功能,

 

 

服务器架构:

游戏分为战斗部分和非战斗部分,战斗的消息同步,应该考虑用可靠UDP实现基本协议,非战斗同步消息,常规手法TCP(RPC or 消息)都可以。

游戏逻辑上2大块,非战斗和战斗部分,

非战斗:非战斗主要是匹配,商城,好友,任务等常规需求,并且一个玩家大部分游戏时间不不会是非战斗。因此常规RPC or 消息模型即可。称为LogicServer,该类型服务器较为综合和常规

战斗:战斗涉及到大量消息转发,主要负载是流量,

 

 

 

 

 

防作弊:

1。服务器在战斗同步上扮演的角色只是中间件,只负责转发消息,对于防作弊手段可以是这样,所有客户端都是一个仲裁者,负责对一些逻辑上限进行仲裁和有效验证,比如瞬移,无限产生道具,秒杀,这种极度极端的网络消息,可以进行验证,但是这种防止不了所有客户端都作弊,并且还存在恶意攻击,让其他客户端是别人作弊(类似于GTA5的某玩家开作弊让服务器认为是你在作弊),这种防作弊机制就提供了这种的可能性,

2。在1的基础上吧这部分的验证代码移至服务器,即服务器也是一个客户端,进行消息仲裁,为了节省开发时间,可以接入C#的客户端代码用mono来跑,也就是说客户端也可以专门针对这种验证写一个模块,服务器和客户端公用,也可以只放在服务器(要把物理引擎去掉),但是实现都是让客户端来实现,来防作弊。基本模式是一个房间转发的同时做消息合法性防作弊验证。这种模式意味着客户端游戏全局的状态会分为2大块,物理输出和状态描述(可以只是对象类型和position)。验证模式下只需要有状态描述这个集合即可,无需要物理输出,状态描述可以是状态快照也是物理输出的快照,一个新的问题又来了,这份状态描述信任那哪个客户端的?都有可能作弊,那么作为作弊验证的依据状态描述部分,该信任谁?或者信任一部分客户端?。。

3。针对2的问题,进一步优化,其实服务器可以接入部分逻辑的,只不过吧客户端的mono代码去掉物理引擎,然后逻辑一样是在C#层跑,比如什么时候该产生一个道具(不能无限产生道具),扣血的合法性不能秒杀(),位移的合法性(不能瞬移),由服务器告知主客户端,非法的消息,服务器直接丢掉,或者认为是作弊。主客户端不唯一这也可以是一种方案,即主客户端会随机切换,比如该局是玩家1,下一局可能是玩家2,甚至一局中也切换, // TODO

 

 

 

 

///TODO

© 著作权归作者所有

共有 人打赏支持
下一篇: Unity CullingMask
梦想游戏人
粉丝 37
博文 441
码字总数 125736
作品 0
成都
私信 提问
最近做了个小游戏

http://4399sy.com/gamezone?id=2460 尝试在游戏里面使用UDP做位置同步; 尝试游戏里面使用一些法线,高光,发光贴图; 还参考了Game Art Trick 上面的文章使用顶点色做星空,自己加了几个粒...

李勇2
2016/06/14
95
0
PHP WebSocket聊天室--workerman-chat

workerman-chat是一个以workerman作为服务器容器,使用PHP开发的基于Websocket协议的一个可分布式部署的聊天室框架。 workerman-chat采用gateway workers 进程模型。gateway只负责网络IO,全...

aliang032
2014/04/12
5.9K
0
学习OpenGL ES之物理引擎

本系列所有文章目录 获取示例代码 牛顿的占位图 前言 本文将介绍3D物理引擎Bullet的基本使用方式以及如何将之前的OpenGL渲染代码和Bullet相结合,制造一个符合物理运动规则的虚拟3D场景。下面...

handyTOOL
2017/10/13
0
0
VR办公不是梦!国外高校为VR文本输入提供解决方案

密歇根理工大学的研究人员为VR用户设计了一种与物理键盘同步的虚拟键盘。 虚拟现实世界奇妙无穷,但一直缺少一种合适的输入方式,使之不仅可以用来玩乐,还可以用来办公。来自密歇根理工大学...

行者武松
2018/03/07
0
0
帧同步游戏开发要点

结论 先说一下我们在研究和使用了帧同步之后,得出的结论: 如果项目没有录像、观战功能,请先放弃使用帧同步的念头,尝试使用状态同步。因为设计得好的状态同步,可以在很少流量基础上,完成...

小匠头
2017/08/10
0
0

没有更多内容

加载失败,请刷新页面

加载更多

spring aop学习

1.aop和spring aop的关系? aop是一种思想,spring aop是aop的一种实现。 2.Spring aop和AspectJ的关系? 这两种都是实现aop的,spring借助AspectJ的语法实现aop的功能 3.@AspectJ support和...

llsydn
51分钟前
3
0
OSChina 周六乱弹 —— 世界的源代码

Osc乱弹歌单(2019)请戳(这里) 【今日歌曲】 @小鱼丁 :#今日歌曲推荐# 分享Jason Mraz的单曲《Prettiest Friend (Demo)》: 《Prettiest Friend (Demo)》- Jason Mraz 手机党少年们想听歌...

小小编辑
今天
288
9
java框架学习日志-13(Mybatis基本概念和简单的例子)

在mybatis初次学习Mybatis的时候,遇到了很多问题,虽然阿里云的视频有教学,但是视频教学所使用的软件和我自己使用的软件不用,我自己用的数据库是oracle数据库,开发环境是idea。而且视频中...

白话
今天
14
0
Java基础:String、StringBuffer和StringBuilder的区别

1 String String:字符串常量,字符串长度不可变。Java中String是immutable(不可变)的。 String类的包含如下定义: /** The value is used for character storage. */private final cha...

watermelon11
今天
6
0
mogodb服务

部署MongoDB 官网: https://www.mongodb.com/download-center/community 创建mongo数据目录 mkdir /data/mongodb 二进制部署 wget -c https://fastdl.mongodb.org/linux/mongodb-linux-x8......

以谁为师
昨天
5
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部