SlideShare una empresa de Scribd logo
1 de 86
Descargar para leer sin conexión
Rev. 2
IGC2017 발표: 2017년 8월 31일
최종 자료 수정: 2017년 8월 31일
https://itunes.apple.com/kr/app/id1124788464?mt=8 https://play.google.com/store/apps/details?id=com.NextFloor.phdiver
넥스트플로어 지하연구소의 모바일 리듬게임
2017년 4월 19일 Google Play 및 iOS AppStore 출시
이하, P:h Diver로 표기
• iOS & Android 동시 지원
• 대부분의 코드는 C++ 기반
• 양 플랫폼 간 공유되는 코드
• OpenGL ES 2.0, OpenAL 등을 이용
• Low-Level 라이브러리리 위에 작성됨
NEW GAME! Vol. 4 - 芳文社
즉, 자체 개발 엔진 사용
이런 게임을…
기술적인 부분에서 개발 포스트모템!
하는 것이 이번 발표의 내용
• 엔진 개발 여부를 결정할 때, 참고할 수 있는 경험
• P:h Diver는 어떤 상황에서, 왜 엔진 레벨부터의 개발을 결정했는가?
• 어떤 과정을 거쳐 개발이 이루어지게 되며, 비용은 어느 정도인지
• 저수준의 모바일 게임 개발 노하우
• 모바일 플랫폼에서의 호환성 있는 엔진 구조 설계
• P:h Diver에서 엔진에서 제공하는 저수준 기능들을 개발한 방식
• 저수준 기능 개발에 있어 참고할 만한 점 = 삽질 간접경험
이번 발표에선 특히 이쪽에 조금 더 포커싱
저수준부터의 모바일 게임 개발에 관심이 있는 분
• 게임 프로그래머
모바일 게임 프로젝트 초기,
기술 스택에 대한 의사결정을 하게 될 분
• 클라이언트 리드 프로그래머 혹은 테크니컬 디렉터
난이도는 초~중급 정도
기초적인, 어떻게 보면 당연한 기술적 내용을 포함
그러나, 실제 삽질경험의 전달이 주된 목적
현재, 넥스트플로어 지하연구소 미공개 신작 디렉터
<Protocol:hyperspace Diver> 디렉터, 프로그래머
<데스티니 차일드> 프로그래머
<마비노기 2: 아레나> 프로그래머
<MapleStory Village> 프로그래머
<MapleStory Adventures> 프로그래머
김영수
넥스트플로어 지하연구소
게임 프로그래머 7년차
디렉터 2년차
01
02
03
04
https://youtu.be/CX6YHf1iKPg
Protocol:hyperspace Diver 게임 플레이 영상
• 3차원 공간 상에 선과 노트가 존재하고,
• 음악의 플레이를 따라 공간을 진행하며
• 터치를 통해 2차원 스크린 상의 노트를 처리하는 게임
• 3D 그래픽 출력/연출이 가능
• 터치 입력을 처리 가능
• 사운드 출력이 가능
• 3차원 공간 상에 선과 노트가 존재하고,
• 음악의 플레이를 따라 공간을 진행하며
• 터치를 통해 2차원 스크린 상의 노트를 처리하는 게임
• 프레임 드랍으로 인한 입력 누락이 없어야 한다
• Unity 기반 리듬게임에서 종종 보이는 문제점
• 프레임 드랍이 없으면 좋지만
• 최소한 큐잉된 입력 처리는 되어야 한다
• 사운드 latency는 낮을 수록 좋다
• 터치음은 터치 디바이스에서 줄 수 있는 강력한 피드백
유저의 게임 경험에 가장 크게 영향을 미치는 부분
• UI가 뛰어난 반응성과 조작 경험을 가지게 하고 싶음
• 멀티터치 환경에서 터치 등의 조작에 적절하게 반응해야 함
• UI에서 쫀득한 조작함을 느낄 수 있게 커스터마이즈 하고 싶음
• 예: iOS의 rubber band scrolling
• 네이티브 해상도 / Responsive Design 지원
• 스마트폰/태블릿을 동시에 지향하는 게임으로선 필수적인 부분
기존에 존재하던 모바일 게임 엔진들의 사용을 고려
Unity Moderato cocos2d-x
• 무겁고 크고 느리다
• 특히 GC에 의한 랙은 실시간성을 요구하는 게임에서 치명적
• 게다가 멀티스레드도 미지원
• UI 도구들이 미묘
• NGUI, UGUI 등등이 있긴 하지만, 크게 좋은 평은 아님
• 최근에 듣기에도 썩 좋은 UI 프레임워크는 아니란 이야기가
• 개인적으로 선호하지 않는 개발 스타일
• FPS/TPS 등의 게임에 맞춰진 엔진 설계
• NextFloor에서 사용하는 인하우스 엔진
• 드래곤 플라이트, 데스티니 차일드 등에서 사용되어 검증
• C++ native 코드가 기반 / Lua로 로직을 올려 연동
• 약간의 애니메이션과 상호작용 지원이 있는 UI 시스템
• 조금은 올드한 엔진
• 구 문법의 C++을 사용하고, 기본적으로 싱글스레드 기반
• OpenGL ES 1.1을 사용 – 쉐이더 이용이 어려움
• Lua로 로직을 짜는 구조에 최적화된 부분이 많음
• 한창 발전하고 있던 엔진
• 빠른 C++11 지원과 함께 3D 지원도 꽤 빠른 속도로 구현되고 있었음(2015년)
• 오픈소스/C++이라, 어쨌든 문제가 생기면 손댈 수 있긴 함
• Native C++ 기반이라 괜찮은 속도를 보여줌
• 엔진 구조도 꽤 단순하면서 개인 취향에 맞는 처리 흐름
• 신뢰성에 약간의 문제가 있었음
• 라이브러리에 다소 만족스럽지 못한 부분이 있었음
• 역시 괜찮은 UI/UX 프레임워크가 부재
• 사운드 라이브가 생각하던 것 만큼 강력하지 않았음
• 프로그래머 및 기술 인력은 1인
• 자체 엔진 사용 프로젝트 종사 경험
• 시작부터 만들진 않았지만 꽤 깊은 곳까지 건드리며 다뤄본 경험
• 비슷한 모바일 프로젝트 경험이 있음
• 데스티니 차일드와 MapleStory Village
• 엔진 구성 및 기술적 노하우를 참고 가능
• 일어날 수 있는 문제도 어느 정도 파악
오마이뉴스
http://m.ohmynews.com/NWS_Web/Mobile/at_pg.aspx?CNTN_CD=A0001516557&CMPT_CD=TAG_M#cb
Unity Moderato Cocos2d-x 자체개발
성능 낮음 보통 높음 높음
제공하는 기능 보통 보통 보통
없음 →
원하는 모든 기능
개발 비용 보통 보통 보통 보통
개발 편의성 낮음 보통 높음 높음
두 가지 선택지 사이에서 많은 갈등
결론은 자체 엔진 개발
비용-효용적인 측면에선 Cocos2d-x와 자체개발이 비슷할 것 같았으나
기술을 끝까지 이해하고, 원하는 방향으로 커스텀 할 수 있을 것 같아 선택
• 개발팀의 인력 구성이 큰 영향을 미쳤음
• 기술 인력이 1명: 의사소통 비용이 거의 0
• ‘전원’이 자체 엔진 사용 프로젝트의 개발 경험이 있게 됨
• 작업 분배에 따른 병목 등도 존재하지 않음
• 조직적인 면에서도 결정해서-실행하면 되는 상황
• 혼자서 엔진부터 개발하며 앞뒤 보지않고 달릴 수 있었던
이성이 증발해서 엔진 개발도
두렵지 않아!
TVアニメ「Fate/Apocrypha」公式サイト
http://fate-apocrypha.com
• iOS & Android 동시 지원
• 스마트폰&태블릿 지원
• 수많은 제조사
• 수많은 제품군
• 수많은 해상도…
• 프로그래머 1인이 대응?
넘을 수 없는 추상화의 벽
게임 로직 구현
플랫폼 로직
Platform별 구동 로직을 밑에 깔고,
그 위에서 플랫폼 중립적인 게임을 만들자!
DIP:
one should “depend upon
abstractions, [not] concretions.”
Robert C. Martin (“Uncle Bob”) (2000),
Design Principles and Design Patterns
• 각 플랫폼에서 지원하는 언어는…
• 양쪽에서 쓸 수 있는 건 C++ 뿐!
• 다행히 C++11/14 등 최신 표준은 발빠르게 지원
Ojbective-C
Swift
Java
iOS Android
++
C++
C++ via NDK
• 엔진이 표준 C++을 이용하므로 라이브러리가 호환
• C/C++이 호환되는 다양한 라이브러리 사용
• 표준 라이브러리와 STL도 다양한 곳에서 사용
• 플랫폼 제공 POSIX 라이브러리도 이용 가능
• iOS/Android에서 호환
• 전부는 아니지만 상당 부분
• 플랫폼 그래픽 라이브러리로는 OpenGL을 사용
• OpenGL ES 2.0을 사용
• iOS 및 Android에서 기본적으로 지원
• 플랫폼 사운드 라이브러리로는 OpenAL을 사용
• iOS의 경우에는 바로 지원
• Android의 경우에는 사용할 수 있는 포팅이 있다.
• iOS/Android 모두 IDE를 호환
• 런타임 디버깅이 가능한 환경을 구축
• 생산성에 큰 영향을 미치므로 반드시 체크해야 할 요소
XCode
iOS
NSight Tegra w/ Visual Studio
Android
• GLKView 이용
GLKViewController
Obj-C++
GLKView
AppDelegate
Obj-C++
Game
C++
Delegate Events
Call via C++
Frame Update,
Graphic Prepare, … App Pause, Background, …
• JNI를 이용해 Java 플랫폼 코드와 C++ 게임 코드 통신
GLSurfaceView.Renderer
Java
GLSurfaceView
FragmentActivity
Java
Game
C API in C++
Call via JNI
Frame Update,
Graphic Prepare, …
App Pause,
Background, …
Logic Side
Platform Library Calls
Activity owns
GLSurfaceView
• Windows PC에 대해서도 호환 플랫폼을 구현
• 개발 중 가장 빠른 이터레이션이 가능한 플랫폼
• 디버깅 등도 매우 용이
• 해 두면 정말 좋습니다!
• OpenGL ES를 이용
• EGL 등을 통해 호환 가능
• 모바일이 1st class 플랫폼이므로 최대한 동일하게
• 호환성을 확보한 후 C++/OpenGL로 원하는 대로 구현
• 로직 코드로 C++11을 이용
넘을 수 없는 추상화의 벽
게임 로직 구현
플랫폼 로직
OpenGL
최대한 얇은 레어어로 추상화
Portability를 중심으로
GAME
Platform
iOS
Android
WindowsPC
Application Graphic File System Input …
Graphic Resource
Manager
OpenGL
ES
• 공용 플랫폼 로직 위에 기능별 인터페이스 구현
• 각 부분기능은 모듈로 격리
• 엔진의 기능들은 모듈들의 조합으로 구성
• 모듈 간의 의존성은 레이어링을 통해 단방향으로 정리
• 게임 로직은 추상화된 모듈에만 의존
• 게임 코드 레이어에 게임 객체의 생성을 위임
• 엔진에는 생성 함수의 인터페이스만 존재
• 게임에서 이용할 기능에 맞게 게임 엔진을 구성
엔
진
모
듈
플
랫
폼
구
현엔
진
기
반
구
조
게임 구현
실제 프로젝트 구성
외부 라이브러리
외부 라이브러리
빌
드
여기까진 쉽죠? 헉, 이건 어떻게 하지?
일단 그림 파일을 읽을 수 있어야 하고(File IO)
png 포맷 파일을 디코딩 할 수 있어야 하고,
OpenGL 텍스처에 올려서…
• PNG Only!
• 투명도, 32비트 색상, 기타 압축 등 게임에 필요한 기능은 거의 갖춤
• JPEG도 리서치 해 봤는데, 퀄리티가 높으면 용량 차이가 별로 안 남
• 텍스처 생성을 추상화 해 두면, 디코더만 붙이면 되니 필요할 때 붙이면 됨
• 어떻게 로드할까? : 단순무식!
• libpng로 디코드해서
• 빌드할 때 neon 설정 같은거 잘 해 주면 조금 더 빨라짐
• 비트맵으로 메모리에 뽑은 다음, OpenGL ES 텍스처에 업로드
• 텍스처가 날아가는 경우가 있음
• 앱이 Background로 가거나 OS가 필요하다고 생각하는 경우
• Android의 경우, setPreserveEGLContextOnPause를 설정해서 막을 수 있음
• 대처 방법은? : 체크하고 복구
• 앱이 Background에서 돌아올 때, 기존 텍스처를 체크할 필요 있음
• glIsTexture 함수를 이용해서 텍스처가 날아갔는지 여부를 검사
• 날아간 텍스처를 복구하기 위해서는 적절한 메커니즘 구현 필요
• P:h Diver에서는 관리되는 텍스처 생성 시에 복구 함수를 함께 전달
• Shared Context를 이용해서 GL Context 간 데이터 공유 가능
• 하나의 context는 하나의 thread에만 대응
• 다른 thread에서 새 context를 생성하며 share_context에 context를
넘겨 context 간 데이터(텍스처, 버퍼 등)를 공유하게 할 수 있다.
• 비동기 텍스처 로딩 등이 가능!
• 동기화에는 주의
• 특히 비표준적인 동작에 주의!
• 여러 스프라이트를 하나의 이미지에 모은 것
• 저장 공간의 효율적 사용 및 성능 향상 등이 목적
• Draw Call을 줄일 수 있음. GL에선 텍스처가 상태라;;
• 정적 Texture Atlas
• 아티스트와의 협업 과정에서 많이 사용
• 툴의 출력을 읽어 사용할 수 있게
구현하는 걸 추천
• TexturePackerhttps://www.codeandweb.com/texturepacker
• 런타임에도 텍스처 아틀라스를 구성할 수 있음
• glTexSubImage2D를 이용해 텍스처 부분 업로드 가능
• 텍스트 랜더링 등에서 사용됨
• 라이트맵 등 Pre-baked texture가 사용되는 경우에도 자주 사용
• 텍스처 복구 매커니즘에 주의
• 동적으로 구성했던 텍스처도 날아갈 수 있다는 사실을 명심!
• 부분 텍스처를 받을 때도, 복구 함수를 함께 받아 저장한다거나
• 데이터를 어딘가 백업해 둔다거나
• Invalidate 여부를 따로 체크하고, 데이터를 재구성 할 수 있게 구현한다거나
• 이미지들을 주면 영역을 확보해 아틀라스를 구성해야 함
• 2차원 냅색 문제
• 해당 주제로 Ph.D. 학위 논문까지 있을 정도
• Lodi, A. (1999). Algorithms for two-dimensional bin packing and assignment problems. Doktorarbeit, DEIS, Universita di Bologna, 16.
• …지만, 글로벌 최적해 찾지 않고 적당히 greedy로 푸는 방법은 꽤 존재
• 개인적으론 blackpawn에서 소개된 방법을 변형하여 이용
• 공간을 binary tree로 관리
• http://blackpawn.com/texts/lightmaps/
• RTT - Render Target Texture
• GL이 랜더링하는 타깃(Framebuffer)를 텍스처로 설정
• glFramebufferTexture2D
• Frame Buffer → Texture Copy
• 프레임 버퍼의 내용을 텍스처로 카피 가능
• glCopyTexSubImage2D
• 스크린 효과 등, 여러 랜더링 효과를 이용할 수 있음
• 게임에 들어간 blur 효과가 이걸 이용
프로그래밍의 기본 하면 역시 Hello, World!
그런데, 모바일 게임에서는 어떻게...?
#include <iostream>
int main()
{
std::cout<<"Hello, World!"<<std::endl;
return 0;
}
• OpenGL 화면에 텍스트를 그려야 한다!
• 텍스트를 텍스처로 만든 다음, 텍스처를 그리는 방식 채택
• 문자열에 대해 한 자 씩 글자 텍스처를 얻어내 그릴 수 있음
• 텍스트 이미지를 얻기 위해서는 폰트를 사용
• 각 문자를 어떻게 그릴지에 대한 정보를 담고 있는 것이 폰트
• 일반적으로 우리가 사용하는 TrueType 등의 폰트는 벡터 방식
• 사용자 화면 크기에 상관없이 깨끗한 폰트를 얻을 수 있다
• 오픈소스 폰트 랜더링 라이브러리
• 레퍼런스가 많고 적당히 쓰기 편한 라이브러리
• FreeType으로 글씨의 이미지를 얻어낼 수 있다
• 폰트 정보에서 개개 글씨의 비트맵 이미지를 얻는 기능 지원
• 기타 지원 기능
• 힌팅, 커닝, 외곽선 추출 등을 지원
• GSUB 미지원: 태국어 등의 언어 지원 시 주의할 것
• FreeType을 통해 문자 이미지 텍스처 생성
• 문자를 이미지로 변경한 다음, 텍스처 아틀라스에 구워둠
• FreeType은 설정과 함께 문자를 주면 비트맵 이미지를 반환
• 이 이미지를 텍스처 아틀라스에 올려 쓰면 되는 것
• 폰트의 종류에 따라서 서로 다른 글자의 모양을 가짐
• 아트 직군에서 결정하는 것이 바람직
• 라이선스나 용량 등을 고려하여 선택한다
• 구글/어도비의 Noto(본) 계열 폰트를 추천
• 여러 언어에 대해 무난한 수준의 글리프를 제공
• 대부분의 문자는 커버된다
• 커닝: 내용에 따라 문자 간의 간격을 조정하는 것
• FreeType에서 지원하므로, 가능하면 구현을 추천
No Kerning, Times New Roman
Kerning Applied, Times New Roman
• 텍스트 블록 구성: 여러 줄 텍스트의 경우
• 자동 줄바꿈 기능은 지원되어야 한다.
• 가능하다면 개행 관련 처리도 해줄 수 있으면 좋다
• 알파벳 문자권 언어의 경우, 단어 중간 개행 시 하이픈 삽입
• CJK의 경우 단어 단위 개행 Hint를 고려
• P:h Diver에서는 개행 처리 미구현
• 텍스트 블록 구성
• 정렬 방식을 잘 선택해야 예쁘다: 특히 배분정렬을 고려
배분정렬 왼쪽정렬
• 한 문장 내에서 다국어 텍스트를 섞어 조판할 때는
• 문자 종류별 Baseline과 크기 세팅이 가능하도록 해야!
• Adobe InDesign과 같은 조판 소프트웨어에는 있는 기능
vs.
동일 크기, baseline 조절 없음
크기와 baseline 조절
• 텍스트 그림자
• 그림자 먼저 찍고, 위에 텍스트 한 번 더 찍으면 된다!
• 텍스트 외곽선
• FreeType의 Stroker를 이용
• Stroke가 된 glyph 비트맵 이미지를 얻을 수 있음
• 허용하지 않는 라이선스의 폰트도 있으므로 주의!!
• UI는 시스템화 시켜서 사용하는 것이 좋다
• 공통적인 동작과 상호작용 로직을 가지는 부분이 많음
• 쓸 만한 기존 라이브러리가 존재하지 않음
• OpenGL 게임과 연동해 쓸 만한 추상적 UI 라이브러리 X
• 입출력~랜더링까지를 직접 처리하는 라이브러리가 대부분
• 만족스러운 경험을 주는 라이브러리는 더 적고…
• 결국 우리가 바퀴를 다시 만들어야
• 터치 이벤트 처리 방식 확립
• UI의 가장 중요한 임무 중 하나는 사용자의 입력에 반응하는 것
• 터치는 모바일 터치 디바이스에서의 가장 중요한 입력
• WPF의 체이닝/버블링이 참고할 만한 사례
MSDN - 라우트된 이벤트 개요
https://msdn.microsoft.com/ko-kr/library/ms742806(v=vs.110).aspx
• 레이아웃 시스템
• 다중 스크린 지원 시 반드시 고민해서 설계해야 하는 부분
• P:h Diver에서는 부모-자식 상대 위치 관계를 기준으로 구현
• 그리드 시스템은 별도로 사용하지 않음
• Stackable 등의 자동 레이아웃은 아직 미구현
0.5
0.5
0.2
0.1
(100, 40)
(-50, -40)
• 부모에 대해 정의된 Reference Point와
자식에 대해 정의된 Anchor Point가
매치되도록 위치를 결정
• 각각의 Point는
• 객체에 대한 비율로 나타내어지는 상대 위치에
절대값으로 나타내어지는 오프셋을 더해 지정
• 게임에 이용되는 UI 정의는 데이터화 하는 것이 좋음
• 빠른 이터레이션을 위해선 가능한 많은 부분을 데이터화 해야
• 특히, 아티스트 분들이 조금씩 손대며 개선할 필요성이 큰 부분
• 버튼 1px 옮기는데 다시 컴파일을 해야 한다면 으어어ㅓㅓㅓ
xkcd
https://xkcd.com/303/
• Mark Up Language 정도는 만들어서 사용하는 것을 추천
• Responsive가 지원되는 HTML의 사례를 참조
• UI는 마크업 언어로 기술하는 방식이 꽤나 잘 맞는 도메인
• 대부분의 화면 구성요소들은 tree 구조로 이해하기 쉬운 편
스크린
카테고리 메뉴 옵션 내용
닫기 버튼타이틀 게임 플레이 버튼
버튼 텍스트 아이콘
…
배경 이미지
• UI Description이라는 마크업 언어를 만들어 사용
• XML 기반
• 간단한 변수, 계산, 네임스페이스 탐색, Import 기능 구현
• UI 구성요소를 정의하는 Prefab
• Tree 구조로 UI 객체들을 정의
• 각각의 객체들은 Entity-Component 모델로, 컴퍼넌트를 조립 가능하게
• 자주 쓰이는 타입의 UI 객체는 사전에 클래스로 정의되어 바로 사용
• Prefab 중첩 가능
• 코드에서 이름을 통해 변수, Prefab 등을 얻어낼 수 있음
• Prefab의 경우 코드에서 실제 UI 객체로 할당 가능
기본 구조 및 변수, 수식 정의
텍스처 정의
폰트 정의
종합 예시
• 게임 데이터 문자열로는 UTF-8 인코딩의 사용을 추천
• 여러 플랫폼 상호운용성이 뛰어나고, 큰 고민 없이 다국어 지원 가능
• 성능 문제는 보통은 신경 쓰지 않아도 될 수준
• 플랫폼 상호 변환도 간편한 편
• Android의 jstring이나 iOS의 NSString도 UTF-8 문자열에서의 변환이 용이
• Windows에서는 UTF-16으로 변환해야 하는 경우가 종종 있다.
• 유저에게 출력되는 문자열은 테이블 – 키 구조로 관리
• 코드에 하드코딩 되는 문자열이 없어야 한다
• 번들 리소스의 이해
• iOS의 번들은 파일
• Android의 번들은 압축된 어떤 데이터
• std::stream 등을 이용해 일관된 인터페이스를 제공할 수 있도록
구현해 두면 편하다
• 빌드 시, 번들 리소스는 파일 시스템 상 하나의 폴더에서
연동되게 하는게 편하다
• iOS의 경우 번들로 패킹
• Android의 경우 Asset 디렉터리
• 저장소 클래스의 구분 사용
• 내부/외부 저장소, 임시/영구적 저장소, 클라우드 백업 여부
등, 특성에 따라 분류해 사용하면
• 플랫폼 독립적인 추상화가 가능
P:h Diver의 파일 시스템 엔진 컴퍼넌트 정의
• 멀티 스레드를 활용할 수 있는 추상화된 상위 구조 설계
• 로직 프로그래밍 단계에서 스레드 하나하나를 만들어 관리하고 이용하는 건
어렵고 번거로움
• 좀 더 추상적인 레벨에서 병렬 처리를 가능하게 하는게 좋음
• 다른 언어의 코루틴, .NET의 Task Parallel Library 등이 이런 관점의 산물
• P:h Diver에서는 태스크 시스템을 구현해 이용
• 추상화된 작업 단위인 ‘태스크’를 중심으로 작업을 수행
• 람다 함수 등으로 태스크를 만들어 던지면 알아서 수행해 줌
• 그래픽, 네트워크 등 작업 특성에 따라 스레드 풀을 구성
• 작업의 상태는 객체화 된 태스크를 통해 확인 가능하게 설계
• iOS의 경우 GCD를 래핑하는 방식으로 구현하는게 안정적이고 편할 수 있음
• 공용 로그 함수부터 만들자!
• 로그는 디버깅의 기본
• 하나의 함수로 NSLog와 안드로이드 Log 등으로 출력되게 하는게 좋다
• Windows의 경우 OutputDebugString 함수의 이용을 고려
• 유틸리티 라이브러리 이용
• C/C++이므로 많은 라이브러리와 호환성을 가짐
• String Format, sqlite, JSON/XML 파서 등을 연동시켜 두면 편하다
• 큐브 띄우기까지 1달 반
• 물론 iOS/Android 호환!
• 어플리케이션 빌드
• 엔진 구조 작성
• 그래픽 기능 구현
• 기본 쉐이더 포함
Primitive 프로토타입 임시 리소스 적용 핵심 빌드
여기까지 2달 반 여기까지 3달 반
• UI 및 정식 비주얼 구현까지 5달
• 게임 플레이가 가능하도록 UI 시스템을 구현
• AD님 합류로 게임 비주얼을 전면적으로 개선
• 클라이언트 기능 완성까지
7달 반
• 신 UI 시스템 구축
• UI Description 기반
• 비동기 및 네트워크 기능
• 게임플레이 로직 플로우
이후, 타 부서 협업을 통한 서버 및 인프라 세팅,
로컬라이제이션, 스토어 및 결제 최적화, QA 등의
출시 준비 작업 수행
LocMetrics
http://locmetrics.com/
LocMetrics이란 툴을 사용해 LoC 측정
LoC(Lines of Code)가 절대적인 정보는 아니지만,
어느 정도 프로젝트 규모에 대한 감을 전달하기에는 좋은 자료
• 엔진: 33,673
▪ 공용: 6,751
▪ 플랫폼: 9,661
▪ 모듈 구현: 17,261
충분한 완성도로 정리하지 않아
게임 레이어에 격리시켜 둔
엔진성 코드
• 게임: 138,230
▪ 사운드 시스템: 4,516
▪ UI 시스템: 37,950
▪ 태스크 시스템: 1,634
▪ 네트워크: 1,959
• 엔진성 코드: 총 79,732 Lines
➢프로젝트 코드: 총 171,903 Lines
• 프로그래머(디렉터 겸업) 인력의 맨먼스는 14 정도로 표기
• 런칭 준비를 위한 엔지니어링 코스트 포함
• 메인 프로그래머 1인 중심의 작업
• 지원 조직 및 차기 프로젝트 프로그래머로부터 플랫폼 특화 구현
관련 기술 지원을 받음
• 실질적으로는 프로그래머 1명, 10 맨먼스 정도
• 엔진 및 게임 로직, 서버 등을 포함한 개발 전반의 비용
• 게임을 개발하여 출시
• 어쨌든 완성은 했습니다.
• 초기 안드로이드 등 성능 이슈가 있었음
• 5월 말 1.2 패치로 최적화 옵션 추가
• 특이한 이상이 가끔 보고되나, 전반적으로는 안정적
• 텍스처 초기화 오류가 굉장히 가끔 보고됨
• 크래시에 대한 보고는 특별히 많지 않음
• 기술적인 요구사항을 원하는 수준까지 맞출 수 있음
• 새로운 플랫폼 기술도 즉시 적용 가능
• 자신/팀에게 맞는 개발 환경을 선택 가능
• IDE나 기술 스택을 필요에 맞춰 고를 수 있음
• 구조 및 개념 설계 등을 최적화할 수 있음
• 생각보다 구현 비용이 크지는 않음
• 파편화된 기기 최적화가 어려움
• 특히 통제가 약한 Android 환경에서, 최종 사용자에 맞춰 최적화가 힘듦
• 각 개발 도메인의 기술을 파고드는 최적화는 어려움
• 안되는 건 아닌데, 그만큼의 시간을 추가로 할당해야 함
• 개발 병목이 될 수 있음
• 게임 구현에 필요한 기능이 늦은 시점에 나오게 될 위험 존재
• 엔진 개발자는 컨텍스트 체인지 비용이 크다
• 팀 환경에 따라 툴이나 (타 직군)개발 환경의 부재가 아쉬울 수도
특별한 결론은 없습니다.
P:h Diver의 사례를 기술적인 관점에서 리뷰하였고
어디까지나 정답이 아닌 ‘참고 사례’로써 받아들여 주셨으면
ガールズ&パンツァー 劇場版
Actas Inc.
[IGC2017] Protocol:hyperspace Diver 개발 포스트모템

Más contenido relacionado

La actualidad más candente

06_게임엔진구성
06_게임엔진구성06_게임엔진구성
06_게임엔진구성
noerror
 
게임 프레임워크의 아키텍쳐와 디자인 패턴
게임 프레임워크의 아키텍쳐와 디자인 패턴게임 프레임워크의 아키텍쳐와 디자인 패턴
게임 프레임워크의 아키텍쳐와 디자인 패턴
MinGeun Park
 
이승재, M2 AI코드 개발 생산성 향상 사례, NDC2013
이승재, M2 AI코드 개발 생산성 향상 사례, NDC2013이승재, M2 AI코드 개발 생산성 향상 사례, NDC2013
이승재, M2 AI코드 개발 생산성 향상 사례, NDC2013
devCAT Studio, NEXON
 
이승재, 강성훈, 내가 만든 언어의 개발환경을 Visual Studio Code로 빠르고 쉽게 구축하기 #1, NDC2017
이승재, 강성훈, 내가 만든 언어의 개발환경을 Visual Studio Code로 빠르고 쉽게 구축하기 #1, NDC2017이승재, 강성훈, 내가 만든 언어의 개발환경을 Visual Studio Code로 빠르고 쉽게 구축하기 #1, NDC2017
이승재, 강성훈, 내가 만든 언어의 개발환경을 Visual Studio Code로 빠르고 쉽게 구축하기 #1, NDC2017
devCAT Studio, NEXON
 
이승재, 실버바인 서버엔진 2 설계 리뷰, NDC2018
이승재, 실버바인 서버엔진 2 설계 리뷰, NDC2018이승재, 실버바인 서버엔진 2 설계 리뷰, NDC2018
이승재, 실버바인 서버엔진 2 설계 리뷰, NDC2018
devCAT Studio, NEXON
 
조정훈, 게임 프로그래머를 위한 클래스 설계, NDC2012
조정훈, 게임 프로그래머를 위한 클래스 설계, NDC2012조정훈, 게임 프로그래머를 위한 클래스 설계, NDC2012
조정훈, 게임 프로그래머를 위한 클래스 설계, NDC2012
devCAT Studio, NEXON
 

La actualidad más candente (20)

엔진, 툴, 그리고 스크립트
엔진, 툴, 그리고 스크립트엔진, 툴, 그리고 스크립트
엔진, 툴, 그리고 스크립트
 
Shader compilation
Shader compilationShader compilation
Shader compilation
 
[IGC 2017] 오토데스크 박준석 - 3ds Max 2018과 Shotgun을 이용한 게임 제작 Pipeline 소개
[IGC 2017] 오토데스크 박준석 - 3ds Max 2018과 Shotgun을 이용한 게임 제작 Pipeline 소개[IGC 2017] 오토데스크 박준석 - 3ds Max 2018과 Shotgun을 이용한 게임 제작 Pipeline 소개
[IGC 2017] 오토데스크 박준석 - 3ds Max 2018과 Shotgun을 이용한 게임 제작 Pipeline 소개
 
내 손에 픽셀을 쥐어다오
내 손에 픽셀을 쥐어다오내 손에 픽셀을 쥐어다오
내 손에 픽셀을 쥐어다오
 
[PandoraCube] '게임메이커'에 대해 알아보자
[PandoraCube] '게임메이커'에 대해 알아보자[PandoraCube] '게임메이커'에 대해 알아보자
[PandoraCube] '게임메이커'에 대해 알아보자
 
NDC 2017 마이크로토크 - Spacemacs: 최고의 에디터는 Emacs도 Vim도 아니다. Emacs와 Vim이다!
NDC 2017 마이크로토크 - Spacemacs: 최고의 에디터는 Emacs도 Vim도 아니다. Emacs와 Vim이다!NDC 2017 마이크로토크 - Spacemacs: 최고의 에디터는 Emacs도 Vim도 아니다. Emacs와 Vim이다!
NDC 2017 마이크로토크 - Spacemacs: 최고의 에디터는 Emacs도 Vim도 아니다. Emacs와 Vim이다!
 
06_게임엔진구성
06_게임엔진구성06_게임엔진구성
06_게임엔진구성
 
게임 프레임워크의 아키텍쳐와 디자인 패턴
게임 프레임워크의 아키텍쳐와 디자인 패턴게임 프레임워크의 아키텍쳐와 디자인 패턴
게임 프레임워크의 아키텍쳐와 디자인 패턴
 
Unite 2015 Seoul : 인디에게 어디가 한계인지는 해봐야 알잖아?
Unite 2015 Seoul : 인디에게 어디가 한계인지는 해봐야 알잖아?Unite 2015 Seoul : 인디에게 어디가 한계인지는 해봐야 알잖아?
Unite 2015 Seoul : 인디에게 어디가 한계인지는 해봐야 알잖아?
 
Ndc2010 김주복, v3. 마비노기2아키텍처리뷰
Ndc2010   김주복, v3. 마비노기2아키텍처리뷰Ndc2010   김주복, v3. 마비노기2아키텍처리뷰
Ndc2010 김주복, v3. 마비노기2아키텍처리뷰
 
이승재, M2 AI코드 개발 생산성 향상 사례, NDC2013
이승재, M2 AI코드 개발 생산성 향상 사례, NDC2013이승재, M2 AI코드 개발 생산성 향상 사례, NDC2013
이승재, M2 AI코드 개발 생산성 향상 사례, NDC2013
 
DirectX + C++을 이용한 WindowsStore App과 Windows Phone용 게임 개발
DirectX + C++을 이용한  WindowsStore App과 Windows Phone용 게임 개발DirectX + C++을 이용한  WindowsStore App과 Windows Phone용 게임 개발
DirectX + C++을 이용한 WindowsStore App과 Windows Phone용 게임 개발
 
[IGC 2016] 유니티코리아 오지현 - “뭣이 중헌디? 성능 프로파일링도 모름서”: 유니티 성능 프로파일링 가이드
[IGC 2016] 유니티코리아 오지현 - “뭣이 중헌디? 성능 프로파일링도 모름서”: 유니티 성능 프로파일링 가이드[IGC 2016] 유니티코리아 오지현 - “뭣이 중헌디? 성능 프로파일링도 모름서”: 유니티 성능 프로파일링 가이드
[IGC 2016] 유니티코리아 오지현 - “뭣이 중헌디? 성능 프로파일링도 모름서”: 유니티 성능 프로파일링 가이드
 
유니티로 해보는 게임 프로토타이핑
유니티로 해보는 게임 프로토타이핑유니티로 해보는 게임 프로토타이핑
유니티로 해보는 게임 프로토타이핑
 
이승재, 강성훈, 내가 만든 언어의 개발환경을 Visual Studio Code로 빠르고 쉽게 구축하기 #1, NDC2017
이승재, 강성훈, 내가 만든 언어의 개발환경을 Visual Studio Code로 빠르고 쉽게 구축하기 #1, NDC2017이승재, 강성훈, 내가 만든 언어의 개발환경을 Visual Studio Code로 빠르고 쉽게 구축하기 #1, NDC2017
이승재, 강성훈, 내가 만든 언어의 개발환경을 Visual Studio Code로 빠르고 쉽게 구축하기 #1, NDC2017
 
이승재, 실버바인 서버엔진 2 설계 리뷰, NDC2018
이승재, 실버바인 서버엔진 2 설계 리뷰, NDC2018이승재, 실버바인 서버엔진 2 설계 리뷰, NDC2018
이승재, 실버바인 서버엔진 2 설계 리뷰, NDC2018
 
Wecanmakeengine
WecanmakeengineWecanmakeengine
Wecanmakeengine
 
[IGC 2016] Photon 운영사무국 - 실시간 게임의 빠른 개발을 위한 솔루션 「Photon」
[IGC 2016] Photon 운영사무국 - 실시간 게임의 빠른 개발을 위한 솔루션 「Photon」[IGC 2016] Photon 운영사무국 - 실시간 게임의 빠른 개발을 위한 솔루션 「Photon」
[IGC 2016] Photon 운영사무국 - 실시간 게임의 빠른 개발을 위한 솔루션 「Photon」
 
NDC2019 - 게임플레이 프로그래머의 역할
NDC2019 - 게임플레이 프로그래머의 역할NDC2019 - 게임플레이 프로그래머의 역할
NDC2019 - 게임플레이 프로그래머의 역할
 
조정훈, 게임 프로그래머를 위한 클래스 설계, NDC2012
조정훈, 게임 프로그래머를 위한 클래스 설계, NDC2012조정훈, 게임 프로그래머를 위한 클래스 설계, NDC2012
조정훈, 게임 프로그래머를 위한 클래스 설계, NDC2012
 

Similar a [IGC2017] Protocol:hyperspace Diver 개발 포스트모템

머신러닝 및 데이터 과학 연구자를 위한 python 기반 컨테이너 분산처리 플랫폼 설계 및 개발
머신러닝 및 데이터 과학 연구자를 위한 python 기반 컨테이너 분산처리 플랫폼 설계 및 개발머신러닝 및 데이터 과학 연구자를 위한 python 기반 컨테이너 분산처리 플랫폼 설계 및 개발
머신러닝 및 데이터 과학 연구자를 위한 python 기반 컨테이너 분산처리 플랫폼 설계 및 개발
Jeongkyu Shin
 
온라인 게임 처음부터 끝까지 동적언어로 만들기
온라인 게임 처음부터 끝까지 동적언어로 만들기온라인 게임 처음부터 끝까지 동적언어로 만들기
온라인 게임 처음부터 끝까지 동적언어로 만들기
Seungjae Lee
 
Javascript everywhere - Node.js | Devon 2012
Javascript everywhere - Node.js | Devon 2012Javascript everywhere - Node.js | Devon 2012
Javascript everywhere - Node.js | Devon 2012
Daum DNA
 
클로져 소개 강의 (한국정보통신산업노동조합)
클로져 소개 강의 (한국정보통신산업노동조합)클로져 소개 강의 (한국정보통신산업노동조합)
클로져 소개 강의 (한국정보통신산업노동조합)
Sang-Kyu Park
 

Similar a [IGC2017] Protocol:hyperspace Diver 개발 포스트모템 (20)

[KGC2014] 울프나이츠 엔진 프로그래밍 기록
[KGC2014] 울프나이츠 엔진 프로그래밍 기록 [KGC2014] 울프나이츠 엔진 프로그래밍 기록
[KGC2014] 울프나이츠 엔진 프로그래밍 기록
 
머신러닝 및 데이터 과학 연구자를 위한 python 기반 컨테이너 분산처리 플랫폼 설계 및 개발
머신러닝 및 데이터 과학 연구자를 위한 python 기반 컨테이너 분산처리 플랫폼 설계 및 개발머신러닝 및 데이터 과학 연구자를 위한 python 기반 컨테이너 분산처리 플랫폼 설계 및 개발
머신러닝 및 데이터 과학 연구자를 위한 python 기반 컨테이너 분산처리 플랫폼 설계 및 개발
 
[야생의 땅: 듀랑고] 지형 관리 완전 자동화 - 생생한 AWS와 Docker 체험기
[야생의 땅: 듀랑고] 지형 관리 완전 자동화 - 생생한 AWS와 Docker 체험기[야생의 땅: 듀랑고] 지형 관리 완전 자동화 - 생생한 AWS와 Docker 체험기
[야생의 땅: 듀랑고] 지형 관리 완전 자동화 - 생생한 AWS와 Docker 체험기
 
[DEVIEW 2016] 네이버의 모던 웹 라이브러리 - egjs
[DEVIEW 2016] 네이버의 모던 웹 라이브러리 - egjs[DEVIEW 2016] 네이버의 모던 웹 라이브러리 - egjs
[DEVIEW 2016] 네이버의 모던 웹 라이브러리 - egjs
 
온라인 게임 처음부터 끝까지 동적언어로 만들기
온라인 게임 처음부터 끝까지 동적언어로 만들기온라인 게임 처음부터 끝까지 동적언어로 만들기
온라인 게임 처음부터 끝까지 동적언어로 만들기
 
[DS Meetup] iPad로 가벼운 분석환경 구축해보기
[DS Meetup] iPad로 가벼운 분석환경 구축해보기[DS Meetup] iPad로 가벼운 분석환경 구축해보기
[DS Meetup] iPad로 가벼운 분석환경 구축해보기
 
HTML5/JSON 을 이용해 범용 2D 맵에디터 제작하기
HTML5/JSON 을 이용해 범용 2D 맵에디터 제작하기HTML5/JSON 을 이용해 범용 2D 맵에디터 제작하기
HTML5/JSON 을 이용해 범용 2D 맵에디터 제작하기
 
Ndc2013 정리(upload버전)
Ndc2013 정리(upload버전)Ndc2013 정리(upload버전)
Ndc2013 정리(upload버전)
 
아이폰에 포팅해보기
아이폰에 포팅해보기아이폰에 포팅해보기
아이폰에 포팅해보기
 
Javascript everywhere - Node.js | Devon 2012
Javascript everywhere - Node.js | Devon 2012Javascript everywhere - Node.js | Devon 2012
Javascript everywhere - Node.js | Devon 2012
 
Auto Scalable 한 Deep Learning Production 을 위한 AI Serving Infra 구성 및 AI DevOps...
Auto Scalable 한 Deep Learning Production 을 위한 AI Serving Infra 구성 및 AI DevOps...Auto Scalable 한 Deep Learning Production 을 위한 AI Serving Infra 구성 및 AI DevOps...
Auto Scalable 한 Deep Learning Production 을 위한 AI Serving Infra 구성 및 AI DevOps...
 
NDC17 장창완(최종)
NDC17 장창완(최종)NDC17 장창완(최종)
NDC17 장창완(최종)
 
격변하는 프로그래밍 언어, 이제는 Let it go
격변하는 프로그래밍 언어, 이제는 Let it go격변하는 프로그래밍 언어, 이제는 Let it go
격변하는 프로그래밍 언어, 이제는 Let it go
 
Gametech 2014: 모바일 게임용 PaaS/BaaS 구현 사례와 디자인 트레이드오프
Gametech 2014: 모바일 게임용 PaaS/BaaS 구현 사례와 디자인 트레이드오프Gametech 2014: 모바일 게임용 PaaS/BaaS 구현 사례와 디자인 트레이드오프
Gametech 2014: 모바일 게임용 PaaS/BaaS 구현 사례와 디자인 트레이드오프
 
클로져 소개 강의 (한국정보통신산업노동조합)
클로져 소개 강의 (한국정보통신산업노동조합)클로져 소개 강의 (한국정보통신산업노동조합)
클로져 소개 강의 (한국정보통신산업노동조합)
 
[Kgc2013] 모바일 엔진 개발기
[Kgc2013] 모바일 엔진 개발기[Kgc2013] 모바일 엔진 개발기
[Kgc2013] 모바일 엔진 개발기
 
Slack과 Rust로 Amazon ECS에서 서비스 배포하기
Slack과 Rust로 Amazon ECS에서 서비스 배포하기Slack과 Rust로 Amazon ECS에서 서비스 배포하기
Slack과 Rust로 Amazon ECS에서 서비스 배포하기
 
인프콘 2022 - Rust 크로스 플랫폼 프로그래밍
인프콘 2022 - Rust 크로스 플랫폼 프로그래밍인프콘 2022 - Rust 크로스 플랫폼 프로그래밍
인프콘 2022 - Rust 크로스 플랫폼 프로그래밍
 
엔지니어링비젼_언리얼엔진4_커스텀______________________
엔지니어링비젼_언리얼엔진4_커스텀______________________엔지니어링비젼_언리얼엔진4_커스텀______________________
엔지니어링비젼_언리얼엔진4_커스텀______________________
 
엔지니어링 비젼_동영상제거.pptx
엔지니어링 비젼_동영상제거.pptx엔지니어링 비젼_동영상제거.pptx
엔지니어링 비젼_동영상제거.pptx
 

[IGC2017] Protocol:hyperspace Diver 개발 포스트모템

  • 1. Rev. 2 IGC2017 발표: 2017년 8월 31일 최종 자료 수정: 2017년 8월 31일
  • 2. https://itunes.apple.com/kr/app/id1124788464?mt=8 https://play.google.com/store/apps/details?id=com.NextFloor.phdiver 넥스트플로어 지하연구소의 모바일 리듬게임 2017년 4월 19일 Google Play 및 iOS AppStore 출시 이하, P:h Diver로 표기
  • 3. • iOS & Android 동시 지원 • 대부분의 코드는 C++ 기반 • 양 플랫폼 간 공유되는 코드 • OpenGL ES 2.0, OpenAL 등을 이용 • Low-Level 라이브러리리 위에 작성됨
  • 4. NEW GAME! Vol. 4 - 芳文社 즉, 자체 개발 엔진 사용
  • 5. 이런 게임을… 기술적인 부분에서 개발 포스트모템! 하는 것이 이번 발표의 내용
  • 6. • 엔진 개발 여부를 결정할 때, 참고할 수 있는 경험 • P:h Diver는 어떤 상황에서, 왜 엔진 레벨부터의 개발을 결정했는가? • 어떤 과정을 거쳐 개발이 이루어지게 되며, 비용은 어느 정도인지 • 저수준의 모바일 게임 개발 노하우 • 모바일 플랫폼에서의 호환성 있는 엔진 구조 설계 • P:h Diver에서 엔진에서 제공하는 저수준 기능들을 개발한 방식 • 저수준 기능 개발에 있어 참고할 만한 점 = 삽질 간접경험 이번 발표에선 특히 이쪽에 조금 더 포커싱
  • 7. 저수준부터의 모바일 게임 개발에 관심이 있는 분 • 게임 프로그래머 모바일 게임 프로젝트 초기, 기술 스택에 대한 의사결정을 하게 될 분 • 클라이언트 리드 프로그래머 혹은 테크니컬 디렉터 난이도는 초~중급 정도 기초적인, 어떻게 보면 당연한 기술적 내용을 포함 그러나, 실제 삽질경험의 전달이 주된 목적
  • 8. 현재, 넥스트플로어 지하연구소 미공개 신작 디렉터 <Protocol:hyperspace Diver> 디렉터, 프로그래머 <데스티니 차일드> 프로그래머 <마비노기 2: 아레나> 프로그래머 <MapleStory Village> 프로그래머 <MapleStory Adventures> 프로그래머 김영수 넥스트플로어 지하연구소 게임 프로그래머 7년차 디렉터 2년차
  • 10.
  • 12. • 3차원 공간 상에 선과 노트가 존재하고, • 음악의 플레이를 따라 공간을 진행하며 • 터치를 통해 2차원 스크린 상의 노트를 처리하는 게임
  • 13. • 3D 그래픽 출력/연출이 가능 • 터치 입력을 처리 가능 • 사운드 출력이 가능 • 3차원 공간 상에 선과 노트가 존재하고, • 음악의 플레이를 따라 공간을 진행하며 • 터치를 통해 2차원 스크린 상의 노트를 처리하는 게임
  • 14. • 프레임 드랍으로 인한 입력 누락이 없어야 한다 • Unity 기반 리듬게임에서 종종 보이는 문제점 • 프레임 드랍이 없으면 좋지만 • 최소한 큐잉된 입력 처리는 되어야 한다 • 사운드 latency는 낮을 수록 좋다 • 터치음은 터치 디바이스에서 줄 수 있는 강력한 피드백 유저의 게임 경험에 가장 크게 영향을 미치는 부분
  • 15. • UI가 뛰어난 반응성과 조작 경험을 가지게 하고 싶음 • 멀티터치 환경에서 터치 등의 조작에 적절하게 반응해야 함 • UI에서 쫀득한 조작함을 느낄 수 있게 커스터마이즈 하고 싶음 • 예: iOS의 rubber band scrolling • 네이티브 해상도 / Responsive Design 지원 • 스마트폰/태블릿을 동시에 지향하는 게임으로선 필수적인 부분
  • 16. 기존에 존재하던 모바일 게임 엔진들의 사용을 고려 Unity Moderato cocos2d-x
  • 17. • 무겁고 크고 느리다 • 특히 GC에 의한 랙은 실시간성을 요구하는 게임에서 치명적 • 게다가 멀티스레드도 미지원 • UI 도구들이 미묘 • NGUI, UGUI 등등이 있긴 하지만, 크게 좋은 평은 아님 • 최근에 듣기에도 썩 좋은 UI 프레임워크는 아니란 이야기가 • 개인적으로 선호하지 않는 개발 스타일 • FPS/TPS 등의 게임에 맞춰진 엔진 설계
  • 18. • NextFloor에서 사용하는 인하우스 엔진 • 드래곤 플라이트, 데스티니 차일드 등에서 사용되어 검증 • C++ native 코드가 기반 / Lua로 로직을 올려 연동 • 약간의 애니메이션과 상호작용 지원이 있는 UI 시스템 • 조금은 올드한 엔진 • 구 문법의 C++을 사용하고, 기본적으로 싱글스레드 기반 • OpenGL ES 1.1을 사용 – 쉐이더 이용이 어려움 • Lua로 로직을 짜는 구조에 최적화된 부분이 많음
  • 19. • 한창 발전하고 있던 엔진 • 빠른 C++11 지원과 함께 3D 지원도 꽤 빠른 속도로 구현되고 있었음(2015년) • 오픈소스/C++이라, 어쨌든 문제가 생기면 손댈 수 있긴 함 • Native C++ 기반이라 괜찮은 속도를 보여줌 • 엔진 구조도 꽤 단순하면서 개인 취향에 맞는 처리 흐름 • 신뢰성에 약간의 문제가 있었음 • 라이브러리에 다소 만족스럽지 못한 부분이 있었음 • 역시 괜찮은 UI/UX 프레임워크가 부재 • 사운드 라이브가 생각하던 것 만큼 강력하지 않았음
  • 20. • 프로그래머 및 기술 인력은 1인 • 자체 엔진 사용 프로젝트 종사 경험 • 시작부터 만들진 않았지만 꽤 깊은 곳까지 건드리며 다뤄본 경험 • 비슷한 모바일 프로젝트 경험이 있음 • 데스티니 차일드와 MapleStory Village • 엔진 구성 및 기술적 노하우를 참고 가능 • 일어날 수 있는 문제도 어느 정도 파악 오마이뉴스 http://m.ohmynews.com/NWS_Web/Mobile/at_pg.aspx?CNTN_CD=A0001516557&CMPT_CD=TAG_M#cb
  • 21. Unity Moderato Cocos2d-x 자체개발 성능 낮음 보통 높음 높음 제공하는 기능 보통 보통 보통 없음 → 원하는 모든 기능 개발 비용 보통 보통 보통 보통 개발 편의성 낮음 보통 높음 높음 두 가지 선택지 사이에서 많은 갈등
  • 22. 결론은 자체 엔진 개발 비용-효용적인 측면에선 Cocos2d-x와 자체개발이 비슷할 것 같았으나 기술을 끝까지 이해하고, 원하는 방향으로 커스텀 할 수 있을 것 같아 선택
  • 23. • 개발팀의 인력 구성이 큰 영향을 미쳤음 • 기술 인력이 1명: 의사소통 비용이 거의 0 • ‘전원’이 자체 엔진 사용 프로젝트의 개발 경험이 있게 됨 • 작업 분배에 따른 병목 등도 존재하지 않음 • 조직적인 면에서도 결정해서-실행하면 되는 상황 • 혼자서 엔진부터 개발하며 앞뒤 보지않고 달릴 수 있었던 이성이 증발해서 엔진 개발도 두렵지 않아! TVアニメ「Fate/Apocrypha」公式サイト http://fate-apocrypha.com
  • 24.
  • 25. • iOS & Android 동시 지원 • 스마트폰&태블릿 지원 • 수많은 제조사 • 수많은 제품군 • 수많은 해상도… • 프로그래머 1인이 대응?
  • 26. 넘을 수 없는 추상화의 벽 게임 로직 구현 플랫폼 로직 Platform별 구동 로직을 밑에 깔고, 그 위에서 플랫폼 중립적인 게임을 만들자! DIP: one should “depend upon abstractions, [not] concretions.” Robert C. Martin (“Uncle Bob”) (2000), Design Principles and Design Patterns
  • 27. • 각 플랫폼에서 지원하는 언어는… • 양쪽에서 쓸 수 있는 건 C++ 뿐! • 다행히 C++11/14 등 최신 표준은 발빠르게 지원 Ojbective-C Swift Java iOS Android ++ C++ C++ via NDK
  • 28. • 엔진이 표준 C++을 이용하므로 라이브러리가 호환 • C/C++이 호환되는 다양한 라이브러리 사용 • 표준 라이브러리와 STL도 다양한 곳에서 사용 • 플랫폼 제공 POSIX 라이브러리도 이용 가능 • iOS/Android에서 호환 • 전부는 아니지만 상당 부분
  • 29. • 플랫폼 그래픽 라이브러리로는 OpenGL을 사용 • OpenGL ES 2.0을 사용 • iOS 및 Android에서 기본적으로 지원 • 플랫폼 사운드 라이브러리로는 OpenAL을 사용 • iOS의 경우에는 바로 지원 • Android의 경우에는 사용할 수 있는 포팅이 있다.
  • 30. • iOS/Android 모두 IDE를 호환 • 런타임 디버깅이 가능한 환경을 구축 • 생산성에 큰 영향을 미치므로 반드시 체크해야 할 요소 XCode iOS NSight Tegra w/ Visual Studio Android
  • 31. • GLKView 이용 GLKViewController Obj-C++ GLKView AppDelegate Obj-C++ Game C++ Delegate Events Call via C++ Frame Update, Graphic Prepare, … App Pause, Background, …
  • 32. • JNI를 이용해 Java 플랫폼 코드와 C++ 게임 코드 통신 GLSurfaceView.Renderer Java GLSurfaceView FragmentActivity Java Game C API in C++ Call via JNI Frame Update, Graphic Prepare, … App Pause, Background, … Logic Side Platform Library Calls Activity owns GLSurfaceView
  • 33. • Windows PC에 대해서도 호환 플랫폼을 구현 • 개발 중 가장 빠른 이터레이션이 가능한 플랫폼 • 디버깅 등도 매우 용이 • 해 두면 정말 좋습니다! • OpenGL ES를 이용 • EGL 등을 통해 호환 가능 • 모바일이 1st class 플랫폼이므로 최대한 동일하게
  • 34. • 호환성을 확보한 후 C++/OpenGL로 원하는 대로 구현 • 로직 코드로 C++11을 이용 넘을 수 없는 추상화의 벽 게임 로직 구현 플랫폼 로직 OpenGL 최대한 얇은 레어어로 추상화 Portability를 중심으로
  • 35. GAME Platform iOS Android WindowsPC Application Graphic File System Input … Graphic Resource Manager OpenGL ES
  • 36. • 공용 플랫폼 로직 위에 기능별 인터페이스 구현 • 각 부분기능은 모듈로 격리 • 엔진의 기능들은 모듈들의 조합으로 구성 • 모듈 간의 의존성은 레이어링을 통해 단방향으로 정리 • 게임 로직은 추상화된 모듈에만 의존
  • 37. • 게임 코드 레이어에 게임 객체의 생성을 위임 • 엔진에는 생성 함수의 인터페이스만 존재 • 게임에서 이용할 기능에 맞게 게임 엔진을 구성
  • 38. 엔 진 모 듈 플 랫 폼 구 현엔 진 기 반 구 조 게임 구현 실제 프로젝트 구성 외부 라이브러리 외부 라이브러리 빌 드
  • 39.
  • 40. 여기까진 쉽죠? 헉, 이건 어떻게 하지? 일단 그림 파일을 읽을 수 있어야 하고(File IO) png 포맷 파일을 디코딩 할 수 있어야 하고, OpenGL 텍스처에 올려서…
  • 41. • PNG Only! • 투명도, 32비트 색상, 기타 압축 등 게임에 필요한 기능은 거의 갖춤 • JPEG도 리서치 해 봤는데, 퀄리티가 높으면 용량 차이가 별로 안 남 • 텍스처 생성을 추상화 해 두면, 디코더만 붙이면 되니 필요할 때 붙이면 됨 • 어떻게 로드할까? : 단순무식! • libpng로 디코드해서 • 빌드할 때 neon 설정 같은거 잘 해 주면 조금 더 빨라짐 • 비트맵으로 메모리에 뽑은 다음, OpenGL ES 텍스처에 업로드
  • 42. • 텍스처가 날아가는 경우가 있음 • 앱이 Background로 가거나 OS가 필요하다고 생각하는 경우 • Android의 경우, setPreserveEGLContextOnPause를 설정해서 막을 수 있음 • 대처 방법은? : 체크하고 복구 • 앱이 Background에서 돌아올 때, 기존 텍스처를 체크할 필요 있음 • glIsTexture 함수를 이용해서 텍스처가 날아갔는지 여부를 검사 • 날아간 텍스처를 복구하기 위해서는 적절한 메커니즘 구현 필요 • P:h Diver에서는 관리되는 텍스처 생성 시에 복구 함수를 함께 전달
  • 43. • Shared Context를 이용해서 GL Context 간 데이터 공유 가능 • 하나의 context는 하나의 thread에만 대응 • 다른 thread에서 새 context를 생성하며 share_context에 context를 넘겨 context 간 데이터(텍스처, 버퍼 등)를 공유하게 할 수 있다. • 비동기 텍스처 로딩 등이 가능! • 동기화에는 주의 • 특히 비표준적인 동작에 주의!
  • 44. • 여러 스프라이트를 하나의 이미지에 모은 것 • 저장 공간의 효율적 사용 및 성능 향상 등이 목적 • Draw Call을 줄일 수 있음. GL에선 텍스처가 상태라;; • 정적 Texture Atlas • 아티스트와의 협업 과정에서 많이 사용 • 툴의 출력을 읽어 사용할 수 있게 구현하는 걸 추천 • TexturePackerhttps://www.codeandweb.com/texturepacker
  • 45. • 런타임에도 텍스처 아틀라스를 구성할 수 있음 • glTexSubImage2D를 이용해 텍스처 부분 업로드 가능 • 텍스트 랜더링 등에서 사용됨 • 라이트맵 등 Pre-baked texture가 사용되는 경우에도 자주 사용 • 텍스처 복구 매커니즘에 주의 • 동적으로 구성했던 텍스처도 날아갈 수 있다는 사실을 명심! • 부분 텍스처를 받을 때도, 복구 함수를 함께 받아 저장한다거나 • 데이터를 어딘가 백업해 둔다거나 • Invalidate 여부를 따로 체크하고, 데이터를 재구성 할 수 있게 구현한다거나
  • 46. • 이미지들을 주면 영역을 확보해 아틀라스를 구성해야 함 • 2차원 냅색 문제 • 해당 주제로 Ph.D. 학위 논문까지 있을 정도 • Lodi, A. (1999). Algorithms for two-dimensional bin packing and assignment problems. Doktorarbeit, DEIS, Universita di Bologna, 16. • …지만, 글로벌 최적해 찾지 않고 적당히 greedy로 푸는 방법은 꽤 존재 • 개인적으론 blackpawn에서 소개된 방법을 변형하여 이용 • 공간을 binary tree로 관리 • http://blackpawn.com/texts/lightmaps/
  • 47. • RTT - Render Target Texture • GL이 랜더링하는 타깃(Framebuffer)를 텍스처로 설정 • glFramebufferTexture2D • Frame Buffer → Texture Copy • 프레임 버퍼의 내용을 텍스처로 카피 가능 • glCopyTexSubImage2D
  • 48. • 스크린 효과 등, 여러 랜더링 효과를 이용할 수 있음 • 게임에 들어간 blur 효과가 이걸 이용
  • 49. 프로그래밍의 기본 하면 역시 Hello, World! 그런데, 모바일 게임에서는 어떻게...? #include <iostream> int main() { std::cout<<"Hello, World!"<<std::endl; return 0; }
  • 50. • OpenGL 화면에 텍스트를 그려야 한다! • 텍스트를 텍스처로 만든 다음, 텍스처를 그리는 방식 채택 • 문자열에 대해 한 자 씩 글자 텍스처를 얻어내 그릴 수 있음 • 텍스트 이미지를 얻기 위해서는 폰트를 사용 • 각 문자를 어떻게 그릴지에 대한 정보를 담고 있는 것이 폰트 • 일반적으로 우리가 사용하는 TrueType 등의 폰트는 벡터 방식 • 사용자 화면 크기에 상관없이 깨끗한 폰트를 얻을 수 있다
  • 51. • 오픈소스 폰트 랜더링 라이브러리 • 레퍼런스가 많고 적당히 쓰기 편한 라이브러리 • FreeType으로 글씨의 이미지를 얻어낼 수 있다 • 폰트 정보에서 개개 글씨의 비트맵 이미지를 얻는 기능 지원 • 기타 지원 기능 • 힌팅, 커닝, 외곽선 추출 등을 지원 • GSUB 미지원: 태국어 등의 언어 지원 시 주의할 것
  • 52. • FreeType을 통해 문자 이미지 텍스처 생성 • 문자를 이미지로 변경한 다음, 텍스처 아틀라스에 구워둠 • FreeType은 설정과 함께 문자를 주면 비트맵 이미지를 반환 • 이 이미지를 텍스처 아틀라스에 올려 쓰면 되는 것
  • 53. • 폰트의 종류에 따라서 서로 다른 글자의 모양을 가짐 • 아트 직군에서 결정하는 것이 바람직 • 라이선스나 용량 등을 고려하여 선택한다 • 구글/어도비의 Noto(본) 계열 폰트를 추천 • 여러 언어에 대해 무난한 수준의 글리프를 제공 • 대부분의 문자는 커버된다
  • 54. • 커닝: 내용에 따라 문자 간의 간격을 조정하는 것 • FreeType에서 지원하므로, 가능하면 구현을 추천 No Kerning, Times New Roman Kerning Applied, Times New Roman
  • 55. • 텍스트 블록 구성: 여러 줄 텍스트의 경우 • 자동 줄바꿈 기능은 지원되어야 한다. • 가능하다면 개행 관련 처리도 해줄 수 있으면 좋다 • 알파벳 문자권 언어의 경우, 단어 중간 개행 시 하이픈 삽입 • CJK의 경우 단어 단위 개행 Hint를 고려 • P:h Diver에서는 개행 처리 미구현
  • 56. • 텍스트 블록 구성 • 정렬 방식을 잘 선택해야 예쁘다: 특히 배분정렬을 고려 배분정렬 왼쪽정렬
  • 57. • 한 문장 내에서 다국어 텍스트를 섞어 조판할 때는 • 문자 종류별 Baseline과 크기 세팅이 가능하도록 해야! • Adobe InDesign과 같은 조판 소프트웨어에는 있는 기능
  • 58. vs. 동일 크기, baseline 조절 없음 크기와 baseline 조절
  • 59. • 텍스트 그림자 • 그림자 먼저 찍고, 위에 텍스트 한 번 더 찍으면 된다! • 텍스트 외곽선 • FreeType의 Stroker를 이용 • Stroke가 된 glyph 비트맵 이미지를 얻을 수 있음 • 허용하지 않는 라이선스의 폰트도 있으므로 주의!!
  • 60. • UI는 시스템화 시켜서 사용하는 것이 좋다 • 공통적인 동작과 상호작용 로직을 가지는 부분이 많음 • 쓸 만한 기존 라이브러리가 존재하지 않음 • OpenGL 게임과 연동해 쓸 만한 추상적 UI 라이브러리 X • 입출력~랜더링까지를 직접 처리하는 라이브러리가 대부분 • 만족스러운 경험을 주는 라이브러리는 더 적고… • 결국 우리가 바퀴를 다시 만들어야
  • 61. • 터치 이벤트 처리 방식 확립 • UI의 가장 중요한 임무 중 하나는 사용자의 입력에 반응하는 것 • 터치는 모바일 터치 디바이스에서의 가장 중요한 입력 • WPF의 체이닝/버블링이 참고할 만한 사례 MSDN - 라우트된 이벤트 개요 https://msdn.microsoft.com/ko-kr/library/ms742806(v=vs.110).aspx
  • 62. • 레이아웃 시스템 • 다중 스크린 지원 시 반드시 고민해서 설계해야 하는 부분 • P:h Diver에서는 부모-자식 상대 위치 관계를 기준으로 구현 • 그리드 시스템은 별도로 사용하지 않음 • Stackable 등의 자동 레이아웃은 아직 미구현 0.5 0.5 0.2 0.1 (100, 40) (-50, -40) • 부모에 대해 정의된 Reference Point와 자식에 대해 정의된 Anchor Point가 매치되도록 위치를 결정 • 각각의 Point는 • 객체에 대한 비율로 나타내어지는 상대 위치에 절대값으로 나타내어지는 오프셋을 더해 지정
  • 63. • 게임에 이용되는 UI 정의는 데이터화 하는 것이 좋음 • 빠른 이터레이션을 위해선 가능한 많은 부분을 데이터화 해야 • 특히, 아티스트 분들이 조금씩 손대며 개선할 필요성이 큰 부분 • 버튼 1px 옮기는데 다시 컴파일을 해야 한다면 으어어ㅓㅓㅓ xkcd https://xkcd.com/303/
  • 64. • Mark Up Language 정도는 만들어서 사용하는 것을 추천 • Responsive가 지원되는 HTML의 사례를 참조 • UI는 마크업 언어로 기술하는 방식이 꽤나 잘 맞는 도메인 • 대부분의 화면 구성요소들은 tree 구조로 이해하기 쉬운 편 스크린 카테고리 메뉴 옵션 내용 닫기 버튼타이틀 게임 플레이 버튼 버튼 텍스트 아이콘 … 배경 이미지
  • 65. • UI Description이라는 마크업 언어를 만들어 사용 • XML 기반 • 간단한 변수, 계산, 네임스페이스 탐색, Import 기능 구현 • UI 구성요소를 정의하는 Prefab • Tree 구조로 UI 객체들을 정의 • 각각의 객체들은 Entity-Component 모델로, 컴퍼넌트를 조립 가능하게 • 자주 쓰이는 타입의 UI 객체는 사전에 클래스로 정의되어 바로 사용 • Prefab 중첩 가능 • 코드에서 이름을 통해 변수, Prefab 등을 얻어낼 수 있음 • Prefab의 경우 코드에서 실제 UI 객체로 할당 가능
  • 66. 기본 구조 및 변수, 수식 정의
  • 69. • 게임 데이터 문자열로는 UTF-8 인코딩의 사용을 추천 • 여러 플랫폼 상호운용성이 뛰어나고, 큰 고민 없이 다국어 지원 가능 • 성능 문제는 보통은 신경 쓰지 않아도 될 수준 • 플랫폼 상호 변환도 간편한 편 • Android의 jstring이나 iOS의 NSString도 UTF-8 문자열에서의 변환이 용이 • Windows에서는 UTF-16으로 변환해야 하는 경우가 종종 있다. • 유저에게 출력되는 문자열은 테이블 – 키 구조로 관리 • 코드에 하드코딩 되는 문자열이 없어야 한다
  • 70. • 번들 리소스의 이해 • iOS의 번들은 파일 • Android의 번들은 압축된 어떤 데이터 • std::stream 등을 이용해 일관된 인터페이스를 제공할 수 있도록 구현해 두면 편하다 • 빌드 시, 번들 리소스는 파일 시스템 상 하나의 폴더에서 연동되게 하는게 편하다 • iOS의 경우 번들로 패킹 • Android의 경우 Asset 디렉터리
  • 71. • 저장소 클래스의 구분 사용 • 내부/외부 저장소, 임시/영구적 저장소, 클라우드 백업 여부 등, 특성에 따라 분류해 사용하면 • 플랫폼 독립적인 추상화가 가능 P:h Diver의 파일 시스템 엔진 컴퍼넌트 정의
  • 72. • 멀티 스레드를 활용할 수 있는 추상화된 상위 구조 설계 • 로직 프로그래밍 단계에서 스레드 하나하나를 만들어 관리하고 이용하는 건 어렵고 번거로움 • 좀 더 추상적인 레벨에서 병렬 처리를 가능하게 하는게 좋음 • 다른 언어의 코루틴, .NET의 Task Parallel Library 등이 이런 관점의 산물 • P:h Diver에서는 태스크 시스템을 구현해 이용 • 추상화된 작업 단위인 ‘태스크’를 중심으로 작업을 수행 • 람다 함수 등으로 태스크를 만들어 던지면 알아서 수행해 줌 • 그래픽, 네트워크 등 작업 특성에 따라 스레드 풀을 구성 • 작업의 상태는 객체화 된 태스크를 통해 확인 가능하게 설계 • iOS의 경우 GCD를 래핑하는 방식으로 구현하는게 안정적이고 편할 수 있음
  • 73. • 공용 로그 함수부터 만들자! • 로그는 디버깅의 기본 • 하나의 함수로 NSLog와 안드로이드 Log 등으로 출력되게 하는게 좋다 • Windows의 경우 OutputDebugString 함수의 이용을 고려 • 유틸리티 라이브러리 이용 • C/C++이므로 많은 라이브러리와 호환성을 가짐 • String Format, sqlite, JSON/XML 파서 등을 연동시켜 두면 편하다
  • 74.
  • 75. • 큐브 띄우기까지 1달 반 • 물론 iOS/Android 호환! • 어플리케이션 빌드 • 엔진 구조 작성 • 그래픽 기능 구현 • 기본 쉐이더 포함
  • 76. Primitive 프로토타입 임시 리소스 적용 핵심 빌드 여기까지 2달 반 여기까지 3달 반
  • 77. • UI 및 정식 비주얼 구현까지 5달 • 게임 플레이가 가능하도록 UI 시스템을 구현 • AD님 합류로 게임 비주얼을 전면적으로 개선
  • 78. • 클라이언트 기능 완성까지 7달 반 • 신 UI 시스템 구축 • UI Description 기반 • 비동기 및 네트워크 기능 • 게임플레이 로직 플로우 이후, 타 부서 협업을 통한 서버 및 인프라 세팅, 로컬라이제이션, 스토어 및 결제 최적화, QA 등의 출시 준비 작업 수행
  • 79. LocMetrics http://locmetrics.com/ LocMetrics이란 툴을 사용해 LoC 측정 LoC(Lines of Code)가 절대적인 정보는 아니지만, 어느 정도 프로젝트 규모에 대한 감을 전달하기에는 좋은 자료
  • 80. • 엔진: 33,673 ▪ 공용: 6,751 ▪ 플랫폼: 9,661 ▪ 모듈 구현: 17,261 충분한 완성도로 정리하지 않아 게임 레이어에 격리시켜 둔 엔진성 코드 • 게임: 138,230 ▪ 사운드 시스템: 4,516 ▪ UI 시스템: 37,950 ▪ 태스크 시스템: 1,634 ▪ 네트워크: 1,959 • 엔진성 코드: 총 79,732 Lines ➢프로젝트 코드: 총 171,903 Lines
  • 81. • 프로그래머(디렉터 겸업) 인력의 맨먼스는 14 정도로 표기 • 런칭 준비를 위한 엔지니어링 코스트 포함 • 메인 프로그래머 1인 중심의 작업 • 지원 조직 및 차기 프로젝트 프로그래머로부터 플랫폼 특화 구현 관련 기술 지원을 받음 • 실질적으로는 프로그래머 1명, 10 맨먼스 정도 • 엔진 및 게임 로직, 서버 등을 포함한 개발 전반의 비용
  • 82. • 게임을 개발하여 출시 • 어쨌든 완성은 했습니다. • 초기 안드로이드 등 성능 이슈가 있었음 • 5월 말 1.2 패치로 최적화 옵션 추가 • 특이한 이상이 가끔 보고되나, 전반적으로는 안정적 • 텍스처 초기화 오류가 굉장히 가끔 보고됨 • 크래시에 대한 보고는 특별히 많지 않음
  • 83. • 기술적인 요구사항을 원하는 수준까지 맞출 수 있음 • 새로운 플랫폼 기술도 즉시 적용 가능 • 자신/팀에게 맞는 개발 환경을 선택 가능 • IDE나 기술 스택을 필요에 맞춰 고를 수 있음 • 구조 및 개념 설계 등을 최적화할 수 있음 • 생각보다 구현 비용이 크지는 않음
  • 84. • 파편화된 기기 최적화가 어려움 • 특히 통제가 약한 Android 환경에서, 최종 사용자에 맞춰 최적화가 힘듦 • 각 개발 도메인의 기술을 파고드는 최적화는 어려움 • 안되는 건 아닌데, 그만큼의 시간을 추가로 할당해야 함 • 개발 병목이 될 수 있음 • 게임 구현에 필요한 기능이 늦은 시점에 나오게 될 위험 존재 • 엔진 개발자는 컨텍스트 체인지 비용이 크다 • 팀 환경에 따라 툴이나 (타 직군)개발 환경의 부재가 아쉬울 수도
  • 85. 특별한 결론은 없습니다. P:h Diver의 사례를 기술적인 관점에서 리뷰하였고 어디까지나 정답이 아닌 ‘참고 사례’로써 받아들여 주셨으면 ガールズ&パンツァー 劇場版 Actas Inc.