50

如何在网络游戏的典型客户端/服务器设置中模拟两个客户端控制的车辆(明智地)碰撞?我确实阅读了这篇关于如何进行分布式网络物理的杰出博客文章(没有传统的客户端预测),但这个问题专门关于如何处理拥有对象的冲突。

例子

假设客户端 A 比服务器提前 20 毫秒,客户端 B 比服务器提前 300 毫秒(计算延迟和最大抖动)。这意味着当两辆车发生碰撞时,两个客户端都会将另一辆车视为落后 320 毫秒 - 与另一辆车的速度方向相反。在瑞典高速公路上正面交锋意味着相差 16 米/17.5 码!

什么不能尝试

几乎不可能推断位置,因为我也有非常复杂的车辆,到处都是关节和车身,它们又具有线性和角位置、速度和加速度,更不用说来自用户输入的状态了。

4

8 回答 8

12

I don't know of a perfect solution, and I have a feeling that one does not exist. Even if you could accurately predict the future position of the vehicle, you would be unable to predict the way the user will operate the controls. So the problem comes down to minimizing the negative effects of client/server lag. With that in mind, I would approach this from the position of the principle of least astonishment (paraphrased from Wikipedia):

In user interface design, the principle of least astonishment (or surprise) states that, when two elements of an interface conflict, or are ambiguous, the behaviour should be that which will least surprise the human user at the time the conflict arises.

In your example, each user sees two vehicles. Their own, and that of another player. The user expects their own vehicle to behave exactly the way they control it, so we are unable to play with that aspect of the simulation. However, the user can not know exactly how the other user is controlling their vehicle, and I would use this ambiguity to hide the lag from the user.

Here is the basic idea:

  1. The server has to make the decision about an impending collision. The collision detection algorithm doesn't have to be 100% perfect, it just has to be close enough to avoid obvious inconsistencies.
  2. Once the server has determined that two vehicles will collide, it sends each of the two users a message indicating that a collision is imminent.
  3. On client A, the position of vehicle B is adjusted (realistically) to guarantee that the collision occurs.
  4. On client B, the position of vehicle A is adjusted (realistically) to guarantee that the collision occurs.
  5. During the aftermath of the collision, the position of each vehicle can be adjusted, as necessary, so that the end result is in keeping with the rest of the game. This part is exactly what MedicineMan proposed in his answer.

In this way, each user is still in complete control of their own vehicle. When the collision occurs, it will not be unexpected. Each user will see the other vehicle move towards them, and they will still have the feeling of a real-time simulation. The nice thing is that this method reacts well in low-lag conditions. If both clients have low-latency connections to the server, the amount of adjustment will be small. The end result will, of course, get worse as the lag increases, but that is unavoidable. If someone is playing a fast-paced action game over a connection with several seconds worth of lag, they simply aren't going to get the full exeperience.

于 2009-05-07T19:10:00.813 回答
6

也许你能做的最好的事情不是实时显示实际的碰撞,而是给人一种事情正在实时发生的错觉。

由于客户端落后于服务器(滞后),并且服务器需要显示碰撞的结果,也许你可以做的,客户端,显示一个闪光或爆炸或其他一些图形来分散用户的注意力并购买足够的东西服务器端计算碰撞结果的时间。当您完成预测后,将其发送回客户端进行演示。

于 2009-05-07T16:35:30.917 回答
2

很抱歉回答“不要尝试什么”,但我从未听说过不涉及预测客户端结果的解决方案。考虑一个简化的例子:

客户 A 静止不动,看着客户 B 的车辆接近悬崖。客户 B 的车辆能够立即将速度降低到 0,并且在越过悬崖之前的最后一刻这样做。

If Client A is attempting to show Client B's state in real time, Client A has no choice but to predict that Client B fell off the cliff. You see this a lot in MMORPGs designed such that a player's character is capable of stopping immediately when running full-speed. Otherwise, Client A could just show Client B's state as the state updates come in, but this isn't viable, as Client A needs to be able to interact with Client B in real time in your scenario (I assume).

Could you try simplifying the collision models so that extrapolation is possible for real time prediction? Maybe make your "joints and bodies all over" have processor-less-intensive physical models, like a few cubes or spheres. I'm not too familiar with how to improve the efficiency of collision detection, but I assume it's done by detecting collisions of models that are less complex than the visual models.

于 2009-05-07T17:26:55.257 回答
2

Regarding "What not to try". You are assuming that you need to predict perfectly, but you are never going to find a perfect solution in a game with complex physics. An approximation is probably the best you can do (for example, most commercial physics engines can cast a shape into the physics scene and return the first point of collision).

For example, I implemented some critical parts of the network physics for Mercenaries 2 under the guidance of Glenn (the blog poster you mentioned). It was impossible to push all of the necessary physics state across the wire for even a single rigid body. Havok physics gradually generates contact points each frame, so the current "contact manifold" is a necessary part of the physics state to keep the simulation deterministic. It's also way too much data. Instead, we sent over the desired transform and velocities and used forces and torques to gently push bodies into place. Errors are inevitable, so you need a good error correction scheme.

于 2010-02-14T05:08:27.127 回答
1

What I eventually ended up doing was simply skipping prediction alltogether and simply doing this:

  1. Client has very much say about its own position,
  2. Server (almost) only says anything about the owning client's position when a "high energy" collision has happened with another dynamic object (i.e. not static environment).
  3. Client takes meshoffset=meshpos-physpos when receiving a positional update from the server and then sets meshpos=physpos+meshoffset each frame and gradually decreases meshoffset.

It looks quite good most of the time (in low latency situation), I don't even have to slerp my quaternions to get smooth transitions.

Skipping prediction probably gives high-latency clients an awful experiance, but I don't have time to dwell on this if I'm ever going to ship this indie game. Once in a while it's nice to create a half-ass solution that works good enough but best. ;)

Edit: I eventually ended up adding the "ownership" feature that Glen Fiedler (the blogger mentioned in the question) implemented for Mercenaries 2: each client gets ownership of (dynamic) objects that they collide with for a while. This was necessary since the penetration otherwise becomes deep in high latency and high speed situations. That soluation works just as great as you'd think when you see the GDC video presentation, can definitely recommend it!

于 2010-05-21T07:43:14.570 回答
1

Few thoughts.

  1. Peer to peer is better at dealing with latency & high speeds.

So if this is your own engine then switch to peer to peer. You then extrapolate the other peer's vehicle based on their button input to move forward to where it is now. You the set collision such that you collide against the other vehicle as if it's world. I.e. you take the hit.

This means as you collide against the other, you bounce off, on the peer's network they bounce off you, so it looks roughly correct. The lower the latency the better it works.

  1. If you want to go client / server then this will be inferior to p2p

Things to attempt o) Extrapolate clients forward as in p2p to perform collision detection. o) Send collision results back to clients and extrapolate forward

Note, this is NEVER going to be as good as p2p. Fundamentally high speed & latency = error so removing latency is the best strategy. P2P does that.

于 2015-07-19T21:14:19.740 回答
0

In addition to predicting on the client side where the other user might be and sending the collision information and how you handled it to the server, what most mmo's do to deal with lag is they have the server run "in the past" as it were. Basically they buffer the recent inputs but only react to what happened .1sec in the past. This lets you "peek into the future" when you need to (ie when a collision is about to happen in your time frame, you can look at the buffered input to see what will happen and decide if the collision is real).

Of course, this adds an extra layer of complexity to your program as you have to consider what data to send to your clients and how they should react to it. For example you could send the entire "future" buffer to the clients and let them see which possible collisions will actually happen and which won't.

于 2009-07-09T10:18:32.937 回答
-1

Ross has a good point. You could simplify the model you use to detect collisions by abstracting it to some simpler volume (i.e. the rough boxy outline of the vehicle). Then you can do the predictions based on the simple volume and the detailed calculations on the exact volumes while you have the user distracted by the "explosion". It may not be perfect but would allow you to speed up your collision detection.

于 2009-05-07T21:25:09.147 回答