이번 연재에서는 컴퓨터 게임 프로그래머가 되기 위해서 무엇을 공부해야 하는지 설명해 보겠다. 개인적으로는 예전 연재에서 이미 설명했듯이 학교에서 배우는 거의 모든 것을 배워 두는 게 좋다고 했었다.
하지만 실제로 모든 것을 다 알기에는 시간이 부족하고, 나 역시 모든 것을 알지 못한 채로 게임을 개발했고 지금도 먹고살고 있다. 그러면 가장 기본적으로 게임 프로그래머가 되기 위해 어떤 것들을 공부해야 하는지 차례차례 알아보도록 하자.
우선 게임 프로그래머는 크게 서버 프로그래머와 클라이언트 프로그래머로 나뉜다. 나는 클라이언트 프로그래머이며, 클라이언트 프로그래머 역시 많은 부분으로 나뉘므로 이것을 먼저 알아보도록 하겠다.
클라이언트 프로그래머는 사용자의 입력을 받아 게임 로직을 실행시키고 화면에 무언가를 그리거나 사운드를 출력해주는 업무를 담당한다. 실제로 게이머들이 접하는 게임의 많은 부분을 클라이언트 프로그래머가 담당하며, 네트워크 기능이 추가되면서 서버 단에서 게임 로직을 돌리거나 데이터베이스를 다루기 위해 서버 프로그래머라는 직종이 생겨났다.
클라이언트 프로그래머를 분류하자면 다음과 같다.
1. 게임 플레이 프로그래머
2. 물리 프로그래머
3. 사운드 프로그래머
4. 렌더링 프로그래머
5. 툴 프로그래머
6. AI(인공지능) 프로그래머
7. 애니메이션 프로그래머
본래 게임 프로그래머가 하던 거의 모든 업무 중 전문화에 따라 떨어져나간 부분의 나머지를 다 해결해야 하는 역할이 게임 플레이 프로그래머다. AI 프로그래머가 이런 게임 플레이 프로그래머를 겸직으로 같이 하는 경우가 많다.
게임회사마다 게임 플레이 프로그래머의 역할이 다른 경우도 많은데, AI 프로그래머가 하는 일인지 게임 플레이 프로그래머가 해야 하는 일인지 분류하기 어려울 때가 많기 때문이다.
AI 프로그래머라고 AI 모듈만 작성하지는 않는다. AI 모듈 역시 어떠한 데이터가 필요하고 그 결과를 이용해 어떠한 결정을 해야 하는 경우가 있는데, 이때는 게임 플레이 프로그래머가 보통 전담한다. 실제 게임 제작 시 게임 플레이 프로그래머는 프로듀서(게임 기획자)와 가장 교류가 많으며 시작부터 끝까지 게임 개발 프로세스에 참여한다.
현실 세계와 같은 물리 현상을 게임 플레이에 접목하기 시작하면서 물리 프로그래머가 생겨났다.
밸브에서 개발한 <하프라이프 2>의 시소 퍼즐.
초기에는 단순히 배경에 흩날리는 천을 표현하는 수준이었지만 물리 현상을 이용하는 게임 플레이가 생겨남에 따라 더 현실적인 물리 모델을 표현하기에 이르렀고, 물리학을 전공하거나 관련 지식이 있는 프로그래머들이 이 업무를 담당하기 시작했다.
보통 강체(Rigid Body)를 주로 다루고 중력, 물을 표현하기에 이르렀다.
디즈니의 <웨어즈 마이 워터?>. 물을 이용한 게임 플레이가 매우 인상 깊다.
보통 물리 프로그래머는 물리 현상을 구현하기 쉽게 하기 위한 물리 엔진 ODE(Open Dynamic Engine), BulletEngine, Box2D, PhysX를 개발하며, 게임에 따라서 튜닝 작업을 한다. 게임 회사에서 직접 물리 엔진을 구현해서 사용하는 경우도 많다.
사운드 프로그래머는 사운드를 출력하기 위한 사운드 엔진를 작성하거나, (개발팀에 따라서는) 게임에서 어떠한 이벤트의 조건이 충족됐을 때 사운드를 플레이하는 로직을 작성한다.
예를 들어 축구 게임의 경우 축구 선수가 멋진 플레이를 하거나 실망스러운 플레이를 할 때 관중이 환호하거나 야유하는 경우가 있다. 사운드 프로그래머는 이럴 때 게임 로직이 올바른 사운드를 플레이하게 만드는 로직을 작성한다. 그냥 말로 설명할 경우에는 매우 간단한 업무라고 여길 수도 있지만 실제로는 그렇지 않다. 축구 선수가 공을 터치할 때마다 환호성이 나오진 않을 테고 정말 멋진 플레이가 나왔을 때만 환호성을 질러야 하기 때문이다.
축구 선수가 360도 드리블을 했다고 해서 항상 환호성이 나오지는 않는다. 예를 들어 수비수가 자기 진영 안에서 공을 걷어 내지 않고 360도 드리블을 했다고 생각해 보자. 어느 관중이 환호성을 지를까? 이런 모든 상황마다 게임 로직을 작성해서 올바른 사운드를 플레이해주는 로직을 만드는 일이 사운드 프로그래머의 업무 중 하나다.
렌더링 프로그래머
렌더링 프로그래머는 화면에 나오는 모든 업무를 담당한다.(UI 프로그래머를 따로 나누는 경우도 있다.)
예를 들어, 3D게임의 경우 화면에 나오는 모든 것들은 폴리곤으로 이루어져 있다. DirectX와 OpenGL를 이용해 화면에 폴리곤을 그리게 되는데 그래픽 디자이너가 만든 모델링 데이터를 화면에 최대한 빠르게 그려줘야 한다. 폴리곤 뿐만 아니라 올바른 텍스처, 라이팅 계산 처리와 같은 것들을 렌더링 프로그래머가 한다.
작은 회사의 경우 캐릭터를 화면에 그릴 때 애니메이션 처리 부분을 렌더링 프로그래머가 직접 맡는 경우도 있지만, 요즘은 렌더링 프로그래머와 캐릭터 애니메이션 프로그래머가 전문화되어 있기 때문에 따로 분류 했다.
게임은 일반적인 응용 프로그램과는 다르게 리소스를 굉장히 많이 사용한다. 텍스처와 모델을 만들기 위해 포토샵, 맥스, 마야와 같은 콘텐츠 제작툴을 사용하는데, 이러한 툴로 만든 데이터 역시 게임에서 바로 사용할 수가 없다.
게임회사마다 게임에 맞게 저작툴을 따로 제작하는데 여기에는 크게 맵 툴, 캐릭터 애니메이션 툴이 존재한다. 게임 디자이너(기획자)가 이러한 저작툴을 이용해서 게임의 콘텐츠를 만들고 게임 플레이 프로그래머가 만든 시스템에 올려놓으면 비로소 게임 시스템이 완성된다.
툴 프로그래머는 그래픽 디자이너, 프로그래머, 프로듀서와 밀접하게 관련해서 일하며 이들이 게임을 완성하는 데 필요한 도구들을 작성한다.
직접 만든 DeadAnimationTool의 스크린샷. 충돌 처리를 위해 라인 집합들을 만들 수 있는 도구를 제공하고 있다.
AI 프로그래머
본래 게임 플레이 프로그래머가 AI도 담당했지만, 전문화가 되면서 따로 분류됐다.
게임에서 사용하는 AI 모듈로는 길찾기(A*), 룰 베이스 시스템, FSM, 신경망, 유전 알고리즘 등이 있으며, AI 프로그래머가 전담해서 만들게 되었다. 게임 플레이 프로그래머가 쉽게 사용할 수 있게 엔진 형태로 제공하는 경우도 있으며, 보통은 게임 플레이 프로그래머와 AI 프로그래머가 번갈아 가면서 업무를 수행한다.
AI 프로그래머 역시 필요에 따라 도구를 작성한다. 과거 <샤이아>(Shaiya)를 개발할 때 사용했던 FSM 도구는 다음과 같이 생겼었다.
인공지능을 구현하기 위해 프로그래머가 코딩하지 않아도 된다.
FSM(Finite State Machine의 약자)은 게임에서 굉장히 많이 사용된다. 가령 고블린이라는 캐릭터가 있을 때 주변에 주인공 캐릭터가 없다면 어슬렁거리다가 주인공 캐릭터가 주변에 나타나면 전투 모드에 들어가 죽을 때까지 싸우거나 위험에 처하면 도망가는 인공지능을 구현할 때, FSM을 이용할 수 있다.
<샤이아> 개발팀 시절에 만들었던 FSM은 프로그래머가 직접 NPC의 의사결정을 하지 않고 게임 디자이너가 의사결정을 할 수 있도록 도와주는 도구였다. 이를 이용해 NPC의 행동 방식을 프로그래머에게 덜 의존해도 되게끔 만들 수 있었다.
※노트: FSM은 인공지능에만 사용되는 것이 아니다. 최근에는 애니메이션 시스템에도 많이 사용하고 있으며 언리얼 엔진의 경우 키즈멧이라는 도구를 이용해서 게임 전체를 코딩 없이 구현할 수 있게 했다. |
애니메이션 프로그래머
원래 렌더링 프로그래머가 직접 이 일을 했었지만, 분야가 전문화되면서 따로 직업이 생겼다. 애니메이터가 캐릭터의 동작을 만들고 그것을 게임에서 사용하기 위해 애니메이션 프로그래머가 로직을 작성한다.
예를 들어, 애니메이터가 캐릭터의 걷는 동작과 뛰는 동작을 만들었다고 치자. 그리고 게이머가 조작하는 조이스틱의 방향에 따라 캐릭터가 걷거나 뛴다. 이때 조이스틱 방향의 크기가 아주 작을 때는 캐릭터가 걷다가 클 때 캐릭터가 뛰는 동작을 구현하고 싶다고 가정하겠다.
조이스틱을 왼쪽으로 했을 때의 각 크기. 가장 왼쪽은 아무런 동작을 취하고 있지 않을 때, 가운데는 왼쪽으로 약간만 움직였을 때, 가장 오른쪽은 조이스틱을 가장 왼쪽으로 밀었을 때.
이때 애니메이터가 만든 캐릭터의 동작은 걷는 동작과 뛰는 동작밖에 없는데 조이스틱의 방향의 크기에 따라 블렌딩(Blending)을 하면 더 자연스러운 걷기 → 뛰기 동작을 할 수 있다.
왼쪽부터 걷기, 걷기-뛰기 중간 형태, 뛰기.
애니메이터는 걷기와 뛰기 동작만 만들고, 애니메이션 블렌딩을 하면 중간 결과를 얻을 수 있다. 단순히 걷기, 뛰기만 예시로 들었지만 실제로 하나의 애니메이션을 위해 아주 다양한 애니메이션들을 블렌딩해서 결과를 얻는 경우도 많다.
예전에 개발했던 축구 게임은 5개 이상의 애니메이션이 블렌딩되어 하나의 애니메이션을 구성하는 경우도 많았다. 이 블렌딩의 경우 단순히 선형 블랜딩(Linear Blending)도 있지만, 그 외에 많은 블렌딩 방법들이 존재한다.
지금까지 클라이언트 프로그래머의 업무를 분류해 보았다. 실제 게임회사에서는 이외에도 여러 부분으로 더 나뉘는 경우도 많으며, 자신의 적성에 맞게 분야를 선택해서 업무를 보게 된다. 클라이언트 프로그래머만 분류해 보았는데도 이렇게 여러 종류로 나뉘는데 그렇다면 공통적으로 배우는 부분들은 어떤 것들이 있을까? 정답은 아니지만, 예비 게임 프로그래머들을 위해 설명해 보겠다.
1. 프로그래밍 언어: 프로그래밍 언어는 무엇이 되든 상관이 없다. 본인이 생각하고 있는 것을 로직으로 작성할 수 있고, 그 결과를 알아볼 수 있기만 한다면 말이다. 굳이 결과가 모니터로 나오지 않아도 상관이 없다.(A4 용지로 프린트돼도 상관없다는 뜻)
단, 어떤 언어를 선택했다면 그 언어를 3년 이상은 써보는 게 중요하다. 만일 한 가지 언어를 선택하는 것이 어렵다면 나는 C++를 추천하고 싶다. 자바나 C#과 같은 언어들도 좋지만 이 글을 쓰고 있는 시점에서 여전히 게임 개발의 주류 언어는 C++다.
조심해야 할 점은 C++을 절대로 어렵게 사용해서는 안 된다. 왜냐하면 실제 현업에서 C++을 어렵게 사용하는 사람은 매우 드물고, 보편화된 문법이나 패턴들만 사용하기 때문이다.
※ 노트: 현재 한국의 경우 유니티(Unity) 엔진으로 게임을 개발하는 회사가 많아졌다. 이를 위해서는 C#을 공부하는 것도 나쁘지 않은 선택이다. 하지만 기본적으로 C계열 언어를 잘 알고 있다면 유니티를 제외한 거의 모든 플랫폼에서 게임을 개발하는 데 어려움은 없을 것이다.
2. 컴퓨터 구조: 프로그래머는 컴퓨터 소프트웨어를 만드는 사람이다. 그래서 컴퓨터라는 물건이 어떻게 동작하는지 내부적으로 알아야 한다. 물론 내부적으로 어떻게 컴퓨터가 동작하는지 몰라도 소프트웨어를 작성하는 데 무리는 없다.
하지만 컴퓨터의 동작 원리를 알고 나면 컴퓨터 소프트웨어를 작성하는 데 많은 도움이 되는 것은 사실이다. 그리고 콘솔 게임 개발자라면 해당 게임기(예를 들어 PS3, Xbox360)의 하드웨어에 대한 이해가 필수다. 하드웨어에 대한 올바른 이해를 갖추고 있어야 해당 게임기의 최고 성능을 이끌어낼 수 있기 때문이다.
3. 수학: 고등학교 수학 수준으로는 요새 출시되는 게임들을 만들 수 없다. 대수학, 삼각함수, 미적분, 선형 대수학 정도는 알아 두어야 게임을 만들 때 막힘이 없을 것이다. 나는 취업 혹은 대학 진학에 대한 질문을 받으면 거의 대부분 대학에 가라고 말한다.
그 이유는 선형 대수학이나 대학 미적분은 고등학교 과정에서 배우지 않기 때문이며, 이러한 과목들은 혼자서 공부하기에는 너무 어렵기 때문이다. 물론 수학자가 될 필요는 없으며, 최소한 수학이라는 도구를 언제 어떻게 써먹는지 정도만 알아도 충분하다.
4. 자료구조, 알고리즘: 이전 연재에서 강조한 바와 같이 자료구조와 알고리즘은 프로그래머에게 필수다. 데이터를 어떻게 표현하는가에 따라 프로그램의 성능이 좌우되는 경우가 많다. 예를 들어 컴퓨터는 캐시 메모리가 있고 이 캐시 메모리를 잘 사용한 자료구조는 성능을 대폭 향상시킨다.
예를 들어 다음과 같이 int형을 가진 2차원 배열(100 x 20)을 선언해 보자.
int values[100][20];
그리고 해당 데이터에 값들이 들어가 있고 모든 요소에 들어간 값들의 합을 구하는 로직을 작성해 보자.
int sum = 0;
for ( int y = 0; y < 100; ++y ) {
for ( int x = 0; x < 20; ++x ) {
sum += values[y][x];
}
}
결과는 똑같이 나오지만 다르게 작성된 로직을 살펴보자.
int sum = 0;
for ( int x = 0; x < 20; ++x ) {
for ( int y = 0; y < 100; ++y ) {
sum += values[y][x];
}
}
컴퓨터의 내부 구조를 잘 아는 사람이라면 2가지 코드의 큰 차이점을 알 수 있다. 혹시 잘 모르겠다면 캐시 메모리에 관한 책을 읽거나 컴퓨터의 내부 구조를 공부해보면 두 코드가 왜 성능 차이가 나는지 알 수 있다.
5. 라이브러리, APIs: 윈도우 프로그래밍을 배워본 사람이라면 한 번쯤은 Win32API라는 말을 들어 봤을 것이다. 이것은 윈도우 운영체제에서 프로그램을 개발하려고 Microsoft에서 제공하는 함수들의 모임인데 이것을 이용하면 프로그래머가 더 쉽게 프로그램을 제작할 수 있다.
매우 다양한 API들과 라이브러리들이 있는데 게임이 동작할 머신의 종류에 따라 제공되는 API도 다르고 사용할 수 있는 라이브러리도 다르다. PC, Xbox용 게임을 개발하기 위해서는 DirectX를 사용해야 하고 MAC이나 PS3는 OpenGL을 사용한다.
PC에서 일반 응용 프로그램을 개발하기 위해 Win32, MFC 사용법을 배우고 Mac에서는 Cocoa를 배운다. 모든 라이브러리나 API 사용법을 알 필요는 없다. 하지만 최소한 본인이 만들어낼 프로그램이 돌아가는 기계의 종류를 알고 거기에 필요한 API나 라이브러리들이 어떠한 것들이 있는지는 알아 두어야 한다.
6. 컴퓨터 그래픽스: 게임은 모니터에 무언가를 그려야 하므로 DirectX, OpenGL 둘 중에 하나는 알아야 한다. 이러한 라이브러리를 사용하는 것뿐만 아니라 원리를 알기 위해서는 컴퓨터 그래픽스라는 것을 공부해야 한다. 내부적인 모든 원리를 알면 좋겠지만 어렵다면 최소한 개론 서적 정도는 읽어 주자. 내부 원리를 알고 라이브러리를 사용하는 것과 모른 채로 사용하는 것은 많은 차이가 있다.
참고로 클라이언트 프로그래밍을 주로 했기 때문에 설명이 클라이언트 분야에 편중된 점, 양해 바란다.
※ 노트: 추후에 서버 분야는 필자 지인의 도움이 있을 때 따로 설명하도록 하겠다. |
이처럼 클라이언트 하나만 보더라도 본인의 관심에 따라 여러 방면으로 전문 지식을 갖출 수 있다. 부족하지만 연재를 보고 있는 예비 게임 프로그래머들에게 이 내용이 직업을 선택할 때 도움이 되길 바란다.