随便聊聊网络游戏开发模式

2024-06-19 03:04

本文主要是介绍随便聊聊网络游戏开发模式,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

本文仅是闲聊罢了,并非开发教程,有意依此学习的同学注意一下.

就网络游戏开发而言,目前主流的同步方式大概是以下两种:

  • 帧同步

顾名思义,就是按"帧"(一般指逻辑帧)来进行网络同步,一般实现上,都是客户端按"帧"来发送自己的操作数据(无操作也是一种操作(也要发送)),服务器收取到所有客户端的操作数据之后统一进行分发,客户端收取到分发数据之后则进行"帧"模拟,由于只同步操作数据(客户端各自进行逻辑模拟),为了能让各个客户端保持同步,对于客户端逻辑的编写有比较高的确定性需求(随机、浮点等不确定因素都需要进行确定性处理,当然纯表现类的内容可以忽略),游戏项目中比较典型使用帧同步技术的应该就是"王者荣耀"(以下简称"王者")了.

  • 状态同步

相比于帧同步,状态同步则是按"状态"(动态单位的位置速度等数据)来进行网络同步,一般实现上,服务器都是在游戏一开始进行一次基准"状态"同步(给客户端),之后在游戏过程中按需进行增量"状态"同步,客户端同样按需对接收到的"状态"数据进行设置处理(也可做些插值外推等操作),一般数据量较大的游戏(尤其是涉及各类LOD处理时),逻辑是很难做到高确定性的,所以帧同步基本就不能使用了,其实"王者"最初选用帧同步应该也并非完全出自技术层面的考量,更多的可能还是当时项目周期的限制,如果现在回过头来重新评估的话,"王者"改用状态同步应该也是可行的.


有些游戏也可能同时使用 帧同步 和 状态同步,具体则根据游戏实际需求来定了,不过不论哪种同步方式,都有一个棘手的问题需要处理:主控端的(本地)操作响应问题:

在帧同步中,由于(本地)操作需要经历上传接收的网络流程才能进行逻辑模拟,所以操作延迟基本是不可避免的,虽然可以做一些本地(预测)表现来优化(譬如技能前摇动作等等),但是因为高确定性的要求,逻辑可优化的空间比较小.

而在状态同步中,如果逻辑允许,客户端本地可以直接执行本地操作(逻辑模拟)并将操作数据上传,服务器接收到客户端操作数据后执行逻辑模拟,然后将结果下发,客户端再依据接收到的下发结果对操作进行"纠错重放",如果一切顺利,主控端将感受不到延迟.

对于诸如云游戏之类将客户端直接作为终端显示的同步模式,更多的考量应该是流量控制方面的(而非具体的同步技术),同时因为同步模式的限制,这类游戏对主控端的(本地)操作响应基本没有优化空间,所以一般来讲这类游戏只适合对(本地)操作响应要求不高的游戏.


接着我们来聊下一个更细节的问题:

如何进行实际的网络同步呢 ?

一般来讲,主流的网络同步操作如下(省略加解密之类的操作):

  • 定义生成数据格式(使用 Protobuf 等工具)
  • 使用对应数据格式编解码数据
  • TCP/UDP 发送接收数据
    • (TCP 可靠但不灵活,游戏中使用 TCP 的话可能会出现更多的延迟问题;UDP 不可靠但灵活,如果游戏使用 UDP 的话可能需要去自行实现 TCP 的某些子集功能以达到一定的可靠性要求,总的来说各有利弊)

当然,上述的流程比较底层,一般游戏开发都会对其进行上层封装,最终的结果大概是以下两个接口(伪代码):

  void SendMessage(Proto);void ReceiveMessage(Proto);

再以 服务器开发 与 客户端开发 的角度来看下网络游戏的开发流程(仅涉及程序开发流程):

  • 服务器开发 与 客户端开发 对齐逻辑开发需求
  • 拆解 服务器程序内容 与 客户端程序内容
  • 定义相关同步协议
  • 服务器开发 与 客户端开发 各自编写代码并持续进行阶段联调

可以看到,该流程下 服务器端代码 与 客户端代码 是完全隔离的,双方仅仅通过协议进行协作交流(其他方面双方可以一无所知).

这本身其实是一个很好的开发范式,很多网络程序也是如此实践的,但对于网络游戏而言,有时候却捉襟见肘了:

考虑我们要开发网络游戏中的技能系统,首当其冲的一个问题是如何进行伤害判定,过去像 MMO 一类的游戏中,伤害判定一般都是在服务器进行的,判定方式往往也很简单,基本上就是检测一些距离方位的限制,同时为了增强手感,客户端还会配合进行一些攻击帧的表现处理,总的来说使用上面那种开发"隔离"的方式还能应付.

但是我们对新的技能系统有更高的需求,我们希望伤害判定能够严格按照动画中配置的攻击帧数进行,同时动画本身也可能带有 Root Motion 和各类动画姿态处理(IK等),此时我们便遇到难题了,摆在我们面前的选项似乎只剩两个:

  • 服务器实现相同一套动画系统(A 方案)
  • 伤害判定转移至客户端进行(B 方案)

两种方案都不尽如人意.

因为 路径依赖 的关系,很多项目可能会选择 B 方案,毕竟 A 方案基本没有可行性,尤其是当项目有之前的服务器继承代码时,而我们又需要坚持上述的开发"隔离"模式 …

但实际上,如果我们抛弃所谓的开发"隔离",我们还有更好的选择:

  • DedicatedServer

所谓的 DedicatedServer,即专用服务器,可以理解为游戏逻辑在开发上不再"隔离",而是同时支持服务器和客户端,由于代码基是相同的,基础功能自然也是相同的,上面提到的动画难题也便迎刃而解了.

说的有些抽象,我们拿 UE 的同步框架来举个例子:

先看下 ENetMode:

enum ENetMode
{/** Standalone: a game without networking, with one or more local players. Still considered a server because it has all server functionality. */NM_Standalone,/** Dedicated server: server with no local players. */NM_DedicatedServer,/** Listen server: a server that also has a local player who is hosting the game, available to other players on the network. */NM_ListenServer,/*** Network client: client connected to a remote server.* Note that every mode less than this value is a kind of server, so checking NetMode < NM_Client is always some variety of server.*/NM_Client,NM_MAX,
};

国情关系,我们一般开发时都不太关心 NM_Standalone 和 NM_ListenServer,但实际从实践角度来讲,一个游戏本身同时支持单机游玩和联机游玩其实是件很正常的事情,但在我们先前的开发"隔离"模式下,同时支持单机游玩和联机游玩基本是不可能实现的 …

再来看下 ENetRole:

/** The network role of an actor on a local/remote network context */
UENUM()
enum ENetRole : int
{/** No role at all. */ROLE_None,/** Locally simulated proxy of this actor. */ROLE_SimulatedProxy,/** Locally autonomous proxy of this actor. */ROLE_AutonomousProxy,/** Authoritative control over the actor. */ROLE_Authority,ROLE_MAX,
};

这个是对 Actor 的网络角色的定义,也是代码同时支持 服务器 和 客户端 的关键,譬如我们做以下判断(伪代码):

if (ActorNetRole == ROLE_Authority)
{// ...
}

基本可以认为是在 服务器 端执行代码(而不会在客户端执行)

接着就是 RPC(远程过程调用)了, UE 中的 RPC 大概可以分为下面两个大类:

  • 按可靠性分

    • Reliable
    • Unreliable
  • 按同步方式分

    • Client
    • Server
    • NetMulticast

另一个重要概念就是 Replicate 了,可以理解为一种服务器向客户端自动同步数据的方式.

简单来说, RPC 可以理解为事件通知(或者狭义上类似于之前的那种协议同步方式(只是方式更简单一些)),Replicate 则可以理解为状态同步,仅会由服务器同步给客户端,简单来讲也可以通过 RPC 来模拟,但是逻辑上使用 Replicate 会更简单,并且是自动化的.


总结来看, DedicatedServer 是更广义上的一种网络游戏开发框架,先前的那种协议同步方式可以认为是其框架下的子集,相互"隔离"的网络游戏开发方式有其适用的场景,但是随着游戏复杂度的提高(因为游戏需求提高等原因), DedicatedServer 在架构层面的优势会愈加明显.

“兼听则明,偏信则暗”

这篇关于随便聊聊网络游戏开发模式的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1073830

相关文章

这15个Vue指令,让你的项目开发爽到爆

1. V-Hotkey 仓库地址: github.com/Dafrok/v-ho… Demo: 戳这里 https://dafrok.github.io/v-hotkey 安装: npm install --save v-hotkey 这个指令可以给组件绑定一个或多个快捷键。你想要通过按下 Escape 键后隐藏某个组件,按住 Control 和回车键再显示它吗?小菜一碟: <template

Hadoop企业开发案例调优场景

需求 (1)需求:从1G数据中,统计每个单词出现次数。服务器3台,每台配置4G内存,4核CPU,4线程。 (2)需求分析: 1G / 128m = 8个MapTask;1个ReduceTask;1个mrAppMaster 平均每个节点运行10个 / 3台 ≈ 3个任务(4    3    3) HDFS参数调优 (1)修改:hadoop-env.sh export HDFS_NAMENOD

嵌入式QT开发:构建高效智能的嵌入式系统

摘要: 本文深入探讨了嵌入式 QT 相关的各个方面。从 QT 框架的基础架构和核心概念出发,详细阐述了其在嵌入式环境中的优势与特点。文中分析了嵌入式 QT 的开发环境搭建过程,包括交叉编译工具链的配置等关键步骤。进一步探讨了嵌入式 QT 的界面设计与开发,涵盖了从基本控件的使用到复杂界面布局的构建。同时也深入研究了信号与槽机制在嵌入式系统中的应用,以及嵌入式 QT 与硬件设备的交互,包括输入输出设

OpenHarmony鸿蒙开发( Beta5.0)无感配网详解

1、简介 无感配网是指在设备联网过程中无需输入热点相关账号信息,即可快速实现设备配网,是一种兼顾高效性、可靠性和安全性的配网方式。 2、配网原理 2.1 通信原理 手机和智能设备之间的信息传递,利用特有的NAN协议实现。利用手机和智能设备之间的WiFi 感知订阅、发布能力,实现了数字管家应用和设备之间的发现。在完成设备间的认证和响应后,即可发送相关配网数据。同时还支持与常规Sof

活用c4d官方开发文档查询代码

当你问AI助手比如豆包,如何用python禁止掉xpresso标签时候,它会提示到 这时候要用到两个东西。https://developers.maxon.net/论坛搜索和开发文档 比如这里我就在官方找到正确的id描述 然后我就把参数标签换过来

在JS中的设计模式的单例模式、策略模式、代理模式、原型模式浅讲

1. 单例模式(Singleton Pattern) 确保一个类只有一个实例,并提供一个全局访问点。 示例代码: class Singleton {constructor() {if (Singleton.instance) {return Singleton.instance;}Singleton.instance = this;this.data = [];}addData(value)

Linux_kernel驱动开发11

一、改回nfs方式挂载根文件系统         在产品将要上线之前,需要制作不同类型格式的根文件系统         在产品研发阶段,我们还是需要使用nfs的方式挂载根文件系统         优点:可以直接在上位机中修改文件系统内容,延长EMMC的寿命         【1】重启上位机nfs服务         sudo service nfs-kernel-server resta

【区块链 + 人才服务】区块链集成开发平台 | FISCO BCOS应用案例

随着区块链技术的快速发展,越来越多的企业开始将其应用于实际业务中。然而,区块链技术的专业性使得其集成开发成为一项挑战。针对此,广东中创智慧科技有限公司基于国产开源联盟链 FISCO BCOS 推出了区块链集成开发平台。该平台基于区块链技术,提供一套全面的区块链开发工具和开发环境,支持开发者快速开发和部署区块链应用。此外,该平台还可以提供一套全面的区块链开发教程和文档,帮助开发者快速上手区块链开发。

Vue3项目开发——新闻发布管理系统(六)

文章目录 八、首页设计开发1、页面设计2、登录访问拦截实现3、用户基本信息显示①封装用户基本信息获取接口②用户基本信息存储③用户基本信息调用④用户基本信息动态渲染 4、退出功能实现①注册点击事件②添加退出功能③数据清理 5、代码下载 八、首页设计开发 登录成功后,系统就进入了首页。接下来,也就进行首页的开发了。 1、页面设计 系统页面主要分为三部分,左侧为系统的菜单栏,右侧

v0.dev快速开发

探索v0.dev:次世代开发者之利器 今之技艺日新月异,开发者之工具亦随之进步不辍。v0.dev者,新兴之开发者利器也,迅速引起众多开发者之瞩目。本文将引汝探究v0.dev之基本功能与优势,助汝速速上手,提升开发之效率。 何谓v0.dev? v0.dev者,现代化之开发者工具也,旨在简化并加速软件开发之过程。其集多种功能于一体,助开发者高效编写、测试及部署代码。无论汝为前端开发者、后端开发者