RTS 客户端-服务器网络

2023-11-23 16:45
文章标签 服务器 客户端 网络 rts

本文主要是介绍RTS 客户端-服务器网络,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Stone Monarch 从一开始就支持多人游戏,但随着时间的推移,网络模型经历了多次迭代。我最初基于这篇著名的帝国时代文章实现了点对点锁步模型。

点对点锁定步骤有一些众所周知的问题。点对点方面使玩家很难相互连接,并增加了每个新玩家的网络负载。锁定步骤方面很容易出现棘手的错误,导致玩家之间的游戏状态不同步。我当前的架构引入了服务器,并且还放宽了锁步的一些确定性要求。它仍然使用“回合”的锁步概念来确保每个客户端运行相同的模拟,并且在没有收到所有玩家的命令的情况下不会继续进行。

客户端-服务器锁定步骤

锁步转弯示例

游戏分为一系列固定持续时间的“回合”。游戏开始时的第一步是确定 1 回合的长度。这是通过测量消息从每个客户端到服务器的往返时间来完成的。服务器选择最长的时间作为回合长度。在游戏过程中,可以根据观察到的网络性能调整回合长度。

每当玩家想要执行某个操作时,请求的操作就会立即发送到服务器。服务器聚合它收到的所有操作,直到到达下一个回合边界。此时,服务器向所有客户端发送轮次消息,其中包含未来 1 轮要执行的操作。当客户准备好执行下一个回合时,他们应该已经收到模拟回合所需的所有信息。

在上面的示例中,转弯长度已设置为 100ms。服务器在第 1 轮期间接收操作,并在第 2 轮开始时发送包含第 3 轮操作的轮次消息。该消息应及时到达客户端,以便客户端执行第 3 轮。

处理延误

客户端延迟

如果其中一个客户端在准备好执行该轮次时没有收到轮次消息,则它必须暂停模拟,直到收到来自服务器的轮次。一旦它收到回合,它就可以立即开始再次执行。此时客户端将稍微落后于服务器的模拟,因此更有可能及时接收轮流。然而,玩家的命令发出和执行之间的延迟将会增加。

服务器端延迟

为了防止客户端远远落后于服务器的模拟(并遭受高命令延迟),服务器可以尝试检测到这一点并暂停其自己的模拟。为此,客户端可以在发送到服务器的每个操作中包含当前游戏时间。然后服务器将该时间与自己模拟中的当前游戏时间进行比较。如果差异大于 1 圈的长度(或任何任意长度),服务器可以暂停以允许客户端赶上。如果任何其他客户端在模拟中进一步领先,这可能会导致它们也暂停,直到所有客户端彼此更加同步。

在我最初的实现中,我使每次暂停的长度等于 1 圈的长度,这似乎是合乎逻辑的,可以防止客户在模拟中向前或向后滑动。然而,当前的方法极大地减少了暂停发生时的持续时间。通常,玩家甚至不会注意到它们。现在可以允许慢速客户端稍微落后于其他客户端,理论上他们可能处于劣势,因为他们的操作将需要更长的时间来执行。然而,这可以被服务器限制,所以我总是可以调整它以找到合适的平衡。

调整转弯长度

如果服务器观察到太多的暂停,它可以通过在轮次消息中包含新的轮次长度来增加轮次长度。所有客户在开始执行新回合时都将应用此规则。这将同等地增加所有玩家的命令延迟。

相反,如果服务器在一段时间内没有观察到任何暂停,它可以减少回合长度,从而为所有玩家提供更低的命令延迟。

非确定性事件

在传统的锁步网络中,每回合仅发出玩家命令,其余模拟预计将在客户端之间确定性地进行。然而,某些游戏逻辑很难保持确定性,尤其是在 Unity 中,游戏引擎不提供任何此类保证。

在这种情况下,我确保非确定性游戏逻辑仅执行一次,并将结果作为其自己的操作以及玩家请求的操作一起发布。

例如,假设玩家攻击了一枚炸弹,导致其爆炸。玩家发出所有客户端执行的攻击动作。在炸弹爆炸的地方,需要检查周围区域,看看哪些单位会被击中。这是使用不确定的 Unity API 完成的。因此,只有一个客户端(可能是拥有炸弹的客户端)将进行此模拟并将结果(应该受到伤害的单位列表)作为新操作发送到服务器。通过这种方式,每个客户端的模拟仍然是相同的

如果存在作弊问题,服务器可以代替客户端来计算这些操作。这将要求服务器运行与客户端相同的模拟。这是我正在努力的方向,尽管目前客户仍然做出一些不确定的决定。

这种方法的优点是,仅当某些特定的游戏逻辑预计是不确定的时才需要发送额外的数据。任何确定性的事情(例如村民继续收集直到他们的资源已满)都不会使用任何额外的网络资源。它也比重写 Unity 功能以使其具有确定性更容易实现,尤其是在物理方面。

缺点是,如果我错了,认为某些事情是确定性的,但事实并非如此,它仍然会导致游戏不同步。

这篇关于RTS 客户端-服务器网络的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

Nginx屏蔽服务器名称与版本信息方式(源码级修改)

《Nginx屏蔽服务器名称与版本信息方式(源码级修改)》本文详解如何通过源码修改Nginx1.25.4,移除Server响应头中的服务类型和版本信息,以增强安全性,需重新配置、编译、安装,升级时需重复... 目录一、背景与目的二、适用版本三、操作步骤修改源码文件四、后续操作提示五、注意事项六、总结一、背景与

Debian 13升级后网络转发等功能异常怎么办? 并非错误而是管理机制变更

《Debian13升级后网络转发等功能异常怎么办?并非错误而是管理机制变更》很多朋友反馈,更新到Debian13后网络转发等功能异常,这并非BUG而是Debian13Trixie调整... 日前 Debian 13 Trixie 发布后已经有众多网友升级到新版本,只不过升级后发现某些功能存在异常,例如网络转

Web服务器-Nginx-高并发问题

《Web服务器-Nginx-高并发问题》Nginx通过事件驱动、I/O多路复用和异步非阻塞技术高效处理高并发,结合动静分离和限流策略,提升性能与稳定性... 目录前言一、架构1. 原生多进程架构2. 事件驱动模型3. IO多路复用4. 异步非阻塞 I/O5. Nginx高并发配置实战二、动静分离1. 职责2

Linux搭建ftp服务器的步骤

《Linux搭建ftp服务器的步骤》本文给大家分享Linux搭建ftp服务器的步骤,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录ftp搭建1:下载vsftpd工具2:下载客户端工具3:进入配置文件目录vsftpd.conf配置文件4:

Linux查询服务器 IP 地址的命令详解

《Linux查询服务器IP地址的命令详解》在服务器管理和网络运维中,快速准确地获取服务器的IP地址是一项基本但至关重要的技能,下面我们来看看Linux中查询服务器IP的相关命令使用吧... 目录一、hostname 命令:简单高效的 IP 查询工具命令详解实际应用技巧注意事项二、ip 命令:新一代网络配置全

Python开发简易网络服务器的示例详解(新手入门)

《Python开发简易网络服务器的示例详解(新手入门)》网络服务器是互联网基础设施的核心组件,它本质上是一个持续运行的程序,负责监听特定端口,本文将使用Python开发一个简单的网络服务器,感兴趣的小... 目录网络服务器基础概念python内置服务器模块1. HTTP服务器模块2. Socket服务器模块

Linux查询服务器系统版本号的多种方法

《Linux查询服务器系统版本号的多种方法》在Linux系统管理和维护工作中,了解当前操作系统的版本信息是最基础也是最重要的操作之一,系统版本不仅关系到软件兼容性、安全更新策略,还直接影响到故障排查和... 目录一、引言:系统版本查询的重要性二、基础命令解析:cat /etc/Centos-release详

Python WSGI HTTP服务器Gunicorn使用详解

《PythonWSGIHTTP服务器Gunicorn使用详解》Gunicorn是Python的WSGI服务器,用于部署Flask/Django应用,性能高且稳定,支持多Worker类型与配置,可处... 目录一、什么是 Gunicorn?二、为什么需要Gunicorn?三、安装Gunicorn四、基本使用启

通过配置nginx访问服务器静态资源的过程

《通过配置nginx访问服务器静态资源的过程》文章介绍了图片存储路径设置、Nginx服务器配置及通过http://192.168.206.170:8007/a.png访问图片的方法,涵盖图片管理与服务... 目录1.图片存储路径2.nginx配置3.访问图片方式总结1.图片存储路径2.nginx配置

Go语言网络故障诊断与调试技巧

《Go语言网络故障诊断与调试技巧》在分布式系统和微服务架构的浪潮中,网络编程成为系统性能和可靠性的核心支柱,从高并发的API服务到实时通信应用,网络的稳定性直接影响用户体验,本文面向熟悉Go基本语法和... 目录1. 引言2. Go 语言网络编程的优势与特色2.1 简洁高效的标准库2.2 强大的并发模型2.