티스토리 뷰
네트워크 게임에서 서로간의 이동을 동기화 하기 위해 여러 방법이 사용될 수 있다.
기본적으로, 이동처리를 하기 위해 매 프레임 마다 이벤트와 상태를 전송하는 방법이 있다.
이론적으로 가장 정확한 동기화를 할 수 있는 방법 같지만 클라이언트가 늘어날 수록 전송하는 횟수가 기하급수적으로 늘어나게 되어 비효율적이다.
키보드를 누르고 있는 동안 움직이는 캐릭터가 있다고 할 때 게임이 60프레임이라면 초당 60번 키가 눌리고 있다는 패킷을 전송한다.
cs로 구성된 게임에서 이 패킷은 (n=클라이언트 수)번 전송된다.
이렇게 많은 패킷을 서버에서 처리하기엔 부하가 너무 크다.
부하를 줄이기 위해 논리적으로 패킷의 전송 횟수를 줄이는 기법이 Dead Reckoning 이다.
Dead Reckoning
이벤트가 발생할 때 마다 이벤트 정보를 패킷으로 전송하고 각 클라이언트가 자체적으로 이벤트에 대한 처리를 하게 하는 기법.
* Dead(네트워크가 끊긴. 신호가 없는 상태) Reckoning(계산, 추정) 하는 기법.
키보드를 눌러서 이벤트가 발생하면 패킷을 전송한다.
이벤트를 수신한 클라이언트는 다른 이벤트가 전송될 때 까지 해당 이벤트에 맞는 처리를 한다.
클라이언트 1 |
클라이언트 2 |
- 이동을 위해 right_arrow를 누른다. - 키보드 이벤트가 패킷으로 전송된다. |
|
|
- 키보드 이벤트를 수신한다. - 이벤트에 맞게 클라이언트 1의 캐릭터를 오른쪽으로 움직인다. |
- 멈추기 위해 키보드에서 손을 뗀다. - key_up이벤트가 패킷으로 전송된다. |
|
|
- 키보드 이벤트를 수신한다. - 캐릭터의 이동을 멈춘다. |
따라서 각 클라이언트는 모든 오브젝트에 대해 특정 이벤트가 발생했을 때 처리 알고리즘에 대해 알고 있어야 한다.
또는 게임의 종류에 따라
이벤트 패킷과 함께 이동에 필요한 수치 (ex. 방향, 속도 등)를 함께 받아서 처리한다.
이벤트가 발생할 때 마다 패킷을 전송하는 방법으로 전송 횟수는 줄었지만 해결해야할 것이 남았다.
위 예처럼 키보드 입력을 끝내고 정지하는 경우를 자세히 보자.
클라이언트1은 캐릭터가 10 위치에 있을 때 키 입력을 멈추고 key_up이벤트를 보낸다.
// 이때 클라이언트1이 보는 캐릭터의 위치는 10이다.
네트워크 전송속도가 무한히 빠르지 않기 때문에 상대방은 key_up이벤트 패킷을 일정시간 후에 받게 된다.
// 하지만 Dead Reckoning 기법에서 클라이언트는 각자 자체적으로 이동을 수행하고 있기 때문에 패킷을 수신하는 순간 클라이언트2가 보는 캐릭터의 위치는 10보다 더 이동한 위치이다.
이러한 위치 오차를 보정하기 위해 이벤트를 전송할 때 현재 위치와 방향 등을 같이 전송해서 수신측에서 처리하도록 한다.
우리가 온라인 게임에서 흔히 볼 수 있는 상대방 캐릭터가 갑자기 이상한 위치로 순간이동 하는 경우가 바로 이 처리 과정에서 생기는 결과라고 볼 수 있다.
'Non-Programming > Game' 카테고리의 다른 글
맵 로딩 방식의 종류 (0) | 2017.02.04 |
---|
- Total
- Today
- Yesterday
- rxswift
- JSP
- mongoDB
- 국내여행
- C
- ios
- 데이터베이스
- Git
- DesignPattern
- database
- machine learing
- Spring
- SHADER
- SOCKET
- 운영체제
- 알고리즘
- game
- SwiftUI
- OS
- 드라마
- scala
- ue4
- winsock
- Java
- C/C++
- 수학
- 자료구조
- swift
- C++
- Cocos2d-x
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |