* 원문링크 :
http://www.gamedev.net/reference/articles/article1370.asp
http://www.gamedev.net/reference/articles/article1370.asp
- 이 글에서는 클라이언트에서의 틱값을 얻어 처리하는 것으로 마무리하고 있는데, 스피드핵을 위한 부가적인 처리에 대해서는 말하고 있지 않습니다.
Targeting은 데드 레커닝(dead reckoning)의 변형입니다. (이것은 보간되지 않은 동적인 위치에 대한 지속적인 보간처리를 통하여 로컬 플레이어의 게임 인스턴스에서 원격 플레이어 움직임을 파악하기위한 방법입니다)
In English, this means that another player on your screen will constantly move closer and closer to where that player really claims to be at all times. We don't keep any historic information about where the player has been; nonetheless, the remote player and any projectile he launches can appear to travel in a smooth, unbroken path.
Before we go any further, let's put a picture on the blackboard so you understand why we're doing this. 여기에는 클라이언트/서버 기반의 네트워크 게임상에는 3가지 개체가 있습니다 : 여러분, 서버, 그리고 다른 플레이어(들).

그림 1: 네트워크 게임에서의 현실; 모든 사람이 겪는 상황
이 예제에서는, 여러분은 여러분의 우주선을 상하좌우로 움직이고 있습니다. 그림을 좀 자세히 보면 서버는 여러분보다는 조금 뒤쳐져 표시되고 있고, 다른 플레이어 또한 서버보다 뒤쳐져 표시된다는 것을 알수 있습니다. 그렇게 보이지 않는다면 웹페이지를 다시 갱신하거나 브라우져를 업그레이드하세요.
이것이 네트워크 게임들의 현재 상황입니다. 랙 현상은 여러분의 컴퓨터에서 다른 모든 사람들에게 게임 데이타를 전달하는데 걸리는 시간인 전송지연시간으로 인해 발생합니다. 서버는 여러분이 실제 움직인 이후 짧은 시간간격을 두고 계속해서 움직이는 것을 모를 수도 있습니다. I tend to think of the game as existing in three different "time zones."
이것이 네트워크 게임들의 현재 상황입니다. 랙 현상은 여러분의 컴퓨터에서 다른 모든 사람들에게 게임 데이타를 전달하는데 걸리는 시간인 전송지연시간으로 인해 발생합니다. 서버는 여러분이 실제 움직인 이후 짧은 시간간격을 두고 계속해서 움직이는 것을 모를 수도 있습니다. I tend to think of the game as existing in three different "time zones."
Big deal you say? 자, 그렇지않다면 여러분은 외계인에게 레이져를 쏠 때가 된 것입니다!

그림 2: 지연(랙)현상은 각각의 플레이어들이 서로 다른 방향으로 게임을 진행하게되는 현상을 일으킵니다.
여러분의 게임 인스턴스에 따르면, 여러분은 외계인이 앞에 있을때 정확히 맞추었습니다. 하지만 서버가 수천마일 멀리 있어서, 이후 몇 밀리초에 이를때까지 여러분이 쏘았다는 사실을 모를 수 있습니다. 몇몇 경우에는 몇 백 밀리초에 이를수도 있습니다! 이렇게 되면, 다른 컴퓨터에서의 외계인은 여러분의 우주선을 그냥 지나쳐가게 될 것입니다! 위 그림을 보고 어떤 상황이 되는지를 보시기 바랍니다.
좋습니다. 이제 서버에게 레이져가 있어야만 하는 위치를 알려줌으로서 여러분의 레이져를 외계인 바로 앞에 강제로 나타나도록 합시다. 이것으로 된 것 같지만, 일단 게임을 보도록 하죠.

그림 3: 전반적으로 지연현상을 보정하는 것은 게임의 품질을 떨어뜨립니다.
서버에서의 플레이어는 다음과 같은 생각을 하게 될 것입니다. "어? 저 레이져가 어디서 나타난거지?". 그리고는 여러분의 게임을 집어던지고는 하프라이프 카운터스트라이크를 하러 가겠죠.
자, 이제 Targeting에 관한 접근법으로 이 문제점을 다뤄보도록 하죠. A target is a structure of information that describes the state, and change of state, of an object that exists in a remote person's instance of a game. 여러분이 레이져를 발사할 때, 여러분은 서버로 (A)를 알려주는 내용의 데이타 패킷을 전송합니다. 여러분은 레이져 (B)를 쏩니다. It was shot at some position in space (ox,oy) and (C). 그런다음 그것은 수직으로 날아갑니다. 다음은 이 과정을 그림으로 설명한 것입니다.

그림 4: 목표(푸른색물체)는 위치(position), 속도(velocity)라는 두가지 요소를 가지고 있습니다.
In this case, the Target is at (x,y) and the Target is moving straight up because the laser is moving straight up. The Target is determined by steps (B) and (C), and one additional factor: The measure of latency, in milliseconds, between you and the server (I will discuss how to calculate that in a moment). However, to keep the game real, the laser has to come from your ship at the position we will call (ox,oy). We want the laser to converge from (ox,oy) to (x,y) every "frame" (that is, once every time your game runs a complete cycle). Because the target is moving up, both (ox,oy) and (x,y) will change at every frame. 다음은 이에 대한 의사코드입니다.
for each frame {
target.x_velocity = target.x_velocity + target.x_acceleration;
target.y_velocity = target.y_velocity + target.y_acceleration;
target.z_velocity = target.z_velocity + target.z_acceleration;
target.x_position = target.x_position + target.x_velocity;
target.y_position = target.y_position + target.y_velocity;
target.z_position = target.z_position + target.z_velocity;
laser.x = (laser.x + target.x_position) / 2;
laser.y = (laser.y + target.y_position) / 2;
laser.z = (laser.z + target.z_position) / 2;
}
그리고 이렇게 처리하면 다음과 같이 보이게 됩니다.

The animation is particularly slow because I want you to study this very closely and carefully. Notice in the frame after you fired your laser, the target appeared for the server in the place that the laser is on your screen...yet, the laser on the server itself appeared at (ox,oy), which is the same placed it appeared for you when you shot it. In the following frame, the target is in approximately the same place on all three machines. Remember, we account for the position, velocity, and latency between you and another machine to figure out where the target should be on that other machine. Because of targeting, the laser on the server moves faster toward the alien than it does on player 1, and faster still on other client machines. The animation that shows targeting at work isn't the best example to explain targeting, but it certainly does a better job keeping the game reasonable than the two animations before it.
Now, you might think that interpolating by half in that pseudocode I gave you makes the laser move too quick to be natural. Well, this doesn't have to be the case. You can also try other ways, like this:
laser.x = (laser.x * 99 + target.x_position) / 100; laser.y = (laser.y * 99 + target.y_position) / 100; laser.z = (laser.z * 99 + target.z_position) / 100;
So, how do you figure out the measure of latency, and where the target should be as a result of latency? Every PC you will probably ever buy comes with an internal timer that counts the number of milliseconds since your computer booted up. The Windows API function to get this number, in units of milliseconds, is called GetTickCount(). Other OS's have other related functions. To calculate latency from computer A to computer B, computer A should send computer B a special packet that, in effect, means "Send me this packet back immediately after you get it." Just before sending it, computer A should call GetTickCount, and store that return value locally. When computer B gets the packet, it will send it right back to computer A. When computer A gets it back, it should call GetTickCount again, subtract the return value by the locally stored return value, and divide the result by 2. This will give computer A the approximate number of milliseconds it takes to get data to computer B. In this example, computer A is the server, and computer A does this latency measuring every couple of seconds, regardless of when or how often you send packets to him. Back to the immediate case study: Since the laser will move a certain distance over a certain amount of time, he can calculate the approximate distance the laser has travelled between the time you fired it, and the time he got it. Since he will then know the distance travelled, he can figure out where the target should be by displacing it by that distance.
Well this is all nice and neat, but there's one little problem: What if the laser is still too slow, and the alien does not explode for the server or the other players? Worse yet, what if there's another alien between the player and the first alien? The player thinks he can wipe out both with the same travelling laser, but the server doesn't, because the laser travels too quickly on his end. There are two ways of dealing with this:
(A) Tell the server you took out that other alien.
If you tell the server which aliens you take out. The server will dismiss the disappearing aliens as something done "because of latency," or the laser apparently grazing the alien ship. The only problem with that is if a no-good-nik figures out how you do this, that person can cheat all the way up to the grand high score!!!
(B) Do nothing and dismiss the problem as caused by lag.
With this thinking, the server is the dictator of what's really going on in everyone's game. Clients won't be able to cheat, but the game will seem less realistic and more frustrating, because you could have sworn you blasted those pesky aliens!
I really hope this puts Targeting in perspective for you. I did a quick implementation of it in one of my projects; and in testing, it has proven to work better than I had hoped, even on a 28.8 connection! If you use this technique in your game, drop me a line. I'd like to know how it turns out.








