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