NDC2010 | 김주복
완벽한 MMO 클라이언트 설계에의 도전
M2아키텍처리뷰
… 질 나 쁜 낚 시 제 목 죄 송 합 니 다 : $ …
Ⓒ 2010 NEXON Corporation & devCAT Studio. All Rights Reserved
M2 team, Game Development Team for Project M2 in longCAT (The 3rd New Development Division in NEXON Corp.). M2 team Director is Kim, Dong-Gun | Project M2 is produced by Kim, Dong-Gun
GT-R team, Engine Development Team for Project M2 and more. GT-R Team Technical Director is Jeon, Hyeong-Kyu
2.
개발중
이강연 내용은 현재 개발 중인 게임의
구현 방식에 대한 것으로,
최종 게임에서는 강연 내용과
다른 형태로 구현되어 있을 수도 있습니다.
공세적 기술개발로 대비
설계에집중할 수 있도록 성능 문제가 될 만한 부분은 사전에 대응하는 기술을 개발
렌더링
버텍스 트랜스폼 부하 | DX 커맨드 제출 비용
전형규, NDC2010 “마비노기 2의 캐릭터 렌더링 기술”
애니메이션
늘어난 본으로 인한 L2 캐시 미스 | 절차적 본 연산 부하
김주복, NDC2009 “프로젝트 M2의 절차적 리깅 시스템”
DIP Dependency InversionPrinciple
상위 레벨의 모듈은 하위 레벨의 모듈에 의존해서는 안되고, 양자 모두 추상화에 의존해야 한다
추상화는 구체적인 구현에 의존해서는 안된다. 구현이 추상화에 의존해야 한다
49.
엄밀하게 레이어 구분
메시관리나 애니메이션 처리와 같은 프리젠테이션 지식을 추상화
이런 식의 구분이 가능하다는 사례의 의미
0.System
게임을 OS 위에 올리기 위한 서비스
1.GenericGame 2.Presentation
‘게임’에 공통적 서비스 표현을 위한 서비스
3.Mabinogi2
1과 2를 구현하고 결합해서 게임을 정의
루프를 기능별로 분해
입출력배분 | 프리젠테이션 처리 (렌더링, 오디오, …) | 게임 시뮬레이션 업데이트
논리적 게임월드
물리적 출력장치
(뷰, 사운드 등)
물리적 입력장치
OS가 인지하는
메인루프
ForEach Console
UpdateInput
ForEach GameLoop
UpdateAndRender
ForEach Console
Present ForEach GameLoop
UpdateInput
컴퍼넌트는 상식?
단방향 그래프로 객체의 관계를 표현할 수 없다 | 상속은 문법적으로 끊기 어려운 의존성
컴퍼넌트를 어그리게이션하여 객체를 표현하는 것이 유연하고 세련된 방식
김성헌, KASA2008 “C++ Component System” 조정훈, NDC2009 “최소 의존 게임 컴포넌트 시스템”
컴퍼넌트통신=메시지?
혹은 다른 컴퍼넌트의 인터페이스를 사용해서 메소드를 호출
게임 개발 커뮤니티에서 컴퍼넌트 시스템을 말할 때 당연하게 언급하는 내용이지만…
GDC Canada 2009 “Theory and Practice of the Game Object
이창희, KASA2008 “Entity System” Component Architecture”
76.
의문1:OCP위반 혐의 Open-ClosedPrinciple
컴퍼넌트 A가 일을 하기 위해서 컴퍼넌트 B 인터페이스에 직접 의존한다면
컴퍼넌트 B에 대한 수정이 컴퍼넌트 A의 수정을 수반해야 한다
77.
의문2:절차에 대한 지식
컴퍼넌트가형식적 OCP를 준수하기 위해서 메시지를 사용하면
여러 컴퍼넌트가 협업해야 하는 절차에 대한 지식이 메시지 전달 순서로 전환되는 셈
다자 관계의 처리에 매우 취약
78.
의문3:메시지 분배 과정
시리얼라이즈와디시리얼라이즈가 객체의 책임이 아닌 것처럼
메시지 해석 및 분배도 컴퍼넌트의 책임은 아닌 게 맞지 않나?
Nebula3의 사례
79.
극단적인 설계 실험
OCP를만족하면서도 다자 관계 절차 처리에 적합한 방법을 찾기 위한 시도
OCP를 맹목적으로 준수
컴퍼넌트는 다른 컴퍼넌트를 절대로 알아서는 안 된다
객체Entity,Object는 없다
객체에 컴퍼넌트의 지식이 없다면 존재 의미가 없고,
반대로 컴퍼넌트의 목록을 안다면 OCP 위반이므로
객체란 것은 세상에 존재하면 안 된다
극단적인 설계 실험에 몰두하고 있는 모습 (대역 재연)
80.
1. 다른 컴퍼넌트참조 금지
한 컴퍼넌트가 다른 컴퍼넌트를 참조하는 것을 엄격히 규제
2. 이벤트로 통지를 선호
다음 처리가 필요한 컴퍼넌트에게 메시징하는 대신
사건 발생을 알아야 하는 쪽이 리스너를 등록
3. 메시지 자체를 객체로 간주
컴퍼넌트가 메시지를 받아서 일을 하는 게 아니라
일이 컴퍼넌트를 찾아서 절차를 수행한다
“아니, TD 양반.
이게 무슨 소리요,
메시지가 객체라니.” 80
재앙 발ㅋ생ㅋ
컴퍼넌트는 일도안 하고 배째라식 세터/게터 노출
인테그레이션 레이어는 클라이언트 전 범위의 객체가 너나없이 날뛰며 해적왕을 꿈꾸고
절차를 강조했더니 작업자들이 발상하는 방식도 절차적 프로그래밍으로 퇴행
87.
♡ 대 개 발 팀 긴 급 담 화 문 ♡
잠시 정규 업무를 중단하고
중대 현실 도피를 하겠습니다.
88.
1차정리:규칙을 분리
절차가 아닌,게임의 규칙을 정의하는 프로시저를 인테그레이션 레이어 최상위로 분류
객체의 기능에 해당하는 프로시저를 따로 분류 (생성/파괴 등)
89.
2차정리:컴퍼넌트 정리
로직 프로시저중 컴퍼넌트를 완결하는 기능에 해당하는 항목을 별도 분류
개념적인 컴퍼넌트를 구성
InventoryProc::Create PickUpItemFromWorld
class Inventory
예전과 마찬가지 상태로 객체의 생성과 어느 한 컴퍼넌트가
다른 컴퍼넌트에 대해서 이벤트 핸들러 와이어링 과정 단독으로 수행할 수
전혀 모르는 컴퍼넌트 혹은 다른 컴퍼넌트를 없는 종류의 작업들
참조하지만 (ex. 스플래시 공격)
일반적인 설계로는
이 컴퍼넌트의 기능인
프로시저들
기존 마인드모델에 부합
객체를 구분하는 동시에 컴퍼넌트 소속이 아닌 로직 프로시저를 구분하는 준거점
전통적인 OOP 방법론과 컴퍼넌트 설계 방법론을 적용 가능
무엇보다 여기 해당되는 함수들이 많지 않음
마음의 평화를 찾은 프로그래머들의 훈훈한 대화
92.
남은 과제?
아직까지도 컴퍼넌트의의존성을 제거하는 실험은 진행중
하지만 컴퍼넌트 프로시저 개념의 도입으로 어려운 문제는 해결
근본적인 서비스
위치나 방향, 행동 수행 가능 여부 락은 특정 컴퍼넌트가 제공하면 OCP 위반이지만
너무나 근본적인 서비스라서 많은 곳에서 의존성이 발생
컴퍼넌트가 프로시저 호출?
컴퍼넌트 프로시저는 조립 레이어에서 정의되지만
하위 레이어의 컴퍼넌트가 필요로 하는 의존성 역전이 존재하고 있음
분류되지 않은 프로시저들
순수한 유틸리티 함수, 데이터에 가까운 함수들을 정리할 기준을 세워야 함
92
94.
요즘 유행하는 이거
주로 쉐이더 편집이나 애니메이션 편집에 사용하고, 컷신이나 카메라 등에도 활용되는 중
업계에서 합의한 용어가 없어서 임의로 모듈 서킷이라고 부름
김성익, KASA2007 “Visual Shader Editor” 김주복, NDC2008 “차세대 애니메이션 기법을 MMO 액션에 적용하기”
96.
시각화의 힘
데이터를 만드는사람도 코드를 만드는 사람도 절차를 시각적으로 이해
특히 새로운 기능을 고안할 때 모듈의 규격을 고려하여 설계하게 됨
UnrealEd3, Epic
97.
모듈서킷의 일반화 시도
애니메이션시스템에서 활용해본 결과, 많은 장점이 있었기 때문에
전체 시스템에서 모듈 서킷 서비스를 사용할 수 있도록 기반 서비스화 시도
98.
커넥션 타입 정의
사전에정의된 타입이 아니라 임의의 타입을 넘겨주고 넘겨 받을 수 있어야 한다
커넥션에서 임의의 값을 꺼낼 수 있어야 한다
99.
모듈 입출력 정의
손이많이 가지 않고 모듈의 입출력을 정의할 수 있는 방법이 있어야 한다
동적으로 입출력 연결의 개수를 변경할 수 있어야 한다
100.
서킷 업데이트 방식
서킷의타입에 따라서 업데이트 방식이 완전히 다를 수 있다
순회 리스트를 구축하는 것으로 간단하게 접근
100