Skip to content

Unreal 学习笔记(四)

网络同步概述

拓扑结构

游戏中的网络同步有如下几种常见的拓扑结构:

  • Peer2Peer:每个客户端和其他所有客户端互相通信。于红警等早期游戏采用,当人数变多时拓扑结构过于复杂。
  • ListenServer:一台客户端作为主机,运行一个ListenServer,其他客户端与其通信(如 MineCraft 局域网联机),也是十分常用的拓扑结构,但当人数过多时会导致主机不堪重负。
  • Client-Server:一个专用服务器(Dedicated Server)或服务器集群来同步各个状态

同步信息

  • 输入模块:同步控制流
  • 核心逻辑模块:同步事件流/状态流
  • 输出控制模块:同步渲染指令流
  • 输出模块:同步视频流(云游戏)

常用的是帧同步(同步控制流)、状态同步(同步事件/状态流)。

帧同步模型

核心理念:输入模块的输入给定时,同样的客户端其他模块的输出都是确定的。

不同的客户端把输入发送给服务器,服务器逐帧计算,将Frame N的数据打包后的一致性输入返回给客户端。客户端再通过确定性逻辑计算得到相同的输出画面。

参考资料:帧同步LockStep:原理与实现

浮点数问题

Q:在不同平台上,浮点数计算精度不一致。

解决方案:

  1. (临时方案)限制浮点数精度,取高N位
  2. 采用定点数计算

Q:定点数开放和超越函数如何实现?

A:泰勒展开后查表

Q:定点数随机函数?

A:线性同余生成伪随机数

参考资料:Emulating Double Precision on the GPU to Render Large Worlds - Godot Engine

逻辑一致性

  1. 基于整数和定点数,算法一致来实现逻辑
  2. 表现和逻辑分离,表现层不可修改逻辑
  3. 注意多线程不确定性

模型的改进

古典同步模型下,服务器需要收到所有Client的ACK才发Frame N+1;现代同步模型则遵从一套自己的复杂协议。

断线重连问题:短单局可以直接追帧,长单局需要结合状态同步,采用内存快照同步技术。

一个内存快照同步的技术方案示例

状态同步模型

状态同步的服务器种类

为实际游戏状态集合,只需保证各个客户端持有的 即可。包括三种实现:

  • 仲裁服务器
  • 游戏服务器
  • 权威服务器(UE实现,与玩法弱相关)

仲裁服务器:客户端处理主体逻辑,服务器只维护极小的部分状态逻辑,如赛车游戏等。

权威服务器:客户端只有一小部分模拟逻辑,即在 Dedicated Server 或 Listen Server 维护了完整的游戏状态,是游戏服务器的一种特例。大多数 FPS 游戏都采用这种方式。

事件冲突

事件冲突:如两个玩家拾取同一个物品。

  • 可以单点仲裁解决,服务器知道这两个事件肯定是有先后顺序的。
  • 但是存在延迟问题,可以考虑用回溯到发生当时进行判断。
  • 采用NTP算法同步逻辑时间:时间同步协议NTP

状态优化

  • 客户端插值
  • 航位预测
  • 视觉掩饰(前摇、后摇)

同步协议的选择

一般都选 UDP。TCP太慢了,归功于重传机制与不再适用于弱网络的RTO(超时重传时间)计算策略。

因此开发了RUDP(Reliable UDP)等协议,一种实现方法是RUDP-ARQ(自动重传请求),实现简化版TCP协议;另一种方式是RUDP-FEC(前向冗余纠错)

TODO: 等计网结课了有空整理一下

FPS 游戏系统概述

武器系统

种类、槽位分类略。

程序逻辑:立刻命中(InstantHit)、投射物(Projectile)

弹道模型:

  • 主视角角度
  • 后坐力(最小值+连发数*递增系数,达到最大值后不再增加)
  • 连发数
  • 精准度
  • 散发度

主弹道子弹射出方向=主视角角度+后坐力+精准度+散发度

特效:维护一个状态机管理开火、停止开火等状态的转换

游戏开发与设计中的“3C”是指什么?(Gameplay程序必看)