SlideShare ist ein Scribd-Unternehmen logo
1 von 107
블루홀 테라본부 콘솔포팅TFT
이해찬
- UE3 게임 현세대 콘솔로 이식하기
<테라> 콘솔 포팅기
TERA
- Free-Targeting MMORPG
- 2007년 개발 시작
- 2011년 한게임 서비스 시작
- 2016년 넥슨 서비스 시작
- 현재 북미, 유럽 포함 8개 지역에서 서비스 중
- 2016년 개발 시작
- 2018년 4월 3일 정식 런칭
- PlayStation4 / XBox One 동시 런칭
- En Masse Entertainment 퍼블리싱
- 북미 / 유럽 서비스
TERA Console
PlayStation Store
XBox Store
테라 콘솔을 만들면서 있었던 이런저런 일들을 공유하고자 합니다.
TV로 보는 엘린짱 TERA~ (감동)
발표자 소개
• 2014.2 ~ : 블루홀 테라본부 클라이언트팀
• 2016.3 ~ : 블루홀 테라본부 콘솔포팅TFT
• haechan@bluehole.net
주요 발표 내용
콘솔포팅에 대한 전략 세우기
• 팀 빌딩, 일정 수립, 그리고 기술적 결정 사항들
• TERA 콘솔의 사례 공유
추천 청강 대상 : 리드급 엔지니어, 프로젝트 매니저
UE3엔진을 현세대기 콘솔에 이식할 때의 최적화 방법
• 콘솔 기기의 최적화 전략
• 리소스 로딩 최적화, 메인 스레드 로직 최적화
추천 청강 대상 : UE3 개발자, 콘솔 플랫폼 개발자
바로 이어서 렌더링 스레드 최적화에 대한 발표가 있습니다
연결되는 내용이니 이 발표도 많이 들어주세요~
목차
1. TERA 콘솔팀의 탄생과 시작
2. TERA 콘솔팀의 2년간 개발 기록
3. UE3 콘솔 최적화 – 리소스 로딩
4. UE3 콘솔 최적화 – 메인 스레드 병렬화
5. 마무리
1. TERA 콘솔팀의 탄생과 시작
• 어쩌다가 TERA를 콘솔로 포팅하게 되었는지
• 어떻게 포팅 전략을 세웠는지
1. TERA 콘솔팀의 탄생과 시작
2. TERA 콘솔팀의 2년간 개발 기록
3. UE3 콘솔 최적화 – 리소스 로딩
4. UE3 콘솔 최적화 – 메인 스레드 병렬화
5. 마무리
※과장된 표현입니다
님아 네버윈터라는 MMORPG가
XBOX ONE으로 나왔는데 너무 멋있어!
우리도 하자!
어.. 그래? 근데 포팅하는 게
쉽지는 않을 것 같은데..
걱정 ㄴㄴ 이런 거 외주하는 업체 많음.
내가 알아서 진행 하겠음
???? (그럴 리가??)
그럼 검토해 볼까?
사건의 시작 (2015년 겨울)
하지만 결국 불발됩니다.
• 해외 업체와 협업 가능한 인프라 구축의 어려움 (Feat. 폐쇄망)
• 서비스를 위한 런처, 패치 시스템, 운영툴 등은 결국 우리가 해야함
• 기획서도 다 써줘야 하고, 질의응답을 위해서라도 우리 비용 들어감
• 추후 유지보수도 어차피 우리 몫
• 너무 비쌈
• 등등등..
한 줄 요약 : 이럴 거면 외주를 왜 하지 싶을 정도로 관리 비용이 비쌌음
핵심 기술을 외주로 해결하는 게 제작의 명가가 나아갈 방향인가에 대한 정체성 고민
기왕 콘솔 서비스를 해볼거면 직접 개발 경험을 쌓는 것이 회사가 발전하는 방향이 아닐까?
(블루홀 홈페이지의 소개 내용)
2016년 3월 4일..
하.. 해찬아 테라를 콘솔로 옮기는 걸 내부에서 할까 하는데,
가능하다고 보니?
음? 별 것도 아니구먼
제가 해드림 ㄱㄱ
코.. 콜!
※과장된 표현입니다
이렇게 TFT가 발족됩니다
(바로 다음 주 월요일 발령 -_-)
관리자급 제외하면 1인 실무자 R&D 팀으로 시작
ⓒShotaro Tokuno, HOUBUNSHA/NEW GAME! Project
어떻게 포팅하지?
기존 UE3 엔진을 개조한다. TERA 엔진을 UE4로 올린다
(TERA를 UE4로 다시 만든다)
UE3 는 PS3, Xbox 360 용 게임 엔진
ⓒWarner Bros. / The Matrix
개발 조건
• 소규모 R&D 팀
• 테라본부 지원 기대하기 힘듦
• 아트 지원은 더더욱 없다
UE4로 가려면?
• UE3 아트리소스를 그대로 UE4에서 읽을 수 있게 하는 것은 정말 힘듦
• 아트팀이 노동 집약적으로 포팅하는 것이 그나마 현실적
• 아트 퀄리티가 필연적으로 달라짐 => 강한 아트 디렉팅이 필요
결론 : 테크 파워만으로 포팅하기 => UE3를 개조하자
개발 자원 고려
UE3-Unsupported의 존재
외주
개발
UE3는 2012년에 업데이트가 끝났지만 외주를 통해 현세대콘솔 지원을 합니다.
개발
TERA는 구형 UE3
<기존 PC TERA의 UE3> <UE3 Unsupported>
- UE3 2010년에서 업데이트 중지
- 32bit
- GFX 3.0
- UE3 최신 (2012년까지 업데이트)
- 64bit
- GFX 4.2
• 단순히 플랫폼 Layer의 코드만 가져와서 될 게 아니라 다른 엔진 코어까지 가져와야 하는 상황
• ‘기존 TERA를 개조’하는게 아니라 ‘UE3-Unsupported에 TERA를 다시 만드는’ 방법으로 결정
• 반대로 했다면 렌더링 되게 만드는데 까지만 몇 달은 걸렸을 것
정리
외주 vs 자체개발
• 콘솔 포팅을 전문적으로 하는 회사들이 많은 것은 사실
• 패키지게임과 달리 온라인 서비스를 지속적으로 할 거면 외주관리가 만만치 않다.
• 블루홀은 콘솔 개발/서비스 경험을 내재화 하고 싶었기에 직접 포팅을 선택
UE3 게임을 포팅할 때에는
• UE4로 가는 것은 좋은 선택이나 아트 파워가 많이 필요함
• 테크 위주의 팀에게는 UE3-Unsupported 를 활용하는 것이 현실적
• 테라는 엔진 변경점이 많아서 게임을 다시 만드는 방법을 선택
2. TERA 콘솔팀의 2년간 개발 기록
• 포팅을 할 때 어떤 일들이 필요한지
• 어떤 일이 어떠한 멤버 구성으로 얼만큼의 일정이 소요되었는지
• 테라 콘솔팀의 사례를 통해 공유
1. TERA 콘솔팀의 탄생과 시작
2. TERA 콘솔팀의 2년간 개발 기록
3. UE3 콘솔 최적화 – 리소스 로딩
4. UE3 콘솔 최적화 – 메인 스레드 병렬화
5. 마무리
주요 마일스톤
2016.3
18.3.9 1차 OBT
18.3.16 2차 OBT
18.3.27 Founders’ Pack 런칭
2017.1 2018.1
16.9 첫 알파 테스트
16.12. 첫 PS4 QA 시작
17.2 첫 XB1 QA 시작
17.9 최적화 1차 마감
17.9 PAX 시연
17.9 2차 Cert 제출
17.12 Technical Test (CBT)
4 5 6 7 8 9 10 11 12 4 5 6 7 8 9 10 11 122 3 42 3
2018.4.3 정식 오픈
17.4 첫 PS4 Cert 제출
17.4 첫 XB1 Cert 제출
16.3.7 프로젝트 시작
프로덕션 폴리싱프리 프로덕션
주요 마일스톤
2016.3
18.3.9 1차 OBT
18.3.16 2차 OBT
18.3.27 Founders’ Pack 런칭
2017.1 2018.1
16.9 첫 알파 테스트
16.12. 첫 PS4 QA 시작
17.2 첫 XB1 QA 시작
17.9 최적화 1차 마감
17.9 PAX 시연
17.9 2차 Cert 제출
17.12 Technical Test (CBT)
4 5 6 7 8 9 10 11 12 4 5 6 7 8 9 10 11 122 3 42 3
2018.4.3 정식 오픈
17.4 첫 PS4 Cert 제출
17.4 첫 XB1 Cert 제출
16.3.7 프로젝트 시작
시작하기
일단 UE3-Unsupported를 PS4 Devkit에서 먼저 돌려봐야죠
<요런 샘플 게임을> <PS4 개발킷에서>
• XB1 Devkit 배송이 늦어져서 PS4 먼저
• UE3-Unsupported의 PS4 SDK 버전이 낮아서 마이그레이션 하느라 몇 주 소요
프리프로덕션 단계
2016.3 4 5 6 7 8 9 10 11 12
프로토 타이핑
이제는 테라를 이식해야죠.
• 최소한의 것만 이식을 합니다.
• InputManager, 플레이어 이동 처리, Skeletal Mesh 로딩
• 가능성을 확인하는 단계
• 엔진 이식이 아닌 테라를 다시 만드는 접근을 취했기에 빠르게 렌더링 결과를 얻음
2016.3 4 5 6 7 8 9 10 11 12
프리프로덕션 단계
팀원 구함
이 시점에 프로그래머를 2명 더 영입
프로그래머 A
• 기존 UI GFX 버전 올리기 및 패드 입력계 구현
프로그래머 B
• 기존 아트 리소스 로딩하기
• SkeletalMesh 뿐 아니라 StaticMesh, Particle, Terrain, Sound 등. 일단 로딩이라도 되게.
• 엔진 버전이 달라서 필요해진 초기 작업
프로그래머 C (저)
• 모든 테라 컨텐츠 코드 이식 및 PS4에 대한 네크워킹 코드 작업
• 게임이 켜지는 것을 우선. 플랫폼 특성상 구동 안되는 코드는 “#if !Console” 후 Todo 처리
2016.3 4 5 6 7 8 9 10 11 12
프리프로덕션 단계
미국으로
그리고 갑자기 미국으로 가게 됩니다 (으잉?)
En Masse Entertainment 사무실 창 밖
시애틀 날씨 좋을 때~
2016.3 4 5 6 7 8 9 10 11 12
프리프로덕션 단계
• UE3-Unsupported PS4 버전을 만든 그 회사
• UE3 포팅 전문이지만, 분야 가리지 않고 기술 컨설팅 해주는 회사
• 마침 시애틀에 있음. En Masse Entertainment 사무실과 가까움
• 외주가 아닌 컨설팅의 형태로 접근 -> 전문가에게 빨리 배우자
미국으로
Hardsuit Labs 로 부터 컨설팅 받기
2016.3 4 5 6 7 8 9 10 11 12
프리프로덕션 단계
미국 팀 : PS4 개발 안정화
미국으로
두 팀으로 나눠진 거죠.
UI 개발하기
• PC TERA에서 개발용 브랜치 생성
• 숏컷, 인벤토리, 스킬, 퀘스트 저널
인원구성
• 프로그래머 1
• UI 스크립터 2
• UX 디자이너 1
• UI 디자이너 1
• QA 5
• 미국팀 작업에 대한 컨설팅
• XB1도 비슷한 수준으로 이식해 주기
한국팀 : UI 개발 Hardsuit Labs : 컨설팅
2016.3 4 5 6 7 8 9 10 11 12
프리프로덕션 단계
PS4 개발 속도 올리기
• 각종 그래픽 버그 수정
• SpeedTree / Bink Migration
• 쿠킹 에러 다수 수정
• 텍스처 캐시 스플리팅
• 패키징 / 배포 연습
인원구성
• 프로그래머 2
• 팀장 1
2016년 7월 중간자료
2016.3 4 5 6 7 8 9 10 11 12
프리프로덕션 단계
• 8월 중순 쯤 한국에 돌아와서 한국팀 UI 작업과 머지를 시작
• Hardsuit Labs 작업이 늦어져서 Xbox One 결과 머지는 미뤄짐
합체!
2016.3 4 5 6 7 8 9 10 11 12
프리프로덕션 단계
9월 7일 첫 알파 테스트 버전 (PS4에서 구동한 것) 2016.3 4 5 6 7 8 9 10 11 12
프리프로덕션 단계
프로덕션 단계 준비
이제는 프로덕션 단계로 넘어가기 위한 준비 단계
• Iteration을 위한 콘솔용 배포 프로세스
• Hardsuit Labs의 XB1 작업 머지
• 로컬라이징 (영어, 불어, 독일어) 작업 환경 만들기
• 플랫폼 서버 연동 (=계정 인증 등) 하기
엔지니어링 목표는
• 콘솔에서 게임이 어떻게든 굴러가게 만드는 것 에서
• 다른 사람들이 일을 잘 할 수 있게 만들어 주는 것으로 바뀜
2016.3 4 5 6 7 8 9 10 11 12
프리프로덕션 단계
그 외에도..
UI 개발 가속화
• UI 스크립팅 팀 단기 외주 (3명)
• 클라이언트 프로그래머 추가 투입
2016.3 4 5 6 7 8 9 10 11 12
프리프로덕션 단계
전투경험 개선
• 알파 테스트 후 생긴 욕심
• 전투 Focus 사내 테스트를 통한 주 단위 Iteration
엔진 버그 수정
• 끊임없는 버그의 산
12월 2차 머지
• 12월 21일 첫 PS4 QA!
(지금까지는 PC로 하고 있었음)
아 망했어요
2017년 새해가 밝았어요
이제 개발 사이클이 가능함
• 작업 -> 배포 -> 콘솔QA -> 무한 반복
• XB1은 2월 부터 가능해짐
프로그래머를 추가 영입
• 다른 프로젝트 중인 테라 출신 시니어들 에게까지 Help 요청
• UI 계속 제작
• 엔진 버그 수정 / 최적화
• 플랫폼, TRC/XR 작업
17.1 3 5 6 7 8 9 10 11 122 4
프로덕션 단계
TRC / XR
• 플랫폼 마다 마스터 패키지에 대한 Checklist가 있습니다.
• PS4 : Technical Requirement Checklist (TRC)
• XB1 : Xbox Requirement (XR)
• 모바일에서 앱 심사 같은 거죠
• 앱을 제출하여 심사를 받는 과정을 Certification이라고 합니다.
17.1 3 5 6 7 8 9 10 11 122 4
프로덕션 단계
TRC / XR
알아 두면 좋은 것
• Certification에 들어가면 두 플랫폼 모두 일주일 걸림
• Sony / MS에 테스트를 하는데 필요한 도구를 제공해야 함
• 항목 별로 면제 요청이 가능하나 절차가 오래 걸리고 통과가 쉽지 않음
• 처음 하는 회사는 보통 4~5번은 떨어진다고 함.
• 1년 걸린다고 생각하고 미리 준비할 것
• 자세한 내용은 NDA 문제로 생략
17.1 3 5 6 7 8 9 10 11 122 4
프로덕션 단계
4월 마일스톤
다음 빌드의 목표
• PS4/XB1 동시 Cert 제출
• 모든 UI 개발 완료 (중요도 낮은 일부 제외하고)
• 로딩 최적화 완료 (다음 챕터에서 자세히 다룹니다)
• 기타 중요 엔진 버그들 수정
Cert 떨어질 것을 감안해도 이 정도 계획이면 여름 쯤에 출시할 수 있겠지 (행복회로)
17.1 3 5 6 7 8 9 10 11 122 4
프로덕션 단계
마일스톤 점검
• XB1은 조금 늦어져서 4월 말에 Cert 제출
• 결과는 당연히 둘 다 FAIL
• 하지만 계속 수정 / 재제출 사이클을 돌기만 하면 된다는 자신감!
17.1 3 5 6 7 8 9 10 11 122 4
프로덕션 단계
빨간불은 다른 데서 켜짐
• 로딩 최적화를 했으나 여전히 프레임이 안 나옴
• 최적화에 총력을 다해야 겠다고 판단
• 런칭 계획은 물거품
최적화 삼매경
5월부터는 최적화에 최대한 많은 프로그래머 리소스 투입
UI팀도 UI 로직 최적화를 같이 진행
컨텐츠 개발 진도로 보면 거의 멈춰 있던 시기
17.1 3 5 6 7 8 9 10 11 122 4
프로덕션 단계
9월 최적화 중간 점검
• 최적화가 끝난 것은 아니나 가능성을 봄
• PAX에서 시연. 꽤 성공적인 반응을 얻음
• 가능성이 보이니 다시 런칭 타이머를 돌리기 시작
=> 연말 전에 CBT 하고, 내년 초에 런칭하자
17.1 3 5 6 7 8 9 10 11 122 4
프로덕션 단계
이제부터는 사실상 폴리싱
• 추가 기획은 정말 중요한 것만
• 버그수정과 최적화만 한다.
• TRC / XR 통과를 위해 최선을 다하기
• 이 이후는 별로 공유할 게 없네요.
UI 프로덕션
프로덕션 폴리싱프리 프로덕션
주요 마일스톤
2016.3
18.3.9 1차 OBT
18.3.16 2차 OBT
18.3.27 Founders’ Pack 런칭
2017.1 2018.1
16.9 첫 알파 테스트
16.12. 첫 PS4 QA 시작
17.2 첫 XB1 QA 시작
17.9 최적화 1차 마감
17.9 PAX 시연
17.9 2차 Cert 제출
17.12 Technical Test (CBT)
4 5 6 7 8 9 10 11 12 4 5 6 7 8 9 10 11 122 3 42 3
2018.4.3 정식 오픈
17.4 첫 PS4 Cert 제출
17.4 첫 XB1 Cert 제출
16.3.7 프로젝트 시작
TRC / XR
멀티스레드 최적화로딩 최적화
정리
테라 콘솔의 사례
• 시작부터 출시까지 2년
• 클라이언트 프로그래머는 1명으로 시작해서 프로덕션 단계에 9명까지 늘었다가 현재는 6명
• Hardsuit Labs에 컨설팅을 함으로써 초기 개발을 가속화
• 기존 PC 서비스 빌드를 적극 활용해 UI 개발을 빨리 시작함
• TRC / XR 준비는 정말로 1년 걸림
• 최적화는 예상치 못한 장벽, UE3를 안정적으로 멀티스레드화 하는데 반년이상 걸림
3. UE3 콘솔 최적화 – 리소스 로딩
• UE3 리소스 로딩 로직이 PC와 콘솔에서 다른 점 공유
• 아트 리소스를 수정할 수 없는 제약 사항에서 TERA 콘솔팀이 해결한 방법 공유
1. TERA 콘솔팀의 탄생과 시작
2. TERA 콘솔팀의 2년간 개발 기록
3. UE3 콘솔 최적화 – 리소스 로딩
4. UE3 콘솔 최적화 – 메인 스레드 병렬화
5. 마무리
MMORPG의 적 로딩랙
MMO가 다른 게임과 다른 점 – 플레이어의 동적 데이터
어떤 플레이어가, 어떤 옷을 입고, 어떤 탈 것을 타고, 어떤 스킬을 쓸지 절대로 알 수 없다
UE3 MMORPG의 한계
앞선 이유로, 게임 플레이 중에도 뭔가를 계속 로딩하고 있음
• 모든 이펙트, 사운드 등을 메모리에 올려놓을 수 없으니까
• 간헐적으로 프레임 드랍이 유발되는 이유
UE3에서 UI 로딩의 한계
• MMORPG는 UI가 많아서 전부다 메모리에 올려 놓는 것이 불가능
• UE3는 한 번에 하나의 파일만 로딩 가능
• 다른 파일을 로딩 중에 UI 오픈을 시도하면 순간 프리징을 걸어서라도 강제 로딩이 필요
(UI를 열었으나 몇 초 씩이나 반응이 없을 수는 없으니까)
• 비동기 로딩이 제대로 동작하지 못하는 이유
UE3 리소스 패키징
예시) 테라에서 이펙트 패키지 하나
PS : UE3의 ParticleSystem 정의
MI : PS에서 쓰는 Material 정의
MAT : MI가 사용하는 MaterialTemplate (Shader)
TEX : MI/MAT이 사용하는 텍스처
하나의 파일에 여러 리소스를 묶어 놓음
=> 몇 백 개의 ParticleSystem이 하나의 패키지에 들어 있음
FX_A_0001_PS
FX_A_0001_TEX
FX_A_0001_MI
FX_A_0001_MAT
FX_A_0002_PS
…
FX_A_0297_TEX
FX_A.upk
UE3의 3가지 로딩 API
StaticLoadObject : 하나의 UObject를 동기 로딩 (FX_A_0001_PS 를 로딩할 때까지 게임이 멈춤)
LoadPackage : 하나의 패키지를 동기 로딩 (FX_A.gpk 내용을 모두 로딩할 때까지 게임이 멈춤)
LoadPackageAsync : 하나의 패키지를 비동기 로딩 (게임 실행 중에 백그라운드에서 FX_A.gpk 내용을 천천히 읽음)
하나의 UObject만 비동기로 읽고 싶으면 어떻게 해야 하나요?
1. 해당 UObject가 들어있는 Package를 LoadPackageAsync로 로딩
2. 완료되면 사용할 오브젝트를 Referencing
3. GC를 돌린다!
Epic 공식 가이드
ⓒ이병건, NAVER WEPTOON CORP / 이말년 시리즈
TERA의 Custom 로딩 API
StaticLoadObject : 하나의 UObject를 동기 로딩 (FX_A_0001_PS 를 로딩할 때까지 게임이 멈춤)
LoadPackage : 하나의 패키지를 동기 로딩 (FX_A.gpk 내용을 모두 로딩할 때까지 게임이 멈춤)
LoadPackageAsync : 하나의 패키지를 비동기 로딩 (게임 실행 중에 백그라운드에서 FX_A.gpk 내용을 천천히 읽음)
TeraLoadObjectAsync : 하나의 Uobject를 비동기 로딩 (게임 실행 중에 백그라운드에서 FX_A_0001_PS 내용을 천천히 읽음)
그나마 이 방법으로 PC 서비스에서 버티고 있음
하지만 콘솔에서는?
Seek-Free 개념의 등장
• UE3는 콘솔에서 Seek-Free 패키징을 강제
Seek-Free 예시
PC의 경우, A_0001_PS를 로딩하려고 하면 B.upk도 찾아가서 B_0001_MI를 로딩함
이 PS 가 B_0001_MI를 사용한다면?
A_0001_PS
A.upk
B_0001_MI
B.upk
Seek-Free 예시
하지만 Seek-Free로 쿠킹을 하고 나면
A_0001_PS
A.xxx
B_0001_MI
B.xxx
B_0001_MI
B_0001_MI 내용이 복사되서 들어감
용량을 희생하고 로딩속도를 올린 (SeekTime을 없앤) 전략
광학 디스크에서의 실행을 가정하고 있기 때문
DVD 판매를 고려하고 있다면 정말 중요한 포인트
Seek-Free의 진짜 문제점
StaticLoadObject : 하나의 Uobject를 동기 로딩 (FX_A_0001_PS 를 로딩할 때까지 게임이 멈춤)
LoadPackage : 하나의 패키지를 동기 로딩 (FX_A.gpk 내용을 모두 로딩할 때까지 게임이 멈춤)
LoadPackageAsync : 하나의 패키지를 비동기 로딩 (게임 실행 중에 백그라운드에서 FX_A.gpk 내용을 천천히 읽음)
TeraLoadObjectAsync : 하나의 Uobject를 비동기 로딩 (게임 실행 중에 백그라운드에서 FX_A_0001_PS 내용을 천천히 읽음)
Object 단위의 로딩이 불가능해지고 항상 풀 패키지를 읽어야 함
TERA 콘솔 Worst 시나리오
1) 다른 유저가 옆에서 스킬을 씀
2) 하필 FX_A에 들어있는 이펙트가 필요해서 로딩을 시작함 (이미 스킬은 이펙트 없이 써졌음)
3) 그 와중에 뭐라도 UI Open을 시도하면?
4) 초 단위 프리징! (개발 초기에는 10초 넘어갈 때도 있었음)
Best Practice
하나의 파일이 너무 크지 않게 잘 관리 할 것
예시)
• 엘린_메이드복.upk
• 무사_스킬이펙트모음.upk
사실 UE3에서 UObject 단위의 비동기 로딩을 지원하지 않는 이유가 이것
• 애초에 그럴 필요가 없게 패키징 할 것
• 로딩의 목적 == 파일에 들어있는 내용 이면 많은 문제가 해결
(TERA는 오른쪽이 너무 큰 상태)
TERA 콘솔의 해결법
제약조건
• 아트 리소스자체는 수정 불가 (PC 서비스와 일관성 유지)
고민
• 콘솔에서 Seek-Free를 안 하게 수정하는 것은 어려움
(Hardsuit Labs도 그건 힘들 거라고 컨설팅)
결국 우리의 Wrapper를 하나 만드는 수밖에!
TERA 콘솔의 해결법
FX_A_0001_PS
FX_A_0001_TEX
FX_A_0001_MI
FX_A_0001_MAT
FX_A_0002_PS
…
FX_A_0297_TEX
FX_A.upk
FX_A_0001_PS_dup
FX_A_0002_PS_dup
Redirect_001.upk
1. 쿠킹을 하기 전에 패키지를 쪼갭니다.
Redirect_002.upk
TERA 콘솔의 해결법
2. 쪼개진 파일로 쿠킹
• Seek-Free 라서 연관 Object가 딸려 들어감
FX_A_0001_PS
FX_A_0002_PS
Redirect_001.upk
Redirect_002.upk
FX_A_0001_PS_dup
FX_A_0002_PS_dup
Redirect_001.xxx
Redirect_002.xxx
FX_A_0001_MI
FX_A_0001_MAT
FX_A_0002_MI
FX_A_0002_MAT
TERA 콘솔의 해결법
3. 이걸 다시 하나의 파일로 합침
FX_A_0001_PS_dup
FX_A_0001_MI
FX_A_0001_MAT
FX_A_0002_PS_dup
FX_A_0002_MI
FX_A_0002_MAT
Composite_001.xxx
FX_A_0001_PS_dup
FX_A_0002_PS_dup
Redirect_001.xxx
Redirect_002.xxx
FX_A_0001_MI
FX_A_0001_MAT
FX_A_0002_MI
FX_A_0002_MAT
TERA 콘솔의 해결법
4. Mapping Table을 들고 관리
• FX_A.FX_A_0001_PS 를 로딩하려고 하면 Redirect_001.FX_A_001_PS_dup 을 로딩하도록 바꿔침
• 파일 I/O에 과정에서 Composite 파일의 일부분을 읽어 그 메모리 주소를 넘겨주도록 바꿔침
• 결과적으로 작은 파일 하나를 LoadPackageAsync 하는 것 처럼 됨
FX_A.FX_A_0001_PS Redirect_001.FX_A_0001_PS_dup Composite_001:0
FX_A.FX_A_0002_PS Redirect_002.FX_A_0002_PS_dup Composite_001:256
… … …
정리
리소스 로딩
• MMORPG는 동적 데이터가 많아서 로딩 퍼포먼스가 문제가 됨
• UE3는 콘솔에서 Seek-Free 로직을 강제함
• 애초에 아트 리소스를 너무 크지 않게 잘 관리하자
TERA 콘솔은
• PC와의 일관성 유지를 위해 아트 리소스 수정을 포기
• 별도의 패키지 Redirecting 기법을 만들어서 문제를 회피
• 대신에 쿠킹시간을 손해 보고 총 패키지 용량이 증가함
4. UE3 콘솔 최적화 – 메인 스레드 병렬화
• UE3 엔진 구조에 대한 대략적인 설명
• 사이드 이펙트를 최소화 하면서 멀티 스레드 도입하기
1. TERA 콘솔팀의 탄생과 시작
2. TERA 콘솔팀의 2년간 개발 기록
3. UE3 콘솔 최적화 – 리소스 로딩
4. UE3 콘솔 최적화 – 메인 스레드 병렬화
5. 마무리
멀티스레드 최적화
현세대 콘솔의 CPU 스펙 : 1.6Ghz * 8코어
(요새 CPU 코어 클럭 수의 반토막)
UE3는 코어 2개만 바쁜 엔진
멀티 스레드로 최적화를 꾀하는 것은 선택이 아닌 필수
Unreal Engine 3 구조
Thread 1
Thread 2
Thread 3
Thread 4
흔히들 UE3는 코어를 2.5개 쓴다고들 하죠.
Render Thread Tick
Main Thread Tick
Render Thread Tick
Main Thread Tick
Render Thread Tick
Main Thread Tick
Render Command Render Command
I/O Request
PhysX Thread
I/O Request
PhysX Thread
I/O Request
PhysX Thread
1 Frame
Main Thread
ProcessInput
ProcessAsyncLoading
WorldTick
InteractionTick
RedrawViewport
Main Thread Tick Input Handle 하는 거죠
비동기 로딩 처리. 필요한 파일들을 Serialize 합니다.
5ms 넘으면 그만하고 다음 틱에 이어서..
실제로 레벨에 존재하는 모든 오브젝트 업데이트
(가장 큰 부하 = 최적화 대상)
추가로 Tick 처리가 필요한 모듈에 대한 처리.
GFX tick이 여기서 수행됨 (최적화 대상)
Scene Rendering을 위한 RenderCommand들을 생성
UE3는 Actor-Component 모델
Actor
StaticMeshComponent
SkeletalMeshComponent
CylinderComponent
ParticleSystemComponent
월드에 존재하는 모든 오브젝트는 Actor
Components
실제 행동 구현은 Component로
Attach
World Tick
PreAsync Tick
DuringAsync Tick
PostAsync Tick
PostUpdate Tick
EffectUpdate
World Tick
PostTickComponent
ProcessInput
ProcessAsyncLoading
InteractionTick
RedrawViewport
Main Thread Tick
WorldTick
세 개의 Tick Group으로 나눠 짐
World Tick
PreAsync Tick
DuringAsync Tick
PostAsync Tick
PostUpdate Tick
EffectUpdate
World Tick
PostTickComponent
ProcessInput
ProcessAsyncLoading
InteractionTick
RedrawViewport
Main Thread Tick
WorldTick
여기서 PhysX thread Start
여기서 PhysX thread Sync
World Tick
PreAsync Tick
DuringAsync Tick
PostAsync Tick
PostUpdate Tick
EffectUpdate
World Tick
PostTickComponent
ProcessInput
ProcessAsyncLoading
InteractionTick
RedrawViewport
Main Thread Tick
WorldTick
물리 시뮬레이션 전에 업데이트 해야 하는 것들
Static / Skeletal MeshComponent가 여기 해당
(최적화 대상)
물리 시뮬레이션과 동시에 실행되어도 상관 없는 것들
ParticleSystemComponent를 포함해
대부분의 Component가 여기 해당
(최적화 대상)
물리 시뮬레이션 후에 업데이트 해야 하는 것들
거의 해당하는 Component가 없음
(최적화 대상 아님)
World Tick
PreAsync Tick
DuringAsync Tick
PostAsync Tick
PostUpdate Tick
EffectUpdate
World Tick
PostTickComponent
ProcessInput
ProcessAsyncLoading
InteractionTick
RedrawViewport
Main Thread Tick
WorldTick
Add/Remove Primitive 등의
RenderCommand를 생성
(최적화 대상)
필요한 후처리들 (최적화 대상 아님)
최적화 전략
전제 조건
1) 테라 콘솔도 지속적인 라이브 서비스를 해야 한다.
2) 1)의 이유로 PC 라이브 서비스의 코드를 지속적으로 머지 해와야 한다.
3) 2) 의 이유로 기존 코드 구조를 최대한 유지할 필요가 있다.
4) 그리고 시간이 없으니 빠르게 구현할 수 있는 방법으로!
결론 : Fork and Join이 정석
Fork and Join
• 특정 구간을 병렬화로 시키고, 다 끝나야 다음 스텝으로 넘어가는 방법
• 구현이 쉽지만 CPU 사용률 100%는 불가능한 방법
• Join이 길어지지 않도록 주의해야 함
Form Wikipedia / Fork-Join Model
실제 구현 - Lambda 만세
• WorldTick 의 간략한 예시 (실제 코드와 똑같지는 않고 일부 각색했습니다)
for(ITER It(ComponentList); It; ++It)
{
It->ConditionalTick(DeltaSeconds)
}
이런 간소화된 모델로 예시를 들면
for(ITER It(ComponentList); It; ++It)
{
#if MultiThread
AsyncTaskManager->AddComponentTick([It, DeltaSeconds]{
#endif
It->ConditionalTick(DeltaSeconds)
#if MultiThread
});
#endif
}
• AsyncTaskManager는 이런 Lambda Job이 30개쯤 모이면 그때 Fork
• 이렇게 기존 코드를 보존한 채 앞뒤로 Lambda 연산을 넣는 것만으로 구현 가능
• 실제로는 매크로 등을 이용해 더 깔끔하게 코드 구현을 했음
World Tick에서 Join 하는 법
• 이렇게 Sync 하는 함수를 넣기만 하면 됨
• Sync 내부는 Task 분배한 것들이 끝나길 기다림
• 만약 아직 시작도 못 있다면 끌어와서 처
• 모든 Task가 끝났다면 모아둔 콜백 처리
TickGroup = TG_PreAsyncWork;
TickActors(this, DeltaSeconds, TickType, GDeferredList);
…
TickGroup = TG_DuringASyncWork;
TickGroup = TG_PreAsyncWork;
TickActors(this, DeltaSeconds, TickType, GDeferredList);
#if Multithread
AsyncTaskManager->Sync();
#endif
…
TickGroup = TG_DuringASyncWork;
Callback?
• 병렬화가 불가능한 로직 덩어리는 분명히 존재함
UParticleSystemComponent::Tick(FLOAT DeltaTime)
{
…
FinializeTickComponent(DeltaTime); // 내부적으로 Component 삭제 로직이 돌기 때문에 병렬화시에 문제가 있음
…
}
UParticleSystemComponent::Tick(FLOAT DeltaTime)
{
…
AddCallBack([this, DeltaTime]{
FinializeTickComponent(DeltaTime); // 내부적으로 Component 삭제 로직이 돌기 때문에 병렬화시에 문제가 있음
});
…
}
Lock으로 해결 가능하기도 함
FParticleDataManager::RemoveParticleSystemComponent(UParticleSystemComponent* InPsysComp)
{
PSysComponent.Remove(InPSysComp)
}
FParticleDataManager::RemoveParticleSystemComponent(UParticleSystemComponent* InPsysComp)
{
Fscopelock Scopedlock(lockObject)
PSysComponent.Remove(InPSysComp)
}
병렬화 전
병렬화 후
Lock을 쓰는 조건
Lock은 Contention이 적을 때만 쓰는 것
• 프레임당 락에 걸려있는 총시간을 말함 -> 직접 재 보면 된다. 마이크로 세컨드 단위일 때에만 Lock 쓰기
• Lock이 없어도 게임이 구동되고 어쩌다가 크래시가 나는 정도의 빈도일 때만 사용한다고 생각하면 됨
• 글로벌 컨테이너에 모든 Component가 접근할 때 정도가 Contention이 문제가 되는데
Thread_local 컨테이너를 만들어서 거기에 작업 수행하다가 Sync할 때 맞추는 우회적 방법 등이 있습니다.
thread_local
//UnAnimTree.cpp
UBOOL UAnimNode::bNodeSearching = FALSE;
INT AnimNode::CurrentSearching = 0;
//UnAnimTree.cpp
thread_local UBOOL UAnimNode::bNodeSearching = FALSE;
thread_local INT AnimNode::CurrentSearching = 0;
• UE3에는 이렇게 임시변수를 전역변수로 쓰는 경우가 있는데 Thread_local화 해버리면 간단.
(함수 콜마다 파라미터로 넘기기 싫어서 이렇게 한 것 처럼 보임)
• 물론 정말 임시변수인지, 글로벌하게 공유할 필요가 있는지는 코드 파악을 확실히 할 것
병렬화 전
병렬화 후
PostTickComponent 병렬화
• World Tick을 Fork and Join으로 병렬화 하는 것은 UE4에도 비슷하게 구현되어 있음
• UE4에서 PostTickComponent는 거의 병렬화를 하지 않았는데 보통 부하가 되지 않기 때문
• Transform 변동에 의한, Octree Add/Remove RenderCommand를 생성하는 부분
PostTickComponent 병렬화
하지만 MMO에서는 아래와 같은 상황이 발생하죠.
PostTickComponent 병렬화
• 해당 상황을 프로파일러로 찍으면 이렇습니다.
• 수백 개 Component의
PostTickComponent를 하는 중
PostTickComponent 병렬화
• 똑같은 방법으로 병렬화
(RingBuffer Write에 Lock을 걸어 버림)
• Lock을 많이 썼음에도 1/3 가량으로 줄어듦
• 움직이는 오브젝트가 많은 게임에서
참고하면 좋을 듯
GFX Tick 병렬화
• Scaleform Update 도 부하의 한 축을 담당
• UI 업데이트가 꼭 World Tick 뒤에 수행되어야 할 이유가 있나? 에 대한 실험을 진행
전략
• 일단 Thread로 뺀다.
• 문제가 나올 때 마다 해결한다.
• 해결 불가능한 문제가 나온다면 포기하고 모두 롤백
• 아니라면 병렬화에 성공했다는 뜻
GFX Tick 병렬화
ProcessInput
ProcessAsyncLoading
WorldTick
InteractionTick
RedrawViewport
Main Thread Tick
SyncGFX
StartGFX
WorldTick 시작하기 전에 Thread Start
원래 수행되던 Interaction Tick 끝나고 Sync
결론 : 쉽지는 않았고, 두 달 정도 걸려서 완성함..
어쨌건 되긴 되더라! (얼렁뚱땅 결말)
최종적인 모습 - Before
1.TERA 로직 1.UE3 로직
최종적인 모습 - After
테라 게임 로직
GFX(UI) 로직
UE3 엔진 로직
렌더링 로직
정리
최적화 전략
• GFX Tick은 엔진 Tick과 분리 가능
• Fork and Join의 방식으로 최대한 기존 코드를 유지하며 빠르게 병렬화 가능
• Critical Section에 대해서는 Callback, Lock, thread_local 등으로 처리
• Lock은 Contention이 적을 때에만 쓰자
• 경우에 따라 로직 자체를 수정할 각오는 필요하며, 언리얼 엔진에 대한 높은 이해는 필수
5. 마무리
1. TERA 콘솔팀의 탄생과 시작
2. TERA 콘솔팀의 2년간 개발 기록
3. UE3 콘솔 최적화 – 리소스 로딩
4. UE3 콘솔 최적화 – 메인 스레드 병렬화
5. 마무리
TERA 콘솔은
• 콘솔 개발/서비스 경험을 내재화 하고자 자체 포팅을 시작
• 이 경험을 토대로, 블루홀 차기 프로젝트에서 콘솔 플랫폼을 고려하기 쉬워 지길 기대
UE3 게임을 현세대 콘솔에 포팅하는 것은
불가능한 일은 아니다!
• UE3-Unsupported 활용 및 전문가 컨설팅으로 빠르게 기반을 만들 수 있음
• TRC / XR은 인내심으로 대응
• 최적화 문제가 있겠지만 어떻게든 해결할 수 있음
• 시장성도 좋아요!
전달하고자 했던 것
콘솔 포팅 개발의 간접 경험
- 어떤 과정을 거쳐 UE3 MMORPG가 콘솔로 포팅 되었는지
- 만약, 콘솔 환경에서 개발하게 되면 어떤 것들을 고려해야 하는지
콘솔 환경에서의 최적화 팁
- UE3 리소스 로딩의 문제점 및 해결을 위해 필요한 지식
- 엔진을 멀티스레드 구조로 개선할 때에 참고할 만한 지식과 사례
테라 콘솔팀 모두 정말 고생 많았고, 고맙습니다
모름지기 컨퍼런스란 기승전 채용 홍보
테라 콘솔 클라이언트 프로그래머 채용 중 (신입/경력 무관)
https://www.bluehole.net/kr/recruit
리마인드, 다음 발표도 듣고 가세요~~
감사합니다.
Q & A
발표 후 Q&A 내용 정리
• Q1. 테크 리소스조차 현재 없는 상태에서 콘솔 포팅을 진행한다면, 한국의 제한된 UE3 개발 인력풀 내에서 외부 인력 채용이 현실적으로 가능할까요?
• A. 아니요. 저는 어렵다고 생각합니다. 발표장에서는 제가 말씀 못 드렸는데, 테라 콘솔팀도 프로그래머 채용을 하려고 굉장히 노력했으나 다
실패했습니다. 한국에 엔진 전문가풀 자체가 많지 않으며, 능력이 있으신 분들도 MMORPG 포팅을 불가능하다고 보시거나, 아니면 연차가 있으셔서
그런지 안정적인 프로젝트를 원하시더라구요. 그래서 테라 콘솔팀도 테라 출신 시니어가 아니라면 아예 신입으로만 채웠습니다. 국내에서 엔진
프로그래머 구하기, 그것도 포팅같은 업무에서는 더더욱 어렵다고 느꼈습니다. 저나 홍상혁님 처럼 회사 내에서 엔진 프로그래머 풀을 늘려갈 계획의
중심이 될 프로그래머가 없는 상황이라면 현실성이 없다고 생각됩니다.
제 발표에 언급된 외주 업체들을 알아보시는 게 차라리 나을 겁니다. 중국, 미국, 캐나다 등지에 정말 많습니다. 저 한테 여쭤 보셔도 몇몇 추천해 드릴 수
있지만, MS나 Sony에 문의하시는 게 확실합니다. 그들은 많은 협력 업체를 알고 있습니다. 저희가 소개받은 업체들도 다 MS와 Sony로 부터 소개받은
회사들입니다.
그리고 포팅 과정은 항상 레거시와의 싸움입니다. 기존 프로젝트에 대해 상당한 지식과 히스토리를 알고 있는 멤버가 없다면 굉장히 힘들어 집니다. 이
점을 감안하시길 추천 드립니다.
발표 후 Q&A 내용 정리
• Q2. 게임 서버는 기존 레거시를 100% 활용하는데 거의 문제가 없었나요?
• A. 네. 테라 콘솔은 서버를 거의 수정하지 않았습니다. 그렇다고 아예 일이 없었던 것은 아닙니다. MS쪽 XR에 보면 네트워크 게임의 경우 통과해야 할
보안 검수가 있는데, 테라가 이걸 탈락 했습니다. 그래서 패킷 암호화 로직을 전반적으로 수정하는 작업이 있었습니다. 그리고 TRC / XR에 의해 일부 추가
구현할 것들이 있습니다. 또한 UI를 수정하다 보니 PC에서는 팝업으로 처리하던 것을 콘솔에서는 한 화면에 정보를 모아 놓기 위해 패킷을 합쳐야 하는
경우도 있었습니다. 최적화 과정에서 중복 패킷을 줄이는 패킷 최적화도 일부 진행 했고요.
어쨌건 지금 테라 콘솔팀은 클라이언트 프로그래머 6명에 서버 프로그래머 1명입니다. 그럼에도 서버 작업이 bottleneck이 되는 경우는 없었습니다.
발표 후 Q&A 내용 정리
• Q3. 테라 피씨는 열심히 했지만 콘솔을 안해봐서 궁금한데요. 2개의 질문이 있습니다. 1. 콘솔로 포팅 하는데 UX.UI에서 가장 크게 변화 된것 2. BM은
콘솔 유저들을 고려 해서 변경을 했는지. 어떻게 하고 왜 변경 했는지요. 발표 잘 들었습니다.
• A. 먼저 UX/UI 에서 가장 크게 변화된 것은 아무래도 폰트 크기입니다. 모든 작업을 할 때에 TV에서 3m 거리를 가정하고 디자인을 했습니다. 폰트와
아이콘을 키우고, 그에 맞게 레이아웃을 수정하는게 기본입니다. 그리고 PC의 마우스 UX를 그대로 가져오면 조작 depth가 늘어납니다. Depth를 줄이기
위해서는 최대한 한 화면에 많은 정보를 보여주고, depth를 들어갈 때에도 각 버튼 별로 다른 기능을 주어서 여러 가지가 나오게 했습니다. 전투 UX에
있어서는 카메라 자동으로 따라가기, 카메라 락온, 타게팅 스킬 락온 범위 관대하게 판정하기, 스킬 발동시 Z 축 보정 일부 넣기 등이 있었고, 스킬 숏컷은
전반적으로 갈아 엎었죠. 많은 게임에서 숏컷이 가장 문제가 될 텐데 테라는 다행히 스킬이 엄청 많은 게임은 아니었습니다. 네버윈터와 디아블로를
레퍼런스로 나름의 연구를 진행한 결과이니 숏컷에 대한 건 테라 콘솔을 직접 플레이 하면서 판단해 주세요
BM에 대해서는 콘솔 유저라고 딱히 PC 유저와 다른 패턴을 보일 것이라 생각하지는 않았습니다. PC와 마찬가지로 F2P로 서비스를 했고, 치장성 아이템
및 편의성 아이템을 DLC로 판매하는 형태입니다. 그래서 실제로 콘솔유저의 구매 패턴이 PC와 다르게 나오는지는 추이를 지켜봐야 알 수 있겠네요.
발표 후 Q&A 내용 정리
• Q4. Seekfree 사용했을 때 용량차이는 어느정도였나요?
• A. PC와 엔진 버전이 다르다 보니 정확한 비교는 어려운데요. PC도 맵에 한해서는 SeekFree로 쿠킹됩니다. 맵에 배치된 static mesh 들을 하나하나 파일
찾아서 읽게 하지 않기 위해서죠. 즉 콘솔은 PC와 비교하면 메시, 이펙트, 사운드 등만 추가로 seekfree로 쿠킹 된다고 보시면 됩니다. 다행히도 이런
단일 파일들은 다른 파일의 내용을 참조하게 설계하면 애초에 그게 멍청한 설계입니다. Material Template에 한해서만 재활용 여지가 있는데,
Reference가 되는 Material Template은 특정 파일에 모아 놓는 것이 언리얼 엔진 활용에서 중요한 포인트입니다.
그리고 Seek-Free는 Serialize할 정보를 복사해오는 거라 실제 용량의 대부분의 차지하게 될 쉐이더 바이너리는 ShaderCache로, 텍스처는
TextureFileCache로 빠집니다. 그래서 Seek-Free라고 해서 파일 용량이 어마어마하게 늘지는 않습니다. 파일 dependency 관리만 잘 하면 우려할
정도는 아니다 라고 이해하시면 됩니다.
그저 Seek-Free가 되었을 때 StaticLoadObject를 못 쓰는게 문제였지요…
발표 후 Q&A 내용 정리
• Q5. 성능 프로파일링은 어떻게 하셨나요?
• A. MS에서 제공하는 PIX라는 툴을 사용했습니다. 저와 홍상혁님의 발표자료에 등장하는 모든 프로파일링 이미지는 PIX에서 캡처한 것입니다. 코드내에
Marker를 박아 놓으면, Visualize된 형태로 프로파일링을 해줍니다. 매우 유용한 툴입니다. PC에서도 DX12를 쓴다면 PIX를 쓸 수 있으니 참고하세요.
PS4에도 Razor CPU라는 비슷한 툴이 있습니다. 실제로는 PIX보다도 더 좋습니다만 Marker가 너무 많으면 약간 부하가 되더라고요. 하지만 PS4의
Razor CPU는 시간 단위로까지 녹화를 해도 무리가 없는 인터페이스입니다. MS의 PIX는 분 단위만 되어도 메모리 사용량이 너무 많아서 툴이
뻗더라구요.
참고로 PS4는 Memory Analyzer도 좋습니다. 메모리 릭 잡을 때 유용하게 사용했습니다. PIX에도 Memory Analyzer가 있지만 너무 느려서 사용하기
힘들더라구요.
아무튼 MS, Sony에서 아주 좋은 프로파일러들을 제공한다고 이해하시면 됩니다. 콘솔 개발을 하게 되시면 이 툴들의 매뉴얼 부터 읽으시면 큰 도움이 될
것입니다.
발표 후 Q&A 내용 정리
• Q6. 3d모델러 입니다. 지원방법이 궁금합니다
• A. 죄송합니다. 질문을 이해 못했습니다. 동시간대 다른 세션에도 그래픽 관련은 없어서 잘못 올리신 질문은 아닌 것 같아요.
두 가지로 해석 가능할 것 같은데, 만약 채용공고에 대한 이야기라면 저희는 프로그래머와 UX 디자이너를 채용 중입니다. 아트 직군은 채용 중이지
않습니다. 테라 콘솔팀은 아트 직군이 따로 없으며 필요한 업무가 있다면 테라 본부에 요청하는 방식으로 일합니다. 테라 본부 아트팀의 채용공고를
확인해 주세요.
혹, 채용공고가 아니라 제가 초반에 언급한 아트 지원이 없어서 UE3 개조로 갔다는 내용에 대한 질문 이신가요? UE3 게임을 UE4로 올린다고 할 때 이건
말이 마이그레이션이지 실제로는 게임을 다시 만드는 겁니다. 이 경우 아트 직군에 부탁할 일은 모든 Max 원본 파일을 가지고 UE4 에디터로 다시
import해서 아트 패키지를 만들어 주시는 겁니다. 3d 모델은 그나마 쉽구요. 배경과 이펙트가 죽어 납니다. 이 일을 실제로 했던 타 회사의 사례를 알지만
제가 함부로 언급하기는 어렵네요. 아무튼 이런 포팅 방법도 충분히 가능한 일입니다. 다만 매우 고비용이며, 발표에서도 언급 했듯이 강한 아트 리더십이
필요합니다.
발표 후 Q&A 내용 정리
• Q7. 최적화 작업에 들어가실 때 프로파일링 이후 전체 일정은 어떤 관점으로 잡으셨나요?
• A. 최적화 일정을 어떻게 산출했냐는 질문이라면, 이건 예측 가능한 영역이 아니었습니다. 아무도 안 해본 일이니까요. 제가 블루홀에서 4년간 일하면서
겪은 작업 방식은 철저한 계획 세우기와는 거리가 멉니다. 모든 기술적 난제에 대해서, 문제를 정확히 파악하고, 아이디어를 정리해 보는 것 까지는 오래
걸리는 일이 아닙니다. 특히 콘솔 최적화의 경우 멀티스레드 구현이 안 되어 있다는 명확한 문제를 인지하고 있었고 , Fork and Join은 현 상황에서 너무
당연한 접근이었죠. UE3 코드 구조도 얼추 알고 있고, 참고할 UE4 코드도 있는 상황이구요. 아마 실제 작업에 들어가면 예상치 못했던 요소들을 많이
만나겠지만 그건 예측 가능한 영역도 아니고, 어차피 다른 선택지도 없었습니다.
그래서 그냥 3개월 열심히 해보고 그 뒤에 판단하자고 정했습니다. 이게 테라 팀이 난제를 극복하는 방식입니다. 경영진 입장에서는 갑갑하겠지만,
실무자에 대한 신뢰를 기반으로 진행하는 거죠. 실무자는 설령 성공하지 못하더라도 다음 결정에 도움될 자료를 준비할 책임이 있습니다. 그래서 기간을
오래 잡지 않습니다. 실제로 제 발표내용의 엔진 Tick 분리하는 프로토타이핑은 한 달 정도 밖에 안 걸렸습니다. 이후에 생각하지 못했던 크래시 잡기, 추가
프로파일링으로 더 뺄 만한 것 찾기의 연속이었죠. 하지만 이 단계가 되면 최적화의 가능성이 충분히 증명됩니다. 만약 Fork and join 전략 자체가 안 먹힐
것이었다면 역시 비슷한 시기에 파악 가능했을 겁니다.
정리하면 ‘9월까지 최적화가 덜 끝나도 상관없으니 가능한 지 최대한 증명해 보고, 만약 어렵다면 또 대책회의를 하자’라는 느낌? 철저한 계산하에 나온
목표가 아니었습니다. 그리고 팀의 사기 관리적 측면에서 접근할 필요도 있습니다. 실무자가 최선을 다할 수 있는 환경을 만들어 주고 중간 검토하는
자리를 마련하기만 하면 됩니다. 테라 팀의 많은 업무들이 이렇게 Bottom-Up 으로 진행됩니다. 그러니까 말도 안 되는 일정에 대한 스트레스를 받을 일도
없죠. 9월에도 여전히 가능성이 안 보였다면 아마 전략 자체를 재검토 하거나, 어떤 부분에서 어려움을 겪고 있는지 분석해 보서나, 아니면 3개월 동안
얻은 정보를 토대로 다음 마일스톤을 정해 보거나 했을 것입니다. 어쨌건 실무자를 믿고 맡기는 것이 핵심입니다.

Weitere ähnliche Inhalte

Was ist angesagt?

김동건, 할머니가 들려주신 마비노기 개발 전설, NDC2019
김동건, 할머니가 들려주신 마비노기 개발 전설, NDC2019김동건, 할머니가 들려주신 마비노기 개발 전설, NDC2019
김동건, 할머니가 들려주신 마비노기 개발 전설, NDC2019devCAT Studio, NEXON
 
NDC 2012 이은석 - 게임회사 취업특강 (커리어세션)
NDC 2012 이은석 - 게임회사 취업특강 (커리어세션)NDC 2012 이은석 - 게임회사 취업특강 (커리어세션)
NDC 2012 이은석 - 게임회사 취업특강 (커리어세션)Eunseok Yi
 
게임 개발자가 되고 싶어요
게임 개발자가 되고 싶어요게임 개발자가 되고 싶어요
게임 개발자가 되고 싶어요Lee Sangkyoon (Kay)
 
게임에서 흔히 쓰이는 최적화 전략 by 엄윤섭 @ 지스타 컨퍼런스 2013
게임에서 흔히 쓰이는 최적화 전략 by 엄윤섭 @ 지스타 컨퍼런스 2013게임에서 흔히 쓰이는 최적화 전략 by 엄윤섭 @ 지스타 컨퍼런스 2013
게임에서 흔히 쓰이는 최적화 전략 by 엄윤섭 @ 지스타 컨퍼런스 2013영욱 오
 
[150124 박민근] 모바일 게임 개발에서 루아 스크립트 활용하기
[150124 박민근] 모바일 게임 개발에서 루아 스크립트 활용하기[150124 박민근] 모바일 게임 개발에서 루아 스크립트 활용하기
[150124 박민근] 모바일 게임 개발에서 루아 스크립트 활용하기MinGeun Park
 
조정훈, 게임 프로그래머를 위한 클래스 설계, NDC2012
조정훈, 게임 프로그래머를 위한 클래스 설계, NDC2012조정훈, 게임 프로그래머를 위한 클래스 설계, NDC2012
조정훈, 게임 프로그래머를 위한 클래스 설계, NDC2012devCAT Studio, NEXON
 
5강 알파와알파소팅
5강 알파와알파소팅5강 알파와알파소팅
5강 알파와알파소팅JP Jung
 
홍성우, 게임 프로그래머는 어떻게 가르치나요?, NDC2018
홍성우, 게임 프로그래머는 어떻게 가르치나요?, NDC2018홍성우, 게임 프로그래머는 어떻게 가르치나요?, NDC2018
홍성우, 게임 프로그래머는 어떻게 가르치나요?, NDC2018devCAT Studio, NEXON
 
02. 게임기획, 재미를 향한 끝없는 여정
02. 게임기획, 재미를 향한 끝없는 여정02. 게임기획, 재미를 향한 끝없는 여정
02. 게임기획, 재미를 향한 끝없는 여정태성 이
 
이승재, 일정대로 출시하기 왜 & 어떻게: 개발자를 위한 제작진행개론, NDC2017
이승재, 일정대로 출시하기 왜 & 어떻게: 개발자를 위한 제작진행개론, NDC2017이승재, 일정대로 출시하기 왜 & 어떻게: 개발자를 위한 제작진행개론, NDC2017
이승재, 일정대로 출시하기 왜 & 어떻게: 개발자를 위한 제작진행개론, NDC2017devCAT Studio, NEXON
 
국내인디게임개발자의현실
국내인디게임개발자의현실국내인디게임개발자의현실
국내인디게임개발자의현실Mingu Heo
 
[IGC 2016] 띵소프트 이득규 - 삼국지조조전 Online L10N 개발 Case Study
[IGC 2016] 띵소프트 이득규 - 삼국지조조전 Online L10N 개발 Case Study[IGC 2016] 띵소프트 이득규 - 삼국지조조전 Online L10N 개발 Case Study
[IGC 2016] 띵소프트 이득규 - 삼국지조조전 Online L10N 개발 Case Study강 민우
 
위대한 게임개발팀의 공통점
위대한 게임개발팀의 공통점위대한 게임개발팀의 공통점
위대한 게임개발팀의 공통점Ryan Park
 
멀티스레드 렌더링 (Multithreaded rendering)
멀티스레드 렌더링 (Multithreaded rendering)멀티스레드 렌더링 (Multithreaded rendering)
멀티스레드 렌더링 (Multithreaded rendering)Bongseok Cho
 
Ndc17 슈퍼판타지워 포스트모템_srpg로 맨땅에 헤딩하기
Ndc17 슈퍼판타지워 포스트모템_srpg로 맨땅에 헤딩하기Ndc17 슈퍼판타지워 포스트모템_srpg로 맨땅에 헤딩하기
Ndc17 슈퍼판타지워 포스트모템_srpg로 맨땅에 헤딩하기JungKeun Lee
 
재미이론의 시사점과 게임 플레이 개선에 적용방안
재미이론의 시사점과 게임 플레이 개선에 적용방안재미이론의 시사점과 게임 플레이 개선에 적용방안
재미이론의 시사점과 게임 플레이 개선에 적용방안Sunnyrider
 
[IGC2015] 엔씨소프트 김주용-내가 사랑한 MMO들
[IGC2015] 엔씨소프트 김주용-내가 사랑한 MMO들[IGC2015] 엔씨소프트 김주용-내가 사랑한 MMO들
[IGC2015] 엔씨소프트 김주용-내가 사랑한 MMO들강 민우
 
[IGC 2016] 컴투스 김동준 - 기획 지망생은 무엇을 준비하나요?
[IGC 2016] 컴투스 김동준 - 기획 지망생은 무엇을 준비하나요?[IGC 2016] 컴투스 김동준 - 기획 지망생은 무엇을 준비하나요?
[IGC 2016] 컴투스 김동준 - 기획 지망생은 무엇을 준비하나요?강 민우
 

Was ist angesagt? (20)

게임강연정리
게임강연정리게임강연정리
게임강연정리
 
김동건, 할머니가 들려주신 마비노기 개발 전설, NDC2019
김동건, 할머니가 들려주신 마비노기 개발 전설, NDC2019김동건, 할머니가 들려주신 마비노기 개발 전설, NDC2019
김동건, 할머니가 들려주신 마비노기 개발 전설, NDC2019
 
NDC 2012 이은석 - 게임회사 취업특강 (커리어세션)
NDC 2012 이은석 - 게임회사 취업특강 (커리어세션)NDC 2012 이은석 - 게임회사 취업특강 (커리어세션)
NDC 2012 이은석 - 게임회사 취업특강 (커리어세션)
 
게임 개발자가 되고 싶어요
게임 개발자가 되고 싶어요게임 개발자가 되고 싶어요
게임 개발자가 되고 싶어요
 
게임에서 흔히 쓰이는 최적화 전략 by 엄윤섭 @ 지스타 컨퍼런스 2013
게임에서 흔히 쓰이는 최적화 전략 by 엄윤섭 @ 지스타 컨퍼런스 2013게임에서 흔히 쓰이는 최적화 전략 by 엄윤섭 @ 지스타 컨퍼런스 2013
게임에서 흔히 쓰이는 최적화 전략 by 엄윤섭 @ 지스타 컨퍼런스 2013
 
[150124 박민근] 모바일 게임 개발에서 루아 스크립트 활용하기
[150124 박민근] 모바일 게임 개발에서 루아 스크립트 활용하기[150124 박민근] 모바일 게임 개발에서 루아 스크립트 활용하기
[150124 박민근] 모바일 게임 개발에서 루아 스크립트 활용하기
 
[PandoraCube] 게임 디자인 원리
[PandoraCube] 게임 디자인 원리[PandoraCube] 게임 디자인 원리
[PandoraCube] 게임 디자인 원리
 
조정훈, 게임 프로그래머를 위한 클래스 설계, NDC2012
조정훈, 게임 프로그래머를 위한 클래스 설계, NDC2012조정훈, 게임 프로그래머를 위한 클래스 설계, NDC2012
조정훈, 게임 프로그래머를 위한 클래스 설계, NDC2012
 
5강 알파와알파소팅
5강 알파와알파소팅5강 알파와알파소팅
5강 알파와알파소팅
 
홍성우, 게임 프로그래머는 어떻게 가르치나요?, NDC2018
홍성우, 게임 프로그래머는 어떻게 가르치나요?, NDC2018홍성우, 게임 프로그래머는 어떻게 가르치나요?, NDC2018
홍성우, 게임 프로그래머는 어떻게 가르치나요?, NDC2018
 
02. 게임기획, 재미를 향한 끝없는 여정
02. 게임기획, 재미를 향한 끝없는 여정02. 게임기획, 재미를 향한 끝없는 여정
02. 게임기획, 재미를 향한 끝없는 여정
 
이승재, 일정대로 출시하기 왜 & 어떻게: 개발자를 위한 제작진행개론, NDC2017
이승재, 일정대로 출시하기 왜 & 어떻게: 개발자를 위한 제작진행개론, NDC2017이승재, 일정대로 출시하기 왜 & 어떻게: 개발자를 위한 제작진행개론, NDC2017
이승재, 일정대로 출시하기 왜 & 어떻게: 개발자를 위한 제작진행개론, NDC2017
 
국내인디게임개발자의현실
국내인디게임개발자의현실국내인디게임개발자의현실
국내인디게임개발자의현실
 
[IGC 2016] 띵소프트 이득규 - 삼국지조조전 Online L10N 개발 Case Study
[IGC 2016] 띵소프트 이득규 - 삼국지조조전 Online L10N 개발 Case Study[IGC 2016] 띵소프트 이득규 - 삼국지조조전 Online L10N 개발 Case Study
[IGC 2016] 띵소프트 이득규 - 삼국지조조전 Online L10N 개발 Case Study
 
위대한 게임개발팀의 공통점
위대한 게임개발팀의 공통점위대한 게임개발팀의 공통점
위대한 게임개발팀의 공통점
 
멀티스레드 렌더링 (Multithreaded rendering)
멀티스레드 렌더링 (Multithreaded rendering)멀티스레드 렌더링 (Multithreaded rendering)
멀티스레드 렌더링 (Multithreaded rendering)
 
Ndc17 슈퍼판타지워 포스트모템_srpg로 맨땅에 헤딩하기
Ndc17 슈퍼판타지워 포스트모템_srpg로 맨땅에 헤딩하기Ndc17 슈퍼판타지워 포스트모템_srpg로 맨땅에 헤딩하기
Ndc17 슈퍼판타지워 포스트모템_srpg로 맨땅에 헤딩하기
 
재미이론의 시사점과 게임 플레이 개선에 적용방안
재미이론의 시사점과 게임 플레이 개선에 적용방안재미이론의 시사점과 게임 플레이 개선에 적용방안
재미이론의 시사점과 게임 플레이 개선에 적용방안
 
[IGC2015] 엔씨소프트 김주용-내가 사랑한 MMO들
[IGC2015] 엔씨소프트 김주용-내가 사랑한 MMO들[IGC2015] 엔씨소프트 김주용-내가 사랑한 MMO들
[IGC2015] 엔씨소프트 김주용-내가 사랑한 MMO들
 
[IGC 2016] 컴투스 김동준 - 기획 지망생은 무엇을 준비하나요?
[IGC 2016] 컴투스 김동준 - 기획 지망생은 무엇을 준비하나요?[IGC 2016] 컴투스 김동준 - 기획 지망생은 무엇을 준비하나요?
[IGC 2016] 컴투스 김동준 - 기획 지망생은 무엇을 준비하나요?
 

Ähnlich wie [NDC 2018] 테라 콘솔 포팅기 - UE3 게임 현세대 콘솔로 이식하기

KGC 2014, 'Software Enginner in Test' in Game Development (Bluehole Studio)
KGC 2014, 'Software Enginner in Test' in Game Development (Bluehole Studio)KGC 2014, 'Software Enginner in Test' in Game Development (Bluehole Studio)
KGC 2014, 'Software Enginner in Test' in Game Development (Bluehole Studio)Sungmin Kim
 
[NDC17] Protocol:hyperspace Diver 개발 포스트모템
[NDC17] Protocol:hyperspace Diver 개발 포스트모템[NDC17] Protocol:hyperspace Diver 개발 포스트모템
[NDC17] Protocol:hyperspace Diver 개발 포스트모템Young Soo Kim
 
Age Of Empires II : Age Of Kings Postmotem
Age Of Empires II : Age Of Kings PostmotemAge Of Empires II : Age Of Kings Postmotem
Age Of Empires II : Age Of Kings PostmotemNam Hyeonuk
 
애자일 게임 개발: 현실 세계의 혼돈을 다루는 법 (Agile Game Development: Dealing With Chaos In Th...
애자일 게임 개발: 현실 세계의 혼돈을 다루는 법 (Agile Game Development: Dealing With Chaos In Th...애자일 게임 개발: 현실 세계의 혼돈을 다루는 법 (Agile Game Development: Dealing With Chaos In Th...
애자일 게임 개발: 현실 세계의 혼돈을 다루는 법 (Agile Game Development: Dealing With Chaos In Th...Kay Kim
 
내가써본 nGrinder-SpringCamp 2015
내가써본 nGrinder-SpringCamp 2015내가써본 nGrinder-SpringCamp 2015
내가써본 nGrinder-SpringCamp 2015Lim SungHyun
 
[IGC 2017] 넥스트플로어 김영수 - Protocol:hyperspace Diver 개발 포스트모템
[IGC 2017] 넥스트플로어 김영수 - Protocol:hyperspace Diver 개발 포스트모템[IGC 2017] 넥스트플로어 김영수 - Protocol:hyperspace Diver 개발 포스트모템
[IGC 2017] 넥스트플로어 김영수 - Protocol:hyperspace Diver 개발 포스트모템강 민우
 
131 deview 2013 yobi-채수원
131 deview 2013 yobi-채수원131 deview 2013 yobi-채수원
131 deview 2013 yobi-채수원NAVER D2
 
[NDC] 인디 게임 개발사의 콘솔도전기
[NDC] 인디 게임 개발사의 콘솔도전기[NDC] 인디 게임 개발사의 콘솔도전기
[NDC] 인디 게임 개발사의 콘솔도전기Seokho Lee
 
애자일 스크럼과 JIRA
애자일 스크럼과 JIRA 애자일 스크럼과 JIRA
애자일 스크럼과 JIRA Terry Cho
 
[IGC2017] Protocol:hyperspace Diver 개발 포스트모템
[IGC2017] Protocol:hyperspace Diver 개발 포스트모템[IGC2017] Protocol:hyperspace Diver 개발 포스트모템
[IGC2017] Protocol:hyperspace Diver 개발 포스트모템Young Soo Kim
 
Battle.ai 2016년 1학기 최종발표
Battle.ai 2016년 1학기 최종발표Battle.ai 2016년 1학기 최종발표
Battle.ai 2016년 1학기 최종발표Osori Hanyang
 
실전 애자일 게임 개발 (Agile Game Agile Game Development From The Trenches)
실전 애자일 게임 개발 (Agile Game Agile Game Development From The Trenches)실전 애자일 게임 개발 (Agile Game Agile Game Development From The Trenches)
실전 애자일 게임 개발 (Agile Game Agile Game Development From The Trenches)Kay Kim
 
취미로 엔진 만들기
취미로 엔진 만들기취미로 엔진 만들기
취미로 엔진 만들기Jiho Choi
 
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...hoondong kim
 
게임 개발에 도움을 주는 CruiseControl.NET과 Windows Terminal
게임 개발에 도움을 주는 CruiseControl.NET과 Windows Terminal게임 개발에 도움을 주는 CruiseControl.NET과 Windows Terminal
게임 개발에 도움을 주는 CruiseControl.NET과 Windows TerminalOnGameServer
 
NDC14 범용 게임 서버 프레임워크 디자인 및 테크닉
NDC14 범용 게임 서버 프레임워크 디자인 및 테크닉NDC14 범용 게임 서버 프레임워크 디자인 및 테크닉
NDC14 범용 게임 서버 프레임워크 디자인 및 테크닉iFunFactory Inc.
 
(게임개발을위한) printf("Hello World!"); 그 이상의 콘솔 프로그래밍
(게임개발을위한) printf("Hello World!"); 그 이상의 콘솔 프로그래밍(게임개발을위한) printf("Hello World!"); 그 이상의 콘솔 프로그래밍
(게임개발을위한) printf("Hello World!"); 그 이상의 콘솔 프로그래밍NDOORS
 
C'est la vie (hello bert!)
C'est la vie (hello bert!)C'est la vie (hello bert!)
C'est la vie (hello bert!)Junho Lee
 
Sccc 서버 사용내역
Sccc 서버 사용내역Sccc 서버 사용내역
Sccc 서버 사용내역성화 이
 

Ähnlich wie [NDC 2018] 테라 콘솔 포팅기 - UE3 게임 현세대 콘솔로 이식하기 (20)

KGC 2014, 'Software Enginner in Test' in Game Development (Bluehole Studio)
KGC 2014, 'Software Enginner in Test' in Game Development (Bluehole Studio)KGC 2014, 'Software Enginner in Test' in Game Development (Bluehole Studio)
KGC 2014, 'Software Enginner in Test' in Game Development (Bluehole Studio)
 
[NDC17] Protocol:hyperspace Diver 개발 포스트모템
[NDC17] Protocol:hyperspace Diver 개발 포스트모템[NDC17] Protocol:hyperspace Diver 개발 포스트모템
[NDC17] Protocol:hyperspace Diver 개발 포스트모템
 
Age Of Empires II : Age Of Kings Postmotem
Age Of Empires II : Age Of Kings PostmotemAge Of Empires II : Age Of Kings Postmotem
Age Of Empires II : Age Of Kings Postmotem
 
애자일 게임 개발: 현실 세계의 혼돈을 다루는 법 (Agile Game Development: Dealing With Chaos In Th...
애자일 게임 개발: 현실 세계의 혼돈을 다루는 법 (Agile Game Development: Dealing With Chaos In Th...애자일 게임 개발: 현실 세계의 혼돈을 다루는 법 (Agile Game Development: Dealing With Chaos In Th...
애자일 게임 개발: 현실 세계의 혼돈을 다루는 법 (Agile Game Development: Dealing With Chaos In Th...
 
내가써본 nGrinder-SpringCamp 2015
내가써본 nGrinder-SpringCamp 2015내가써본 nGrinder-SpringCamp 2015
내가써본 nGrinder-SpringCamp 2015
 
[IGC 2017] 넥스트플로어 김영수 - Protocol:hyperspace Diver 개발 포스트모템
[IGC 2017] 넥스트플로어 김영수 - Protocol:hyperspace Diver 개발 포스트모템[IGC 2017] 넥스트플로어 김영수 - Protocol:hyperspace Diver 개발 포스트모템
[IGC 2017] 넥스트플로어 김영수 - Protocol:hyperspace Diver 개발 포스트모템
 
131 deview 2013 yobi-채수원
131 deview 2013 yobi-채수원131 deview 2013 yobi-채수원
131 deview 2013 yobi-채수원
 
[NDC] 인디 게임 개발사의 콘솔도전기
[NDC] 인디 게임 개발사의 콘솔도전기[NDC] 인디 게임 개발사의 콘솔도전기
[NDC] 인디 게임 개발사의 콘솔도전기
 
애자일 스크럼과 JIRA
애자일 스크럼과 JIRA 애자일 스크럼과 JIRA
애자일 스크럼과 JIRA
 
[IGC2017] Protocol:hyperspace Diver 개발 포스트모템
[IGC2017] Protocol:hyperspace Diver 개발 포스트모템[IGC2017] Protocol:hyperspace Diver 개발 포스트모템
[IGC2017] Protocol:hyperspace Diver 개발 포스트모템
 
Battle.ai 2016년 1학기 최종발표
Battle.ai 2016년 1학기 최종발표Battle.ai 2016년 1학기 최종발표
Battle.ai 2016년 1학기 최종발표
 
161004 battle ai
161004 battle ai161004 battle ai
161004 battle ai
 
실전 애자일 게임 개발 (Agile Game Agile Game Development From The Trenches)
실전 애자일 게임 개발 (Agile Game Agile Game Development From The Trenches)실전 애자일 게임 개발 (Agile Game Agile Game Development From The Trenches)
실전 애자일 게임 개발 (Agile Game Agile Game Development From The Trenches)
 
취미로 엔진 만들기
취미로 엔진 만들기취미로 엔진 만들기
취미로 엔진 만들기
 
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...
 
게임 개발에 도움을 주는 CruiseControl.NET과 Windows Terminal
게임 개발에 도움을 주는 CruiseControl.NET과 Windows Terminal게임 개발에 도움을 주는 CruiseControl.NET과 Windows Terminal
게임 개발에 도움을 주는 CruiseControl.NET과 Windows Terminal
 
NDC14 범용 게임 서버 프레임워크 디자인 및 테크닉
NDC14 범용 게임 서버 프레임워크 디자인 및 테크닉NDC14 범용 게임 서버 프레임워크 디자인 및 테크닉
NDC14 범용 게임 서버 프레임워크 디자인 및 테크닉
 
(게임개발을위한) printf("Hello World!"); 그 이상의 콘솔 프로그래밍
(게임개발을위한) printf("Hello World!"); 그 이상의 콘솔 프로그래밍(게임개발을위한) printf("Hello World!"); 그 이상의 콘솔 프로그래밍
(게임개발을위한) printf("Hello World!"); 그 이상의 콘솔 프로그래밍
 
C'est la vie (hello bert!)
C'est la vie (hello bert!)C'est la vie (hello bert!)
C'est la vie (hello bert!)
 
Sccc 서버 사용내역
Sccc 서버 사용내역Sccc 서버 사용내역
Sccc 서버 사용내역
 

[NDC 2018] 테라 콘솔 포팅기 - UE3 게임 현세대 콘솔로 이식하기

  • 1. 블루홀 테라본부 콘솔포팅TFT 이해찬 - UE3 게임 현세대 콘솔로 이식하기 <테라> 콘솔 포팅기
  • 2. TERA - Free-Targeting MMORPG - 2007년 개발 시작 - 2011년 한게임 서비스 시작 - 2016년 넥슨 서비스 시작 - 현재 북미, 유럽 포함 8개 지역에서 서비스 중
  • 3. - 2016년 개발 시작 - 2018년 4월 3일 정식 런칭 - PlayStation4 / XBox One 동시 런칭 - En Masse Entertainment 퍼블리싱 - 북미 / 유럽 서비스 TERA Console
  • 6. 테라 콘솔을 만들면서 있었던 이런저런 일들을 공유하고자 합니다. TV로 보는 엘린짱 TERA~ (감동)
  • 7. 발표자 소개 • 2014.2 ~ : 블루홀 테라본부 클라이언트팀 • 2016.3 ~ : 블루홀 테라본부 콘솔포팅TFT • haechan@bluehole.net
  • 8. 주요 발표 내용 콘솔포팅에 대한 전략 세우기 • 팀 빌딩, 일정 수립, 그리고 기술적 결정 사항들 • TERA 콘솔의 사례 공유 추천 청강 대상 : 리드급 엔지니어, 프로젝트 매니저 UE3엔진을 현세대기 콘솔에 이식할 때의 최적화 방법 • 콘솔 기기의 최적화 전략 • 리소스 로딩 최적화, 메인 스레드 로직 최적화 추천 청강 대상 : UE3 개발자, 콘솔 플랫폼 개발자
  • 9. 바로 이어서 렌더링 스레드 최적화에 대한 발표가 있습니다 연결되는 내용이니 이 발표도 많이 들어주세요~
  • 10. 목차 1. TERA 콘솔팀의 탄생과 시작 2. TERA 콘솔팀의 2년간 개발 기록 3. UE3 콘솔 최적화 – 리소스 로딩 4. UE3 콘솔 최적화 – 메인 스레드 병렬화 5. 마무리
  • 11. 1. TERA 콘솔팀의 탄생과 시작 • 어쩌다가 TERA를 콘솔로 포팅하게 되었는지 • 어떻게 포팅 전략을 세웠는지 1. TERA 콘솔팀의 탄생과 시작 2. TERA 콘솔팀의 2년간 개발 기록 3. UE3 콘솔 최적화 – 리소스 로딩 4. UE3 콘솔 최적화 – 메인 스레드 병렬화 5. 마무리
  • 12. ※과장된 표현입니다 님아 네버윈터라는 MMORPG가 XBOX ONE으로 나왔는데 너무 멋있어! 우리도 하자! 어.. 그래? 근데 포팅하는 게 쉽지는 않을 것 같은데.. 걱정 ㄴㄴ 이런 거 외주하는 업체 많음. 내가 알아서 진행 하겠음 ???? (그럴 리가??) 그럼 검토해 볼까? 사건의 시작 (2015년 겨울)
  • 13. 하지만 결국 불발됩니다. • 해외 업체와 협업 가능한 인프라 구축의 어려움 (Feat. 폐쇄망) • 서비스를 위한 런처, 패치 시스템, 운영툴 등은 결국 우리가 해야함 • 기획서도 다 써줘야 하고, 질의응답을 위해서라도 우리 비용 들어감 • 추후 유지보수도 어차피 우리 몫 • 너무 비쌈 • 등등등.. 한 줄 요약 : 이럴 거면 외주를 왜 하지 싶을 정도로 관리 비용이 비쌌음
  • 14. 핵심 기술을 외주로 해결하는 게 제작의 명가가 나아갈 방향인가에 대한 정체성 고민 기왕 콘솔 서비스를 해볼거면 직접 개발 경험을 쌓는 것이 회사가 발전하는 방향이 아닐까? (블루홀 홈페이지의 소개 내용)
  • 15. 2016년 3월 4일.. 하.. 해찬아 테라를 콘솔로 옮기는 걸 내부에서 할까 하는데, 가능하다고 보니? 음? 별 것도 아니구먼 제가 해드림 ㄱㄱ 코.. 콜! ※과장된 표현입니다
  • 16. 이렇게 TFT가 발족됩니다 (바로 다음 주 월요일 발령 -_-) 관리자급 제외하면 1인 실무자 R&D 팀으로 시작 ⓒShotaro Tokuno, HOUBUNSHA/NEW GAME! Project
  • 17. 어떻게 포팅하지? 기존 UE3 엔진을 개조한다. TERA 엔진을 UE4로 올린다 (TERA를 UE4로 다시 만든다) UE3 는 PS3, Xbox 360 용 게임 엔진 ⓒWarner Bros. / The Matrix
  • 18. 개발 조건 • 소규모 R&D 팀 • 테라본부 지원 기대하기 힘듦 • 아트 지원은 더더욱 없다 UE4로 가려면? • UE3 아트리소스를 그대로 UE4에서 읽을 수 있게 하는 것은 정말 힘듦 • 아트팀이 노동 집약적으로 포팅하는 것이 그나마 현실적 • 아트 퀄리티가 필연적으로 달라짐 => 강한 아트 디렉팅이 필요 결론 : 테크 파워만으로 포팅하기 => UE3를 개조하자 개발 자원 고려
  • 19. UE3-Unsupported의 존재 외주 개발 UE3는 2012년에 업데이트가 끝났지만 외주를 통해 현세대콘솔 지원을 합니다. 개발
  • 20. TERA는 구형 UE3 <기존 PC TERA의 UE3> <UE3 Unsupported> - UE3 2010년에서 업데이트 중지 - 32bit - GFX 3.0 - UE3 최신 (2012년까지 업데이트) - 64bit - GFX 4.2 • 단순히 플랫폼 Layer의 코드만 가져와서 될 게 아니라 다른 엔진 코어까지 가져와야 하는 상황 • ‘기존 TERA를 개조’하는게 아니라 ‘UE3-Unsupported에 TERA를 다시 만드는’ 방법으로 결정 • 반대로 했다면 렌더링 되게 만드는데 까지만 몇 달은 걸렸을 것
  • 21. 정리 외주 vs 자체개발 • 콘솔 포팅을 전문적으로 하는 회사들이 많은 것은 사실 • 패키지게임과 달리 온라인 서비스를 지속적으로 할 거면 외주관리가 만만치 않다. • 블루홀은 콘솔 개발/서비스 경험을 내재화 하고 싶었기에 직접 포팅을 선택 UE3 게임을 포팅할 때에는 • UE4로 가는 것은 좋은 선택이나 아트 파워가 많이 필요함 • 테크 위주의 팀에게는 UE3-Unsupported 를 활용하는 것이 현실적 • 테라는 엔진 변경점이 많아서 게임을 다시 만드는 방법을 선택
  • 22. 2. TERA 콘솔팀의 2년간 개발 기록 • 포팅을 할 때 어떤 일들이 필요한지 • 어떤 일이 어떠한 멤버 구성으로 얼만큼의 일정이 소요되었는지 • 테라 콘솔팀의 사례를 통해 공유 1. TERA 콘솔팀의 탄생과 시작 2. TERA 콘솔팀의 2년간 개발 기록 3. UE3 콘솔 최적화 – 리소스 로딩 4. UE3 콘솔 최적화 – 메인 스레드 병렬화 5. 마무리
  • 23. 주요 마일스톤 2016.3 18.3.9 1차 OBT 18.3.16 2차 OBT 18.3.27 Founders’ Pack 런칭 2017.1 2018.1 16.9 첫 알파 테스트 16.12. 첫 PS4 QA 시작 17.2 첫 XB1 QA 시작 17.9 최적화 1차 마감 17.9 PAX 시연 17.9 2차 Cert 제출 17.12 Technical Test (CBT) 4 5 6 7 8 9 10 11 12 4 5 6 7 8 9 10 11 122 3 42 3 2018.4.3 정식 오픈 17.4 첫 PS4 Cert 제출 17.4 첫 XB1 Cert 제출 16.3.7 프로젝트 시작
  • 24. 프로덕션 폴리싱프리 프로덕션 주요 마일스톤 2016.3 18.3.9 1차 OBT 18.3.16 2차 OBT 18.3.27 Founders’ Pack 런칭 2017.1 2018.1 16.9 첫 알파 테스트 16.12. 첫 PS4 QA 시작 17.2 첫 XB1 QA 시작 17.9 최적화 1차 마감 17.9 PAX 시연 17.9 2차 Cert 제출 17.12 Technical Test (CBT) 4 5 6 7 8 9 10 11 12 4 5 6 7 8 9 10 11 122 3 42 3 2018.4.3 정식 오픈 17.4 첫 PS4 Cert 제출 17.4 첫 XB1 Cert 제출 16.3.7 프로젝트 시작
  • 25. 시작하기 일단 UE3-Unsupported를 PS4 Devkit에서 먼저 돌려봐야죠 <요런 샘플 게임을> <PS4 개발킷에서> • XB1 Devkit 배송이 늦어져서 PS4 먼저 • UE3-Unsupported의 PS4 SDK 버전이 낮아서 마이그레이션 하느라 몇 주 소요 프리프로덕션 단계 2016.3 4 5 6 7 8 9 10 11 12
  • 26. 프로토 타이핑 이제는 테라를 이식해야죠. • 최소한의 것만 이식을 합니다. • InputManager, 플레이어 이동 처리, Skeletal Mesh 로딩 • 가능성을 확인하는 단계 • 엔진 이식이 아닌 테라를 다시 만드는 접근을 취했기에 빠르게 렌더링 결과를 얻음 2016.3 4 5 6 7 8 9 10 11 12 프리프로덕션 단계
  • 27. 팀원 구함 이 시점에 프로그래머를 2명 더 영입 프로그래머 A • 기존 UI GFX 버전 올리기 및 패드 입력계 구현 프로그래머 B • 기존 아트 리소스 로딩하기 • SkeletalMesh 뿐 아니라 StaticMesh, Particle, Terrain, Sound 등. 일단 로딩이라도 되게. • 엔진 버전이 달라서 필요해진 초기 작업 프로그래머 C (저) • 모든 테라 컨텐츠 코드 이식 및 PS4에 대한 네크워킹 코드 작업 • 게임이 켜지는 것을 우선. 플랫폼 특성상 구동 안되는 코드는 “#if !Console” 후 Todo 처리 2016.3 4 5 6 7 8 9 10 11 12 프리프로덕션 단계
  • 28. 미국으로 그리고 갑자기 미국으로 가게 됩니다 (으잉?) En Masse Entertainment 사무실 창 밖 시애틀 날씨 좋을 때~ 2016.3 4 5 6 7 8 9 10 11 12 프리프로덕션 단계
  • 29. • UE3-Unsupported PS4 버전을 만든 그 회사 • UE3 포팅 전문이지만, 분야 가리지 않고 기술 컨설팅 해주는 회사 • 마침 시애틀에 있음. En Masse Entertainment 사무실과 가까움 • 외주가 아닌 컨설팅의 형태로 접근 -> 전문가에게 빨리 배우자 미국으로 Hardsuit Labs 로 부터 컨설팅 받기 2016.3 4 5 6 7 8 9 10 11 12 프리프로덕션 단계
  • 30. 미국 팀 : PS4 개발 안정화 미국으로 두 팀으로 나눠진 거죠. UI 개발하기 • PC TERA에서 개발용 브랜치 생성 • 숏컷, 인벤토리, 스킬, 퀘스트 저널 인원구성 • 프로그래머 1 • UI 스크립터 2 • UX 디자이너 1 • UI 디자이너 1 • QA 5 • 미국팀 작업에 대한 컨설팅 • XB1도 비슷한 수준으로 이식해 주기 한국팀 : UI 개발 Hardsuit Labs : 컨설팅 2016.3 4 5 6 7 8 9 10 11 12 프리프로덕션 단계 PS4 개발 속도 올리기 • 각종 그래픽 버그 수정 • SpeedTree / Bink Migration • 쿠킹 에러 다수 수정 • 텍스처 캐시 스플리팅 • 패키징 / 배포 연습 인원구성 • 프로그래머 2 • 팀장 1
  • 31. 2016년 7월 중간자료 2016.3 4 5 6 7 8 9 10 11 12 프리프로덕션 단계
  • 32. • 8월 중순 쯤 한국에 돌아와서 한국팀 UI 작업과 머지를 시작 • Hardsuit Labs 작업이 늦어져서 Xbox One 결과 머지는 미뤄짐 합체! 2016.3 4 5 6 7 8 9 10 11 12 프리프로덕션 단계
  • 33. 9월 7일 첫 알파 테스트 버전 (PS4에서 구동한 것) 2016.3 4 5 6 7 8 9 10 11 12 프리프로덕션 단계
  • 34. 프로덕션 단계 준비 이제는 프로덕션 단계로 넘어가기 위한 준비 단계 • Iteration을 위한 콘솔용 배포 프로세스 • Hardsuit Labs의 XB1 작업 머지 • 로컬라이징 (영어, 불어, 독일어) 작업 환경 만들기 • 플랫폼 서버 연동 (=계정 인증 등) 하기 엔지니어링 목표는 • 콘솔에서 게임이 어떻게든 굴러가게 만드는 것 에서 • 다른 사람들이 일을 잘 할 수 있게 만들어 주는 것으로 바뀜 2016.3 4 5 6 7 8 9 10 11 12 프리프로덕션 단계
  • 35. 그 외에도.. UI 개발 가속화 • UI 스크립팅 팀 단기 외주 (3명) • 클라이언트 프로그래머 추가 투입 2016.3 4 5 6 7 8 9 10 11 12 프리프로덕션 단계 전투경험 개선 • 알파 테스트 후 생긴 욕심 • 전투 Focus 사내 테스트를 통한 주 단위 Iteration 엔진 버그 수정 • 끊임없는 버그의 산
  • 36. 12월 2차 머지 • 12월 21일 첫 PS4 QA! (지금까지는 PC로 하고 있었음) 아 망했어요
  • 37. 2017년 새해가 밝았어요 이제 개발 사이클이 가능함 • 작업 -> 배포 -> 콘솔QA -> 무한 반복 • XB1은 2월 부터 가능해짐 프로그래머를 추가 영입 • 다른 프로젝트 중인 테라 출신 시니어들 에게까지 Help 요청 • UI 계속 제작 • 엔진 버그 수정 / 최적화 • 플랫폼, TRC/XR 작업 17.1 3 5 6 7 8 9 10 11 122 4 프로덕션 단계
  • 38. TRC / XR • 플랫폼 마다 마스터 패키지에 대한 Checklist가 있습니다. • PS4 : Technical Requirement Checklist (TRC) • XB1 : Xbox Requirement (XR) • 모바일에서 앱 심사 같은 거죠 • 앱을 제출하여 심사를 받는 과정을 Certification이라고 합니다. 17.1 3 5 6 7 8 9 10 11 122 4 프로덕션 단계
  • 39. TRC / XR 알아 두면 좋은 것 • Certification에 들어가면 두 플랫폼 모두 일주일 걸림 • Sony / MS에 테스트를 하는데 필요한 도구를 제공해야 함 • 항목 별로 면제 요청이 가능하나 절차가 오래 걸리고 통과가 쉽지 않음 • 처음 하는 회사는 보통 4~5번은 떨어진다고 함. • 1년 걸린다고 생각하고 미리 준비할 것 • 자세한 내용은 NDA 문제로 생략 17.1 3 5 6 7 8 9 10 11 122 4 프로덕션 단계
  • 40. 4월 마일스톤 다음 빌드의 목표 • PS4/XB1 동시 Cert 제출 • 모든 UI 개발 완료 (중요도 낮은 일부 제외하고) • 로딩 최적화 완료 (다음 챕터에서 자세히 다룹니다) • 기타 중요 엔진 버그들 수정 Cert 떨어질 것을 감안해도 이 정도 계획이면 여름 쯤에 출시할 수 있겠지 (행복회로) 17.1 3 5 6 7 8 9 10 11 122 4 프로덕션 단계
  • 41. 마일스톤 점검 • XB1은 조금 늦어져서 4월 말에 Cert 제출 • 결과는 당연히 둘 다 FAIL • 하지만 계속 수정 / 재제출 사이클을 돌기만 하면 된다는 자신감! 17.1 3 5 6 7 8 9 10 11 122 4 프로덕션 단계 빨간불은 다른 데서 켜짐 • 로딩 최적화를 했으나 여전히 프레임이 안 나옴 • 최적화에 총력을 다해야 겠다고 판단 • 런칭 계획은 물거품
  • 42. 최적화 삼매경 5월부터는 최적화에 최대한 많은 프로그래머 리소스 투입 UI팀도 UI 로직 최적화를 같이 진행 컨텐츠 개발 진도로 보면 거의 멈춰 있던 시기 17.1 3 5 6 7 8 9 10 11 122 4 프로덕션 단계
  • 43. 9월 최적화 중간 점검 • 최적화가 끝난 것은 아니나 가능성을 봄 • PAX에서 시연. 꽤 성공적인 반응을 얻음 • 가능성이 보이니 다시 런칭 타이머를 돌리기 시작 => 연말 전에 CBT 하고, 내년 초에 런칭하자 17.1 3 5 6 7 8 9 10 11 122 4 프로덕션 단계
  • 44. 이제부터는 사실상 폴리싱 • 추가 기획은 정말 중요한 것만 • 버그수정과 최적화만 한다. • TRC / XR 통과를 위해 최선을 다하기 • 이 이후는 별로 공유할 게 없네요.
  • 45. UI 프로덕션 프로덕션 폴리싱프리 프로덕션 주요 마일스톤 2016.3 18.3.9 1차 OBT 18.3.16 2차 OBT 18.3.27 Founders’ Pack 런칭 2017.1 2018.1 16.9 첫 알파 테스트 16.12. 첫 PS4 QA 시작 17.2 첫 XB1 QA 시작 17.9 최적화 1차 마감 17.9 PAX 시연 17.9 2차 Cert 제출 17.12 Technical Test (CBT) 4 5 6 7 8 9 10 11 12 4 5 6 7 8 9 10 11 122 3 42 3 2018.4.3 정식 오픈 17.4 첫 PS4 Cert 제출 17.4 첫 XB1 Cert 제출 16.3.7 프로젝트 시작 TRC / XR 멀티스레드 최적화로딩 최적화
  • 46. 정리 테라 콘솔의 사례 • 시작부터 출시까지 2년 • 클라이언트 프로그래머는 1명으로 시작해서 프로덕션 단계에 9명까지 늘었다가 현재는 6명 • Hardsuit Labs에 컨설팅을 함으로써 초기 개발을 가속화 • 기존 PC 서비스 빌드를 적극 활용해 UI 개발을 빨리 시작함 • TRC / XR 준비는 정말로 1년 걸림 • 최적화는 예상치 못한 장벽, UE3를 안정적으로 멀티스레드화 하는데 반년이상 걸림
  • 47. 3. UE3 콘솔 최적화 – 리소스 로딩 • UE3 리소스 로딩 로직이 PC와 콘솔에서 다른 점 공유 • 아트 리소스를 수정할 수 없는 제약 사항에서 TERA 콘솔팀이 해결한 방법 공유 1. TERA 콘솔팀의 탄생과 시작 2. TERA 콘솔팀의 2년간 개발 기록 3. UE3 콘솔 최적화 – 리소스 로딩 4. UE3 콘솔 최적화 – 메인 스레드 병렬화 5. 마무리
  • 48. MMORPG의 적 로딩랙 MMO가 다른 게임과 다른 점 – 플레이어의 동적 데이터 어떤 플레이어가, 어떤 옷을 입고, 어떤 탈 것을 타고, 어떤 스킬을 쓸지 절대로 알 수 없다
  • 49. UE3 MMORPG의 한계 앞선 이유로, 게임 플레이 중에도 뭔가를 계속 로딩하고 있음 • 모든 이펙트, 사운드 등을 메모리에 올려놓을 수 없으니까 • 간헐적으로 프레임 드랍이 유발되는 이유 UE3에서 UI 로딩의 한계 • MMORPG는 UI가 많아서 전부다 메모리에 올려 놓는 것이 불가능 • UE3는 한 번에 하나의 파일만 로딩 가능 • 다른 파일을 로딩 중에 UI 오픈을 시도하면 순간 프리징을 걸어서라도 강제 로딩이 필요 (UI를 열었으나 몇 초 씩이나 반응이 없을 수는 없으니까) • 비동기 로딩이 제대로 동작하지 못하는 이유
  • 50. UE3 리소스 패키징 예시) 테라에서 이펙트 패키지 하나 PS : UE3의 ParticleSystem 정의 MI : PS에서 쓰는 Material 정의 MAT : MI가 사용하는 MaterialTemplate (Shader) TEX : MI/MAT이 사용하는 텍스처 하나의 파일에 여러 리소스를 묶어 놓음 => 몇 백 개의 ParticleSystem이 하나의 패키지에 들어 있음 FX_A_0001_PS FX_A_0001_TEX FX_A_0001_MI FX_A_0001_MAT FX_A_0002_PS … FX_A_0297_TEX FX_A.upk
  • 51. UE3의 3가지 로딩 API StaticLoadObject : 하나의 UObject를 동기 로딩 (FX_A_0001_PS 를 로딩할 때까지 게임이 멈춤) LoadPackage : 하나의 패키지를 동기 로딩 (FX_A.gpk 내용을 모두 로딩할 때까지 게임이 멈춤) LoadPackageAsync : 하나의 패키지를 비동기 로딩 (게임 실행 중에 백그라운드에서 FX_A.gpk 내용을 천천히 읽음)
  • 52. 하나의 UObject만 비동기로 읽고 싶으면 어떻게 해야 하나요? 1. 해당 UObject가 들어있는 Package를 LoadPackageAsync로 로딩 2. 완료되면 사용할 오브젝트를 Referencing 3. GC를 돌린다! Epic 공식 가이드 ⓒ이병건, NAVER WEPTOON CORP / 이말년 시리즈
  • 53. TERA의 Custom 로딩 API StaticLoadObject : 하나의 UObject를 동기 로딩 (FX_A_0001_PS 를 로딩할 때까지 게임이 멈춤) LoadPackage : 하나의 패키지를 동기 로딩 (FX_A.gpk 내용을 모두 로딩할 때까지 게임이 멈춤) LoadPackageAsync : 하나의 패키지를 비동기 로딩 (게임 실행 중에 백그라운드에서 FX_A.gpk 내용을 천천히 읽음) TeraLoadObjectAsync : 하나의 Uobject를 비동기 로딩 (게임 실행 중에 백그라운드에서 FX_A_0001_PS 내용을 천천히 읽음) 그나마 이 방법으로 PC 서비스에서 버티고 있음
  • 54. 하지만 콘솔에서는? Seek-Free 개념의 등장 • UE3는 콘솔에서 Seek-Free 패키징을 강제
  • 55. Seek-Free 예시 PC의 경우, A_0001_PS를 로딩하려고 하면 B.upk도 찾아가서 B_0001_MI를 로딩함 이 PS 가 B_0001_MI를 사용한다면? A_0001_PS A.upk B_0001_MI B.upk
  • 56. Seek-Free 예시 하지만 Seek-Free로 쿠킹을 하고 나면 A_0001_PS A.xxx B_0001_MI B.xxx B_0001_MI B_0001_MI 내용이 복사되서 들어감 용량을 희생하고 로딩속도를 올린 (SeekTime을 없앤) 전략 광학 디스크에서의 실행을 가정하고 있기 때문 DVD 판매를 고려하고 있다면 정말 중요한 포인트
  • 57. Seek-Free의 진짜 문제점 StaticLoadObject : 하나의 Uobject를 동기 로딩 (FX_A_0001_PS 를 로딩할 때까지 게임이 멈춤) LoadPackage : 하나의 패키지를 동기 로딩 (FX_A.gpk 내용을 모두 로딩할 때까지 게임이 멈춤) LoadPackageAsync : 하나의 패키지를 비동기 로딩 (게임 실행 중에 백그라운드에서 FX_A.gpk 내용을 천천히 읽음) TeraLoadObjectAsync : 하나의 Uobject를 비동기 로딩 (게임 실행 중에 백그라운드에서 FX_A_0001_PS 내용을 천천히 읽음) Object 단위의 로딩이 불가능해지고 항상 풀 패키지를 읽어야 함
  • 58. TERA 콘솔 Worst 시나리오 1) 다른 유저가 옆에서 스킬을 씀 2) 하필 FX_A에 들어있는 이펙트가 필요해서 로딩을 시작함 (이미 스킬은 이펙트 없이 써졌음) 3) 그 와중에 뭐라도 UI Open을 시도하면? 4) 초 단위 프리징! (개발 초기에는 10초 넘어갈 때도 있었음)
  • 59. Best Practice 하나의 파일이 너무 크지 않게 잘 관리 할 것 예시) • 엘린_메이드복.upk • 무사_스킬이펙트모음.upk 사실 UE3에서 UObject 단위의 비동기 로딩을 지원하지 않는 이유가 이것 • 애초에 그럴 필요가 없게 패키징 할 것 • 로딩의 목적 == 파일에 들어있는 내용 이면 많은 문제가 해결 (TERA는 오른쪽이 너무 큰 상태)
  • 60. TERA 콘솔의 해결법 제약조건 • 아트 리소스자체는 수정 불가 (PC 서비스와 일관성 유지) 고민 • 콘솔에서 Seek-Free를 안 하게 수정하는 것은 어려움 (Hardsuit Labs도 그건 힘들 거라고 컨설팅) 결국 우리의 Wrapper를 하나 만드는 수밖에!
  • 62. TERA 콘솔의 해결법 2. 쪼개진 파일로 쿠킹 • Seek-Free 라서 연관 Object가 딸려 들어감 FX_A_0001_PS FX_A_0002_PS Redirect_001.upk Redirect_002.upk FX_A_0001_PS_dup FX_A_0002_PS_dup Redirect_001.xxx Redirect_002.xxx FX_A_0001_MI FX_A_0001_MAT FX_A_0002_MI FX_A_0002_MAT
  • 63. TERA 콘솔의 해결법 3. 이걸 다시 하나의 파일로 합침 FX_A_0001_PS_dup FX_A_0001_MI FX_A_0001_MAT FX_A_0002_PS_dup FX_A_0002_MI FX_A_0002_MAT Composite_001.xxx FX_A_0001_PS_dup FX_A_0002_PS_dup Redirect_001.xxx Redirect_002.xxx FX_A_0001_MI FX_A_0001_MAT FX_A_0002_MI FX_A_0002_MAT
  • 64. TERA 콘솔의 해결법 4. Mapping Table을 들고 관리 • FX_A.FX_A_0001_PS 를 로딩하려고 하면 Redirect_001.FX_A_001_PS_dup 을 로딩하도록 바꿔침 • 파일 I/O에 과정에서 Composite 파일의 일부분을 읽어 그 메모리 주소를 넘겨주도록 바꿔침 • 결과적으로 작은 파일 하나를 LoadPackageAsync 하는 것 처럼 됨 FX_A.FX_A_0001_PS Redirect_001.FX_A_0001_PS_dup Composite_001:0 FX_A.FX_A_0002_PS Redirect_002.FX_A_0002_PS_dup Composite_001:256 … … …
  • 65. 정리 리소스 로딩 • MMORPG는 동적 데이터가 많아서 로딩 퍼포먼스가 문제가 됨 • UE3는 콘솔에서 Seek-Free 로직을 강제함 • 애초에 아트 리소스를 너무 크지 않게 잘 관리하자 TERA 콘솔은 • PC와의 일관성 유지를 위해 아트 리소스 수정을 포기 • 별도의 패키지 Redirecting 기법을 만들어서 문제를 회피 • 대신에 쿠킹시간을 손해 보고 총 패키지 용량이 증가함
  • 66. 4. UE3 콘솔 최적화 – 메인 스레드 병렬화 • UE3 엔진 구조에 대한 대략적인 설명 • 사이드 이펙트를 최소화 하면서 멀티 스레드 도입하기 1. TERA 콘솔팀의 탄생과 시작 2. TERA 콘솔팀의 2년간 개발 기록 3. UE3 콘솔 최적화 – 리소스 로딩 4. UE3 콘솔 최적화 – 메인 스레드 병렬화 5. 마무리
  • 67. 멀티스레드 최적화 현세대 콘솔의 CPU 스펙 : 1.6Ghz * 8코어 (요새 CPU 코어 클럭 수의 반토막) UE3는 코어 2개만 바쁜 엔진 멀티 스레드로 최적화를 꾀하는 것은 선택이 아닌 필수
  • 68. Unreal Engine 3 구조 Thread 1 Thread 2 Thread 3 Thread 4 흔히들 UE3는 코어를 2.5개 쓴다고들 하죠. Render Thread Tick Main Thread Tick Render Thread Tick Main Thread Tick Render Thread Tick Main Thread Tick Render Command Render Command I/O Request PhysX Thread I/O Request PhysX Thread I/O Request PhysX Thread 1 Frame
  • 69. Main Thread ProcessInput ProcessAsyncLoading WorldTick InteractionTick RedrawViewport Main Thread Tick Input Handle 하는 거죠 비동기 로딩 처리. 필요한 파일들을 Serialize 합니다. 5ms 넘으면 그만하고 다음 틱에 이어서.. 실제로 레벨에 존재하는 모든 오브젝트 업데이트 (가장 큰 부하 = 최적화 대상) 추가로 Tick 처리가 필요한 모듈에 대한 처리. GFX tick이 여기서 수행됨 (최적화 대상) Scene Rendering을 위한 RenderCommand들을 생성
  • 70. UE3는 Actor-Component 모델 Actor StaticMeshComponent SkeletalMeshComponent CylinderComponent ParticleSystemComponent 월드에 존재하는 모든 오브젝트는 Actor Components 실제 행동 구현은 Component로 Attach
  • 71. World Tick PreAsync Tick DuringAsync Tick PostAsync Tick PostUpdate Tick EffectUpdate World Tick PostTickComponent ProcessInput ProcessAsyncLoading InteractionTick RedrawViewport Main Thread Tick WorldTick 세 개의 Tick Group으로 나눠 짐
  • 72. World Tick PreAsync Tick DuringAsync Tick PostAsync Tick PostUpdate Tick EffectUpdate World Tick PostTickComponent ProcessInput ProcessAsyncLoading InteractionTick RedrawViewport Main Thread Tick WorldTick 여기서 PhysX thread Start 여기서 PhysX thread Sync
  • 73. World Tick PreAsync Tick DuringAsync Tick PostAsync Tick PostUpdate Tick EffectUpdate World Tick PostTickComponent ProcessInput ProcessAsyncLoading InteractionTick RedrawViewport Main Thread Tick WorldTick 물리 시뮬레이션 전에 업데이트 해야 하는 것들 Static / Skeletal MeshComponent가 여기 해당 (최적화 대상) 물리 시뮬레이션과 동시에 실행되어도 상관 없는 것들 ParticleSystemComponent를 포함해 대부분의 Component가 여기 해당 (최적화 대상) 물리 시뮬레이션 후에 업데이트 해야 하는 것들 거의 해당하는 Component가 없음 (최적화 대상 아님)
  • 74. World Tick PreAsync Tick DuringAsync Tick PostAsync Tick PostUpdate Tick EffectUpdate World Tick PostTickComponent ProcessInput ProcessAsyncLoading InteractionTick RedrawViewport Main Thread Tick WorldTick Add/Remove Primitive 등의 RenderCommand를 생성 (최적화 대상) 필요한 후처리들 (최적화 대상 아님)
  • 75. 최적화 전략 전제 조건 1) 테라 콘솔도 지속적인 라이브 서비스를 해야 한다. 2) 1)의 이유로 PC 라이브 서비스의 코드를 지속적으로 머지 해와야 한다. 3) 2) 의 이유로 기존 코드 구조를 최대한 유지할 필요가 있다. 4) 그리고 시간이 없으니 빠르게 구현할 수 있는 방법으로! 결론 : Fork and Join이 정석
  • 76. Fork and Join • 특정 구간을 병렬화로 시키고, 다 끝나야 다음 스텝으로 넘어가는 방법 • 구현이 쉽지만 CPU 사용률 100%는 불가능한 방법 • Join이 길어지지 않도록 주의해야 함 Form Wikipedia / Fork-Join Model
  • 77. 실제 구현 - Lambda 만세 • WorldTick 의 간략한 예시 (실제 코드와 똑같지는 않고 일부 각색했습니다) for(ITER It(ComponentList); It; ++It) { It->ConditionalTick(DeltaSeconds) } 이런 간소화된 모델로 예시를 들면 for(ITER It(ComponentList); It; ++It) { #if MultiThread AsyncTaskManager->AddComponentTick([It, DeltaSeconds]{ #endif It->ConditionalTick(DeltaSeconds) #if MultiThread }); #endif } • AsyncTaskManager는 이런 Lambda Job이 30개쯤 모이면 그때 Fork • 이렇게 기존 코드를 보존한 채 앞뒤로 Lambda 연산을 넣는 것만으로 구현 가능 • 실제로는 매크로 등을 이용해 더 깔끔하게 코드 구현을 했음
  • 78. World Tick에서 Join 하는 법 • 이렇게 Sync 하는 함수를 넣기만 하면 됨 • Sync 내부는 Task 분배한 것들이 끝나길 기다림 • 만약 아직 시작도 못 있다면 끌어와서 처 • 모든 Task가 끝났다면 모아둔 콜백 처리 TickGroup = TG_PreAsyncWork; TickActors(this, DeltaSeconds, TickType, GDeferredList); … TickGroup = TG_DuringASyncWork; TickGroup = TG_PreAsyncWork; TickActors(this, DeltaSeconds, TickType, GDeferredList); #if Multithread AsyncTaskManager->Sync(); #endif … TickGroup = TG_DuringASyncWork;
  • 79. Callback? • 병렬화가 불가능한 로직 덩어리는 분명히 존재함 UParticleSystemComponent::Tick(FLOAT DeltaTime) { … FinializeTickComponent(DeltaTime); // 내부적으로 Component 삭제 로직이 돌기 때문에 병렬화시에 문제가 있음 … } UParticleSystemComponent::Tick(FLOAT DeltaTime) { … AddCallBack([this, DeltaTime]{ FinializeTickComponent(DeltaTime); // 내부적으로 Component 삭제 로직이 돌기 때문에 병렬화시에 문제가 있음 }); … }
  • 80. Lock으로 해결 가능하기도 함 FParticleDataManager::RemoveParticleSystemComponent(UParticleSystemComponent* InPsysComp) { PSysComponent.Remove(InPSysComp) } FParticleDataManager::RemoveParticleSystemComponent(UParticleSystemComponent* InPsysComp) { Fscopelock Scopedlock(lockObject) PSysComponent.Remove(InPSysComp) } 병렬화 전 병렬화 후
  • 81. Lock을 쓰는 조건 Lock은 Contention이 적을 때만 쓰는 것 • 프레임당 락에 걸려있는 총시간을 말함 -> 직접 재 보면 된다. 마이크로 세컨드 단위일 때에만 Lock 쓰기 • Lock이 없어도 게임이 구동되고 어쩌다가 크래시가 나는 정도의 빈도일 때만 사용한다고 생각하면 됨 • 글로벌 컨테이너에 모든 Component가 접근할 때 정도가 Contention이 문제가 되는데 Thread_local 컨테이너를 만들어서 거기에 작업 수행하다가 Sync할 때 맞추는 우회적 방법 등이 있습니다.
  • 82. thread_local //UnAnimTree.cpp UBOOL UAnimNode::bNodeSearching = FALSE; INT AnimNode::CurrentSearching = 0; //UnAnimTree.cpp thread_local UBOOL UAnimNode::bNodeSearching = FALSE; thread_local INT AnimNode::CurrentSearching = 0; • UE3에는 이렇게 임시변수를 전역변수로 쓰는 경우가 있는데 Thread_local화 해버리면 간단. (함수 콜마다 파라미터로 넘기기 싫어서 이렇게 한 것 처럼 보임) • 물론 정말 임시변수인지, 글로벌하게 공유할 필요가 있는지는 코드 파악을 확실히 할 것 병렬화 전 병렬화 후
  • 83. PostTickComponent 병렬화 • World Tick을 Fork and Join으로 병렬화 하는 것은 UE4에도 비슷하게 구현되어 있음 • UE4에서 PostTickComponent는 거의 병렬화를 하지 않았는데 보통 부하가 되지 않기 때문 • Transform 변동에 의한, Octree Add/Remove RenderCommand를 생성하는 부분
  • 84. PostTickComponent 병렬화 하지만 MMO에서는 아래와 같은 상황이 발생하죠.
  • 85. PostTickComponent 병렬화 • 해당 상황을 프로파일러로 찍으면 이렇습니다. • 수백 개 Component의 PostTickComponent를 하는 중
  • 86. PostTickComponent 병렬화 • 똑같은 방법으로 병렬화 (RingBuffer Write에 Lock을 걸어 버림) • Lock을 많이 썼음에도 1/3 가량으로 줄어듦 • 움직이는 오브젝트가 많은 게임에서 참고하면 좋을 듯
  • 87. GFX Tick 병렬화 • Scaleform Update 도 부하의 한 축을 담당 • UI 업데이트가 꼭 World Tick 뒤에 수행되어야 할 이유가 있나? 에 대한 실험을 진행 전략 • 일단 Thread로 뺀다. • 문제가 나올 때 마다 해결한다. • 해결 불가능한 문제가 나온다면 포기하고 모두 롤백 • 아니라면 병렬화에 성공했다는 뜻
  • 88. GFX Tick 병렬화 ProcessInput ProcessAsyncLoading WorldTick InteractionTick RedrawViewport Main Thread Tick SyncGFX StartGFX WorldTick 시작하기 전에 Thread Start 원래 수행되던 Interaction Tick 끝나고 Sync 결론 : 쉽지는 않았고, 두 달 정도 걸려서 완성함.. 어쨌건 되긴 되더라! (얼렁뚱땅 결말)
  • 89. 최종적인 모습 - Before 1.TERA 로직 1.UE3 로직
  • 90. 최종적인 모습 - After 테라 게임 로직 GFX(UI) 로직 UE3 엔진 로직 렌더링 로직
  • 91. 정리 최적화 전략 • GFX Tick은 엔진 Tick과 분리 가능 • Fork and Join의 방식으로 최대한 기존 코드를 유지하며 빠르게 병렬화 가능 • Critical Section에 대해서는 Callback, Lock, thread_local 등으로 처리 • Lock은 Contention이 적을 때에만 쓰자 • 경우에 따라 로직 자체를 수정할 각오는 필요하며, 언리얼 엔진에 대한 높은 이해는 필수
  • 92. 5. 마무리 1. TERA 콘솔팀의 탄생과 시작 2. TERA 콘솔팀의 2년간 개발 기록 3. UE3 콘솔 최적화 – 리소스 로딩 4. UE3 콘솔 최적화 – 메인 스레드 병렬화 5. 마무리
  • 93. TERA 콘솔은 • 콘솔 개발/서비스 경험을 내재화 하고자 자체 포팅을 시작 • 이 경험을 토대로, 블루홀 차기 프로젝트에서 콘솔 플랫폼을 고려하기 쉬워 지길 기대
  • 94. UE3 게임을 현세대 콘솔에 포팅하는 것은 불가능한 일은 아니다! • UE3-Unsupported 활용 및 전문가 컨설팅으로 빠르게 기반을 만들 수 있음 • TRC / XR은 인내심으로 대응 • 최적화 문제가 있겠지만 어떻게든 해결할 수 있음 • 시장성도 좋아요!
  • 95. 전달하고자 했던 것 콘솔 포팅 개발의 간접 경험 - 어떤 과정을 거쳐 UE3 MMORPG가 콘솔로 포팅 되었는지 - 만약, 콘솔 환경에서 개발하게 되면 어떤 것들을 고려해야 하는지 콘솔 환경에서의 최적화 팁 - UE3 리소스 로딩의 문제점 및 해결을 위해 필요한 지식 - 엔진을 멀티스레드 구조로 개선할 때에 참고할 만한 지식과 사례
  • 96. 테라 콘솔팀 모두 정말 고생 많았고, 고맙습니다
  • 97. 모름지기 컨퍼런스란 기승전 채용 홍보 테라 콘솔 클라이언트 프로그래머 채용 중 (신입/경력 무관) https://www.bluehole.net/kr/recruit
  • 98. 리마인드, 다음 발표도 듣고 가세요~~
  • 100. Q & A
  • 101. 발표 후 Q&A 내용 정리 • Q1. 테크 리소스조차 현재 없는 상태에서 콘솔 포팅을 진행한다면, 한국의 제한된 UE3 개발 인력풀 내에서 외부 인력 채용이 현실적으로 가능할까요? • A. 아니요. 저는 어렵다고 생각합니다. 발표장에서는 제가 말씀 못 드렸는데, 테라 콘솔팀도 프로그래머 채용을 하려고 굉장히 노력했으나 다 실패했습니다. 한국에 엔진 전문가풀 자체가 많지 않으며, 능력이 있으신 분들도 MMORPG 포팅을 불가능하다고 보시거나, 아니면 연차가 있으셔서 그런지 안정적인 프로젝트를 원하시더라구요. 그래서 테라 콘솔팀도 테라 출신 시니어가 아니라면 아예 신입으로만 채웠습니다. 국내에서 엔진 프로그래머 구하기, 그것도 포팅같은 업무에서는 더더욱 어렵다고 느꼈습니다. 저나 홍상혁님 처럼 회사 내에서 엔진 프로그래머 풀을 늘려갈 계획의 중심이 될 프로그래머가 없는 상황이라면 현실성이 없다고 생각됩니다. 제 발표에 언급된 외주 업체들을 알아보시는 게 차라리 나을 겁니다. 중국, 미국, 캐나다 등지에 정말 많습니다. 저 한테 여쭤 보셔도 몇몇 추천해 드릴 수 있지만, MS나 Sony에 문의하시는 게 확실합니다. 그들은 많은 협력 업체를 알고 있습니다. 저희가 소개받은 업체들도 다 MS와 Sony로 부터 소개받은 회사들입니다. 그리고 포팅 과정은 항상 레거시와의 싸움입니다. 기존 프로젝트에 대해 상당한 지식과 히스토리를 알고 있는 멤버가 없다면 굉장히 힘들어 집니다. 이 점을 감안하시길 추천 드립니다.
  • 102. 발표 후 Q&A 내용 정리 • Q2. 게임 서버는 기존 레거시를 100% 활용하는데 거의 문제가 없었나요? • A. 네. 테라 콘솔은 서버를 거의 수정하지 않았습니다. 그렇다고 아예 일이 없었던 것은 아닙니다. MS쪽 XR에 보면 네트워크 게임의 경우 통과해야 할 보안 검수가 있는데, 테라가 이걸 탈락 했습니다. 그래서 패킷 암호화 로직을 전반적으로 수정하는 작업이 있었습니다. 그리고 TRC / XR에 의해 일부 추가 구현할 것들이 있습니다. 또한 UI를 수정하다 보니 PC에서는 팝업으로 처리하던 것을 콘솔에서는 한 화면에 정보를 모아 놓기 위해 패킷을 합쳐야 하는 경우도 있었습니다. 최적화 과정에서 중복 패킷을 줄이는 패킷 최적화도 일부 진행 했고요. 어쨌건 지금 테라 콘솔팀은 클라이언트 프로그래머 6명에 서버 프로그래머 1명입니다. 그럼에도 서버 작업이 bottleneck이 되는 경우는 없었습니다.
  • 103. 발표 후 Q&A 내용 정리 • Q3. 테라 피씨는 열심히 했지만 콘솔을 안해봐서 궁금한데요. 2개의 질문이 있습니다. 1. 콘솔로 포팅 하는데 UX.UI에서 가장 크게 변화 된것 2. BM은 콘솔 유저들을 고려 해서 변경을 했는지. 어떻게 하고 왜 변경 했는지요. 발표 잘 들었습니다. • A. 먼저 UX/UI 에서 가장 크게 변화된 것은 아무래도 폰트 크기입니다. 모든 작업을 할 때에 TV에서 3m 거리를 가정하고 디자인을 했습니다. 폰트와 아이콘을 키우고, 그에 맞게 레이아웃을 수정하는게 기본입니다. 그리고 PC의 마우스 UX를 그대로 가져오면 조작 depth가 늘어납니다. Depth를 줄이기 위해서는 최대한 한 화면에 많은 정보를 보여주고, depth를 들어갈 때에도 각 버튼 별로 다른 기능을 주어서 여러 가지가 나오게 했습니다. 전투 UX에 있어서는 카메라 자동으로 따라가기, 카메라 락온, 타게팅 스킬 락온 범위 관대하게 판정하기, 스킬 발동시 Z 축 보정 일부 넣기 등이 있었고, 스킬 숏컷은 전반적으로 갈아 엎었죠. 많은 게임에서 숏컷이 가장 문제가 될 텐데 테라는 다행히 스킬이 엄청 많은 게임은 아니었습니다. 네버윈터와 디아블로를 레퍼런스로 나름의 연구를 진행한 결과이니 숏컷에 대한 건 테라 콘솔을 직접 플레이 하면서 판단해 주세요 BM에 대해서는 콘솔 유저라고 딱히 PC 유저와 다른 패턴을 보일 것이라 생각하지는 않았습니다. PC와 마찬가지로 F2P로 서비스를 했고, 치장성 아이템 및 편의성 아이템을 DLC로 판매하는 형태입니다. 그래서 실제로 콘솔유저의 구매 패턴이 PC와 다르게 나오는지는 추이를 지켜봐야 알 수 있겠네요.
  • 104. 발표 후 Q&A 내용 정리 • Q4. Seekfree 사용했을 때 용량차이는 어느정도였나요? • A. PC와 엔진 버전이 다르다 보니 정확한 비교는 어려운데요. PC도 맵에 한해서는 SeekFree로 쿠킹됩니다. 맵에 배치된 static mesh 들을 하나하나 파일 찾아서 읽게 하지 않기 위해서죠. 즉 콘솔은 PC와 비교하면 메시, 이펙트, 사운드 등만 추가로 seekfree로 쿠킹 된다고 보시면 됩니다. 다행히도 이런 단일 파일들은 다른 파일의 내용을 참조하게 설계하면 애초에 그게 멍청한 설계입니다. Material Template에 한해서만 재활용 여지가 있는데, Reference가 되는 Material Template은 특정 파일에 모아 놓는 것이 언리얼 엔진 활용에서 중요한 포인트입니다. 그리고 Seek-Free는 Serialize할 정보를 복사해오는 거라 실제 용량의 대부분의 차지하게 될 쉐이더 바이너리는 ShaderCache로, 텍스처는 TextureFileCache로 빠집니다. 그래서 Seek-Free라고 해서 파일 용량이 어마어마하게 늘지는 않습니다. 파일 dependency 관리만 잘 하면 우려할 정도는 아니다 라고 이해하시면 됩니다. 그저 Seek-Free가 되었을 때 StaticLoadObject를 못 쓰는게 문제였지요…
  • 105. 발표 후 Q&A 내용 정리 • Q5. 성능 프로파일링은 어떻게 하셨나요? • A. MS에서 제공하는 PIX라는 툴을 사용했습니다. 저와 홍상혁님의 발표자료에 등장하는 모든 프로파일링 이미지는 PIX에서 캡처한 것입니다. 코드내에 Marker를 박아 놓으면, Visualize된 형태로 프로파일링을 해줍니다. 매우 유용한 툴입니다. PC에서도 DX12를 쓴다면 PIX를 쓸 수 있으니 참고하세요. PS4에도 Razor CPU라는 비슷한 툴이 있습니다. 실제로는 PIX보다도 더 좋습니다만 Marker가 너무 많으면 약간 부하가 되더라고요. 하지만 PS4의 Razor CPU는 시간 단위로까지 녹화를 해도 무리가 없는 인터페이스입니다. MS의 PIX는 분 단위만 되어도 메모리 사용량이 너무 많아서 툴이 뻗더라구요. 참고로 PS4는 Memory Analyzer도 좋습니다. 메모리 릭 잡을 때 유용하게 사용했습니다. PIX에도 Memory Analyzer가 있지만 너무 느려서 사용하기 힘들더라구요. 아무튼 MS, Sony에서 아주 좋은 프로파일러들을 제공한다고 이해하시면 됩니다. 콘솔 개발을 하게 되시면 이 툴들의 매뉴얼 부터 읽으시면 큰 도움이 될 것입니다.
  • 106. 발표 후 Q&A 내용 정리 • Q6. 3d모델러 입니다. 지원방법이 궁금합니다 • A. 죄송합니다. 질문을 이해 못했습니다. 동시간대 다른 세션에도 그래픽 관련은 없어서 잘못 올리신 질문은 아닌 것 같아요. 두 가지로 해석 가능할 것 같은데, 만약 채용공고에 대한 이야기라면 저희는 프로그래머와 UX 디자이너를 채용 중입니다. 아트 직군은 채용 중이지 않습니다. 테라 콘솔팀은 아트 직군이 따로 없으며 필요한 업무가 있다면 테라 본부에 요청하는 방식으로 일합니다. 테라 본부 아트팀의 채용공고를 확인해 주세요. 혹, 채용공고가 아니라 제가 초반에 언급한 아트 지원이 없어서 UE3 개조로 갔다는 내용에 대한 질문 이신가요? UE3 게임을 UE4로 올린다고 할 때 이건 말이 마이그레이션이지 실제로는 게임을 다시 만드는 겁니다. 이 경우 아트 직군에 부탁할 일은 모든 Max 원본 파일을 가지고 UE4 에디터로 다시 import해서 아트 패키지를 만들어 주시는 겁니다. 3d 모델은 그나마 쉽구요. 배경과 이펙트가 죽어 납니다. 이 일을 실제로 했던 타 회사의 사례를 알지만 제가 함부로 언급하기는 어렵네요. 아무튼 이런 포팅 방법도 충분히 가능한 일입니다. 다만 매우 고비용이며, 발표에서도 언급 했듯이 강한 아트 리더십이 필요합니다.
  • 107. 발표 후 Q&A 내용 정리 • Q7. 최적화 작업에 들어가실 때 프로파일링 이후 전체 일정은 어떤 관점으로 잡으셨나요? • A. 최적화 일정을 어떻게 산출했냐는 질문이라면, 이건 예측 가능한 영역이 아니었습니다. 아무도 안 해본 일이니까요. 제가 블루홀에서 4년간 일하면서 겪은 작업 방식은 철저한 계획 세우기와는 거리가 멉니다. 모든 기술적 난제에 대해서, 문제를 정확히 파악하고, 아이디어를 정리해 보는 것 까지는 오래 걸리는 일이 아닙니다. 특히 콘솔 최적화의 경우 멀티스레드 구현이 안 되어 있다는 명확한 문제를 인지하고 있었고 , Fork and Join은 현 상황에서 너무 당연한 접근이었죠. UE3 코드 구조도 얼추 알고 있고, 참고할 UE4 코드도 있는 상황이구요. 아마 실제 작업에 들어가면 예상치 못했던 요소들을 많이 만나겠지만 그건 예측 가능한 영역도 아니고, 어차피 다른 선택지도 없었습니다. 그래서 그냥 3개월 열심히 해보고 그 뒤에 판단하자고 정했습니다. 이게 테라 팀이 난제를 극복하는 방식입니다. 경영진 입장에서는 갑갑하겠지만, 실무자에 대한 신뢰를 기반으로 진행하는 거죠. 실무자는 설령 성공하지 못하더라도 다음 결정에 도움될 자료를 준비할 책임이 있습니다. 그래서 기간을 오래 잡지 않습니다. 실제로 제 발표내용의 엔진 Tick 분리하는 프로토타이핑은 한 달 정도 밖에 안 걸렸습니다. 이후에 생각하지 못했던 크래시 잡기, 추가 프로파일링으로 더 뺄 만한 것 찾기의 연속이었죠. 하지만 이 단계가 되면 최적화의 가능성이 충분히 증명됩니다. 만약 Fork and join 전략 자체가 안 먹힐 것이었다면 역시 비슷한 시기에 파악 가능했을 겁니다. 정리하면 ‘9월까지 최적화가 덜 끝나도 상관없으니 가능한 지 최대한 증명해 보고, 만약 어렵다면 또 대책회의를 하자’라는 느낌? 철저한 계산하에 나온 목표가 아니었습니다. 그리고 팀의 사기 관리적 측면에서 접근할 필요도 있습니다. 실무자가 최선을 다할 수 있는 환경을 만들어 주고 중간 검토하는 자리를 마련하기만 하면 됩니다. 테라 팀의 많은 업무들이 이렇게 Bottom-Up 으로 진행됩니다. 그러니까 말도 안 되는 일정에 대한 스트레스를 받을 일도 없죠. 9월에도 여전히 가능성이 안 보였다면 아마 전략 자체를 재검토 하거나, 어떤 부분에서 어려움을 겪고 있는지 분석해 보서나, 아니면 3개월 동안 얻은 정보를 토대로 다음 마일스톤을 정해 보거나 했을 것입니다. 어쨌건 실무자를 믿고 맡기는 것이 핵심입니다.

Hinweis der Redaktion

  1. 안녕하세요. 테라 콘솔 포팅기, 언리얼 엔진 3 게임 현세대 콘솔로 이식하기 라는 주제로 발표를 할 블루홀의 이해찬이라고 합니다. 반갑습니다.
  2. 우선 테라에 대한 소개부터 해야겠네요. 테라는 Free-Targeting MMORPG로 2007년에 개발을 시작해서 2011년에 한게임을 통해 서비스를 시작했구요. 2016년 부터는 넥슨에서 서비스를 하고 있습니다. 현재 북미, 유럽 등을 포함해서 총 8개 지역에서 7년째 서비스를 하고 있는 블루홀의 간판 프로젝트입니다.
  3. 오늘 발표 주제는 테라 콘솔이죠? 국내 서비스를 안 하기 때문에 소식을 잘 모르실 수도 있는데 이번 달에 런칭했습니다. Playstation4 와 XBox One 동시에 런칭했구요. 블루홀의 자회사인 En masse Entertainment 와 함께 북미/유럽에서 서비스를 하고 있습니다.
  4. 이렇게 PlayStation 스토어에 올라와 있구요.
  5. Xbox Store에도 있습니다. 둘 다 보시면 무료게임 순위에서 포트나이트 다음으로 2등까지 갔었어요.
  6. 어쩄건 국내에 콘솔 프로젝트가 흔하지 않으니까, 누군가에겐 도움이 될 것 같아서 저흰 어떻게 포팅을 했는지 공유하고자 발표를 준비했습니다.
  7. 그래서 제 소개를 하자면, 2014년에 블루홀에 입사했고, 2년 동안 테라 라이브 서비스 업무를 했습니다. 그 후에 콘솔포팅 TFT를 만들어서 포팅 업무를 주도했습니다. 네 제가 테라 콘솔팀의 창단 멤버 같은 거라서 이 발표를 하고 있는 거에요.
  8. 주요 발표 내용은 두 가지 인데요 첫째는 기존게임을 콘솔에 이식하고자 할 때 어떻게 전략을 세울지에 대한 이야기입니다. 블루홀이 어떻게 했는지를 가감없이 공유 드릴 거구요. 리드급 엔지니어나 프로젝트 매니저 분들에게 도움이 되겠네요. 그 다음에는 최적화에 대한 이야기를 좀 하려고 합니다. 테라 콘솔 포팅 과정에서 기술적으로 가장 어려운 부분이었기 때문에 특별히 챕터를 할애했습니다. 이 부분은 언리얼 엔진 개발자 분들에게 도움이 될 거라고 생각합니다.
  9. 이 발표에서 최적화는 메인 스레드 부분만 다룹니다. 바로 이어서 11시에 렌더링 스레드 최적화에 대한 발표가 있으니 이 발표도 많이 들어주세요.
  10. 목차입니다. 말씀 드렸듯이 테라 콘솔 개발 과정을 소개하고, 그 다음에 최적화에 대한 이야기를 해보죠.
  11. 먼저 TERA를 어쩌다가 콘솔로 포팅하게 되었고, 어떤 초기 전략을 세웠는지 말씀드리겠습니다.
  12. 맨 처음 이야기가 나온 것은 2015년 겨울이었는데, 블루홀의 자회사인 En Masse Entertainment가 먼저 제안을 했습니다. 당시에 네버윈터라는 MMORPG가 Xbox One 플랫폼에 나왔는데 상당한 성공을 거두었거든요. 그래서 우리도 해보자는 것이죠. 포팅을 전문적으로 해주는 기술 회사들이 있어서 쉽게 타 플랫폼 서비스가 가능하다? 라는 제안이었습니다.
  13. 그래서 검토를 해봤으나 쉬운 일이 아니었습니다. 패키지 게임이라면 가능할 법 한데, TERA는 지속적인 온라인 서비스를 하는 게임이다 보니까 생기는 문제들이 많더라구요. 단순히 돈이 많이 든다는 게 아니라 블루홀에서 써야할 사람과 시간이 꽤 많더라는 얘깁니다
  14. 그리고 블루홀은 게임 제작의 명가가 되는 것을 비전으로 삼고 있어요. (클릭) 그런데 핵심 기술을 외주 주는 것이 제작의 명가가 나아갈 방향인가에 대한 고민을 좀 했구요. (클릭) 기왕이면 직접 하는게 회사가 발전하는 거라는 생각이 들었어요. 그래야 다음 게임도 콘솔로 만들어볼 생각을 하기 쉬워질 거잖아요?
  15. 그래서 이런 이야기가 오갑니다. 회사에서 고민을 하고 있을 때, 그냥 제가 한다고 손들었어요.
  16. 그랬더니 바로 팀이 발족됩니다. 무슨 회사가 이래요 그죠? 그래서 시작은 저 혼자 하는 연구 프로젝트에 가까웠어요.
  17. 자 그래서 저는 어떻게 포팅할지 고민을 합니다. UE3는 PS3와 Xbox 360 용으로 만들어진 옛날 엔진이에요. 자 일단 두 가지 방법이 있겠죠? 기존 엔진을 개조하거나, UE4로 바꾸거나
  18. 하지만 개발 자원을 고려해 봐야 합니다. 일단 저에게 주어진 제약은 이랬어요. 사람은 저 밖에 없고, PC 테라팀은 도와주기 어렵다. 아트지원은 더더욱 안 된다. 테라 PC 서비스를 계속 해야 하니까, 콘솔팀에 리소스를 많이 할당하기 어려운 상황이었죠. (클릭) 그런데 UE4로 가려면 일단 UE3의 아트 리소스를 그대로 UE4에서 쓸 수 있게 만드는 것은 불가능에 가깝습니다. 이걸 하려면 노동 집약적인 방법 밖에 없는 데다가 아트 퀄리티도 필연적으로 바뀝니다. 즉, 인력을 떠나서 강한 아트 디렉팅이 필수불가결합니다. 그리고 저흰 그런 사람이 없었어요. (클릭) 결론은 테크 파워만 가지고 포팅을 해야 하니 당연히 기존 것을 개조하는 방향으로 갑니다.
  19. 다행히도 조사를 해보니 UE3-Unsupported 라는 게 있었어요. 에픽의 외주를 받아서 Hardsuit Labs 라는 회사가 Playstation 4 버전의 UE3를, Iron Galaxy 라는 회사가 Xbox one 버전의 UE3를 만들어 놓은 게 있었습니다. 이 코드를 기반으로 작업을 시작할 수 있었습니다. 네 맨땅에 헤딩한 거는 아니에요.
  20. 그런데 테라는 다른 문제가 하나 더 있었어요. Unsupported를 가져오려고 보는데 코드가 너무 다른 거죠. 테라는 2010년에 엔진 업데이트를 중지했지만 Unsupported는 당연히 최신 코드를 다 포함하고 있습니다. 일단 에디터가 완전 다르고, 데칼이나 라이트맵을 비롯해 상당한 feature의 detail 들이 바뀌었습니다. 그래서 플랫폼 Layer만 가져와서 될 게 아니라 다른 엔진 코어까지 가져와야 하는 상황이었고 이럴 바에는 새 엔진에 테라를 빠르게 올리는게 낫겠다는 판단을 했습니다. 이게 UE4로 올리는 것과는 다르게 아트리소스 호환 문제가 해결 가능한 범위거든요. 이제 와서 보면 잘했다고 생각합니다. 반대로 했다면 뭔가 렌더링이 되는 상황까지만 몇 달은 걸렸을 거에요.
  21. 자, 정리를 해봅시다. 외주와 자체 개발에 대한 비교를 해보자면, 일단 포팅 전문 회사들이 많은 것은 사실입니다. 우리나라에 없을 뿐이지 해외에 많이 있어요. 하지만 MMORPG는 컨텐츠가 방대한 것도 있고, 온라인 서비스를 지속할 것이라는 점에서 비용이 상당합니다. 잘 판단해 보셔야 하구요. 블루홀은 직접 경험을 쌓고 싶었기에 자체 개발을 선택했습니다. 그리고 UE3 게임을 콘솔로 포팅할 때에는 UE4로 마이그레이션 하는 것이 장기적으로 좋은 선택이나 아트 파워가 많이 필요합니다. 테크 위주의 팀이라면 UE3-Unsupported를 적극적으로 활용하는게 현실적입니다. 그리고 테라는 엔진 변경점이 많아서 게임을 다시 만드는 방법을 취했는데, 이미 UE3 최신 버전으로 제작된 프로젝트라면 플랫폼 Layer만 이식해 오는 것도 괜찮을 것입니다.
  22. 이제 대략적인 초기 전략을 세웠으니 실제로 2년간 어떻게 개발이 진행되었는지 얘기해 봅시다. 포팅을 하면서 어떤 일들이 필요하고, 어떤 식으로 비용이 들었는지 말이죠
  23. 한눈에 보는 마일스톤입니다. 2016년 3월에 시작해서 2018년 4월에 출시를 하는 2년 짜리 달력입니다.
  24. 중요하게 보실 것은 16년 12월에 처음으로 PS4 QA가 가능했던 지점이구요. 17년 9월에 최적화 마감 및 PAX 시연입니다. 이 기점들을 기준으로 (클릭) 프로젝트 상태가 바뀌어 왔다고 볼 수 있습니다. 이 그림을 염두 하시고, 시간순으로 하나씩 살펴보죠.
  25. 네, 오른쪽 위에 달력이 있으니 참고하세요. 일단 UE3-Unsupported와 친해져야죠. 운 나쁘게도 PS4 SDK가 큰 업데이트를 했던 시기였어서.. 그거 마이그레이션 하느라 몇 주 썼구요. 어쨌건 샘플이 잘 돌아가는 것을 확인합니다.
  26. 그 다음에는 테라를 이식해야죠. 새 엔진에 테라를 다시 만든다는 게 이런 뜻입니다. 딱 최소한의 코드만 머지해 와서, PS4에서 엘린이 뛰어다니는 모습을 빠르게 구현할 수 있었습니다. 여기까지 한 달여 정도 밖에 안 걸렸어요. 가능성이 있음을 빨리 어필할 수 있었죠.
  27. 그래서 테라 클라이언트 팀에서 2명을 더 납치해 옵니다. 이제 3명이 되었어요. (클릭) 한 명은 기존 UI를 새 GFX에 붙이는 실험 및 패드 입력을 UI로 전달하는 것을 조사하고 (클릭) 한 명은 SkeletalMesh 뿐만 아니라 다른 모든 리소스도 쿠킹 및 로딩에 문제 없는지를 조사합니다. (클릭) 저는 이제 모든 테라 컨텐츠 코드를 이식하면서, PS4에서도 서버에 붙을 수 있게 작업을 진행합니다.
  28. 그런데 얼추 작업이 되어갈 무렵, 갑자기 미국에 가게 됩니다. En Masse Entertainment 사무실에 자리 하나 만들고 2달간 출장을 가게 돼요.
  29. 이유는 Hardsuit Labs로 부터 컨설팅을 받기 위해서였습니다. 프로젝트가 가시성이 보이니까 아예 빠르게 푸시하기로 한 거에요. UE3 Unsupported의 PS4 버전을 만든 그 회사구요. 마침 시애틀에 있습니다. En Masse Entertainment 와도 가까웠어요. 하드숫 랩은 전문 엔지니어만 수십명 있는 기술 컨설팅 회사로 포팅 전문이지만 그게 아니더라도 가리지 않고 일을 합니다. 이미 수많은 게임들을 현세대 콘솔로 포팅한 경험이 있는 회사에요. 그래서 외주가 아니라 컨설팅의 형태로 계약을 맺고, Hardsuit Labs 에게서 빠르게 배운다를 목표로 설정합니다.
  30. 자, 팀이 쪼개진 거에요. 한국팀은 UI 개발에 몰두합니다. PS4 빌드가 불안정 하니까 아예 PC 테라에서 개발 브랜치를 만들어 거기서 작업합니다. 열심히 PC 에서 UI를 개발하고 나중에 머지해 오기로 한 거죠. (클릭) 미국팀은 어떻게든 게임이 돌아가게 만드는 일에 집중합니다. 렌더링 버그가 어마어마하게 많았기 때문이지요. (손짓하며) 저런 일들을 했어요. Hardsuit Labs에게는 기본적으로 실시간 컨설팅을 부탁합니다. 바로바로 질의응답도 해주고 코드도 짜주고 그랬어요. 그리고 저희가 아직도 XB1 Devkit이 없을 때라, 미국팀이 PS4 작업하는 동안, XB1도 비슷한 수준으로 이식하는 일을 부탁합니다.
  31. 이게 7월 쯤의 중간 자료입니다. 맵, 파티클 등의 로딩이 어느정도 가능해지고, 네트워크도 연동된 상태죠. 보시면 NPC가 까맣게 보이죠? 렌더링 버그가 굉장히 많았었어요. 엔진 버전이 올라가서 생긴 문제도 있고, 저희가 만든 쉐이더들이 PS4에서 제대로 동작하지 않는 문제도 있고 뭐 그랬습니다. 그리고 원래 캐릭터 뒤에 큰 나무가 있어야 하는데 없네요, 아직 SpeedTree 이식을 못했을 때의 모습입니다. 아무튼 이런 문제들을 Hardsuit의 도움을 받아가며 빠르게 해결했었습니다.
  32. 그렇게 두 달 동안 상당한 진도를 뽑은 후에, 한국으로 돌아와서 한국팀 작업과 머지를 합니다. 원래는 Hardsuit의 XB1 작업도 같이 하려고 했는데 이건 조금 늦어져서 미뤄졌어요.
  33. 머지 완료하고, 9월에 첫 사내테스트를 진행하게 됩니다. 전부 다 PS4에서 찍은 스크린샷이에요. 실제로 TERA 1렙에서 10렙까지의 튜토리얼 구간을 랙이 좀 심한 것만 빼면 큰 문제없이 진행할 수 있었습니다. 6개월 만에 여기까지 올 수 있었습니다. 이쯤 되면 포팅 가능성은 검증 되었다고 봐야죠.
  34. 그래서 이제 제대로된 프로덕션 단계를 준비합니다. 이터레이션을 위한 배포 환경을 만들고, Xbox one 작업도 마무리 지어야 하고, 로컬라이징 작업 환경도 만들어야죠. 슬슬 계정 인증 등의 백엔드 준비도 시작해야 하구요. 즉 저의 목표는 어떻게든 게임이 구동되게 하는 것에서, 다른 사람들이 일을 잘 할 수 있게 만들어 주는 것으로 바뀝니다. 9월 부터 12월 까지는 이런 일들을 했어요.
  35. 그 외에도 몇가지 추가 업무가 있었는데 아예 단기 외주 팀을 구해서 UI 개발을 가속화 합니다. 이쪽은 이미 프로덕션 단계가 굴러가고 있었으니까요. 그리고 알파 테스트를 해보니 욕심이 생겨서 전투 Focus 팀을 만들어 개발 이터레이션을 돌립니다. 물론 여전히 엔진 버그가 많으니 그것들 고치면서 말이죠.
  36. 최종적으로 12월에 다시 모든 작업의 결과물을 합칩니다. 그리고 처음으로 PS4에서 QA를 시작할 수 있었어요. (클릭) 물론 이렇게 처참하게 fail 리포트가 오지만, 되는 게 있는게 중요해요. 잘 되는 것 부터라도 QA를 하기 시작하면 되는 거였습니다. 이게 크리스마스 있는 주 였습니다. 이 리포트 보고 다들 연말까지는 쉬었던 기억이 납니다.
  37. 자 새해가 밝았고, 이제 개발 사이클이 가능해져 있는 상태였죠. 작업, 배포, QA의 개발 이터레이션을 계속 돌기만 하면 됩니다. (클릭) 그래서 프로그래머도 추가 영입하면서 개발에 박차를 가합니다. 심지어 다른 프로젝트 중인 테라 출신 시니어들에게까지 도움 요청을 하면서요. 그리고 UI 만들고 엔진 버그 고치고 하는 것은 원래 하던 일이지만, TRC / XR 이라는 것을 챙기기 시작한 게 이 시점입니다.
  38. TRC / XR이라 함은 MS와 Sony에서 만든 CheckList를 말합니다. 모바일에서 앱 심사 같은 거죠. 꽤 상당한 분량을 자랑합니다. 할 일이 많아요. 이 심사 과정을 Certification이라고 하며, 통과해야지만 실제 제품으로 출시가 가능합니다.
  39. 알아 두면 좋을 팁을 몇 개 방출합니다. 심사 절차는 두 플랫폼 모두 일주일 정도 걸립니다. 그리고 테스트에 필요한 도구를 제공해야 합니다. 만렙 달성해주고 이런 거요. 저흰 운영툴로 해결했습니다. 이 Checklist들은 면제 요청이 가능하지만 통과가 쉽지 않고, 절차가 오래 걸립니다. 그리고 처음 하면 4~5번은 떨어지는게 보통이라고 합니다. 저희도 딱 저 정도 떨어지더라구요. 아무튼 정말로 통과하기까지 오래 걸립니다. 1년 걸린다고 생각하고 미리미리 준비하세요. 아마 이미 콘솔 개발을 하고 계신 분이 있다면 여기서 궁금한 점들이 가장 많으실텐데, 자세한 내용은 NDA 문제로 발표에 담기 곤란합니다. 차라리 개인적으로 연락 주시는 게 나을 것 같네요.
  40. 자, 아무튼 4월에 두 플랫폼에 모두 심사를 넣는 것을 다음 목표로 설정합니다. 모든 UI도 개발 완료하고, 로딩 최적화도 끝내고, 기타 엔진 버그들도 다 잡으면서 말이죠. (클릭) 이런 행복회로룰 굴리던 시기였어요.
  41. 4월 말에 Cert를 제출하게 되고 결과를 5월에 받아 봅니다. 결과야 당연히 둘다 FAIL 이긴 했지만, 어떤 식으로 하면 되는지 감을 잡을 수 있었어요. 리포트에 친절하게 뭐를 어떻게 고치라고 다 알려줍니다. 그러면 이터레이션을 돌기만 하면 될 것 같네요! (클릭) 하지만 빨간 불은 다른 데서 켜집니다. 로딩 최적화를 했지만 프레임이 여전히 심각하게 안 나오고 있었어요. 어쩔 수 없이 런칭 계획을 미루고 최적화에 총력을 다하기로 합니다.
  42. 그래서 5월에서 9월 까지는 최적화에 총동원 기간이었습니다. UI 팀도 UI 최적화를 하구요. 그래서 개발 진도는 거의 멈춰있었던 시기입니다.
  43. 그 최적화 하던 것을 9월에 중간 점검을 하는데, 최적화가 끝나진 않았지만 가능성이 보였습니다. 아 할 수 있겠다 에 대한 자신감이 조금 생겼어요. 이때에 PAX에서 시연도 했습니다. 최적화가 덜 되었어도 새로 만든 UI나 전투 조작성에 대한 고객 피드백을 받은 것인데 상당히 긍정적이었어요. (클릭) 그래서 다시 런칭 타이머를 돌리기 시작합니다. 이때다 9월 말이었으니 연말에 CBT를 하고, Certification 여부에 따라 런칭일을 조정하면 되겠다라는 계획이었죠. 이번 행복회로는 거의 성공했죠.
  44. 그래서 이 때 부터는 정말 폴리싱만 하는 단계였습니다. 추가 기획은 최대한 자제하고, 버그 수정과 최적화에만 집중하는 것으로요 Cert 대응 팀은 계속 그것 준비하구요. 그래서 이 이후는 별로 공유할 게 없습니다.
  45. 그래서 다시 이 그래프를 돌아와서 정리를 해봅시다. 빌드의 전반적인 관점에서 보면 2016년이 프리 프로덕션 단계였지만 (클릭) PC 빌드와의 병행 구조로 인해 이렇게 UI 프로덕션은 더 빨리 시작할 수 있었지요. (클릭) 그리고 TRC / XR은 정말로 1년 넘게 걸렸습니다. Cert에 계속 떨어졌기 때문에 출시일이 계속 미뤄진 것도 있어요. (클릭) 최적화에 투자한 시간도 꽤 많았구요. 최적화는 지금도 계속 하고 있습니다.
  46. 정리하면 다음과 같습니다. 테라 콘솔은 총 2년 걸린 프로젝트이고, 클라이언트 프로그래머는 1명을 시작해서 최대 9명까지 갔다가 지금은 6명인 상태입니다. Hardsuit Labs에 컨설팅을 받음으로써 초기 개발을 가속화 할 수 있었구요. 기존 PC 서비스 빌드를 적극 활용해 UI 및 전투 UX 개발을 빨리 시작했습니다. TRC / XR 준비는 정말로 1년 이상 걸렸구요. 최적화는 예상치 못한 장벽이었고, UE3를 안정적으로 멀티 스레드화 하는데 반년 이상 걸렸습니다. 여기까지 테라 콘솔의 개발 과정이었구요. 뭔가 여러분의 프로젝트에서 참고할 만한 사항들이 있기를 바랍니다.
  47. 이제 최적화에 대한 얘기를 합시다. 테라 콘솔은 최적화 문제가 없었다면 훨씬 빨리 출시 할 수 있었어요. UE3 게임을 콘솔로 가져가실 분들은 분명히 저희와 비슷한 문제를 겪게 됩니다 그래서 최적화에 대한 팁이 필요할 것 같아서 별도의 세션으로 준비했습니다. 도움이 되었으면 좋겠네요. 먼저 로딩에 대한 얘기를 해볼까요
  48. MMORPG가 다른 게임과 다른 점은 유저들의 동적 데이터가 많다는 것입니다. 어떤 플레이어가 어떤 옷을 입고 어떤 탈 것을 타고 어떤 스킬을 쓸지 모르기 때문에 미리 로딩해 놓을 수 없다는 점이죠
  49. 그래서 MMORPG는 게임 플레이 중에도 뭔가를 계속 로딩하고 있게 됩니다. 간헐적 프레임 드랍의 이유가 여기에 있죠. (클릭) 여기에 UE3의 구조적 문제가 함께합니다. MMORPG는 UI가 많아서 전부 다 메모리에 올려놓는 것이 불가능 해요. 그리고 UE3는 한 번에 하나의 파일만 로딩이 가능하구요. 이래서 다른 파일을 로딩 중인에 UI를 갑자기 열면 프리징이 발생하게 됩니다. UE3에서 비동기 로딩이 제대로 동작하지 못하는 이유입니다.
  50. 이걸 테라의 이펙트 패키지 하나로 예로 들어 보겠습니다. FX_A 라는 이펙트 패키지가 있다고 치면, 여기에는 Particle System이 들어있을 거고 그 Particle System이 들어있는 Material Instance와 Template이 있을 거고 Texture도 있겠죠. 그리고 여러 ParticleSystem들을 하나의 파일에 묶어 놓게 되지요. 한 패키지 파일에 수백개의 파티클 시스템이 들어 있다고 보시면 됩니다.
  51. 이걸 로딩하려고 하면, UE3는 세가지 로딩 API가 있습니다. (클릭) 하나의 Particle System을 로딩하고 싶으면 StaticLoadObject를 쓰면 되는데, 이건 Block Loading 입니다. 프리징이 걸려요. (클릭) 그리고 하나의 파일을 Block Loading 하는 API가 있고 (클릭) AsyncLoading 하는 API가 있죠.
  52. 그런데 하나의 Uobject만 비동기로 읽는 API가 없죠? 이에 대한 언리얼 가이드는 이렇습니다. (클릭) 해당 Uobject가 들어있는 Package를 LoadPackageAsync로 로딩 (클릭) 완료되면 사용하려고 했던 오브젝트를 Referencing 하고 (클릭) GC를 돌린다 근데 인게임에서 실시간에 이러고 있을 수는 없잖아요.
  53. 그래서 테라팀은 과거에 엔진을 개조해서 하나의 UObject만 비동기 로딩하는 함수를 만들었습니다. 그나마 이 방법으로 PC 서비스에서 최소한의 퍼포먼스를 내고 있습니다. 즉, 로딩으로 인한 랙 자체는 어쩔 수 없으니, 대신에 그 로딩 시간 자체를 짧게 하는데 주안 점을 둔 것이죠.
  54. 하지만 콘솔 플랫폼에 오면서 Seek-Free 라는 개념을 만납니다. UE3는 콘솔일 때에 코드 레벨에서 Seek-Free를 강제하고 있어요.
  55. 무슨 개념인지 간략하게 설명해 보죠. 만약 이렇게 두 개의 패키지 파일이 있고, A 파일의 Particle System이 B 파일의 Material Instance를 쓴다고 가정해 봅시다. PC의 경우 A 파일의 Particle System을 로딩하려고 하면 로딩 과정에서 B 파일도 로딩하게 됩니다. 그냥 파일 두개 로딩 하는 거에요.
  56. 하지만 Seek-Free 로 쿠킹을 하고 나면 이렇게 B 파일의 내용이 A 파일로 복사되서 들어갑니다. 용량을 희생하고 로딩속도를 올린 거에요. (클릭) 이건 UE3가 콘솔에서 광학 디스크를 가정하고 있기 때문입니다. 광학디스크는 위치에 따라 Seek-Time이 수십에서 수백 ms도 나옵니다. 그래서 DVD 판매를 가정하고 있다면 이 전략 자체는 굉장히 훌륭해요.
  57. 하지만 Seek-Free의 문제는 Object 단위 로딩이 불가능해지고, 항상 풀 패키지를 로딩해야 한다는 점에 있습니다. 저 두 API를 못 쓰게 되요.
  58. 그래서 테라 콘솔의 워스트 케이스는 다음과 같은 상황이 되죠. 하필 누가 옆에서 스킬을 써서 그 이펙트를 로딩하고 있는데 그 와중에 내가 UI 를 오픈하면? 네, 초단위 프리징이 발생합니다. 개발 초기에는 10초 넘게 걸렸었어요. 이펙트 하나를 로딩하기 위해 해당 파일에 들어있는 모든 이펙트를 다 로딩해야해서 그렇습니다.
  59. 이 문제를 해결하기 위한 Best Practice는 하나의 파일이 너무 크지 않게 관리 하는 것입니다. 저 정도 예시면 충분 할 것 같네요. (클릭) 사실 UE3에서 UObject 단위의 비동기 로딩을 지원하지 않는 이유가 이거죠. 로딩의 목적과 파일에 들어있는 내용이 일치하면 많은 문제가 해결됩니다. TERA는 오른쪽이 너무 크죠 이걸 개발 초기에 반드시 숙지하고 작업하시기를 바랍니다.
  60. 테라는 또 제약 조건이 있죠 아트 리소스 수정은 불가능합니다. PC 서비스의 내용을 계속 머지해 와야 하니까요. 반대로 저흰 DVD 판매 없이 DownLoad 전용으로 판매할 거니까, 사실 Seek-Free를 안해도 된단 말이죠. 그래서 엔진을 개조해서 Seek-Free를 안 하게 해보려고도 했는데, 이건 모든 Uobject 타입에 대해서 Serialize와 Cooking 로직을 조사해야 합니다. 조금 시도를 해봤는데 시작부터 난관이 많아서 포기했어요. Hardsuit Labs와도 상담을 해봤는데 다른 방법을 찾는게 낫다고 하더라구요. 그럼 결론은? 우리의 Wrapper를 하나 만드는 수 밖에 없겠죠.
  61. 그래서 저희의 해결법을 공유 합니다. 먼저 쿠킹하기 전에 파일을 Uobject 단위로 쪼갭니다. 아예 다른 파일에 복사하는 거죠. 에디터의 Rename 과 비슷하게 구현 하면 됩니다.
  62. 이제 쪼개진 파일로 쿠킹합니다. Seek-Free 라서 연관 Object는 딸려 옵니다.
  63. 이러면 파일이 10만개는 나오거든요 -_- 너무 많으니까 이걸 다시 합칩니다.
  64. 이걸 이제 mapping table로 관리하는 겁니다. 예를 들어보죠. FX_A.FX_A_0001_PS를 로딩하려고 하면, 코드에서 mapping table을 보고 Redirect 파일의 것으로 바꿔 칩니다. 그리고 파일 I/O 스레드 쪽에서도 파일 핸들을 만들 때 Composite 파일의 특정 지점으로 넘겨주도록 바꿔 치구요. 이렇게 훼이크를 두 번 하면, 결과적으로 작은 파일 하나를 LoadPackageAsync 하는 것 처럼 됩니다. 테라 콘솔은 이 방법으로 로딩 문제를 회피했습니다.
  65. 정리 하면 MMORPG는 로딩 퍼포먼스가 문제가 됩니다. 그리고 UE3는 콘솔에서 Seek-Free를 강제하기 때문에 퍼포먼스가 더 나빠질 수도 있어요. TERA 콘솔은 PC와의 일관성을 유지해야 해서 아트 리소스 자체를 수정할 수는 없었습니다. 그래서 별도의 Redirecting 기법을 만들어서 문제를 회피했습니다. 대신 쿠킹시간과 용량을 희생하구요. 어쨌건 UE3로 콘솔에 가면 Seek-Free 때문에 당황하실 수도 있습니다. 그래서 이런 방법도 있다는 점을 공유 드리고 싶었습니다.
  66. 다음은 메인 스레드 최적화에 대한 이야기 입니다. 리소스 로딩 문제는 그나마 조기에 해결했지만 이 멀티스레드 최적화는 반년 넘게 걸렸다는 것은 앞에서 공유 드렸죠. 다시 말씀드리지만, 최적화를 할 필요가 없었다면 테라 콘솔은 작년 여름에도 런칭 할 수 있었습니다. 그 만큼 UE3 게임의 콘솔 포팅을 고려하는 분들은 최적화 개발 일정과 전략을 조기에 설정하시는 게 좋습니다. 저흰 몰랐으니까요.
  67. 자, 현세대 콘솔의 CPU 스펙을 보면 1.6GHz가 8코어 붙어있습니다. 이 1.6Ghz는 요새 나오는 CPU 클럭 수의 절반 밖에 안 됩니다. (클릭) 그런데 UE3는 코어 2개만 바쁜 펜티엄 시절의 엔진이에요. 즉, 멀티 스레드로 최적화를 꾀하는 것은 선택이 아닌 필수 입니다.
  68. 이해를 돕기 위해 언리얼 엔진3의 구조를 대략적으로 설명 드리겠습니다. 이렇게 메인 스레드에서 로직을 업데이트 하구요. Ring Buffer를 통해서 렌더스레드에 렌더커맨드를 넘겨주는 방식입니다. 즉, 렌더 스레드는 한 틱 전의 정보로 렌더링 하는 것이죠. 이렇게 두 개의 스레드만 바쁘고 나머지는 놉니다. (클릭) 이렇게 자잘한 Thread 들이 있긴 하지만 오래 걸리는 로직들이 아니에요. (클릭) 그래서 흔히들 UE3는 코어를 2.5개 사용한다고들 말합니다.
  69. 저는 메인 스레드 병렬화에 대한 주제만 다룹니다. 그래서 메인 스레드를 좀 더 세부적으로 파볼게요. 저 순서대로 실행되는데 (클릭) 먼저 Input 처리하고 (클릭) 비동기 로딩을 합니다. (클릭) 그리고 실제 레벨에 존재하는 모든 오브젝트 업데이트를 하죠. 이 World Tick 이 가장 큰 부하입니다. (클릭) 다음에는 추가 Tick 처리가 필요한 모듈들의 Update를 수행하는데, GFX Tick이 여기에서 수행됩니다. 이것도 최적화 대상입니다. (클릭) 마지막으로는 Scene Rendering을 위한 RenderCommand 들을 생성하죠.
  70. 그래서 World Tick을 최적화를 해야 하는데, 그 전에 언리얼 엔진의 Actor-Component 모델을 이해 하셔야 해요. (클릭) 월드에 존재하는 모든 오브젝트는 Actor고 (클릭) 행동 구현을 Component로 하신다고 보면 됩니다. 그래서 World Tick의 업데이트는 모든 Actor에 대한 업데이트 이고, 실제로는 각 Component에 대한 Tick을 수행하는 것이 World Tick 의 핵심입니다.
  71. 그래서 World Tick 내부에서 일어나는 일들을 순서대로 적어보면 이렇게 표시할 수 있구요. 이 세 개의 Tick Group이 중요합니다.
  72. 저렇게 TickGroup이 나눠지는 이유는 DuringAsync Tick 전후로 PhysX 연산의 Sync를 맞추기 때문이에요.
  73. 그래서 PreAsync 때에는 물리 시뮬레이션 전에 수행되어야 할 업데이트들을 하구요. 주로 Static / Skeletal MeshComponent 들이죠. 그리고 DuringAsync Tick에서 나머지 Component들이 대부분 시행됩니다. PostAsync Tick 은 물리 연산 이후에 해야 하는 것들을 하는데, 거의 해당사항이 없습니다. 무시하셔도 되구요. 그래서 저 PreAsync와 DuringAsync가 엔진 업데이트의 핵심입니다.
  74. 그 다음에 실행 되는 것도 설명 드리자면 PostTickComponent는 변화가 있었던 Component에 대해서 RenderCommand를 생성하는 부분입니다. 여기도 최적화를 해야 합니다. 그리고 그 밑에 두 개는 메모리 정리 등의 필요한 후처리를 하는 부분인데, 프로파일러에 검출되지 않아서 역시 무시해도 되는 부분이었어요.
  75. 자 여기 까지 엔진 구조를 파악했으니, 최적화 전략을 세워 봅시다. 가장 큰 조건은 테라 콘솔도 지속적인 라이브 서비스를 해야 하고, 그래서 기존 코드 구조를 최대한 유지해야 한다는 점이죠. 그리고 시간도 없었죠. 이럴 때에는 Fork and Join이 정석입니다. 많은 게임 엔진에서 쓰는 방법이에요.
  76. 위키피디아에서 그림을 가져왔습니다. 마스터 스레드가 작업을 수행하다가 병렬화가 가능할 것 같은 지점이 되면 쫙 병렬화를 하고 모두 끝나기를 기다렸다가 다음 작업으로 넘어가는 것이죠. 간단합니다. 장점은 구현이 쉽고 사이드 이펙트가 적다는 것이고 단점은 CPU 사용률 100%가 불가능하다는 점입니다. 그리고 Join이 길어질수록 성능이 떨어지게 되므로 그렇지 않도록 주의할 필요가 있지요.
  77. 실제 코드 구현을 보시면 왜 구현이 쉽다고 하시는 지 알 수 있을 거에요. World Tick을 최대한 간소하게 표현하면 다음과 같습니다. 그냥 모든 컴포넌트에 대해 Tick을 도는 거죠. (클릭) 이걸 이렇게 앞 뒤로 Lambda capture를 떠 버리면 됩니다. AsyncTaskManager는 이런 Lambda Job이 일정 수 모이면 그 때 fork 합니다. 너무 작은 단위로 fork 하면 그것도 비용이거든요. 아무튼 이렇게 기존 코드를 보존한 채로 Fork and Join 모델을 도입할 수 있습니다.
  78. Join은 간단합니다. World Tick에 Sync 하는 지점을 설정만 하면 됩니다. 저 TickActors 함수의 내부가 아까 보신 모든 컴포넌트 Tick을 하는 부분입니다. 이렇게 TickActors 바로 밑에서 Join을 걸면 됩니 Sync 함수는 내부에서 Task 분배한 것들이 끝나길 기다리며, 만약 아직 시작도 못한 것이 있다면 가져와서 자기가 합니다. 어차피 노니까요. 그리고 모든 Task가 끝났다면 모아둔 콜백을 처리합니다.
  79. 콜백에 대한 얘기가 나왔는데, 분명이 이렇게 병렬화를 하고 나면 그 task 내에서 병렬화가 불가능한 로직 덩어리가 분명히 존재합니다. 예시로 가져온 것은 ParticleSystemComponent Tick의 마지막 부분인데요. FinalizeTickComponent는 내부에서 Component 삭제 로직 등이 돌아서 병렬화에 문제가 좀 있습니다. (클릭) 이런 경우 이렇게 또 Lambda capture를 떠서 메인스레드에 다시 콜백으로 주면 됩니다. 그러면 Join이 끝나고 이어서 수행되게 될 겁니다. 이 콜백이 또 너무 크다면 Join이 길어지고 병렬화 효과를 못 보게 됩니다. 그래서 콜백이 너무 크지 않도록 로직 자체를 수정해야 할 때도 있었습니다.
  80. 그리고 Lock으로 해결가능한 경우도 있습니다. 이렇게 전역 컨테이너에 추가/삭제하는 경우 인데, 한 틱에 몇 번 안 들어옵니다. Lock Contention이 매우 작죠 (클릭) 이럴 때에는 간단하게 Lock 을 거는 것으로 넘어가도 됩니다.
  81. 락은 Contention이 적을 때에만 쓰는 겁니다. 프레임당 락에 걸린 총 시간을 말하는 거구요. 직접 재보시면 됩니다. 마이크로 세컨드 단위일 때만 Lock을 쓴다고 생각하시면 됩니다. 아니면 Lock이 없어도 게임이 구동되고 어쩌다가 크래시나는 정도의 빈도일 때만 쓴다고 생각하셔도 됩니다. 이렇게 룰을 정해야 성공적인 병렬화가 가능합니다. Contention이 많은 Lock 활용은, 전역 컨테이너를 빈번하게 접근해야 하는 경우 같은 것이 있을 것인데 Thread_local 컨테이너를 만들어서 거기에 작업을 수행하고 나중에 Sync 맞추는 등의 우회 방법들이 있습니다
  82. Thread_local 얘기가 나왔는데, 각 변수를 Thread 마다 따로 생성하게 해주는 키워드 입니다. 예시를 들면 이렇게 UE3에서 임시변수를 전역 변수로 쓰는 경우가 있는데, thread_local 선언 해주면 임시변수가 thread 개수 만큼 생기는 거죠. 물론 이게 정말 임시변수 인지 아닌지는 코드 파악을 확실하게 하셔야 합니다. thread_local은 꼭 이게 아니더라도 로직을 thread_safe 하게 수정할 때에 매우 유용합니다.
  83. 자, Fork and Join으로 병렬화를 하는 아주 기초적인 접근법을 설명 드렸구요. 지금 제가 말씀 드린 방법은 사실 UE4에 거의 비슷하게 구현되어 있습니다. 여기에 추가로 공유하고 싶은 것은 PostTickComponent 병렬화 인데요, Transform 변동에 의한 render command를 생성하는 것인데, 보통 이게 부하가 되지는 않습니다.
  84. 하지만 MMO는 이런 상황이 발생하요. 저희가 최적화 할 때 사용하는 논 클라봇 100명을 풀어놓은 상황입니다.
  85. 이 상황을 프로파일러로 찍으면 이렇게 보입니다. 수백 개 Component의 PostTickComponent 로직이 수행되면 이렇게 과부화가 걸릴 수 있습니다.
  86. 그래서 똑같은 방법으로 병렬화를 했습니다. 사실 핵심은 RingBuffer Write에 Lock을 쓰는 거에요. 이건 Lock Contention이 좀 있습니다. 하지만 그래도 이전 보다 성능이 확연하게 좋아지는 것을 볼 수 있기 때문에, contention을 감수하고 Lock을 썼습니다. 움직이는 오브젝트가 많은 게임이라면 한 번쯤 고려해 보세요.
  87. 마지막으로 GFX Tick 최적화에 대해 얘기해 보죠. 테라는 UI가 많아서 이것도 부하가 됩니다. 숏컷 쿨타임 이런것들 말하는 거에요. UI가 Actor들이랑 별 상관도 없는데 꼭 World Tick 뒤에 수행되어야 할 이유가 있나? 라는 궁금증이 있었고 실험을 시작한 겁니다. (클릭) 이게 전략이었어요. 일단 스레드로 빼고, 문제가 나올 때까지 고친다 정말 해결 불가능한 문제가 나오지 않는 한 계속 하다보면 성공하겠죠?
  88. 도식화 하면 이렇게 되는 거죠. World Tick 전에 미리 시작해서, 뒤에서 Sync 맞추는 거죠. (클릭) 결론은 쉽지는 않았고, 두 달 정도 걸려서 결국 완성했습니다. 어쨌건 되긴 되더라! 라는 것 자체가 꿀팁입니다요 여러분.
  89. 최종적인 모습을 보여드리겠습니다. 이게 작업 하기 전의 모습이구요. 앞에 TERA 게임 영역이라고 표시되어 있는데, TERA의 게임 로직만 따로 모아놓은 구간입니다. UE3 엔진틱 앞에서 수행되요. 여기도 똑같은 전략으로 병렬화가 가능하기 때문에 시간 관계상 설명을 생략했습니다. 아무튼 3번 이후의 CPU가 놀고 있는 걸 보실 수 있죠.
  90. 이게 작업 끝난 이후의 모습입니다. 빨간 부분이 테라 로직, 파란색 부분이 언리얼 엔진 로직입니다. 노란 색 부분이 UI 로직 빠져있는 거에요. 초록색은 렌더링 로직으로, 렌더링이 훨씬 하는 일이 많아요. 이건 다음 발표에서 들어 보시구요. Fork and Join 모델의 단점은 CPU 사용율 100%가 불가능하다는 점이라고 말씀 드렸죠? 네 그래서 중간중간 구멍이 좀 있습니다. 그래도 이전의 모습에 비교하면 장족의 발전이 있었죠.
  91. 정리하면 GFX tick은 엔진 tick에서 분리해 낼 수 있습니다. 그리고 기존 코드를 최대한 유지하기 위해 Fork and Join 방식으로 병렬화를 시도했구요. Critical Section은 Callback, Lock, Thread_local 등으로 해결할 수 있습니다. 물론 Lock은 contention이 적을 때에만 써야 하구요. 경우에 따라 퍼포먼스를 위해 로직 자체를 수정할 각오는 당연히 필요하구요. 그걸 위해 언리얼 엔진에 대한 높은 이해는 필수입니다.
  92. 이제 마무리를 하죠.
  93. TERA 콘솔은 콘솔 개발/서비스 경험을 회사의 자산으로 남기고자 자체 포팅을 시작했습니다. 이 경험을 토대로, 블루홀 차기 프로젝트에서 콘솔 플랫폼 개발이 더 많이 고려되기를 기대하고 있어요.
  94. 어쨌건 UE3 게임을 현세대 콘솔에 포팅하는 게 불가능한 일은 아닙니다. Unsupported 코드도 있고, 도움 받을 곳들도 많이 있구요 TRC / XR 등은 인내심으로 대응하면 됩니다. 최적화 문제는 굉장히 고생스럽지만.. 해결하고 나면 프로그래머로서 최고의 희열을 느껴보실 수 있습니다. 시장성도 좋아요.
  95. 어쨌건 제가 전달하고자 했던 것은 첫째는 콘솔 포팅 개발에 대한 간접 경험입니다. 어떤 과정을 거쳐서 UE3 MMORPG가 콘솔로 포팅 되었는지 말이죠. 그래서 콘솔 시장에 도전하는 회사가 많아 졌으면 좋겠습니다. 둘째는 최적화 팁입니다. UE3 의 리소스 로딩에 대한 문제점과 멀티 스레드 최적화에 대한 지식 전달이 목표였습니다. 잘 전달 되었으면 좋겠네요.
  96. 이 발표 내용이 저 혼자한 것도 아니고, 2년 동안 많은 동료분들이 정말 고생 많으셨습니다. 이 자리를 빌어 저희 팀에 감사하다는 말씀 드리고 싶습니다.
  97. 그리고 모름지기 컨퍼런스란 기승전 채용 홍보죠. 테라 콘솔 클라이언트 프로그래머를 채용 중이니 관심 주시면 감사합니다.
  98. 끝으로 다음 발표도 들어주시는 것 잊지 마세요.
  99. 이걸로 발표를 마칩니다. 감사합니다.
  100. 질문 받습니다.
  101. TERA 콘솔은 콘솔 개발/서비스 경험을 회사의 자산으로 남기고자 자체 포팅을 시작했습니다. 이 경험을 토대로, 블루홀 차기 프로젝트에서 콘솔 플랫폼 개발이 더 많이 고려되기를 기대하고 있어요.
  102. TERA 콘솔은 콘솔 개발/서비스 경험을 회사의 자산으로 남기고자 자체 포팅을 시작했습니다. 이 경험을 토대로, 블루홀 차기 프로젝트에서 콘솔 플랫폼 개발이 더 많이 고려되기를 기대하고 있어요.
  103. TERA 콘솔은 콘솔 개발/서비스 경험을 회사의 자산으로 남기고자 자체 포팅을 시작했습니다. 이 경험을 토대로, 블루홀 차기 프로젝트에서 콘솔 플랫폼 개발이 더 많이 고려되기를 기대하고 있어요.
  104. TERA 콘솔은 콘솔 개발/서비스 경험을 회사의 자산으로 남기고자 자체 포팅을 시작했습니다. 이 경험을 토대로, 블루홀 차기 프로젝트에서 콘솔 플랫폼 개발이 더 많이 고려되기를 기대하고 있어요.
  105. TERA 콘솔은 콘솔 개발/서비스 경험을 회사의 자산으로 남기고자 자체 포팅을 시작했습니다. 이 경험을 토대로, 블루홀 차기 프로젝트에서 콘솔 플랫폼 개발이 더 많이 고려되기를 기대하고 있어요.
  106. TERA 콘솔은 콘솔 개발/서비스 경험을 회사의 자산으로 남기고자 자체 포팅을 시작했습니다. 이 경험을 토대로, 블루홀 차기 프로젝트에서 콘솔 플랫폼 개발이 더 많이 고려되기를 기대하고 있어요.
  107. TERA 콘솔은 콘솔 개발/서비스 경험을 회사의 자산으로 남기고자 자체 포팅을 시작했습니다. 이 경험을 토대로, 블루홀 차기 프로젝트에서 콘솔 플랫폼 개발이 더 많이 고려되기를 기대하고 있어요.