1. 해당 이미지는 DSP 엔터테인먼트의 자산입니다
NDC2012 | 김주복
Ⓒ 2012 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. 이 강연을 저의 멘붕 방지에 지대한 도움을 주신
카라 멤버 여러분과 DSP 미디어에 헌정합니다
죽어라 들은 건 점핑인데 사진은 루팡
맥락없이 카라 짤이 나오니 양해를…
4. 컴퍼넌트 시스템 논의의 연장
프로시저 레이어의 문제 해결 방안 등
뻔하고 당연한 이야기
게다가 페이지 수도 글자도 많…
해당 이미지는 네이버 만화와 김성모 프로덕션의 자산입니다
5. w o r k i n p r o g r e s s
이 강연은 현재 개발 중인 게임의 구현 방식에
대한 것으로, 최종적으로 발매된 게임은 전혀 다른
형태로 구현되어 있을 수도 있음을 알려드립니다
6. 해당 이미지는 DSP 엔터테인먼트의 자산입니다
개념 미제 소고
지속효과 의존성 금지와 사건 통지 설계 원칙과 인지적 한계
지속효과 클래스 프리젠테이션 액터 기획자 무용론?
탈출처리
이터레이션 속도 재활용에 대한 관점
메시지 트랜잭션
설계 목표 재변경
피처
7. 김주복
넥슨12년차|NDC강연6년차
@eiaserinnys | beforu.egloos.com
2001 무선사업팀 도트디자이너
2001 마비노기팀 리드 프로그래머
2003 마비노기 프로그래밍팀 팀장
2005 그 룹 웨 어 개 발 팀 팀 장
2006 W 팀 테 크 니 컬 디 렉 터
2008 개 발 3 본 부 3 실 실 장
2009 마비노기 2 개발 디렉터
2010 신규개발3본부 1실 실장
2011 GDC 엔지니어링 세션 강연
9. 컴퍼넌트의 상호의존성을 전면금지하는 설계를 시험
설계 원칙을 엄밀하게 지키는 것이 유지보수에 더 나은 코드가 될 것이다!
NDC2010 – M2 아키텍처 리뷰, 완벽한 MMO 클라이언트 설계에의 도전
10. 익숙하지 않은 설계가 이상한 구현으로 발현
절차와 객체가 서로 책임을 떠넘기는 이상한 세계
NDC2010 – M2 아키텍처 리뷰, 완벽한 MMO 클라이언트 설계에의 도전
11. 나름대로 기준을 세워 프로시저 함수군을 정리
게임의 규칙에 해당하는 함수와 컴퍼넌트를 구성하는 함수로 분류
NDC2010 – M2 아키텍처 리뷰, 완벽한 MMO 클라이언트 설계에의 도전
12. 개별 작업자가 각자 이해한 상태를 기준으로 작업
이 시스템이 뭔지 잘 모르겠긴 한데 일은 해야 하는데 어쩔 거야
수많은 버그로 귀결
일어나다가 다시 쓰러진다거나
위치가 이곳저곳으로 튄다거나
T 포즈로 굳은 채로 이동한다거나
뒷목이 뻣뻣한 채로 디버깅한다거나
어째 아침에 회사 가기가 싫다거나
이게 사는 건가
13. 엔지니어링 리부트란 이름으로 4개월간 진행
개발 진도가 상당히 나간 프로젝트에서는 이례적인 결정
엔지니어링 리부트 OT NDC2011 – 이무림, 고양이가 개발한다
17. 1. 액션이 데이터화
액션 로직이라고 부름
게임 디자이너가 제어
타이밍, 이동 가능 여부 등
이터레이션 시간을 줄여줌
타당한 요구사항
18. 2. 동적 분기가 필요한 디자인이 추가
액션 로직에서 제어는 어려움
서버 상에서 판정을 받아야 하는데, 기술 가능하다고 해도 게임 디자이너가 작성하는 것은 무리
코드가 데이터를 '잇는' 처리
'액션 로직을 단순히 처리하는 과정'에서 '특정한 상황인 경우 다른 데이터로 연결하는 과정'으로의 전환
19. Write-Only-Code
데이터와 비동기 처리가 연달아 이어짐
사실 작업자는 있는 도구로 성실하게 구현한 것
프로시저 레이어의 혼돈과 맞물려 상승작용
비동기 처리의 중간 단계 코드가 여기저기 파편화되어 존재
20. 액션에는 어떤 효과가 수반되는 것이 보통
공격은 보통 일정 시간 동안 이동과 추가 공격이 불가
피격은 보통 처음부터 끝까지 이동이나 여타 동작이 불가
이동할 수 없고 다른 짓할 수 없고 등등…
마법 시전을 시작하면서
별도 조작계로 변경
21. 효과는 반드시 종료되어야
이전엔 액션 로직 단위로 처리했으나…
시작하는 시점에 설정한 효과를 처리가 종료되는 시점에 일괄 해제
분기가 들어가며 문제
효과가 액션 로직이 바뀌어도 유지되어야 함
분기가 발생할 때 해제하고 다시 설정하면 오동작의 가능성
23. 정의
게임이 인지하는 객체 동작의 최소 단위
사실 게임 디자이너는 블로우~벽에 부딪히는 동작을 별개라고 인지하지 않는다
ex. 공격 동작, 날리기 과정 전체 등
특성
코드에서 구현
액션 로직의 분기를 처리
끝날 때 종속된 효과를 모두 해제
☆☆☆ 서로 중첩되지 않음 ☆☆☆
새로운 액션이 실행되면 이전 액션이 종료됨
24.
25. 괄호 닫기 처리의 완결성 확보
어떤 경로를 타고 실행되더라도 액션이 끝나면 정리됨
서로 중첩되지 않는다는 특성으로부터 가능
26. 복잡도의 본질을 해결한 것과는 거리가 있다
있는 도구를 바탕으로 요구사항에 대응해서 생긴 문제를 해결한 것 뿐
+ =
당연히 문제들은 산더미처럼 남아있고…
34. 연관 없는 시스템의 간섭이 중단의 원인
ex. 필드에 탑승물을 남긴 채로 로그아웃하면 탑승물은 자기 상태를 정리해야 함
조합 폭발의 가능성
새 시스템이 기존 구현을 찾아서 검토해야 함
탑승 → 피격
탑승 → 로그아웃
탑승 → 지역이동
탑승 → 거래
탑승 → 물건 집기
탑승 → …
35. 로그아웃
죽을 때
지역 이동 시
보기만 해도 딱 '이 골치아픈 것들…'이란 생각이 드는데,
36. 또 다른 종류의 괄호 닫기, 상태 이상
액션/스테이터스와는 다르다
ex. 독, 스턴, 슬로우와 같은 상태 이상
걸려있는 동안 특정한 효과가 지속
보통 공격(액션)하거나 탑승(스테이터스)하더라도 끊기지 않음
37. 당연하다, 게임의 모든 효과는 둘 중 하나
순간적이고 영구적이거나,
레벨업이 되어 체력의 최대치가 증가하는 연산은 순간적이고 영구적으로 반영된다
지속적이고 단기적이다
독에 걸려 체력이 감소하는 효과는 지속적이고 끝나면 사라지는 단기적인 것이다
vs.
해당 이미지는 Activision Blizzard의 자산입니다
38. 처리하고 지나가면서 잊어버리면 된다
체력을 회복하거나, 위치를 이동하거나…
DB에 반영하는 문제로 가면 또 다른 문제가 되긴 하지만
40. 예상할 수 없는 사유의 종료에 대응해야 하기 때문
고로 게임에서 괄호 닫기가 중요한 문제인 것은 너무나 당연
( )
41. 정의
수명을 가짐
시작/종료 시점과 지속 중 정해진 효과를 실행
☆☆☆ 종료할 때 괄호 닫기를 수행 ☆☆☆
모든 효과를 클린업
많은 개념에 연계
여러 동작이 지속효과를 수반
액션, 스테이터스, 상태이상 등
사실 마음에 드는 이름은 아닌데 명확하면서 길지 않은 표현이 잘 없어서… 차라리 괄호 효과라고 할까
58. 현재 지역 이동 탈출 처리의 의존성
ㅁㅂㄴㄱ보다 구현된 시스템 요소 수가 적어서 단순한 요인은 제외하고
GrappleProcedure.
EndGrappleAndSync
EscapeSequence. EscapeSequence.
LeanbackProcedure.
EndGrapplingRelation EndGrapplingRelation
ByGrappler ByGrappledOne EndAndSync
EscapeSequence. PropProcedure.
EndLeanBack SetPropInstaller
EscapeSequence.
EscapeAndSync
EscapeSequence. PropProcedure.
EndRidingRelation DestroyInstalledProp
WorldProcedure.
LeaveRegion EscapeSequence.
EndCurrentAction RidingProcedure.
ByLeavingRegion RideOffVehicleAndSync
ActionProcedure.
End
LocationComponent.
OnLeaveRegion
59.
60. 장점
사건/지속효과 양쪽의 코드가 단순해짐
유사한 처리의 파편화를 방지
구현부가 일원화되어 있으므로, 새로운 전이와 모든 조합에 대해서 검토해 보게 됨
단점
탈출 처리기는 모든 사건/지속효과를 알아야 함
손 댈 수 없이 거대한 코드 블록으로 자라날 가능성이 있음
테이블화시켜서 비교적 단순한 형태로 줄이는 것이 가능하리라고 예상
어떻든 문제 해결?
61. ex. 탑승 중 피격
function 피격
{
탈출처리요청(사유:피격)
{ 피격 처리는
이 과정에 대해서
탑승자를 탑승이 아닌 상태로 전환 전혀 인지하지 못함
탑승물을 태운 사람이 없는 상태로 전환
}
피격에 수반되는 실제 처리
}
62. 1. 처리가 발생할 때마다 발송?
function 피격
{
탈출처리요청(사유:피격)
{
각각의 시점마다
탑승자를 탑승이 아닌 상태로 전환 클라이언트가
탑승물을 태운 사람이 없는 상태로 전환 상응하는 동작을 하도록
메시지를 발송
}
피격에 수반되는 실제 처리
}
63. 2. 전체를 하나의 메시지로?
function 피격 전체를
"탑승 중 피격"이라는
{ 하나의 메시지로
탈출처리요청(사유:피격)
{
탑승자를 탑승이 아닌 상태로 전환
탑승물을 태운 사람이 없는 상태로 전환
}
피격에 수반되는 실제 처리
}
64. 처리가 발생할 때마다 발송하는 경우
클라이언트에서 메시지를 동시에 받지 못함
이후 메시지가 늦게 도착할 경우 이상한 모습이 보이거나 심지어 그 사이에 조작도 가능해짐
65. 전체를 메시지로 보내는 경우
취지에도 어긋나고 논리적으로 불가능
외부에서는 탈출처리에서 어떤 지속효과에 영향을 미칠 지 모르고, 따라서 전체 메시지가 무슨 동작을 해야 할 지 모름
가능하다고 해도 낭비
(각기 다른 탈출처리 이유)×(각기 다른 지속효과)의 조합만큼 메시지를 만들어야 함
On…Handler() 같은 형태로 코드가 만들어지는 이유
사실 이런 형태로 구현하는 것은 메시징 방식의 제약 안에서 문제를 풀어야 하기 때문이기도 함
…………
완전히 다른 접근이 필요하다는 결론
68. 장점
코드가 단순해짐
탈출처리가 적용 가능해지기 때문에 메시지 구성을 위해서 다양한 맥락을 고려하지 않아도 됨
몇 종류의 응답 프로토콜을 범용적으로 활용
예를 들어 특정 락을 걸고 풀거나, 스테이터스를 설정하거나, 액션을 실행하는 등의 간단한 동작은 조합해서 메시지를 발송
이터레이션 가속화의 가능성 해당 이미지는 한승연 본인의 자산입니다
미제를 설명하면서 다시 설명할 예정
단점
메시지의 크기를 통제하기 어려움
작은 메시지를 합산하면서 헤더의 오버헤드가 늘어나고, 얼마나 커질지 파악하기가 어려움
자주 쓰이는 형태의 조합을 컴파일하는 방법으로 최적화가 가능할 것으로 예상
뭐 어쨌든 간에…
69. 지속효과
괄호 닫기를 개념화하여 안전한 클린업을 보장
탈출처리
다른 지속효과간의 전이 과정을 단순화
메시지 트랜잭션
전이 과정을 자연스러운 형태로 코딩 가능
71. 복잡하고 불편하다!
한 컴퍼넌트를 두 개로 나눠서 만들어야 함
분류 기준이 없다!
컴퍼넌트 소속이 아닌 프로시저군은 분류가 어렵다
72. 딱히 문제도 아니고 문제가 아닌 것도 아니고…
맞는 방향이란 생각은 드는데 이론적 기반이 없는 것이 문제
객체 지향 패러다임에서 크게 벗어난 접근
지속 가능한 개발 방법론으로 정립할 수 있을지 의문 해당 이미지는 아마도 한승연…본인의 자산입니다
73. <도메인 주도 설계>
'소프트웨어의 복잡성을 다루는 지혜'라는 부제
뭔가 막 해결될 것 같은 기분이 든다 레드썬
좀 날림으로 소개를 하자면…
74. 소프트웨어는 도메인 지식의 반영
소프트웨어를 사용하는 사용자의 활동이나 관심사
해결해야 하는 핵심 문제 영역을 의미
은행용 소프트웨어라면 계좌 개설이나 대출 업무 절차에 관한 지식과 개념들
게임이라고 하면 게임 디자인
UI 애플리케이션 도메인 인프라스트럭처
75. 온라인 게임에서는 익숙한 모델
클라이언트 언어가 C++이라 서버까지 객체 지향 패러다임이 강력히 주도한 덕분?
OOP 따라서
객체 모델링하고
함수가 쿼리 DB에
직접 날리지 말고
중간에 대리자 넣고…
같은 당연한 이야기
당장의 내용과는 무관하지만 강력히 읽어보실 것을 추천
76.
77. =객체로 모델링하는 것이 부자연스러운 연산
1. 객체를 구성하는 게 아니라 도메인의 개념과 관련
2. 인터페이스가 모델의 외적 측면에서 정의 해당 이미지는 DSP…, 아니 셀카니 아마도 한승연…본인의 자산입니다
3. 연산이 상태를 갖지 않는다
오늘날 흔히 하는 실수는 행위를 적절한 객체로 다듬는 것
을 너무나도 쉽게 포기해서 점점 절차적 프로그래밍에 빠지는
것이다. 하지만 객체의 정의에 어울리지 않는 연산을 강제로 객
체에 포함시킨다면 해당 객체는 자신의 개념적 명확성을 잃어버
리고 이해하거나 리팩터링하기 힘들어질 것이다. 복잡한 연산은
단순한 객체를 손쉽게 궁지로 몰아넣어 해당 객체의 역할을 불
분명하게 만들 수 있다. pp107, 도메인 주도 설계
프로시저 레이어의 특성과 일치!
78. 게임 로직을 서술하는 서비스
컴퍼넌트를 조작하는 과정을 기술
상태의 정합성은 컴퍼넌트가, 절차는 피처가 책임
독립된 게임 시스템의 기능 집합
게임 디자이너가 보는 게임 시스템의 단위
'새로운 기획을 만들었다'고 할 때, 기획 하나와 피처 하나가 대강 대응
ex. 전투, 거래, 마법, 원거리교전, 탑승, ...
79. 파트 1에서 지적했던 문제
컴퍼넌트가 메시지를 핸들링하는 것은 설계 원칙에 어긋난다
피처에 두면 된다!
메시지 = 게임 시스템의 기능 명세이므로
82. 메시지 컨트랙트 정의 피처 펑션으로 토스하는 어댑터
피처 구성
메시징 코드 (자동 생성) 피처 펑션
83.
84. 장점
설계 원칙 면에서 깔끔하다!
탈출 처리, 메시지 트랜잭션과 함께 개별 기능 구현이 다른 기능에 의존하지 않는 높은 독립성을 획득 가능
피처와 컴퍼넌트 간의 임피던스 불일치 해결
거래 같은 다자 관계는 하나의 컴퍼넌트에서 해결할 수 없기 때문에 필연적으로 발생
개별 기능 단위로 엄밀하게 가용 조건을 통제 가능
단점
일반적인 설계에 비해 간접층이 늘어남
각각의 구현체가 단순해진 대신, 전체 흐름을 파악하기 위해서 알아야 하는 구조가 늘어남
트레이드 오프?
85. 너무 간단해서 인생이 허무한 지경
Feature : IFeature 컴퍼넌트 레이어 지속 효과들
FunctionA :
IFeatureFunction
IFeatureContract ActionComponent
RequestA() Use() Flag
ReplyA() = 0 Do() StatusComponent
Flag
RequestB() FunctionB AbnormalCondition
Component
Use() Flag
ReplyB() = 0
ActionLockComponent
Do()
86. 여러가지 심각한 문제를 해결하긴 했는데…
뭔가 아직도 해결이 미진한 부분이 많고…
…결정적으로 새로운 문제들도 수면 위로 부상
87. 의존성 금지와 사건 통지
프리젠테이션 액터 해당 이미지는 DSP 엔터테인먼트의 자산입니다
이터레이션 속도
89. 불편한 탄생 과정
컴퍼넌트 간 의존성은 강력하게 금지되나 자신의 정합성은 유지해야 함
의존성이 객체만으로 프로그래밍을 한다는 건 불가능한 일
어쩔 수 없이 컴퍼넌트 프로시저 개념이 도출
그 외의 프로시저 코드는 피처의 기능으로 정리되었음 NDC2010 – M2 아키텍처 리뷰, 완벽한 MMO 클라이언트 설계에의 도전
97. 타입에 따라서 패스가 다른 경우가 보통
로직 프로그래머 입장에서는 수정하기가 어려운 경우가 많다
98. 서버에서는 로직 액터의 생성까지만 관여
프리젠테이션 액터는 로직 액터의 정보를 바탕으로 자신을 구축
로직이 UI에 정보를 통지하지 않고, UI가 로직을 모니터링하는 것과 유사
CharacterTag 로직 프리젠테이션
Animator
Inventory
RenderActor
EquipmentHolder
로직 생성 이후에
SoundActor
Status
별도 과정으로 구축
AbnormalCondition Particle ControllerBackLink
99. 프리젠테이션 액터를 균일화
게임 디자이너나 아티스트가 '얘는 왜 이걸 할 수 없어요?'라고 놀랄 필요가 없음
게임 로직에서 특정한 프리젠테이션 처리가 가능한지 알 필요가 없음
프리젠테이션 쪽에서 게임 로직에 대해서 알 필요가 없음
게임 플레이의 프로토타이핑이나 연출을 시험할 때 좀 더 용이
CharacterTag 로직 프리젠테이션
Animator
Inventory
RenderActor
EquipmentHolder
SoundActor
Status
AbnormalCondition Particle ControllerBackLink
eoi
101. 프로토타이핑, 빠른 이터레이션의 중요성
프리젠테이션에 투자하면 팔 수 있던 시대가 지나버렸음
주류 (콘솔) 게임이 NDS와 소셜 게임이 가져온 "파괴적 혁신"에 패배
GDC2011 동향보고
102. 라이브 시스템의 복잡도
기존 피처와 상호 작용하므로 독립적 프로토타이핑이 어려움
돌아가는 시스템 위에서 테스트하지 않으면 의미가 없는 경우가 많음
103. 서버-클라이언트 메시징 변경에 재컴파일이 필요
필연적으로 이터레이션 속도의 감소가 동반
ServiceContract
RequestA
ReplyA
Feature : IFeature
IFeatureContract MessageHandler
FunctionA :
IFeatureFunction
RequestA() 메시지 분배기
Use() 로직 처리
ReplyA() = 0
Do()
클라이언트 서버
104. 스크립트로 작성된 피처에 전달하면 다운 없는 개발이 가능
ServiceContract
RequestA
ReplyA
Feature : IFeature
FunctionA : MessageHandler
IFeatureFunction IFeatureContract
Use() RequestA() 메시지 분배기
로직 처리
Do() ReplyA() = 0
스크립트 스크립트 라우터
스크립트 스크립트
스크립트 라우터
클라이언트 서버 eoi
105. 설계 원칙과 인지적 한계
기획자 무용론? 해당 이미지는 DSP 엔터테인먼트의 자산입니다
재활용에 대한 관점
설계 목표 재변경
106. 사실, 프로시저와 피처의 논리적 구조는 동일
설계 원칙 측면에서는 큰 차이가 없으나 인지적 차이는 하늘과 땅
코드가 마음 속의 어떤 모델에 대응하는가 여부가 매우 중요함
분류 방식,
실제 구현 등에서
거의 차이가 없음
107. 올바른 설계에는 인지적인 측면이 중요
설계 원칙으로 해결되지 않는 문제의 판단 기준은 인간의 인지 능력
OAOO를 지켜야 하는 이유가 곰곰히 생각해보면 인간의 인지 능력의 한계 때문
마인드 모델을 공유하기 위해서 노력이 필요 엔지니어링 리부트 OT
도메인 주도 설계에서 강조하는 것도 일맥상통
108. 결론이 난 개념과 구조는 허탈할 정도로 간단
그럼에도 개념을 정제하고 게임 디자이너와 동기화하는데 어려움을 겪음
아니 게임 디자이너가 문제가 아니라 프로그래머들끼리도 힘들었음;;;
Feature : IFeature 컴퍼넌트 레이어 지속 효과들
FunctionA :
IFeatureFunction
IFeatureContract ActionComponent
RequestA() Use() Flag
ReplyA() = 0 Do() StatusComponent
Flag
RequestB() FunctionB AbnormalCondition
Component
Use() Flag
ReplyB() = 0
ActionLockComponent
Do()
109. 우리 스스로 무엇을 만들고 있는지 정확히 모르고 있기 때문?
합의된 모델을 구현하는 게 아니라 프로그래머가 원하는 대로 구현하는 게 보통
디자인과 불일치하는 구현체에 대해서 게임 디자이너가 통제를 할 방법이 없는 게 당연
게임 로직의 모델을 정식화하고 공유하는 노력이 필요
게임 디자인에 있어서도 팀 전체의 인지적인 한계가 똑같이 문제가 됨
게임 디자이너는 올바른 모델을 제시하기 위해 프로그래밍을 알아야 한다.
반대로, 프로그래머도 게임 디자이너의 모델을 성실하게 구현해야 한다.
110. 목표는 게임 로직 코드를 재활용하는 것이었으나…
로직이 프리젠테이션에 암묵적 의존 관계를 형성하지 않을 수가 없다
그리고 프리젠테이션 의존성은 게임 로직 재활용에 가장 큰 걸림돌
하지만 프리젠테이션을 개선하지 않는다면 게임을 다시 만드는 의미가 없다!
꼭 그런 건 아니지만 많은 경우 그렇다
111. 게임 디자인 도메인에서 개념의 재활용을 목표로
재활용 가능한 개념을 증류하려는 노력이 유효하다고 판단
112. 원칙을 준수하는 설계의 추후 수익률은 높지 않을 전망
→ 큰 문제는 해결, 완벽한 설계보다는 인지친화적인 설계가 더욱 중요
게임 디자인을 정확하게 반영하는 설계의 중요성
→ 정확한 설계
많은 이터레이션과 게임의 성공 가능성 문제가 부각
→ 기민한 설계
113. '인지 친화적이고 / 정확하며 / 기민한 설계에의 도전'
……중언부언이라 결국 파트 3에서도 '완벽한'이라고 줄여서 쓸 거 같긴 함
해당 이미지는 DSP 엔터테인먼트의 자산입니다
114. R e f e r e n c e s
에릭 에반스, 2003“도메인 주도 설계”
김주복, NDC2010“M2 아키텍처 리뷰: 완벽한 MMO 클라이언트 설계에의 도전”
이무림, NDC2011“고양이가 개발한다”
김주복, 2011“GDC2011 동향보고”
김주복, 2011“엔지니어링 리부트 OT”
김주복, 2011“엔지니어링 리부트: 복합액션 도입 계획”
김주복, 2011“엔지니어링 리부트: 스테이터스란 무엇인가”
김주복, 2011“엔지니어링 리부트: 메시지 라우팅 방식 변경”
김주복, 2011“엔지니어링 리부트: 탈출 처리 도입과 이후 진행”
Special thanks to“카라 and DSP 미디어”