除了其他答案中链接的文章之外,我还可以介绍Arianne项目的经验。
如何保持事物同步?
我们围绕动作和感知的概念构建了框架“ Marauroa ”:动作从客户端发送到服务器,并携带用户输入,例如(向左走,攻击怪物47,说“你好”)。感知从服务器发送到客户端,告诉客户端周围的世界状况。那些感想无处不在。根据游戏的不同,我们使用30毫秒至300毫秒的翻转时间。
我们有两种类型的感知:在登录时和玩家进入新区域(区域)时发送完整感知。之后,发送差异感知,仅包括经修改对象的经修改属性(例如位置),当然还包括新对象和已删除对象。
如何解决延迟问题?
我们坚信“服务器永远是正确的”。客户端会进行一些预测,例如平稳步行,碰撞检查等。但是,如果客户端和服务器不同意某件事,则服务器获胜。子项目Stendhal(一个2D RPG)默认情况下使用300ms的转换时间(在客户端进行了大量的平滑操作)。这使得Stendhal非常耐滞后。
注意:其他一些游戏会在一定程度上信任客户端,以最大程度地减少网络延迟的影响。在《魔兽世界》中,它经常被用于战场之一,称为“战歌峡谷”。带有旗帜的玩家可以选择两种方式:通过隧道的中间位置和沿着山坡的右眼位置之一。因此,作弊玩家朝着隧道奔跑,然后为自己造成了滞后。服务器和其他客户端将继续看到他向服务器运行。但是过了一会儿,该客户端可以告诉服务器它已驶向山丘。WoW将检查最后传输的坐标与当前坐标之间的距离是否在该时间段内,并接受。
使用UDP与TCP
在早期版本中,我们使用UDP来减少TCP的开销。我们自己处理丢失的数据包。在项目的早期阶段,这非常完美。但是,几年前,当服务器从某个家庭DSL连接移到一个真实的数据中心时,我们遇到了很多问题。UDP对防火墙硬件的CPU功能(或至少在5年前是非常苛刻的):必须将规则集应用于每个单个UDP数据包。但是,对于TCP,规则集仅适用于前3个数据包。之后,建立连接。随后的所有数据包都将绕过常规规则集,因为它们在连接跟踪表中或没有SYN标志。
如何保护通信和客户端免受逆向工程的影响?
Arianne是完全开源的,其中包括客户端,服务器,图形,音乐。当然,其中包括我们的协议文档,甚至包括用于调试的分析器。
可以很容易地防止通信受到第三方使用SSL的未经授权的嗅探。
但是,要保护它免受逆向工程是不可能的。当然,您可以对其进行混淆并使用反调试技术。但是最后,您不能阻止您对用户赠送的软件进行反向工程。尽管开发人员在反调试技术上投入了大量精力,但有关如何进行Skype反向工程的演讲非常有趣:http : //recon.cx/en/f/vskype-part1.pdf
注意:在某些国家/地区反向工程是非法的,或者允许在许可或ToS中添加一段以禁止反向工程。但是还有其他一些国家(例如我所居住的国家)明确允许在开发兼容的数据存储格式或传输协议,许可证中的条款或ToS禁止这样做的情况下进行逆向工程。(据我所知,本节内容全都不是律师)
应该在本地计算哪些内容,在服务器上计算哪些内容?
我们计算与服务器上的游戏逻辑相关的所有内容。客户将预测某些事件,以使游戏顺利进行。但是最后服务器总是正确的。
预测的事件例如是发生碰撞时停止运动。Stendhal使用网格定位元素。从服务器的角度来看,每个实体的左上角正好在一个正方形上。但是客户将在瓷砖之间平稳地移动它们。它还将绘制伪3d效果。因此,客户端中以1x1为基数的实体可能会更高。
如何平衡负载问题?
尽量保持简单,以简化维护。
静态内容的负载平衡在http服务器群集和内容分发网络领域是众所周知的。
游戏服务负载平衡的一个相当简单的概念是将服务器划分为多个区域/区域。因此,区域AC位于一台服务器上,区域DF在另一台服务器上。如果您无法从一组中的区域查看到另一组中的区域,则这特别容易。您需要在其中进行一些检查,以便客户端只能连接到负责播放器所在区域的区域服务器。
将播放器从一台服务器转移到另一台服务器的最简单方法是将其写入数据库,告诉客户端连接到另一台区域服务器,并将它们与当前服务器断开连接。然后,客户端将连接到新的区域服务器,该服务器将从数据库中加载它。(由于仍然需要从/存储到数据库代码的负载,因此稍后可在服务器之间进行直接通信以进行切换)。
通过以下方式需要一些其他全局服务:登录时,必须告知客户端连接到正确的区域服务器。您可能需要一个全球聊天系统。
我在“ 如何在MMO中实现负载平衡”上详细介绍了此主题。