实现实时多人游戏存在哪些问题
我有一些使用套接字制作多人回合制游戏的经验,但我从未尝试过实时动作游戏。 我还需要处理哪些额外问题? 我是否需要保留玩家操作的历史记录,以防落后的玩家过去做过某事? 我真的需要使用 UDP 数据包还是 TCP 就足够了? 还有什么?
我还没有真正决定要制作什么,但出于这个问题的目的,您可以考虑一款具有 XY 运动的 10 人 2D 游戏。
I have some experience making multiplayer turn-based games using sockets, but I've never attempted a realtime action game. What kind of extra issues would I have to deal with? Do I need to keep a history of player actions in case lagged players do something in the past? Do I really need to use UDP packets or will TCP suffice? What else?
I haven't really decided what to make, but for the purpose of this question you can consider a 10-player 2D game with X Y movement.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
如果您在 LAN 上运行,TCP 就可以了。 但如果你想在线玩,你必须使用UDP并实现你自己的类似TCP的层:有必要通过扔NAT路由器。
您需要在点对点通信或客户端-服务器通信之间进行选择。 在客户端-服务器模型中,同步和世界状态更容易实现,但您可能缺乏在线反应性。 在点对点中,情况更复杂,但对玩家来说速度更快。
不要出于游戏目的保留玩家操作的历史记录(这样做,但仅用于重播功能)。 如果你到了有必要的时候,最好让每个玩家都等待。
TCP is fine if your run on a LAN. But if you want to play online, you must use UDP and implement your own TCP-like layer: it's necessary to pass throw NAT routers.
You need to choose between Peer-to-peer or Client-Server communication. In Client-Server model, synchronisation and state of the world are easier to implement, but you might have a lack of reactivity online. In Pee-to-peer it's more complicated, but faster for the player.
Don't keep history of player action for game purpose (do it, but only for replay functionality). If you reach a point where it is necessary, prefer make every player wait.
对于回合制游戏,通常很容易说“服务器拥有最终权力,我们就完成了”。 对于实时游戏,这种设计通常是一个很好的起点,但一旦增加延迟,客户端的移动/操作就会感觉没有响应。 因此,您添加某种“延迟隐藏”,允许客户端输入立即影响其角色或单位来解决该问题,现在您必须在客户端和服务器游戏状态开始出现分歧时处理协调问题。 10 次中有 9 次很好,你将客户端影响的对象弹出或 lerp 到权威位置,但是十分之一是当对象是玩家头像或其他东西时,该解决方案是不可接受的,所以你开始授予客户对某些行动的权力。 现在,如果您关心这类事情,您必须协调服务器上的多个游戏状态,并让自己面临恶意客户端潜在的“作弊”。 这基本上是每个传送/欺骗/任何错误/作弊出现的地方。
当然,您可以从一个模型开始,其中“每个客户都对“他们的”对象拥有权限”并忽略作弊问题(在相当多的情况下很好)。 但现在,如果该客户端退出,或者甚至“只是在跟上模拟方面落后了一点”,那么您很容易受到游戏模拟的巨大影响 - 实际上,每个玩家的游戏最终都会受到/感受到落后或表现不佳的客户端,要么等待落后的客户端赶上,要么让他们控制的游戏状态不同步。
确保所有玩家在同一游戏状态下操作的常见策略是简单地就玩家输入列表达成一致(通过上述模型之一),然后让游戏模拟在所有玩家上同步进行。机器。 这意味着模拟逻辑必须完全匹配,否则游戏将不同步。 这实际上比听起来更容易也更难。 这更容易,因为游戏只是代码,并且当给出相同的输入(甚至是随机数生成器)时,代码几乎执行完全相同的操作。 这更困难,因为有两种情况并非如此:(1)当您在游戏模拟之外不小心使用随机数时;(2)当您使用浮动时。 前者可以通过对哪些游戏系统使用哪些 RNG 制定严格的规则/断言来纠正。 后者是通过不使用浮动来解决的。 (浮动实际上有两个问题,一是根据项目的优化配置,它们的工作方式非常不同,但即使解决了这个问题,它们在不同的处理器架构上工作也不一致,哈哈)。 星际争霸/魔兽争霸和任何提供“重玩”的游戏很可能使用此模型。 事实上,拥有重播系统是测试 RNG 是否保持同步的好方法。
通过异步解决方案,游戏状态当局只需以某种频率向所有其他客户端广播整个状态。 客户端获取这些数据并将其输入到他们的游戏状态中(通常会进行一些简单的推断,直到他们获得下一次更新)。 这就是“udp”成为一个可行的选择的地方,因为你每隔约 1 秒左右就会向整个游戏状态发送垃圾邮件,丢弃这些更新的一部分是无关紧要的。 对于游戏状态相对较少的游戏(《地震》、《魔兽世界》),这通常是最简单的解决方案。
With turn based games, normally it's very easy to just say 'the server has ultimate authority and we're done'. With real time games, often that design is a great place to start, but as soon as you add latency the client movement/actions feels unresponsive. So you add some sort of 'latency hiding' allowing the clients input to affect their character or units immediately to solve that problem, and now you have to deal with reconciling issues when the client and servers gamestate starts to diverge. 9 times outta 10 that just fine, you pop or lerp the objects the client has affected over to the authoritative position, but that 1 out of 10 times is when the object is the player avatar or something, that solution is unacceptable, so you start give the client authority over some actions. Now you have to reconcile the multiple gamestates on the server, and open yourself up to a potentially 'cheating' via a malicious client, if you care about that sort of thing. This is basically where every teleport/dupe/whatever bug/cheat comes up.
Of course you could start with a model where 'every client has authority over 'their' objects' and ignore the cheating problem (fine in quite a few cases). But now you're vulnerable to a massive affect on the game simulation if that client drops out, or even 'just falls a little behind in keeping up with the simulation' - effectively every players game will end up being/feeling the effects of a lagging or otherwise underperforming client, in the form of either waiting for lagging client to catch up, or having the gamestate they control out of sync.
A common strategy to ensure all players are operating on the same gamestate is to simply agree on the list of player inputs (via one of the models described above) and then have the gameplay simulation play out synchronously on all machines. This means the simulation logic has to match exactly, or the games will go out of sync. This is actually both easier and harder than it sounds. It's easier because a game is just code, and code pretty much executes exactly the same when it's give the same input (even random number generators). It's harder because there are two cases where that's not the case: (1) when you accidently use random outside of your game simulation and (2) when you use floats. The former is rectified by having strict rules/assertions over what RNGs are use by what game systems. The latter is solved by not using floats. (floats actually have 2 problems, one they work very differently based on optimization configuration of your project, but even if that was worked out, they work inconsistently across different processor architectures atm, lol). Starcraft/Warcraft and any game that offers a 'replay' most likely use this model. In fact, having a replay system is a great way to test that your RNGs are staying in sync.
With an asynchronus solution the game state authorities simply broadcast that entire state to all the other clients at some frequency. The clients take that data and slam that into their gamestate (and normaly do some simplistic extrapolation until they get the next update). Here's where 'udp' becomes a viable option, because you are spamming the entire gamestate every ~1sec or so, dropping some fraction of those updates is irrelevant. For games that have relatively little game state (quake, world of warcraft) this is often the simplest solution.
设置多人游戏涉及几个因素
协议,决定是使用 TCP 还是 UDP 非常重要。 UDP 的开销较小,但不能保证交付。 相反TCP更值得信赖。 每个游戏都有自己喜欢的协议。 例如,UDP 适用于第一人称射击游戏,但可能不适合信息需要一致的 RTS。
防火墙/连接的 RTS。 确保您的多人游戏不必建立 2000 个出站连接并使用标准端口,以便轻松进行端口转发。 将其与 Windows 防火墙连接可能会带来额外的好处。
带宽。 这很重要,您打算通过网络连接推送多少数据? 我想这将归结为播放测试和记录吞吐量。 如果您需要每个客户端超过 200kb/s,您可能需要重新考虑一些事情。
服务器负载。 这也很重要,一个正常的游戏需要服务器进行多少处理? 您是否需要具有 16GB RAM 的超 8 核服务器来运行它? 有办法减少它吗?
我想还有更多,但您确实想要一款可以通过网络和各种连接舒适地玩的游戏。
There are a few factors involved in setting up multiplayer
The protocol, it's important that you decide whether you want TCP or UDP. UDP has less overhead but isn't guaranteed delivery. Conversely TCP is more trustworthy. Each game will have their preferred protocol. UDP for instance will work for a first person shooter but may not be suited for an RTS where information needs to be consistent
Firewall/Connection. Making sure your multiplayer game doesn't have to make 2000 outbound connections and uses a standard port so portforwarding is easy. Interfacing it with windows firewall will probably be an added bonus.
Bandwidth. This is important, how much data are you intending to push through a network connection? I guess this will come down to play testing and recording throughput. If you're requiring upwards of 200kb/s for each client you may want to rethink a few things.
Server Load. This is also important, how much processing is required by a server for a normal game? Do you need some super 8 core server with 16gb of RAM to run it? Are there ways of reducing it?
I guess there are heaps more, but really you want a game that is comfortable to play over the network and over a variety of connections.
避免作弊有多重要?
[您可以信任来自客户端的任何信息吗?或者它们可以被信任和验证吗?]
对象模型
对象如何从一台机器传送到另一台机器? 如何对对象执行操作?
你是在做客户端/服务器还是点对点?
随机数
如果您进行点对点,那么您需要保持它们同步并且随机数同步。
如果你正在做客户端/服务器,你如何处理延迟? [航位推算?]
网络编码涉及很多重要问题。
查看 RakNet,它可以免费下载代码,也可以查看它的讨论组。
How important is avoiding cheating ?
[Can you trust any information coming from a client or can they be trusted and authenticated ?]
Object model
How are objects communicated from one machine to another ? How are actions carried out on an object ?
Are you doing client/server or peer to peer ?
Random Numbers
If you do a peer to peer then you need to keep them lock-stepped and the random numbers synchronized.
If you are doing client/server how do you deal with lag ? [dead reckoning ?]
There are a lot of non-trivial problems involved in network coding.
Check out RakNet both it's free to download code and it's discussion groups.
计划是你最好的朋友。 弄清楚你的真正需求是什么。
加载数据:每台计算机都将具有相同的模型和图形,并且只是名称和位置通过网络移动。 如果每个玩家都可以自定义他们的角色或其他物品,那么您将必须移动这些数据。
作弊:你需要担心吗? 你能相信每个客户所说的话吗? 如果没有,那么您的服务器端逻辑将看起来与客户端逻辑不同。 想象一下这个简单的情况,您的 10 名玩家中的每一位都可能因为能力提升而具有不同的移动速度。 为了最大限度地减少作弊行为,您应该计算每个玩家在服务器的通信更新之间可以移动多远,否则玩家可能会加速黑客攻击,而没有什么可以阻止他们。 如果玩家持续比预期快一点或有一次跳跃,服务器只会将他们重新定位到可能的最近位置,因为这可能是时钟偏差或通信中的一次性中断。 然而,如果玩家不断地移动两倍的距离,那么将他们踢出游戏可能是明智的做法。 数学越多,您可以在服务器上仔细检查的游戏状态部分越多,游戏就越一致,顺便说一句,这将使作弊变得更加困难。
点对点是怎样的:即使游戏是点对点的,您也可能希望让一个玩家开始游戏并将其用作服务器,这比尝试管理一些基于云的游戏要容易得多接近。 如果没有服务器,那么您需要制定一个协议来解决游戏状态不一致的两台机器之间的争议。
再说一遍,计划是你最好的朋友计划、计划、计划。 如果你对一个问题思考得足够多,你就能想出解决大部分问题的方法。 然后你就可以开始思考那些你还没有解决的问题了。
Planning is your best friend. Figure out what your needs truly are.
Loading Data: Is every computer going to have the same models and graphics, and just names and locations are moved over the net. If every player can customize their character or other items, you will have to move this data around.
Cheating: do you have to worry about it? Can you trust what each client is saying. If not then you server side logic will look different than you client side logic. Imagine this simple case, each of your 10 players may have a different movement speed because of power ups. To minimize cheating you should to calculate how far each player can move between communication updates from the server, otherwise a player could hack there speed up and nothing would stop them. If a player is consistently a little faster than expected or has a one time jump, the server would just reposition them in the closest location that was possible, because it is likely clock skew or a one time interruption in communications. However if a player is constantly moving twice as far as possible then it may be prudent to kick them out of the game. The more math, the more parts of the game state you can double check on the server, the more consistent the game will be, incidentally this will make cheating harder.
How peer to peer is it: Even if the game is going to be peer to peer you will probably want to have one player start a game and use them as a server, this is much easier than trying to manage some of the more cloud based approaches. If there is no server then you need to work a protocol for solving disputes between 2 machines with inconsistent game states.
Again planning is your best friend Plan, Plan, Plan. If you think about a problem enough you can think your way through most of the problems. Then you can start thinking about the ones you haven't solved yet.