网络游戏
网络游戏作为网络程序的一个重要类目,自然先从大家喜闻乐见的开始YY。网络游戏设计需要考虑用户间的交互。此处的交互定义宽泛,包括游戏中玩家的互动(攻击判定,交易,聊天)。挑几个设计上值得思考的说说。
(一)对实时要求高的FPS场景
比如CS,土匪与警察迎面相遇,收刀,拔枪,跳蹲,爆头。一套动作下来,少则半秒,多也不过半分钟,胜负必出。在这样短的时间内,如何综合玩家动作与位置变动,并判断双方伤害(判断错了多几个子弹就死了),即时发送结果给双方的游戏客户端,怎么做呢?
用现在分布式系统最流行的CAP理论来说,我们需要一个C(强一致),即双方客户端在判断玩家位置和对方开枪时一瞬间需要的是双方数据的强一致场景,而这个瞬间在双方交战的时候是随着鼠标的按动(开枪)频繁出现的,这里为了简单化只涉及了两个玩家迎面的情况。
如果是三个以上,那会更高,要求三方的客户端交互的数据都要有一个方式可以做仲裁,而这个仲裁要求非常快,可能超过200ms的延时就会被玩家感知了,体现就是玩家觉得开了枪但是没有打到对方,这个在非局域网场景的《穿越火线》经常会有感觉,莫名其妙自己就死了,手感很差。我并不知道《CS GO》在设计的时候是怎样在广域网上达到这个设计需求的,但感觉上就是玩《CS GO》的射击手感比《穿越火线》好多了。
模型一
解决这样的问题应该怎么做?CS的房间最多20人,一个自然的想法就是由其中一个玩家的机器当服务器,充当房间里其他人的网络数据的仲裁,其他所有人的数据都发给房间的主机(创建者),由此人的机器对三维空间的位置,碰撞,开枪进行计算,CS 1.6在由玩家建立主机时应该就是这么设计的,因为主机的响应延迟是0ms,在面对面交火时明显能感觉到主机优势,水平差不多的玩家主机赢得次数更多。这样做的问题也很明显,很多的逻辑处理都放在了客户端上,服务器端基本没有做仲裁的逻辑,如果有恶意程序(外挂)模拟客户端的数据,比如在获取了主机转发过来的对方位置信息后,直接篡改发送给主机的射击数据,把射击的坐标钉在了对方的头上,那么就无敌了。
之所以能这么做还因为一般这种对延迟要求低的游戏都会首选UDP发包,UDP包的一个特点就是一个包就要包含整个交互的完整数据,每个包都是独立而又完整的;它不像TCP这种流式的处理方式,经过繁琐的连接建立后,所有的数据发送都不需要考虑封包重传这种相对底层的操作,但这种高层抽象要付出的代价就是不能精确控制数据包,TCP的重试,顺序控制机制对于低延时是致命的。
模型二
除了用玩家主机当服务器的模式,另一个想法自然就是有一个独立的服务器,此服务器承载所有计算逻辑,而所有的玩家客户端都只是把自己的动作和位置不间断的发送给服务器,由服务器将处理的结果发送给客户端。
这样的一个好处就是所有计算都在服务器端,想要升级程序只要升级一个服务器端就可以了,对程序员来说很方便,不依赖客户端软件的升级,这在目前手游很多的情况下很重要,大部分手机用户都不会愿意频繁更新软件,除非是那种看到图标上有数字的处女座强迫症重度患者。
坏处也很明显,鸡蛋都在一个篮子里,这个服务器端挂了,整个游戏就瘫了,所有客户端都无法工作了。所以对服务器集群的高可用保障那是必须的。
未完待续
文章来自微信平台「麦芽面包」
微信公众号「darkjune_think」转载请注明。
如果觉得有趣,微信扫一扫关注公众号。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。