로그인

회원가입 | ID/PW 찾기

연재

게임은 다른 프로그램과 무엇이 다를까?

게임 프로그래머 문기영의 ‘게임 프로그래머 이야기’ ⑥

ProgC 2013-11-05 14:23:19
게임 제작에 관련된 지식을 습득하기 위해 관련된 책이란 책은 다 사서 읽어보고 오래돼서 못 읽는 책들은 도서관에 가서 읽었다. 그리고 책에서 나오지 않는 내용은 flipcode, gamedev, gpgstudy와 같은 사이트를 참고해가면서 공부를 했다.

생각해보면 커뮤니티 활동도 열심히 했었다. 실제로 게임 개발을 하는 선배님들과 친해지고 싶었던 이유도 있었고 특히 내가 알고 있는 것들이 진짜 맞는 건지 아닌지 알아보고 싶었던 이유도 있었다. 아무래도 혼자서 게임 개발 공부를 했기 때문에 항상 의문이 들었다.

“이렇게 하는 게 맞는 걸까? 다른 사람은 어떻게 할까?”

커뮤니티 활동을 하면서 사람들과 친해지고 개발에 관한 이런저런 이야기들도 많이 나누었지만, 어느 날 갑자기 그런 생각이 들었다.

“다른 사람들은 자신이 만든 게임이 있는데 왜 나는 없는 거지?”

왜 나는 게임을 완성 못 했을까?
게임을 완성하려면 어떻게 해야 할까?
게임을 완성하려면 어떤 공부가 필요할까?

나 스스로 질문을 계속 던졌고 알게 된 것은 꾸준한 노력, 포기하지 않으면 된다는 것이었다.

“뭐가 되던 포기하지 말자!”

첫 회사가 문을 닫고 쉬게 되었지만 얼마 지나지 않아 다른 회사에서 연락이 왔다. 같이 게임을 개발하자는 것이었다. 이번에도 역시 고민하지 않았다. 나는 당장 일하고 싶었기 때문에 거부할 이유가 없었다.

그렇게 두 번째 회사에 입사하게 되었다. 첫 회사는 프로그래머가 혼자였기 때문에 나 혼자 모든 걸 다 해야 했지만, 이번 회사는 아니었다. 나 말고도 다른 프로그래머들이 있었고 모두 훌륭해 보였다.

같이 일하던 사람들도 모두 좋았지만, 시간이 지나자 문제가 있어 보였다. 가장 큰 문제가 있었다.

“왜 아무도 우리가 만들 게임에 대해서 말하는 사람들이 없는 거지…?”

당시에 메인 프로그래머가 있었고 기획자도 있었고 디자이너도 있었지만 정작 우리가 어떤 게임을 만들지 이야기하려는 사람들이 없었다. 그리고 회사에서 나를 뽑아 놓고 어떤 업무를 해야 하는지도 말해주지 않았다. 물론 내 성격상 수동적으로 일을 받아서 하는 타입은 아니지만, 당시에는 사회 초년생이었고 엄연히 메인 프로그래머가 있었기 때문에 일을 기다렸다. 하지만 일을 기다려도 나에게 일은 주어지지 않았다.  

어느 날 내가 물었다.

“우리 어떤 게임 만드나요?”

돌아오는 대답은 엔진 개발이었다.

 
현대 자동차 GDi엔진. 출처: blog.hyundai.com

자동차의 핵심 부품인 자동차 엔진이 있듯이 3D 게임에는 3D 게임 엔진이 필요했다.

“그럼 난 뭘 해야 하지?”

나에게 주어진 일이 없었고 스스로 게임 엔진을 만들려면 어떤 것들이 필요한지 알아보았다.

C4 Engine의 구조 다이어그램. 출처: //www.terathon.com/architecture.php

당시에 메인 프로그래머가 만들어 놓은 렌더러는 있었기 때문에 렌더러는 내가 만들 필요가 없었다. 하지만 그 외에 것들은 거의 없다고 봐도 될 정도로 아무것도 없었다.

“UI는 예전에 해봤으니 다시 해볼까?”

그래서 UI 시스템을 만들기로 했다.

“UI 시스템이 없어 보이니… 제가 만들어 볼까요?”

그렇게 UI 시스템 개발을 했다.

열심히 UI 시스템을 개발해서 버튼을 만들고 드래그가 가능한 윈도우를 만들었다. 하지만 이 시스템은 사용되지 않았다. 메인 프로그래머가 생각하고 있던 것과 달랐기 때문이라고 생각된다.

이제 시간이 지나서 생각해보면 그냥 그 회사는 게임을 만들려는 의지가 보이지 않았다. 다른 사람들은 모르겠지만, 특히 프로그래밍 쪽에서 진도가 전혀 안 나갔다. 오죽하면 내가 직접 소스 코드에 주석을 적었을 정도니까 말이다.

// 우리 일은 언제 하나요? 게임 안 만드나요?

“나에게 줄 일이 없으면 나를 왜 뽑은 거지?”

당시에는 전혀 이해하지 못했다. 그리고 깨달은 사실이 하나 있다.

“디자이너가 실력이 없으면 그림이 이상하고…
기획자가 실력이 없으면 게임이 재미가 없고…
사운드 디자이너가 실력이 없으면 음악이 귀에 거슬리겠지만…
프로그래머가 실력이 없으면 게임은 안 나온다.”

그 회사는 딱 1년을 채우고 관두게 되었다.


두 번째 회사를 나오고 난 뒤, 프로그래밍 공부에 더욱 매진했다. 프로그래밍 실력이 부족하면 게임을 완성할 수 없다는 걸 두 번째 회사를 통해 깨달았기 때문이다. 아는 사람은 별로 없었고 마냥 책만 읽었다.

필자의 서재. 이 정도 분량의 책이 3배 정도 더 있다.

어떤 책을 읽어야 하는지는 잘 몰랐고 그냥 나오는 책은 죄다 구매해서 읽었다. 돈이 많았던 것은 아니고 회사 다니면서 번 돈을 전부 책에 썼다고 보면 되겠다.

게임 회사에 다니면서 항상 UI 시스템을 새로 제작했었는데 UI 시스템을 만들다 보니 내가 만들고 있는 게 사실은 윈도우즈에 이미 있는 것들이었다. 윈도우에도 버튼이 있고 윈도우를 드래그해서 이리저리 움직일 수 있고, 텍스트 박스가 있어서 사용자로부터 입력을 받고, 입력 내용을 화면에 보여주고 수정할 수 있고….

나는 게임도 컴퓨터에서 동작하는 하나의 응용 프로그램이라고 깨닫게 되는 데까지 꽤 오랜 시간이 걸렸다. 컴퓨터 자체도 혼자서 공부했고 게임 제작에 관한 지식도 혼자서 공부했기 때문이다. 게다가 공부 자체도 넓게 공부했던 것이 아니라 게임 제작이라는 주제 하나에만 몰두했기 때문에 더욱 심했다. 그리고 그것을 주변에서 알려주는 사람도 없었기 때문에 내가 스스로 깨닫게 되는 데까지 남들보다 오래 걸렸다.

컴퓨터 공학을 전공으로 하는 학생들은 아마 전자계산기 구조, 컴퓨터구조, 자료구조, 운영체제, C언어, 컴퓨터 그래픽스, 컴파일러, 이미지 프로세싱, 선형 대수학, 공업 수학 등등… 학교에서 대부분을 공부할 것이다. 지금 학생이라면 진심으로 이 모든 분야를 죄다 공부 열심히 해두는 게 좋을 것이다. 왜냐면 컴퓨터 게임을 만드는데 이 모든 분야가 다 사용되기 때문이다.

“어? 나는 현업에서 일하는데 이런 부분은 사용되지 않는데?”

라고 생각하는 분들도 있을 거로 생각한다. 그건 간단하게 대답할 수 있다.

“그 정도까지 경험을 안 쌓아서 그렇습니다.”

모든 것은 개념이 중요한데 컴퓨터 게임이라는 것도 하나의 소프트웨어일 뿐이다. 운영체제라고 하는 것 역시 컴퓨터에서 동작하는 하나의 소프트웨어라고 생각하는 것이 굉장히 중요하다고 생각한다. 나는 이걸 알아내는데 꽤 오래 걸렸다.

컴퓨터 소프트웨어는 컴퓨터에서 제공하는 주변 기기들을 사용한다. CPU도 사용하고 메모리도 사용한다. 화면에 그림을 그리기 위해 VGA 메모리를 건드리기도 한다. 게다가 더 재밌는 사실은….

우리가 사용하는 키보드의 LED를 깜빡이게 만드는 것도 결국 메모리를 수정하면 된다는 점이다. 예를 들어 Num Lock 키가 켜져 있거나 꺼져 있다는 상태를 저장하려면 그 정보를 어딘가에 저장해 놓아야 한다. 컴퓨터는 이러한 정보를 모두 메모리에 저장한다. 즉, 이 Num Lock 키가 켜지거나 꺼진 상태는 메모리의 값이 어떤 값이냐 에 따라 결정된다.

 
Num Lock의 LED가 꺼진 상태, 켜진 상태

Num Lock LED가 이 메모리의 데이터를 어떻게 사용하느냐 에 따라서 불이 켜지거나 꺼진다. 예를 들어서 메모리의 값이 1일 때 불이 켜지고 0일 때 불이 꺼진다고 하면 메모리의 값이 1일 때 LED가 켜지고 0일 때 LED가 꺼질 것이다. 그 반대로 메모리의 값이 1일 때 꺼지고 0일 때 LED가 켜지게 구현해 놓았다면 메모리의 값이 1일 때 LED가 꺼지고 0일 때 LED가 켜질 것이다.

말을 반복적으로 쓴 것 같은데… 결국 핵심은 이 데이터를 어디에 저장해 놓느냐 와 그 데이터를 어떻게 사용하고 있느냐를 아는 게 컴퓨터 프로그래밍의 핵심이 아닐까 싶다.

컴퓨터의 자료는 메모리에 저장된다. 그리고 이러한 자료(메모리의 값)를 어떻게 사용하는지가 알고리즘이다. 알고리즘에 대한 정의는 알고리즘 관련 서적을 참고하길 바란다.

 

 ※ 노트: 알고리즘에 관한 책은 ‘C로 배우는 알고리즘’, ‘The Art of Computer Programming’ 한국판은 ‘컴퓨터 프로그래밍의 예술’, ‘자료 구조와 C’를 추천한다.

 


좋은 알고리즘은 프로그램의 성능을 향상 시킨다. 그리고 좋은 알고리즘은 거기에 맞는 자료구조를 필요로 한다. 올바른 자료구조와 그것을 효과적으로 활용할 수 있는 알고리즘이 쌍으로 맞을 때 프로그램 성능이 가장 좋아진다.

우리가 플레이하는 게임이라는 것은 겉보기에는 다른 응용 프로그램과 달라 보인다. 하지만 내부적으로는 다 똑같다! 이 글에서 자료구조와 알고리즘을 강조했는데 이것들이 게임에서 어떻게 효과적으로 활용되는지 예를 들어 보도록 하겠다.

MMORPG는 특성상 한 화면에 매우 많은 캐릭터가 나타나며 최근에 출시되는 게임들의 경우 캐릭터, 배경, 애니메이션, 이펙트, 사운드 등 많은 것들이 최고 퀄리티로 제작된다. 10년 전과 비교했을 때 그래픽 카드의 발전으로 엄청나게 많은 폴리곤을 빠르게 화면에 그려낼 수 있지만, 굳이 화면에 보이지도 않는 것들을 위해 컴퓨터가 계산하는 것은 게임의 성능을 저해할 수 있다.

예를 들어, 다음 그림과 같이 캐릭터 한 마리가 필드 위에 있다고 치자.
 
UDK에서 캐릭터를 화면에 띄워본 것.

 

 노트: UDK는 Unreal Development Kit의 약자로써 Epic에서 만든 공개용 게임 개발 툴이다. 서점에 가보면 UDK 관련 책들이 많으므로 그것들을 참고하면 도움이 될 듯하다. 물론 필자가 번역한 UDK 책도 있으니 관심 있으신 분들은 참고해주시길.

 


이제 카메라를 캐릭터에게서 멀리 떨어져서 바라보도록 하자.
 
캐릭터를 멀리서 바라보면 거의 보이지 않는다.

그림을 보면 알 수 있듯이 캐릭터가 너무 멀리 있는 경우 캐릭터가 머리를 긁적이고 있는지, 입을 벌리고 있는지, 눈을 깜빡이는지 와 같은 행동들은 거의 볼 수가 없다. 이럴 때 Animation LOD라는 것을 사용하는데 이 LOD라는 것은 Level Of Detail이라는 것의 약자로써 디테일에 레벨을 주어 레벨에 맞게 애니메이션의 퀄리티를 결정하는 것이다.

만일 캐릭터 하나를 그리는 코드가 다음과 같다고 치자.

void Draw()
{
    Character.Draw(IdleAnimation);
}

Draw라는 함수안에 Character라는 변수의 Draw 함수를 호출해 캐릭터를 화면에 그린다. IdleAnimation은 가만히 서 있는 동작을 하는 애니메이션인데 눈도 깜빡이고, 입도 벌리고, 기침도 하는 애니메이션이라고 생각해보자.

이렇게 코드를 구성할 경우에 카메라의 거리와 상관없이 캐릭터는 눈을 깜빡이고 입도 벌리고 기침도 한다. 당연히 이러한 애니메이션을 화면에 보여주기 위해서 컴퓨터는 내부적으로 많은 계산을 한다. 하지만 그림을 보면 알 수 있듯이 멀리 떨어져 있는 경우에 눈을 깜빡이거나 입을 벌리거나 기침을 하는 것들은 굳이 계산하지 않아도 된다. 왜냐하면, 캐릭터가 너무 작아 그냥 가만히 멈춰 있는 얼굴을 해도 상관이 없기 때문이다. (게이머가 알아차릴 수 없기 때문)

조금만 머리를 굴려 보면 다음과 같이 개선할 수 있다.

void Draw()
{
    float distance = GameMath.GetDistance(CameraPosition - Character.GetPosition());
    if ( distance >= 1000 )
    {
        Character.Draw(IdleAnimationLow);
    }
    else
    {
        Character.Draw(IdleAnimationHigh);
    }
}  

위 코드는 다음과 같이 동작한다.

1. 카메라의 위치에서 캐릭터의 위치를 뺀 후 GameMath의 GetDistance 함수를 이용해 벡터의 길이(결과로는 카메라와 캐릭터의 거리)를 distance라는 변수에 저장한다.
2. 카메라와 캐릭터의 거리가 1,000보다 크다면 캐릭터의 Draw 함수에 IdleAnimationLow(애니메이션의 퀄리티가 매우 낮은)를 이용해서 애니메이션 시킨다.
3. 만일 거리가 1,000보다 크지 않다면 IdleAnimationHigh(애니메이션의 퀄리티가 매우 높은)를 이용해 캐릭터를 애니메이션 시킨다.

조금만 생각해보면 이것은 프로그래밍 언어를 몰라도 누구나 이해할 수 있는 부분이다. 실제 게임의 소스는 이것보다 복잡하지만, Animation LOD의 핵심은 이게 전부다. 


<블랙 & 화이트>의 경우 당시에 획기적인 장면이 있었는데 게임이 돌아가던 중간에 아무런 로딩도 없이 화면이 축소되면서 게임 전체 섬을 모두 한눈에 바라볼 수 있었던 점이다. 당시에 이 장면을 본 많은 사람은

“어? 뭐야?? 로딩이 없는데… 게다가 저 많은 걸 어떻게 다 렌더링하지?”

비밀은 바로 LOD의 사용이었다. 여러 레벨의 캐릭터, 배경 메쉬를 준비한 후 카메라의 거리에 따라서 이것들을 교체하면서 화면에 그려주면 그래픽 카드의 성능이 좋지 않은 상황에서도 게임이 끊기지 않고 플레이 가능했다.

이것을 정말로 잘 구현한 또 다른 게임이 있다.


락스타에서 개발한 블록버스터 게임 GTA5.

GTA를 실행하고 게임을 잘 살펴보면 구석구석에 LOD를 아주 많이 사용한 것을 살펴볼 수 있다.

LOD를 예를 들어 좋은 알고리즘(혹은 아이디어)이 얼마나 성능을 개선 시킬 수 있는지 알아보았다.

 

 ※ 노트: 사실 좋은 알고리즘의 필요성을 이야기하기 위해 충돌 처리하는 부분을 이야기하려 했지만, 다소 이해하기 어려울 수 있고 눈으로 볼 수 있는 예제가 더 적합해 보여 Animation LOD로 설명했다.

 


게임은 거의 항상 리소스(CPU성능, GPU 성능)가 부족하다. 그 이유는 아무리 좋은 성능의 CPU나 GPU가 나와도 거기에 걸맞은 최고 퀄리티의 캐릭터 모델링, 애니메이션, 인공지능, 이펙트 등등… 이 사용되기 때문이다. 그래서 거의 모든 부분에서 항상 최고로 성능이 좋은 로직을 작성해야 한다. 그것이 게임 프로그래머의 숙명이자 목표다.

이제 원래 6화의 주제에 대한 이야기를 해보자. 게임은 일반 응용 프로그램과 다른가?

“다르지 않다”

이것이 필자의 견해다. (지극히 프로그래머 관점에서 보면 그렇다.) 게임이라고 해서 다른 컴퓨터 응용 프로그램과 다를 바가 없다. 똑같이 메모리를 사용하며 자료구조, 알고리즘을 이용해서 동작한다.

이런 관점으로 게임 프로그래밍을 하면 다른 분야에서 사용되는 아주 다양한 자료구조, 알고리즘들을 왜 공부해야 하는지 알게 된다. 그리고 전혀 다를 것 같았던 분야에서 사용되던 알고리즘이나 아이디어들이 게임에서도 사용된다. (물론 그 역도 성립한다.)

앞서 이야기했지만, 학교에서 공부하는 내용이 정말 거의 하나도 빼놓지 않고 모두 게임 프로그래밍에서 사용된다는 것이 결코 과언이 아님을 알 수 있다. 그러니 꼭 학생이라면 열심히 공부해 두도록 하자. 믿기지 않겠다면 강요하고 싶은 생각은 없다. 본인이 필요하면 언젠가 다시 공부하게 되어 있으니까 말이다.

  • 게임 프로그래밍을 위해 C언어를 배우다

  • 고3에 첫 게임 도전, 실전으로 게임 프로그래밍을 배우다

  • 게임은 다른 프로그램과 무엇이 다를까?

  • 게임 프로그래머는 수학을 배워야 할까?

  • 게임 프로그래머가 되려면 무엇을 공부해야 할까?