网络游戏架构进阶
网络游戏架构进阶
本章节主要是介绍网络游戏在底层通信上的需要完成重要架构。
Character Movement Replication 角色位移同步

角色位移同步(character movement replication)是现代大型网络游戏必须要实现的功能。
由于网络环境的不稳定,玩家操作角色在自己视角和其他玩家视角下的行为往往会有一定的延迟,即角色在其他玩家视角下的动作会滞后于操作玩家的第一视角。
- 玩家A的信息通过服务器同步到玩家B的机器上,需要经历A->服务器,服务器→B的延迟
Interpolation & Extrapolation 移动插值

为了解决角色移动的同步问题, 我们可以使用内插(interpolation)和外插(extrapolation)两种插值方法来缓解延迟,让角色平缓移动。
Interpolation

内插是指利用已知的控制点来获得中间的状态。
当网络存在波动时利用内插的方法可以保证角色的动作仍然是足够平滑的。

在具体进行插值时还可以人工设置一个offset来保证buffer中有足够多的控制点,这样虽然会提高一些延迟但可以获得更加光滑稳定的插值结果。
- 把server端来的角色状态cache到一个buffer, 加入一点offeset, 这样在S1和S2之间插值的时候有足够的时间等S3到来。
- 如果server到client的延迟已经确定(比如50ms), 本地会buffer(100ms)来确保平滑。

当然内插也存在一些问题。由于内插加剧了网络延迟的问题,同样的游戏世界在操作者和其他玩家的视角下会有非常大的差别。
这样的问题在一些延迟要求很高的游戏中可能是不可接受的。
- 上图中在红车的世界中对灰车的判断就会出现误差
Extrapolation

相比于内插,外插的本质是利用已有的信息来预测未来的状态。
当我们对网络延迟有一定的估计时就可以通过外插的方法来推断角色的状态。
- 考虑信息在传递过程中的时间耽误,比如古代的战报。

实际上外插的思想在很多领域都有非常多的应用,dead reckoning算法那就是外插在导航领域的实践。
- 如果从收到的网络信息知道已经和真实状态不同时,怎么去追踪(调整)。
Projective Velocity Blending 投影速度混合


回到游戏领域的应用中来,projective velocity blending (PVB)是一种使用外插来更新角色位置的算法。
通过角色在client和server获取的位置,速度和加速度数据先进行速度插值,再进行位置插值。
需要注意的是PVB算法并不符合动力学原理,它仅仅是一种插值方法---确保位置,速度这些最后能重合。
Collision Issues



外插在处理碰撞时会容易产生严重的物体穿插问题。

要处理这样的情况一般需要切换到本地物理引擎来处理碰撞问题:
- 客户端提前进行物理检测,如果检测到碰撞,把位置同步的权利从网络同步切换为物理引擎,过了一段时间才恢复为网络同步。
- 比如说在看门狗2中是出现碰撞后1秒后控制权交往给网络来的消息,
- 问题:在不同客户端上物理检测是存在差异的。
Usage Scenarios



简单总结一下:
- 对于玩家操作角色经常出现瞬移或是具有很大加速度的情况比较适合内插;
- 对于操作角色比较符合物理规律的情况比较适合外插;
- 在一些大型在线游戏中还会同时结合这两种插值方法来提升玩家的游戏体验。
Hit Registration 命中判定

命中判定(hit registration)同样是现代网络游戏必须要提供的基本服务。
以FPS游戏为例,从玩家开枪到击中敌人爆头这一过程实际上有着非常大的一段延迟,在各种不确定因素的影响下如何判断玩家确实击中目标就需要一些专门的设计。
Challenges

命中判定的难点之一在于确定敌人在什么位置。
由于网络延迟和插值算法的存在,玩家视角下的目标是落后于服务器上目标的真实位置的。
- 上图中最右边是玩家A上面的位置,中间是服务器的位置,最后才是当前客户端观察到的位置

命中判定的另一个难点在于如何判定是否击中了目标。在游戏场景中目标往往是运动的,而且往往会位于一些掩体附近。
当弹道不是瞬间命中时就需要一些额外的算法来进行判断。
Client-Side Hit Detection

因此命中判定的目标是保证游戏中的玩家就是否命中的问题能够达成一个共识(consensus)。
目前主流的处理方法包括在客户端上进行检测,称为client-side hit detection,以及在服务器端进行判断的server-side hit registration。


在客户端上进行检测时的基本思想是一切以玩家客户端视角下的结果为准。
玩家开枪后的弹道轨迹以及击中判断都先在本地进行,然后发送到服务器上再进行验证。
- Hitscan: 认为速度很快,瞬间到达,早期游戏的风格
- Projective: 存在飞行时间,玩家可以闪躲
- Projective + Gravity: 弓箭弹道

在服务器上会对玩家的行为进行一些验证从而保证确实击中了目标。
当然在实际的游戏中这个验证过程是相当复杂的,涉及到大量的验证和反作弊检测。


在客户端上进行命中检测的优势在于它非常高效而且可以减轻服务器的负担,
但它的核心问题在于它不够安全,一旦客户端被破解或是网络消息被劫持就需要非常复杂的反作弊系统来维持游戏平衡。
- 左图的守望1的服务器判定是简单确定红色区被击中
Server-Side Hit Registration

在服务器端进行检测的一个难点在于服务器上角色的位置和状态是领先于玩家视角的,当玩家开枪时目标很可能已经移动到其它的位置上了。
从这样的角度来看,玩家很难命中移动中的目标。


因此我们需要对网络延迟进行一定的补偿。
当服务器收到射击的消息时不会直接使用当前的游戏状态,而是根据延迟使用之前保存的游戏状态。
Cover Problems


对于掩体的问题,由于网络延迟的存在可能会出现射击者优势或窥视者(peeker)优势的情况。
→ 所以FPS游戏比赛的时候会尽量使用局域网来降低优势

为了缓解延迟的问题在游戏设计时还可以利用动作前摇(startup frames)来掩盖掉网络同步。
→ 前摇的目的是为了给网络同步争取时间

类似地,也可以使用各种特效来为服务器同步争取时间。
MMOG Network Architecture 大型多人在线游戏网络架构


对于大型多人在线游戏(massively multiplayer online game, MMOG)我们还需要一些额外的网络架构设计。
MMO Architecture

MMOG中一般会有各种子系统来组成整体的玩法系统。
简单的MMO分层架构如下:

连接层(link layer), 服务层(Business layer), 数据层(Data layer)是最核心的三层。
Link Layer

连接层(link layer)是玩家和游戏建立连接的一层。
在MMO中为了保护服务器不受攻击,我们需要单独的连接层来分离玩家和服务器数据。
- Login Server: 需要提供保护,完成连接和握手.
- Gateway: 网关服务器最核心作用是隔绝服务器的内外网,用户只连接Gateway, 就是一个防火墙。
会同时有很多个,就像客服。
Business layer
Lobby

连接到link layer后玩家会进入大厅(lobby)。
大厅可以理解为一个特殊的游戏模式,从而方便管理等待进行游戏的玩家。
- Lobby很多时候会作为一个缓冲池,让玩家等待MatchMaking的时候被管理起来。
Lobby很多时候是一个虚拟概念, 不存在实体。
Character Server

由于MMO中玩家的数据往往非常巨大,玩家的数据一般会保存在一个专门的服务器上称为character server。
Trading System

交易系统(trading system)是MMO的重要组成部分,在设计交易系统时需要保证系统有绝对的安全性。
Social System

玩家之间的聊天和交互功能一般会通过专门的社交系统(social system)来进行实现。
Matchmaking

很多MMO还需要实现玩家的匹配。→ 比如Mobile需要考虑平衡Ranking,延迟。
Data Storage

数据存储(data storage)是MMO中非常重要的问题。
不同于单机游戏,在MMO中玩家可能会随时下线但服务器则必须要保证一直运行。
因此如何存储和调用数据是一个非常重要也非常困难的问题。
- Relational Data Storage

- 关系数据库是最基本的数据存储方式,像游戏中玩家数据和游戏数据都会使用关系数据库进行存储。
现代网络游戏中往往还会结合分布式的技术进行存储。 → 确保网络波动不会影响存储.
- 关系数据库是最基本的数据存储方式,像游戏中玩家数据和游戏数据都会使用关系数据库进行存储。
- Non-Relational Data Storage

- 除了关系数据库外,非关系数据库也是目前非常流行的数据存储方法。
像游戏中的日志还有各种game state就比较适合使用非关系数据库。
- 除了关系数据库外,非关系数据库也是目前非常流行的数据存储方法。
- In-Memory Data Storage

- 随着游戏系统变得越来越复杂,在服务器运行过程中会产生大量的中间数据存储在内存中。
因此我们需要一些内存数据管理工具。
- 随着游戏系统变得越来越复杂,在服务器运行过程中会产生大量的中间数据存储在内存中。
Distributed System 分布式系统


随着玩家数量的增长,在单个服务器上支撑所有玩家进行游玩是几乎不可能的。
在这种情况下就需要使用分布式系统(distributed system)来提供游戏服务。
分布式系统要做好,有很多挑战:

Load Balancing 负载均衡

负载均衡(load balancing)是分布式系统中非常重要的概念,我们希望在不同服务器上都有相近的负载从而避免某些服务器负载过大的问题。



consistent hashing(一致性hash)是实现负载均衡的经典技术。
它的核心在于为服务器以及玩家设计对应的hashing算法,然后把服务器和玩家映射到一个环上,当玩家需要连接服务器时只需要利用hashing值寻找最近的服务器即可。
当某个服务器从圆环上删除时只需要把玩家连接到下一个服务器上即可,类似地添加新的服务器只需要在圆环上添加新的节点。

显然consistent hashing算法的效果很大程度上依赖于hashing函数,当服务器或是玩家在环上的分布不够均匀时是很难保证负载均衡的。
为了缓解这样的问题我们可以在环上设置一些虚拟的服务器,然后再把虚拟服务器链接到真实服务器上。
Servers Management 服务管理

分布式系统的另一大难点在于如何管理大量同时运行的服务。


我们可以使用Apache或是etcd这样的工具来监视和管理各种服务。
Bandwidth Optimization 带宽优化

带宽优化(bandwidth optimization)是现代网络游戏必须要解决的问题。
网络带宽不仅仅是游戏运营成本的重要组成部分,对玩家的游戏体验也有着重要的影响。
带宽的计算实际上非常简单,根据计算视角的不同我们有不同的衡量指标:

Data Compression

数据压缩(data compression)是经典的带宽优化方法。
在网络游戏中我们可以把浮点数转换为低精度的定点数来减少数据量。

我们甚至可以对游戏地图进行分区然后在小区域中使用定点数来缓解低精度数值带来的影响。
Object Relevance

另一种缓解带宽需求的方式是只同步和玩家相关的对象,这样可以极大地减少每次和玩家同步的数据量。

我们可以把整个游戏世界划分为若干个区域 Zone,这样每个玩家都会位于某个区域中。
不同区域的数据是相互隔绝的,因此在同步时只需要同步区域中的数据即可。

在一些开放世界游戏中我们不希望出现区域的划分,此时则可以利用area of inerest (AOI)的概念。
AOI的意义在于我们只需要关注玩家附近的情况而无需考虑更远区域的信息。

AOI最简单的实现方法是利用一个半径来查询附近信息。



当玩家数量很多时还可以利用网格划分的方法来加速查询。




除此之外我们也可以使用十字链表这样的数据结构来进行加速。

当然也可以使用PVS这样的技术来剔除不相关的对象。
Varying Update Frequency

除了上面介绍的方法我们也可以通过调整更新频率的方式来降低带宽。
一种经典的策略是根据物体和玩家之间的距离来设置更新频率,使得距离玩家远的物体更新得慢一些,距离近的更新得快一些。
Anti-Cheat 反作弊

反作弊(anti-cheat)同样是现代网络游戏必须要实现的功能,作弊行为对游戏运营和其他玩家都会造成非常巨大的伤害。

网络游戏中的作弊手段是相当多样的,比如说可以修改本地的代码或是内存中的数据,
骇入底层三方库的接口,甚至可以通过劫持网络通信来实现作弊行为。
Obfuscating Memory 内存混淆

作弊最基本的方法是修改本地的内存。
对于很多在客户端进行校验的游戏只需要修改游戏内存中的数据就可以进行作弊。


为了应对这种作弊方式,我们可以对客户端套一个壳来防止侵入。
类似地,也可以对内存数据进行加密来防止侵入。
Verifying Local Files by Hashing 本地文件哈希值验证

另一种常见的作弊方法是修改本地的资源文件。
我们可以通过对比本地和服务器上资源的hashing来进行处理。
→ 比如针对透明挂.
Packet Interception and Manipulation 数据包拦截和篡改

消息的劫持和篡改是网络游戏中经常遇到的作弊方式,因此对于客户端和服务器发出的包就必须进行加密。


目前主流的加密算法包括对称加密和非对称加密两种。
对称加密是指客户端和服务器共享一副秘钥,它的缺陷在于当客户端被破解后秘钥就是公开的了,此时加密也就失效了。
因此在实践中更多地使用的是非对称加密算法,此时客户端只有公钥而在服务器端存有私钥。
这样即使客户端被破解了也无法完全获知所有数据。
System Software Invoke 系统软件注入

除此之外,作弊者还可以通过修改底层游戏引擎代码来进行作弊。

针对这种情况可以使用各种安全软件来检测游戏引擎是否存在注入的情况。
AI Cheat AI作弊
目前随着AI技术的发展还出现了使用AI进行作弊的现象,这对下一代反作弊系统的开发又提出了新的挑战。





Build a Scalable World
构建可拓展的游戏世界可以说是每个游戏从业者的梦想。







引用






