테라로 살펴본
MMORPG의 논타겟팅 시스템
박순광 ∙ 김광일 ∙ 김재경
타겟팅? 논타겟팅?
• 몇 가지 예를 살펴보자
▪ WOW
▪ Blade & Soul
▪ TERA
https://youtu.be/fHns_YZDj_I?list=PLx9kQPn0UG9sA5ZFWiVKBQz6CePIDQ1UH&t=827
• 13분 47초 ~ 14분 5초
WOW
WOW
https://www.youtube.com/watch?v=3ZeH2fXQ-iQ&feature=youtu.be&t=177
• 2분 57초 ~ 3분 15초
Blade & Soul
https://youtu.be/ih-2hct930s
TERA
https://www.youtube.com/watch?v=4mgNGQo4cqY&feature=youtu.be
무슨 타겟팅이 이렇게 많아…
• 오토냐 프리냐는 중요하지 않음
• 게임에 알맞은 타겟팅으로 구현했을 뿐
• 한 게임에 여러 타겟팅이 존재할 수도 있음
• 그래서 타겟팅과 논타겟팅은 어떻게 구별?
타겟팅과 논타겟팅의 정의
출처 - http://www.thisisgame.com/webzine/community/tboard/?board=36&n=98814
타겟팅 vs 논타겟팅
그래서 어떻게 구현하죠?
그래서 어떻게 구현하죠?
라이덴2
출처 - http://go9ma.tistory.com/1481
• 핵심은 물리 판정이
실시간으로 일어나는 점
마영전의 경우
NDC 2010 이은석 - 마비노기 영웅전 포스트모템 2부 中
NDC 2012 마비노기 영웅전 카이 포스트모템 中
NDC 2012 마비노기 영웅전 카이 포스트모템 中
NDC 2012 마비노기 영웅전 카이 포스트모템 中
NDC 2012 마비노기 영웅전 카이 포스트모템 中
NDC 2012 마비노기 영웅전 카이 포스트모템 中
NDC 2012 마비노기 영웅전 카이 포스트모템 中
https://www.youtube.com/watch?v=moDNvqCjYS4&feature=youtu.be
피격 프레딕션 유무 차이
NDC 2012 마비노기 영웅전 카이 포스트모템 中
NDC 2012 마비노기 영웅전 카이 포스트모템 中
https://www.youtube.com/watch?
v=fW7HIRuIpfs&feature=youtu.be
피격 프레딕션 로직
Frame loop
{
if ( isFirst && cl_hit
&& false == sv_hit )
{
play( flinch )
pause(0)
}
If ( sv_hit )
{
play( flinch )
resume(0)
}
}
NDC 2012 마비노기 영웅전 카이 포스트모템 中
실시간 물리 판정
라이덴2
출처 - http://go9ma.tistory.com/1481
던전앤파이터
• 싱글 or MO일 경우
• 클라에서 처리하거나
서버에서 모두 처리하면 됨
테라의 경우
• 심리스 월드로 구현된
MMORPG
• 프레임당 모든 유저의
물리 판정을 처리한다?
출처 - http://www.inven.co.kr/webzine/news/?news=60184
+
테라의 경우
출처 - http://blog.daum.net/chumakjung/12782784
서버
테라의 경우
• 서버 부하를 어떻게 줄이는지가 중요
※ 사진은 본문과 관계 없습니다
연산 ∙ 동기화
충돌 공간
• 테라의 물체는 공격할 수 있는
실린더로 이루어짐
충돌 공간
• 각 공격은 시간에 따른 충돌 공간을 포함
• 타겟의 실린더와 충돌 공간의 충돌을
체크함으로써 공격이 적중했는지 판단
스킬 정보
• 이전 슬라이드 스킬의 정보
• Targeting time은 공격을
시작하고 충돌 체크하는
시간을 의미
샘플 테이블(XML)
2단계 처리
• 각 공격(힐, 버프 포함)은 타겟팅 시간을 여러 개 갖고 있음
• 공격 유형에 따라 2 ~ 12가지 이상의 타겟팅 시간을 가질 수 있음
• 각 타겟팅 시간은 Front-End와 Back-End의 2단계로 구성
2단계 처리
• Front-End
공격 범위을 검색해서
충돌하는 대상을 수집
• Back-End
수집된 타겟들에게
데미지 적용
첫번째 공격(내리찍기)의 처리 과정
2단계 처리
두번째 공격(휘두르기)의 처리 과정
2단계 처리
• Front-End
충돌 체크를 위한 타겟 검색이 자주 일어남
• Back-End
타겟의 정보를 자주 업데이트 해야 함
빠른 동기화가 필요
Lock-Free 구현
• 락을 걸면 성능이 내려가므로 좋지 않음
• 락 없이 동기화하는 방법은?
Worker Thread Pattern
• 효과적으로 락을 제거하기 위해 썼다고 함
• 정확한 개념은 구글을 참고
• 한 줄 요약: 스레드 풀
• 테라에서는 CPU 코어 개수 = 스레드 개수
• 코어의 개수, 성능은 스레드와 비례
Worker Thread Pattern
• 서버의 모든 요청은 IOCP
• IoCompletionPortTask
패킷 처리
• TimerTask
시스템의 현재 시간 검사
• ClusterTask
타겟 유효 영역 검사
• 루프 처리 시간에 따라 0 ~ 16ms의
타임 아웃 값을 가짐
Front-End 구현
클러스터(Cluster)
• 테라의 심리스 월드는 클러스터라는 사각형들로 이루어짐
• 물체의 포인터를 가진 컨테이너
• 모든 물체는 클러스터에 붙어 있어야 됨
Front-End 구현
• 물체가 32 -> 33로 이동하면
32 클러스터는 물체를 제거
33 클러스터는 물체를 추가
• 소환이나 죽음도 추가나 삭제로
처리
• Worker Thread는 클러스터를
TLS에 저장하여 유지
Thread Local Storage(TLS)
• 전역 변수로 접근하나
각 스레드에 독립된 공간
• 전역 공간을 스레드 별로
사용하고 싶을 때 사용
출처 - http://www.inven.co.kr/webzine/news/?news=60184
Cluster Update Queue
• 클러스터를 업데이트 하기위한 Dispatcher
• 전역 변수로 모든 Worker Thread가 공유
• 어떤 행동이 클러스터의 업데이트를 필요로 하면
Worker Thread는 업데이트 큐 뒤쪽에 작업을 추가
• 모든 Worker Thread는 같은 알고리즘을 사용하여
같은 큐를 처리하므로 스레드별 TLS에 저장된
클러스터 정보는 모두 동일해야 한다
C++ Pseudo code with windows API
ClusterUpdateTask
C++ Pseudo code with windows API
CUT
C++ Pseudo code with windows API
CUT
C++ Pseudo code with windows API
• Worker Thread는 가장 최근에 수행된 작업의 위치를 가리키는 인덱스를 가지고 있다
(TLS_CurrentTaskIndex)
• final이 true면 업데이트 큐에서 삭제
Cluster Update Task
• 클러스터가 업데이트되는 작업
• 모든 TLS에 동기화되는 것을 보장하기 위해
레퍼런스 카운트를 가지고 있음
C++ Pseudo code with windows API
Atomic Operation
• Interlocked… 함수가 여기에 포함
• 멀티 스레드를 사용할 때 연산이 중간에 끼어들지 않는 것을 보장
• DB의 트랜잭션을 생각하면 됨
클러스터의 특징
• 물체를 검색할 때 락이 필요하지 않다
TLS에서 바로 포인터를 얻을 수 있음
• 물체가 움직인다면 모든 Worker Thread는 TLS에 있는 클러스터를 업데이트 해야 됨
클러스터의 특징
• 클러스터의 장단점
NDC12 MMO 서버 개발 포스트 모템
https://www.slideshare.net/devcatpublications/mmo-ndc2012
38p ~ 47p, 94p ~ 107p, 125p ~ 127p
NDC13 게임 서버 디자인 가이드
https://www.slideshare.net/devcatpublications/ndc2013-19986939
48p ~ 62p
Front-End 결론
• Front-End는 충돌된 물체를 검색하는 단계
• 테라에서 구현한 클러스터는 검색에 별도의 동기화 과정이 필요 없으므로
적절한 자료구조라 할 수 있다
Back-End 구현
• 업데이트를 자주 해야 함
• Critical Section이나 Spin Lock을 사용하면?
• Critical Section
Blocking으로 인한 성능 하락
• Spin Lock
급격한 CPU 사용 증가로 성능 하락
Lock-Free Executor
• 락이 없는 작업 Dispatcher
• 모든 물체는 멤버 함수의 실행 순서를 보장하기 위해 LFE를 가지고 있음
• 업데이트를 위한 함수 포인터를 Task에 랩핑하고 LFE에 랩핑한 Task를 등록
사실 이렇게 인자를 넘기는게 아니라 Task에 랩핑해서 넘긴다
Task
대충 요렇게???
C++ Pseudo code with windows API
Lock-Free Executor
결론
• 빈번한 업데이트로 인해 Atomic Operation을 활용하여 Lock-Free로 구현
• LockFreeTaskQueue는 논블락킹 동시 큐를 기반으로 하여 함수 호출 순서 보장
• 이러한 Front-End, Back-End 처리 과정은 CPU 사용량을 1/20로 줄임
• 1 ~ 6000명의 유저에 대한 CPU(Intel Xeon E5630) 사용율은 1 ~ 6%
• 대기 시간을 줄임으로써 프리 타겟팅 전투를 가능하게 함
Q / A

테라로 살펴본 MMORPG의 논타겟팅 시스템