制作快节奏的多人网络游戏非常困难(译文)
By robot-v1.0
本文链接 https://www.kyfws.com/games/making-fast-paced-multiplayer-networked-games-is-h-zh/
版权声明 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
- 26 分钟阅读 - 12877 个词 阅读量 0制作快节奏的多人网络游戏非常困难(译文)
原文地址:https://www.codeproject.com/Articles/1023864/Making-Fast-Paced-Multiplayer-Networked-Games-is-H
原文作者:markmnl
译文由本站 robot-v1.0 翻译
前言
Overview of making fast-paced multiplayer networked games - the challenges and techniques to overcome them.
制作快节奏的多人网络游戏概述-挑战和克服这些挑战的技术.
[
介绍(Introduction)
很难将Internet上快节奏的多人网络游戏开发到仍能带来乐趣的标准.尽管如此,诸如<反恐精英>,<虚幻竞技场>和<雷神之锤>等快节奏的多人游戏已经定义了一代.此类别中的所有独立游戏在哪里?我不是在谈论诸如图形富足之类的AAA,它只是一种快节奏的游戏,我可以通过互联网与朋友们一起玩.我最喜欢的童年记忆是在局域网聚会上用火箭发射器轰炸我的朋友,那是1999年在10Mb/s的集线器上.现在,我们有了流行的宽带互联网.有一些独立游戏:Soldat是其中之一,我能想到的其他游戏都是基于现有引擎(例如Open Arena)构建的,但是有哪些独立的独立游戏呢?我怀疑没有那么多的一个原因是开发快节奏的多人网络游戏的难度.(Fast-paced multiplayer networked games over the Internet are difficult to develop to a standard where the experience is still fun. Nonetheless, fast-paced multiplayer games like Counter Strike, Unreal Tournament and Quake have defined a generation. Where are all the Indie games in this category? I am not talking about AAA like graphics bonanza, just a fast-paced game I can play with my friends over the Internet. Some of my favourite childhood memories are at LAN parties blasting my friends with a rocket launcher and that was 1999 on a 10Mb/s hub. Now we have prevalent broadband Internet. There are some Indie games: Soldat is one, others I can think of off the top of my head are built on existing engines such as Open Arena, but what standalone Indie titles are there? I suspect one reason there are not so many is the difficulty in developing a fast-paced multiplayer networked game.) 我是一名网络程序员(I am a network programmer on) 方形英雄(Square Heroes) –快速节奏的多人竞技场射击游戏.那我们怎么((– a fast paced multiplayer arena shooter. So how did we () Gnomic Studios(Gnomic Studios) )吗?在本文中,我将介绍事物的网络方面.对于Internet上快节奏的多人网络游戏的问题以及克服这些问题的一些技术,我尝试保持游戏逻辑水平.无需过多地了解位和字节,就可以使用UDP,IP,套接字,网络拓扑,NAT遍历…如果您也希望我在它们上面写博客,请打我-我非常乐意.() do it? In this post, I cover the networking side of things. I try to stay at the game logic level on the problems with fast-paced multiplayer networked games over the Internet and some techniques to overcome them. Without getting too much into the bits and bytes, working with UDP, IP, Sockets, network topologies, NAT traversal… If you would like me to blog on them too, hit me up – I would be more than happy to.) 只是在谈论"快节奏"时要澄清一下:抽搐射手就是典型的例子,属于我在这里谈论的类别(其他类型的游戏也有). RTS和在线RPG游戏,我会认为是"中速",而任何回合制都是"慢速".即使游戏可能很快出现,但重要的,需要联网的基本动作可能相对较少,并且相比而言并不是时间紧迫的.例如,<最终幻想>作为回合制游戏:虽然铁杆格斗的动画可能正在播放,但无需联网-仅启动该动作的命令:“玩家1用巨大的剑攻击敌人3” –之后,双方都知道事件的顺序并将其显示出来,即,它是确定性的. (我没有玩<最终幻想>,但这似乎是它的要旨).那么多人游戏如何做到呢?好吧,我在示例中给出的这种方法称为"锁定步骤".(Just to clarify when talking about “fast-paced”: twitch shooters are the typical example and would fall into the category I am talking about here (there are specific games in other genres too). RTS and online RPG games I would consider “medium-paced” and anything turn based “slow-paced”. Even though a game may appear fast, the underlying actions that matter and need to be networked may be relatively few and not time critical in comparison. For example, Final Fantasy as a turn based game: while a hardcore fighting animation might be playing out nothing needs to be networked – only the command that started the action: “player 1 attacks enemy 3 with gigantic sword” – thereafter, both peers know the sequence of events and play them out, i.e., it is deterministic. (I do not play Final Fantasy but that seems to be the gist of it). So how do multiplayer games do it? Well, this approach I just gave in the example is called “lock-step”.)
他们是如何做到的呢?(How Did They Do It?)
锁定步骤是指游戏"锁定"直到拥有所有必需的信息,然后再继续执行下一步.这种方法本质上适用于以回合制为基础的游戏,反正是以回合为核心的游戏方式,例如国际象棋-在对手完成游戏之前就不能回合!虽然可以在任何游戏中使用锁定步,但是射手(例如)可以在任何帧中更改输入,例如"消防火箭发射器"和/或"向左转".因此,如果与网络对等方进行游戏,则该游戏可以:(Lock-step is when the game “locks” until it has all the required information before continuing another step. This method is inherently suited to turn based games where that is the core gameplay anyway, another example of this is Chess – you cannot have your turn until your opponent has completed theirs! Lock-step can be used in any game though, a shooter (say) could change input in any frame, e.g., “fire rocket launcher” and/or “turn left”. So if playing against a network peer, the game could:)
- 获取本地玩家的输入并将其发送给远程对等方(Get local players input and send this to remote peer)
- 等待远程输入(即"锁定")(Wait for remote input (i.e. “lock”))
- 用大家的输入更新游戏并重复(Update the game with everyone’s input and repeat) 实际上,这是DOOM中使用的方法.怎么了约翰`卡马克(John Carmack)(In fact, this is the method used in DOOM. What is wrong with it? John Carmack in) <毁灭战士>经典版的开发(Development on Doom Classic) :(:) 引用:(Quote:)Doom PC确实是点对点的…它也停滞不前,直到其他所有玩家都收到了有效数据…这样的安排的好处是,这确实是公平的,没有客户比其他任何人都有任何优势,甚至如果一个或多个播放器通过质量较低的链接连接.每个人都有最差的共同点行为[原文如此].(Doom PC was truly peer to peer … It also stalled until valid data had arrived from every other player… The plus side of an arrangement like this is that it is truly fair, no client has any advantage over any other, even if one or more players are connected by a lower quality link. Everyone gets the worst common denominator behavior [sic].) 这完全取决于步骤2所需的时间以及它如何影响游戏玩法.在国际象棋中,如果需要250毫秒(即四分之一秒)的通知时间,则您的对手已经完成回合,没问题.在习惯于以每秒60帧(即每16.6毫秒)更新一次的射击游戏中,游戏将冻结该刻钟的四分之一秒,即15帧!这就是为什么DOOM多人游戏在LAN上可以正常运行,但您的ping越高,在Internet上变得无法忍受的原因.(It all depends on how long Step 2 takes and how that affects the gameplay. In Chess, if it takes 250 milliseconds (i.e., a quarter of a second) to be notified, your opponent has completed their turn, no problem. In a shooter which you are used to updating at 60 frames per second (i.e., every 16.6’ milliseconds), the game would freeze for that quarter of a second, i.e., 15 frames! This is why DOOM multiplayer is fine over LAN but becomes intolerable over the Internet the higher your ping gets.)
我们在做什么?(What Are We Working With?)
那么我们要面对的是,通过Internet进行网络连接需要多长时间?它需要多长时间取决于对等点之间的距离以及信号必须经过哪些信号,这些信号是可变的:网络设备,线路质量,拥塞等.当超过其带宽并开始积压时,任何链路上都会发生拥塞.数据-排队以便稍后传输,甚至在这些队列已满时也可以丢弃数据.无论如何,要点是:(So what are we up against, how long does it take to network stuff over the Internet? How long it takes depends on the distance between the peers and what the signals have to go through some of which is variable: networking devices, quality of line, congestion, etc. Congestion can happen on any link when its bandwidth is exceeded and starts backlogging data - queueing it for transmission later, data can even be dropped when these queues become full. Anyway, the points are:)
-
每个对等方花费的时间是可变的((It takes a variable amount of time to each peer ()潜伏(latency)),并在较小的程度上,每次(() and to a lesser degree, a variable amount time each time ()抖动(jitter)).().)
-
如果您发送/接收的信息超出了最弱的链接所能处理的范围(除了通过该链接的其他所有内容),数据将被延迟.因此,我们还有另一个限制:可用的(If you are sending/receiving more than the weakest link can deal with (in addition to everything else going through that link), data will be delayed. So we have another limit: our available)带宽(bandwidth).(.)
-
数据以离散单位传输:数据包可以通过不同的路径到达(Data is transmitted in discrete units: packets, which can go through different routes and arrive)乱序(out-of-order)他们被送进来,根本没有到达:(to that they were sent in, not arrive at all:)数据包丢失(packet loss),或多次到达:(, or arrive more than once:)复制(duplication)!数据包丢失可能会由于无数种原因而发生,除了过多地超出带宽之外,例如,使我的网络电缆受阻.并且可以尽快恢复正常工作,例如ISP跳线.(! Packet loss can occur for an infinite number of reasons in addition to exceeding bandwidth excessively, e.g., dog ate my network cable; and can just as quickly start working normally again, e.g., ISP patched network cable.) 好的,因此我们不能一直等待数据(即锁定步骤),因为这意味着冻结我们快节奏的游戏可能无法忍受.让我们在获取数据时不断更新和使用数据-当远程播放器告诉我们它们处于此位置时,请将其置于该位置!抱歉,该方法也不起作用:(OK, so we cannot wait for data all the time (i.e., lock-step) as that means freezing our fast-paced game for potentially intolerable periods. Let’s just keep updating and use the data when we get it - when remote player tells us they are at this position, put them at that position! Sorry, that is not going to work either:)
-
如果该信息在运输过程中被重新排序并且我们在旧信息之前收到新信息并在以后处理旧信息怎么办?(What if that information got re-ordered in transit and we receive newer information before the older and process the older later?)
-
如果信息在传输过程中丢失了怎么办?(What if the information got lost in transit?)
-
他们现在可能不在这个位置,他们在一段时间之前就在那个位置.如果您发射火箭发射器并在机器上的这个位置击中它们,那么火箭可能会飞过它们在机器上的位置!(They are probably not at the position now, they were at that position some time ago. If you fire your rocket launcher and hit them at this position on your machine, your rocket could go whizzing past them on their machine!) 我将快速讨论乱序,丢失和重复的数据包,以防它们影响游戏逻辑.网络层通常会抽象化发送和接收数据,因此重复项将被丢弃,您可以指定是否应按顺序,可靠地处理数据(即,如果丢失则再次发送直到接收到数据),或同时指定两者.可靠地发送信息会产生额外的流量,因为我们必须确认收到了流量以确保另一端收到了该流量,如果另一端没有收到该流量,则必须再次发送.如果我们按顺序可靠地发送了一些数据,并且丢失了一个数据包(不可避免地会通过Internet丢失),那么我们必须等到重新发送一个数据包并使其通过之前,才能处理后续的数据包.由于发件人只知道会在一段时间后重新发送,因此在快节奏的游戏中,这会大大延迟事情,最多可能延迟几秒钟. (这是使用UDP的主要原因,TCP/IP可靠且有序地发送所有内容,这只会延迟太多时间,因此在本文中,我仅谈论UDP,因为它确实是快节奏游戏的唯一选择通过互联网).因此,我们按顺序但不可靠地发送大多数游戏中数据-数据包按照发送的顺序进行处理,但是我们可能会丢失更多的数据包,因为如果后来的数据包已经完全乱序到达,则数据包将完全无法处理具有.仍然需要知道游戏中的关键事件(例如玩家死亡和死亡,当然还有游戏结束),因此必须可靠地发送(也无需指定顺序),因此即使必须重新发送可靠的消息,也不会延迟未来的数据包-发送). !(I will quickly cover out-of-order, lost and duplicate packets to the extent they are a concern to the game logic. A networking layer usually abstracts away sending and receiving data so duplicates are discarded and you can specify whether the data should be processed in-order, reliably (i.e., if lost send it again till it is received) or both. Sending things reliably generates extra traffic because we have to acknowledge receipt of traffic to be sure the other end got it, also should the other end not get it we have to send it again. If we send something in-order and reliably and one packet gets lost (as it inevitably will over the Internet), we have to wait until that one packet is re-sent and gets through before subsequent packets can be processed. Since the sender only knows to re-send after some time, this delays things considerably, up to seconds, too long in a fast-paced game. (This is the main reason UDP is used, TCP/IP sends everything reliably and in-order which simply delays things too much, so throughout this article, I am only talking about UDP as it really is the only option for fast-paced games over the Internet). So we send most in-game data in-order but not reliably – packets are processed in the order they were sent but we may get more packets lost as packets arriving out-of-order will not be processed at all if a later packet already has. Critical events in the game still need to be known (such as player kills and deaths and of course game over) so are sent reliably (without specifying in-order as well so future packets are not delayed even if the reliable one has to be re-sent). Phew!) 我们的约束是什么?(What are our constraints?) 根据Bungie为Halo 3 Beta 2007进行的研究(From a study conducted by Bungie for Halo 3 Beta 2007) :(:)
-
两个对等方之间的200ms单向延迟(即400 ping),抖动为10%(200ms one-way latency (i.e. 400 ping) between any two peers with 10% jitter)
-
带宽增加8 KB/s,速度降低8 KB/s(8 KB/s bandwidth up and 8 KB/s down)
-
丢包率高达5%(up to 5% packet loss) Xbox的99%具有这些值或更高.几天来,我们现在可能会增加几KB的带宽,但请记住,考虑到通过该链接的其他所有内容,它是最弱的链接–如果您是从另一个对等方下载,则其上游可能是最弱的链接,通常这是很多少于一个人的下载量.请记住,保持99%的快乐仍然会使每100个游戏玩家中不满意的人中有1个感到高兴,而且他们可能比快乐的玩家更能表达自己的经历!(99% of Xbox’s had these values or better. We could probably sneak in a few KB more bandwidth now days but remember, it is the weakest link taking into account everything else going through that link – if you are downloading from another peer, their upstream is probably the weakest link which is usually a lot less than one’s download. Remember keeping 99% happy is still leaving 1 in every 100 gamers unhappy and they are likely to be more vocal about their experience than the happy ones!)
第一次尝试(First Attempt)
好的,那么我们就按顺序发送所有状态吧!只需在8人游戏中发送单个玩家的一些属性,例如:位置,面向角,装备武器和发射标志,您就可能超出带宽限制!别开玩笑了,让我们加起来:(OK, so let’s just send all our state in-order then! Simply sending a few attributes of a single player in an 8 player game such as: position, angle facing, weapon equipped and a firing flag and you could exceed your bandwidth limits! No kidding, let’s add it up:)
属性(Attribute) | 数据类型(Data Type) | 字节数(Number of bytes) |
---|---|---|
Position | 3单打(3 Singles) | 12 |
Angle | Single | 4 |
装备武器(Weapon Equipped) | byte | 1 |
正在射击(Is Firing) | byte | 1 |
Overhead | bytes | 34 |
Total | 52个字节(52 bytes) |
等等,什么是"间接费用"?它是每个数据包(至少20个字节)中包含的IP标头信息,再加上UDP标头(8个字节),再加上网络层标头(具有诸如序号等信息,以便数据包可以按顺序传递,其中5个字节是保守的-例如XNA的网络层增加了大约23个字节).好的,现在我们有52个字节:(Wait, what is “Overhead”? It’s the IP header information included on every packet (at least 20 bytes) plus the UDP header (8 bytes) plus the networking layer header (with information such as sequence numbers so packets can delivered in-order, 5 bytes is conservative - for example XNA’s Networking layer adds about 23 bytes). OK so now we are at 52 bytes:) 52字节x每秒60次x 7个其他播放器=21840字节或大约(52 bytes x 60 times a second x 7 other players = 21840 bytes or approximately)21KB/秒!(21KB/s!) 那只是一个玩家!那需要联网的所有其他对象呢?(And that is only a single player! What about all the other objects that need to be networked?!) 为什么我们要乘以玩家人数?在Internet上,您必须单播发送,即分别发送给每个对等方.但是,如果我具有服务器-客户端拓扑,那我只需要发送到服务器,并且服务器将必要的信息中继到所有其他对等节点上怎么办?没错,但是"服务器"可以是其他参与者之一,因此有人必须将所有内容发送给所有人.或者它可以是专用服务器(请注意是否仍要向所有人发送专用服务器,因此服务器将需要上游带宽,而客户端需要下游);或者但是,这会带来一系列问题,例如延迟增加-现在,如果您与邻居打架,则必须经过专用服务器,如果附近没有服务器,那很好,但是如果您的互联网质量不佳连接是,游戏玩法会很落后.因此,Titan Fall多人游戏在全球范围内不可用-就我个人而言,我认为在世界的某个偏远角落长大后真糟-它使世界的某些部分失去了游戏的使用权.一种解决方案是允许任何人运行一台专用服务器,最好是您的ISP可以运行一台专用服务器,但是如果没有人可以运行呢?我离开了,网络拓扑本身可能是一个完整的话题,关键是我们无法在每个帧中发送状态来保持事物同步,此外,远程对等体获得状态时状态将已经过时.(Why did we multiply by the number of players? Over the Internet, you have to send unicast, i.e., to every peer individually. But what if I have a Server-Client topology then I need to only send to the server and the server relays the necessary info onto all other peers? True, however “the server” can be one of the other players so someone has to send all to everyone; or it could be a dedicated server (note dedicated server or not it is still going to be sending to everyone so the server is going to need the upstream bandwidth and the clients the downstream); however that comes with its own set of problems for instance increasing latency – now if you play against your neighbour, you have to go via a dedicated server which it would be great if it is close by but if not, no matter how good your Internet connection is, gameplay will be laggy. For this reason, Titan Fall multiplayer is not available worldwide – personally, I think that sucks having grown up in a remote corner of the world – it disenfranchises part of the world from your game. One solution is to allow anyone to run a dedicated server – preferably someone at your ISP does – but what if no one does? I digress, network topology can be a whole topic in itself, the point is we cannot send state every frame to keep things in sync, furthermore that state would be old by the time remote peers get it.) 此时,您会发现游戏网络程序员在他们的办公桌前作梦,梦想着他们在编写经典物理算法时能遇到更简单的时代.(At this point, you will find game network programmers cowering under their desk dreaming of simpler times when they were writing classical physics algorithms.) 大多数情况下都比我给出的参数要好,但有些情况则更糟,通常情况下,游戏应该是可玩的,而不会引起玩家注意到这些值的异常.您可以按自己的意愿摇动拳头,但是这样做无济于事.实际上,花一点时间来反思一下,如果我们能在四分之一秒内将信息发送到世界各地一半,那将是多么出色!阅读Shawn Hargreaves的精彩演讲:网络交通拥堵和Schrodingers Cat,我从中学到了很多.尽早开始思考如何尽可能减少发送邮件,不要指望事情会变得更好.延迟将保持不变,光速并没有提高,并且在物理上似乎不可能比这更快!也许随着带宽的增加,我们可以发送更多的信息来进行更多的预测.(Most cases are better than the parameters I gave but some are worse, generally a game should be playable without players noticing and being annoyed by anomalies at these values. You can shake your fist at these all you like, I did, but it is not going to help. In fact, take a moment to reflect how remarkable it is if we can send information half way around the world in a quarter of second! Have a read of Shawn Hargreaves excellent presentation: Networking Traffic Jams and Schrodingers Cat, from which I learnt an enormous amount. Start early thinking how you get away with sending as little as possible and don’t count on things getting better. Latency is here to stay, the speed of light is not getting any faster and it does not appear to be physically possible to communicate faster than that! Perhaps with more bandwidth, we can send more to predict more.)
预测(Prediction)
举一个简单的例子:如果我们知道一个玩家处于位置:p,在几秒钟前以t的速度v移动-他们现在假设的速度恒定?简单:(By way of a simple example: if we know a player was at position: p, moving with a velocity v, t seconds ago - where are they now assuming constant velocity? Easy:)
p2 = p + vt
他们在t秒后的位置是p2,我们可以预测给定的p,v和t. (当然,您的对象可能比常数v的直线走更复杂的路径,但是考虑到所有可以解决的变量,想法都是一样的).因此,远程播放器仅需要告诉我们其速度何时变化以及其速度在什么位置变化.由于玩家动作的变化依赖于缓慢的人类的输入-发生频率远低于每秒60次-通常每秒仅发生几次.太好了,因此我们可以大幅减少带宽以解决远程播放器的位置.但是,现在出现了一些新问题-我们根据他们的旧状态推断出他们的新位置,并了解他们的移动方式,但是随着时间的推移,玩家会怎样:(Their position after t seconds is p2 which we can predict given p, v, and t. (Of course, your objects likely take a more complex path than the straight line of constant v, but the idea is the same given all the variables you can solve it). So a remote player only needs to tell us when their velocity changes and from what position they were at when it changed. Since a change in player’s movement relies on input from a slow human - that is going to happen far less frequently than 60 times a second – typically only a few times a second. Great, so we can cut down on our bandwidth considerably to solve the remote player’s position. However, there are some new problems now – we extrapolated their new position based on their old state with knowledge of how they move but what if over time t the player:)
- 与墙壁,射弹或大猩猩等物体相撞(嘿,我不知道您在玩什么游戏)(Collided with something, e.g., a wall, a projectile or a gorilla (hey I don’t know what game you are making))
- 方向改变(Changed direction)
要检测在此期间可能发生的碰撞,您必须通过从其旧位置进行插补来解决,实际上,这取决于您游戏中物理的工作方式,而不是推断其新位置,您只需设置新信息即可在播放器上,然后假装时间t过去了,因此物理效果得以播放,就像它在t秒钟前拥有新信息一样.将预测与物理相结合可能是所有挑战中最具挑战性的部分之一,不要惧怕开箱即用,不同的解决方案适用于不同的游戏以及这些游戏中的不同对象.(To detect for collisions that could happen over the period, you will have to work it out by interpolating from their old position, in fact depending on how the physics in your game works rather than extrapolating their new position, you could simply set the new information on the player, then pretend time t has elapsed so the physics plays out as it would have had it have the new information t seconds ago. Integrating prediction with your physics can be one of the most challenging parts of all this, don’t be afraid to think out of the box, different solutions work for different games and different objects within those games.) 如果玩家在更新后不久改变了方向,我们也应该尽快获取该更新,但与此同时,我们会让玩家朝相反的方向移动.这扩大了更新延迟的问题:当我们收到新信息并计算他们的新位置时,远程玩家会突然跳动或"弹出"到他们的新位置,因为我们让他们在另一个方向上行驶的时间比实际时间长.除了锁定步骤之外,还没有100%完美的解决方案–远程控制的行进物体会在存在延迟的情况下超调,并且延迟和速度变化越大,其超调量就越大.第一步是尽我们最大的努力减少问题:重要的对象(如玩家)应尽快发送其状态更改(远程对等方应知道该做出正确的预测).除此之外,我们需要解决玩家的"爆裂"问题-它破坏了游戏的虚拟现实.(If the player changed direction soon after the update, we should get that update soon too but in the meantime, we have the player moving in potentially the opposite direction. This amplifies a problem with the delayed updates: when we receive the new information and calculate their new position, remote players will appear to jerk or “pop” to their new position because we had them travelling in another direction for longer than they actually were. There is no 100% perfect solution to this beyond a lock-step approach – remotely controlled travelling objects will overshoot where there is latency and the greater the latency and change in velocity, the greater the amount they will overshoot by. The first step is to reduce the issue as much as we can: important objects such as players should send their changes in state (that remote peers should know about to make correct predictions) ASAP. Beyond that, we need to resolve the players “popping” issue – it ruins the virtual reality of the game.)
平滑处理(Smoothing)
当我们收到更新通知我们某个对象在此处时,我们会预测它现在在哪里.如果距当前位置的距离比对象通常在一帧中移动的距离远,则该对象似乎"弹出"到新位置.什么时候可以通过"平滑"来减少这种影响–跟踪对象最有可能出现的位置,并在一段时间内(比正常速度快,因此可以赶上)将视觉对象移到对象上,而不是一次全部.将物理比视觉更快地移动到最可能的位置也可能是一个主意,因此命中框等更加同步-但这是以物理与本地机器上的视觉不同步为代价的.这听起来可能像烟雾和镜子一样,因为那正是它的本质–我们只是在幻想游戏在挂钟时间内正在玩,即使更新来自过去.(When we receive an update telling us an object was here, we predict where it is now. If this is further away from the current position than the object normally moves in one frame, the object will appear to “pop” to the new position. When can reduce this effect by “smoothing” – track a position of where the object most likely is and move the visual to it over a period of time (at faster than the normal rate so it can catch up) rather than all at once. It may also be an idea to move the physics quicker than the visual to the most likely position so hit boxes and such are more in sync – but that would be at the cost of having the physics out of sync with the visual on the local machine. This may all sound like smoke and mirrors because that is exactly what it is – we are just maintaining the illusion the game is playing out in wall clock time even though updates are arriving from the past.) 有时更新到达得太晚和/或对象移动太快,以至于具有更准确的状态比具有正常外观但不同步的状态更受青睐.因此我们放弃了,让对象"弹出"到当前位置.这在带有远程对等方的FPS中经常可见,当玩家从一个位置"弹出"到另一个位置时,您有很高的延迟(可能通过服务器). (请注意,这并不意味着较高的延迟就意味着更高的准确性!落后的对等方的下一次更新也将为时已晚,因此它们的位置将再次消失,从而导致它们再次"弹出".平滑是优先于不平滑即使在较低的延迟下,它也会导致远程播放器比临时播放器更加不同步,因为它不仅看起来更好,而且与不稳定的人相比,它可以更好地判断正常的移动物体)(Sometimes updates arrive too late and/or objects are moving too fast that having a more accurate state is preferential to having a normal looking but out of sync state. So we give-up and let the object’s “pop” to the current position. This is often visible in FPSs with remote peers to which you have a high latency to (possibly via a server) as players “pop” from one position to another. (Note this doesn’t mean the higher latency the higher the accuracy! The next update from a lagging peer will also be too late so their position would have got way out again causing them to “pop” again. Smoothing is preferential to not smoothing at lower latencies even though it results in remote player being more out-of-synch than need be temporarily because not only does it look better, but humans can better judge the normal moving thing than an erratic one))
现在几点了?(What Is the Time?)
我们如何知道在预测计算中使用的时间(即自发送更新并收到更新以来经过的时间)?我们可以测量已知的请求即时响应(网络层可能会为您执行此操作)的数据包的往返时间(RTT),并将其除以2(我们仅对单向延迟感兴趣).不幸的是,RTT不是恒定的,与平均RTT的差异称为抖动.因此,我们只能基于以前的RTT来估计数据包到达接收所花的时间.可以尝试使用更复杂的技术来推断此时间段,例如可以在数据包中包括时间戳,但是只有在时钟同步到几毫秒以内的情况下,时间戳才有用-这肯定不是系统时间!时间只是一个估计而得不到及时更新,这激怒了一个问题,那就是:事情不会总是在所有同伴上发挥出来.如果我用狙击步枪在机器上击中了敌方的远程同伴,但他们刚从机器上移开怎么办?(How do we know t used in the prediction calculations (i.e., the time elapsed since an update was sent and we receive it)? We can measure Round Trip Times (RTT) on packets which we know solicit an immediate response (the networking layer may do this for you) and divide that by 2 (we are only interested in the one-way latency). Unfortunately, RTT is not constant, this difference from the average RTT is called jitter. So we can only estimate how long a packet took to arrive on receipt based on previous RTTs. More elaborate techniques to try deduce this period such as including timestamps in the packet can be used however timestamps are only useful if you have synchronized clocks to within a few milliseconds – which system time is certainly not! A problem exasperated by time only being an estimate and receiving delayed updates is: things will not always play out the same on all peers. What if I hit the enemy remote peer with my sniper rifle on my machine but they had just moved out the way on their machine?)
谁是权威?(Who is da Authority?)
最终,我们不能同时做到这两种方式–在挂钟时间玩游戏,同时接收过去的更新,并使所有同伴完全同步.我们也不能离开每个对等方来确定自己的事件版本–如果我们让一个对等方认为某个玩家在另一人死亡时还活着,那么我们是否会显示他们的尸体在射击时飞来飞去,因为该玩家仍然活在控制之下同行?谁赢得比赛?我们可以解决一个对等端实际发生的情况,并说该对等端发生的事情是其他所有人都必须使用的版本.在服务器-客户端拓扑中,将此权限设置为服务器是有意义的,因为它已经与每个对等方直接接触(逻辑上位于网络中心).拥有服务器权限还可以帮助防止作弊者修改游戏,以使其获得不公平的优势,因为他们无法修改服务器.(Ultimately we cannot have it both ways – play our game at wall clock time while receiving updates from the past and have all peers be perfectly in sync. Nor can we leave each peer to determine its own version of events – if we let one peer think a player was still alive while they are dead on another, do we show their dead body flying around shooting because the player is still alive on the controlling peer? Who wins the match? We can resolve what actually happened on one peer and say what happened on that peer is the version everyone else must go with. In Server-Client topologies, it makes sense for this authority to be the server since it is in direct contact with each peer already (logically in the centre of network). Also having a server authority can help prevent cheats who have modified their game to give themselves an unfair advantage because they cannot modify the server.) 无论如何,在任何拓扑中,它都可以是任何对等方,此外,不同的对等方可以成为不同事物上的权威.如果不是授权者的同行弄错了怎么办?该同伴必须从他们的"错误"中恢复过来.一种方法是简单地等待授权机构提供事件的"真实"版本,这样我们就不会出错.但是,对于快节奏的游戏,这可能意味着延迟玩家期望立即发生的事情.例如,在您的游戏玩法中预料到这些"错误":如果我在计算机上推动"矮胖子",但从当局的角度来看,“矮胖子"在我推他之前就马上移开了,我们该怎么办?我们如何从尚未发生的矮矮胖胖的秋天中恢复过来-每个人都知道您不能再将矮矮胖胖的屁股重新绑在一起!我们预计我们会得到"错误"的信息,因此我们会通过延迟构建来给自己一些余地,直到我们知道"真实"版本为止-当您在他跌倒之前推动他(提供即时反馈)时,矮胖可能会摆动半秒,您有足够的时间了解Humpty Dumpty管理局是否也对他进行了注册-否则(由于您的预测,这种情况将很少见),您可以比摇摇欲坠的Humpty Dumpty更容易恢复!(Anyway in any topology, it could be any peer, furthermore different peers could be the authority on different things. What do we do when a peer who is not the authority got it wrong? That peer has to recover from their “mistake”. One way is to simply wait for the authority to give us the “true” version of events so we cannot make mistakes. However for fast-paced games, that could mean delaying things players expect to happen immediately. Anticipate these “mistakes” in your gameplay, for example: if I push Humpty Dumpy on my machine, but from the authority’s view point, Humpty Dumpty moved aside immediately before I pushed him – what do we do then? How do we recover from Humpty Dumpty’s fall that didn’t happen – everyone knows you cannot stick Humpty Dumpty back together again! We anticipate we could get it “wrong” so we give ourselves some leeway by building in some delay till we know the “true” version – Humpty could wobble for half a second when you push him (providing immediate feedback) before he falls, giving you enough time to learn whether the Humpty Dumpty Authority also registered him has being pushed – if not (which will hopefully be rare because of your prediction) you can recover from a wobbling Humpty Dumpty easier than a broken one!)
老派技巧(Old School Tricks)
预测有助于使我们的数据速率大大降低,因此我们不必不断发送状态,但是经常需要将很多东西联网,这些东西加起来仍然会导致我们超出可用带宽.不幸的是,我们不能像说HTML文档那样仅对数据包进行gzip压缩-多达几百个字节的二进制数据将压缩得很少,并且只会消耗CPU.请注意,我在上面的示例中所说的"正在触发"标志占用了一个字节–不需要(大多数编程语言只是存储布尔数据类型),我们可以使用按位运算将8个布尔标志压缩为一个字节.我们真的需要知道其他球员不开火时面对的精确角度吗?我们可以使用半精度浮点数而不是单精度数(2个字节而不是4个字节).我们通常将数字存储为4个字节的整数,但它们将始终为正,并且不会超过255(可以容纳1个字节)或65535(可以容纳2个字节).值的压缩将使您有所收获,但是在进行这些优化之前,请考虑:(Prediction helps keep our data rate down considerably so we don’t have to constantly send state but there are often lots things that need to be networked which when added up can still cause us to exceed our available bandwidth. Unfortunately, we cannot just gzip our packets like we could say a HTML document – up to a few hundred bytes of binary data will compress very little and will just cost CPU. Notice how I said the “is firing” flag in the above example took one byte – it doesn’t need to (most programming languages just store Boolean data types as such) we could squeeze 8 Boolean flags into a byte using bitwise operations. Do we really need to know the precise angle other players are facing in when they are not firing? We could use half precision floats instead of single precision (2 bytes instead of 4). We often store numbers as 4 byte integers but will they always be positive and never exceed 255 (could fit in 1 byte) or 65535 (could fit in 2 bytes). This compacting of values will get you someway but before you do these optimisations consider:)
- 延迟非时间关键的更新,以便它们可以与其他内容同时发送,因此可以将其附加到同一数据包中,并减少数据包的数量,从而节省每个数据包的开销.(Delaying non-time critical updates so they can be sent the same time as other stuff so it can be appended to the same packet and reduce the number packets which saves on overhead each packet has.)
- 仅在重要时才发送网络更新-如果另一个玩家轮流旋转但仍在同一地点,每个人都需要知道吗?也许只有当他们旋转1/16时(Only sending network updates when they matter – if another player rotates a small amount but is still in the same place, does everyone need to know this? Perhaps only when they rotate 1/16)日(th)需要我们让别人知道.(of circle need we let others know.)
- 是否完全需要发送?也许这是您可以问自己的最重要的问题-如果树上的叶子不同步,远程玩家将不会在意.更好的是,经过足够的思考,可以使许多事情具有确定性,因此无需联网.例如,甚至看似随机的事件(例如,该板条箱包含多少电量)也可以基于预定的伪随机种子.(Does it need to be sent at all? Perhaps this is the most important question you can ask yourself – remote players won’t care so much if the leaves on the tree are out of synch. Better yet given enough thought many things can be made deterministic so do not need to be networked. For instance, even seemingly random events such as what power up does this crate contain can be based on a pre-determined pseudo random seed.)
包起来(Wrapping Up)
互联网上快节奏的多人游戏很难,但有可能.首先要了解您的约束条件,然后在这些约束条件中建立.我希望我能阐明这些约束是什么以及可以在其中建立的一些技术.毫无疑问,还有其他方法和尚待使用的方法.每个游戏都是不同的,并有其自己的优先级.从以前所做的事情中吸取教训可能会大有帮助.希望,我们将看到更多独立游戏站在巨人的肩膀上,他们探索极限并在不断完善的互联网上创造新的多人游戏体验.(Fast-paced multiplayer games over the Internet are hard, but possible. First understanding your constraints then building within them is essential. I hope I have shed some light on what those constraints are and some of the techniques you can use to build within them. No doubt there are other ways out there and ways yet to be used. Each game is different and has its own set of priorities. Learning from what has been done before could help a great deal. Hopefully, we will see more Indie games standing on the shoulders of the giants that have come before them to explore the limits and create new multiplayer gaming experiences possible on the ever improving Internet.)
有用的链接(Useful Links)
(我从这些链接中学到的很多东西,在它们渗入我的大脑大约一年后,我以某种形式或间接地对它们进行了反流).((A lot of what I learnt is from these links and I have regurgitated them in some form or another in-directly after they have been percolating in my brain for a year or so).)
- 哈格里夫斯,肖恩.日期?使用XNA框架制作网络游戏:(Hargreaves, Shawn. Date? Making Networked Games with the XNA Framework:) http://www.shawnhargreaves.com/MakingNetworkedGames.pdf(http://www.shawnhargreaves.com/MakingNetworkedGames.pdf)
- 哈格里夫斯,肖恩.日期?博客索引中的网络类别(Hargreaves, Shawn. Dates? Networking category in index of blogs) http://www.shawnhargreaves.com/blogindex.html#networking(http://www.shawnhargreaves.com/blogindex.html#networking)
- 菲德勒,格伦.日期?游戏网络(各种深入编程的游戏网络文章):(Fiedler, Glenn. Date? Game Networking (various in-depth programming game networking articles):) http://gafferongames.com/networking-for-game-programmers/(http://gafferongames.com/networking-for-game-programmers/)
- 大卫`奥尔德里奇. 2011.我首先向您射击:网络游戏<光晕>的网络连接:覆盖面:(Aldridge, David. 2011. I Shot You First: Networking the Gameplay of Halo: Reach:) http://www.gdcvault.com/play/1014345/I-Shot-You-First-Networking(http://www.gdcvault.com/play/1014345/I-Shot-You-First-Networking)
- 法比恩`桑格拉德. 2012年.Quake3源代码审查:网络模型(第3部分,共5部分):(Sanglard, Fabien. 2012. Quake 3 Source Code Review: Network Model (Part 3 of 5):) http://fabiensanglard.net/quake3/network.php(http://fabiensanglard.net/quake3/network.php)
- Valve Corp.正在进行吗?来源多人网络(许多链接在此页面中挂掉):(Valve Corp. Ongoing? Source Multiplayer Networking (many links hang off this page):) https://developer.valvesoftware.com/wiki/Source_Multiplayer_Networking(https://developer.valvesoftware.com/wiki/Source_Multiplayer_Networking)
历史(History)
- 1个(1)圣(st)2015年9月-从我的原始作品添加到Code Project(September, 2015 - Added to Code Project from my original) 加马苏特拉(Gamasutra) 稍加修改即可发布2(post with small amendments to bring 2)nd(nd)该款最新游戏现已发布(paragraph up-to-date now game has been released)
许可
本文以及所有相关的源代码和文件均已获得The Code Project Open License (CPOL)的许可。
C#5 Dev Architect 新闻 翻译