我有一些使用套接字制作多人回合制游戏的经验,但我从未尝试过实时动作游戏。我需要处理哪些额外的问题?我是否需要保留玩家行为的历史记录,以防落后玩家过去做某事?我真的需要使用 UDP 数据包还是 TCP 就足够了?还有什么?
我还没有真正决定要制作什么,但出于这个问题的目的,您可以考虑一个 10 人 2D 游戏与 XY 运动。
我有一些使用套接字制作多人回合制游戏的经验,但我从未尝试过实时动作游戏。我需要处理哪些额外的问题?我是否需要保留玩家行为的历史记录,以防落后玩家过去做某事?我真的需要使用 UDP 数据包还是 TCP 就足够了?还有什么?
我还没有真正决定要制作什么,但出于这个问题的目的,您可以考虑一个 10 人 2D 游戏与 XY 运动。
对于回合制游戏,通常很容易说“服务器拥有最终权限,我们完成了”。对于实时游戏,这种设计通常是一个很好的起点,但是一旦您添加延迟,客户端的移动/动作就会感觉没有响应。因此,您添加了某种“延迟隐藏”,允许客户端输入立即影响其角色或单位以解决该问题,现在您必须在客户端和服务器的游戏状态开始分歧时处理协调问题。9 次超过 10 次就好了,你将客户影响的对象弹出或 lerp 到权威位置,但是 10 次中有 1 次是当对象是玩家头像或其他东西时,这个解决方案是不可接受的,所以你开始授予客户对某些操作的权限。现在你必须协调服务器上的多个游戏状态,如果你关心这类事情,你必须通过恶意客户端向潜在的“作弊”敞开心扉。这基本上是每个传送/欺骗/任何错误/作弊出现的地方。
当然,您可以从“每个客户都对“他们的”对象拥有权限”的模型开始,而忽略作弊问题(在很多情况下都可以)。但是现在,如果该客户端退出,或者甚至“在跟上模拟的速度上落后了一点”,你很容易受到对游戏模拟的巨大影响——实际上每个玩家的游戏最终都会受到/感受到滞后或表现不佳的客户端,其形式是等待滞后的客户端赶上,或者让他们控制的游戏状态不同步。
确保所有玩家都在相同游戏状态下操作的常见策略是简单地同意玩家输入列表(通过上述模型之一),然后让游戏模拟在所有机器上同步播放。这意味着模拟逻辑必须完全匹配,否则游戏将不同步。这实际上比听起来更容易也更难。这更容易,因为游戏只是代码,并且当它给出相同的输入(甚至是随机数生成器)时,代码的执行几乎完全相同。这更难,因为有两种情况并非如此:(1)当您在游戏模拟之外不小心使用随机数时,以及(2)当您使用浮点数时。前者通过对哪些游戏系统使用哪些 RNG 有严格的规则/断言来纠正。后者通过不使用浮点数来解决。(浮点数实际上有 2 个问题,一个是根据您项目的优化配置,它们的工作方式非常不同,但即使解决了,它们在不同的处理器架构 atm 上的工作方式也不一致,哈哈)。星际争霸/魔兽争霸和任何提供“重播”的游戏最有可能使用此模型。事实上,拥有回放系统是测试 RNG 是否保持同步的好方法。
使用异步解决方案,游戏状态当局只需以某种频率将整个状态广播给所有其他客户端。客户端获取这些数据并将其放入他们的游戏状态(并且通常会进行一些简单的推断,直到他们获得下一次更新)。这就是“udp”成为一个可行选项的地方,因为您每隔约 1 秒左右就会向整个游戏状态发送垃圾邮件,删除这些更新的一部分是无关紧要的。对于游戏状态相对较少的游戏(地震、魔兽世界),这通常是最简单的解决方案。
设置多人游戏涉及一些因素
协议,重要的是您决定是否需要 TCP 或 UDP。UDP 的开销较小,但不能保证交付。相反,TCP 更值得信赖。每场比赛都会有他们喜欢的协议。例如,UDP 适用于第一人称射击游戏,但可能不适合信息需要一致的 RTS
防火墙/连接。确保您的多人游戏不必进行 2000 个出站连接并使用标准端口,以便轻松进行端口转发。将它与 Windows 防火墙连接可能是一个额外的好处。
带宽。这很重要,您打算通过网络连接推送多少数据?我想这将归结为播放测试和记录吞吐量。如果您要求每个客户端超过 200kb/s,您可能需要重新考虑一些事情。
服务器负载。这一点也很重要,一个服务器需要多少处理才能完成一个正常的游戏?您是否需要一些具有 16GB RAM 的超 8 核服务器来运行它?有没有办法减少呢?
我想还有更多,但你真的想要一款可以通过网络和各种连接轻松玩的游戏。
计划是你最好的朋友。弄清楚你真正的需求是什么。
加载数据:是否每台计算机都将具有相同的模型和图形,只是名称和位置在网络上移动。如果每个玩家都可以自定义他们的角色或其他物品,那么您将不得不移动这些数据。
作弊:你有必要担心吗?你能相信每个客户所说的话。如果不是,那么您的服务器端逻辑看起来与您的客户端逻辑不同。想象一下这个简单的例子,你的 10 名玩家中的每一个都可能因为能量提升而有不同的移动速度。为了最大限度地减少作弊,您应该计算每个玩家可以在服务器的通信更新之间移动多远,否则玩家可以在那里加速并且没有任何东西可以阻止他们。如果玩家总是比预期快一点或有一次跳跃,服务器只会将他们重新定位在可能的最近位置,因为这可能是时钟偏差或一次通信中断。但是,如果玩家不断地移动两次,那么将他们踢出游戏可能是明智的。数学越多,
点对点如何:即使游戏将是点对点的,您可能希望让一个玩家开始游戏并将其用作服务器,这比尝试管理一些更基于云的游戏要容易得多方法。如果没有服务器,那么您需要制定一个协议来解决两台游戏状态不一致的机器之间的争议。
再次计划是您最好的朋友计划,计划,计划。如果你对一个问题思考得足够多,你就可以想办法解决大部分问题。然后,您可以开始考虑尚未解决的问题。
避免作弊有多重要?[您可以信任来自客户端的任何信息,还是可以信任和验证它们?]
对象模型 对象 如何从一台机器传送到另一台机器?如何对对象执行操作?
您是在做客户端/服务器还是点对点?
随机数 如果您进行点对点操作,那么您需要使它们保持同步并且随机数同步。
如果你在做客户端/服务器,你如何处理滞后?[航位推算?]
网络编码涉及到很多重要的问题。
查看 RakNet,它可以免费下载代码,它是讨论组。
如果您在 LAN 上运行,则 TCP 很好。但是如果你想在线玩,你必须使用UDP并实现你自己的类TCP层:需要通过throw NAT路由器。
您需要在对等或客户端-服务器通信之间进行选择。在客户端-服务器模型中,同步和世界状态更容易实现,但您可能缺乏在线反应性。在 Pee-to-peer 中,它更复杂,但对玩家来说更快。
不要为游戏目的保留玩家行动的历史(这样做,但仅用于重播功能)。如果你达到了必要的程度,最好让每个玩家等待。