본문 바로가기

관심분야/게임

시야관리 - 데이터 최적화

여기에서 말하고자 하는 것은 시야 범위내 객체의 이동으로 인해 주변 객체에 전달해야 하는 데이터를 최적화 하는 방식에 대해 논하고자 하는 것이다.


사용자 삽입 이미지
화면은 일반적으로 MMO 계열의 객체 관리 방식을 나타낸 것이다. 일반적으로 3x3 방식의 블럭을 통해 객체에 대한 시야를 관리하고 데이터를 관리(전송)하게 된다.

이 방식의 장점은 데이터 발생에 대한 처리를 범위내 객체에 제한 되어 데이터 처리의 효율성을 증가시킨다는 장점을 가지고 있고, 물론 현재 대부분의 MMO 계열에서 사용되고 있다.

그러나 해당 방식의 가장 큰 단점은 바로 객체가 해당 3x3 블럭에 모여 있을 경우 데이터에 대한 처리가 많아 진다는 것이다. 즉, 100개의 객체가 존재한다면 발생 데이터당 100번의 데이터 전송을 해야 한다는 내용이 된다.

이로 인해 대량의 객체(사용자 또는 NPC)가 모이는 것을 제한한다.

여기서 말하고자 하는 것은 기존의 3x3 블럭 제어의 단점을 조금이라도 극복해 보고자 하는 처리 방식에 대해 이야기 하고자 하는 것이다 - 최근에 개발되어 지는 구조에서는 대부분 이야기 하는 방식에 대해 사용하는 곳도 분명히 있다.

그럼, 말하고자 하는 방식에 대한 장점을 논해 보자.
   1. 데이터의 처리 권한을 영역별로 분리하여 처리할수 있다.
   2. 데이터 전송 대여폭 제한할수 있다.
실제로 개발에 사용되는 3x3 블럭의 크기는 게임내에서 넓은 지역이다.
 
물론, 해당 방식(시야 범위별 관리)도 기존의 처리 방식의 단점을 100% 극복하지는 못한다. 그러나, 서버에
발생되는 부하는 최소화 할수 있다는 장점이 있다.

  == 개발을 하여 서비스를 하는 시점에서, 내부 데이터 처리 부하보다 데이터 전송 부하가 크다는 것을
      느끼는 순간, 이 방식의 필요성을 더욱더 실감할수 있다.


그럼, 실제 구현에 대해 이야기 해보자.

현재 이동하는 객체(사용자)를 중심으로 시야를 3단계 이상으로 관리한다는것이 방식의 핵심이다.
   1. 가장 근접한 시야에서 발생되는 다른 객체의 모든 정보를 받는다.
   2. 조금 떨어진 거리에서 발생된 객체의 정보(이동,전투 등)의 정보의 전송 패킷을 제한한다.
      : 이동의 중간 경로 생략과 전투 표현의 상세 정보 생략, 그리고 객체의 모양(장비 등)등의 정보 최소화
   3. 멀리 떨어진 객체에 대한 정보(이동, 전투 등)의 정보를 좀더 많이 제한한다.
      : 모든 경로 이동의 직선화 및 전투 생략, 그리고 객체의 모양정보 제한

등의 처리를 통해 네트워크로 발생되는 데이터를 줄이는 것이다.

위의 값에서 nsight는 전체 시야에 대한 가중치를 나타내는 것이다. (30%,50%,70%,100%)로 분리하여 처리를
한다. == 필자는, 현재 시야 레벨을 8단계 까지 설정하여 처리하도록 구성해 둬서, 범위를 세밀화 했다.

는 객체 이동이 발생되었을때, 이동의 처리를 세부화 하기 위한 handler로 호출 되는 함수는 조건에 따라
   do_in()  - 시야 범위 안으로 이동
   do_out() - 시야 범위 밖으로 이동
   do_passby() - 시야 범위 내에서 범위의 변화 없이 이동
가 있다.

이러한 처리를 통해, 데이터를 좀더 세분화 하고 시야변화에 적합한 처리를 행할수 있다.

참고로, do_in()과 do_out()의 입력값 중에 baseline은 객체의 시야 변경값이 마스킹되어 들어온다.
           해당 함수에서는 객체의 장비에 대한 정보를 전송한다거나, 값의 전송 데이터량을 결정하고

do_passby() 함수는 3x3블럭에는 존재하지만, 실제 시야에는 존재하지 않는 이동이 발생되었음을 처리한다.
     == 이 함수는 NPC와 같은 객체를 깨우거나 할때 사용될수 있다.
do_moving()은 시야 범위내에서 데이터 처리를 수행하는 함수이다.

해당 함수는 LOCK 상태에서 처리가 되므로, 실제 데이터 전송에 대한 부분은 이들 처리가 완료된후 UNLOCK된 상태에서 데이터를 전송하도록 처리하여 DEAD LOCK 상태를 해제한다.

함수를 통해, 해당 시야값에만 데이터를 전송한다.
  참고로, 해당 처리는 RW LOCK을 사용하고 있다 - RW LOCK의 처리 방식은 생략

** do_...() 계열 함수는 데이터 처리용 함수이며, 데이터 전송을 처리하는 함수는 아니다