나는 이렇게 게임 프로그래머가 되었다 -1-

게임을 만들기 위해 공부할 것은 지나치다 싶을 정도로 많습니다. 진심입니다. 진심으로 공부할게 너무 많습니다. 아마 단일 소프트웨어로는 운영체제, DBMS 다음으로 복잡한 물건이 아닌가 싶을 정도입니다. 아마 모두 다 공부하려고 책을 쌓아놓는다면 미리 포기부터하게 될 겁니다. 따라서 흥미가 있는 부분을 하나씩 파헤쳐보는 점진적인 과정이 중요하죠.

옛날 얘기를 좀 해보지요.

제가 게임 프로그래밍을 본격적으로 공부한 것은 94년부터입니다. 그때부터는 게임 프로그래밍에 필요한 것이 뭔지 닥치는 대로 찾아봤죠. 우선 대부분의 게임을 C로 만든다기에 C언어 부터 공부했습니다. 한동안 (한 반년쯤?) 포인터에서 딱 막혀서 탱자탱자 (게임하며) 놀던 기간도 있었지만 대개는 책 보면서 닥치는 대로 짜 봤습니다. 포인터의 개념을 터득한 후에는 책에 나온 도서관리 프로그램 따위의 예제를 짜봤죠.

C로 기본적인 것들을 대충 익히고서는 본격적인 게임에서 많이 쓰이던 그래픽을 어떻게 구현하는지가 궁금했죠. 당시 대부분의 게임이 320*200*8bpp[각주:1], 혹은 640*480*4bpp의 그래픽 품질로 구현되고 있었고, 일부 고사양게임들은 640*480*8bpp의 그래픽 품질을 보여주던 시절이었습니다. 그리고 그중에서도 극히 고사양을 요구하는 (윙커맨더[각주:2]와 같은) 게임들은 640*480*8bpp에서 3D 렌더링을 구현하고 있었습니다. 당연히 이러한 그래픽을 어떻게 구현하는지가 궁금했죠. 그때까지 쓰던 터보 C++ 2.0 에서 제공하는 그래픽 라이브러리(BGI)에서는 저런걸 할 수 없었기 때문이죠. 하더라도 끔찍하게 느린 속도를 감수해야 했죠. 게임에서 쓰던 방식은 아니란 걸 알았습니다.

그 답은 PC통신의 프로그래밍/게임제작 동호회 등을 뒤져가며 인터럽트란 것에 대한 개념을 주워들으면서 얻을 수 있었죠. 하드웨어에 인터럽트를 날리면 하드웨어에서 특정한 동작을 수행하며, 그래픽스 하드웨어에 인터럽트를 날리면 그래픽에 관한 원하는 동작을 수행할 수 있다는 것 정도가 파악되었습니다. 그때부터 여기저기서 찾아본 정보로 (지금도 업데이트되고 있는) Ralph Brown's Interrupt List 라는 것의 존재를 파악했습니다. 거의 모든 하드웨어의 인터럽트 펑션에대한 자세한 정보가 기술되어 있는 리스트였죠. 당시에 조금이라도 프로그래밍을 한다 싶은 사람들은 저마다 하나같이 RalphBrown's Interrupt List가 중요한 참고자료 중 하나였을 겁니다. 저도 DOS에서 그래픽스 라이브러리를 구현해 보는 데에 RBIL이 매우 좋은 참고자료가 되었습니다.

옛날 DOS게임을 할 때 궁금했던 것 중 하나는 게임을 실행하면 (DOOM같은 것들) 프롬프트에 스크롤되어 올라가던 다음과 같은 문구였습니다.
약간 설명을 하자면, 당시 640*480*8bpp 이상의 그래픽 품질을 구현하고자 했을 때 가장 걸림돌이 되었던 것은 16비트 운영체제였던 DOS의 64kb 세그먼트[각주:3] 제한이었습니다. 단순 산술계산으로도 640 * 480 * 8bpp = 2457600bit = 300kb 이기 때문에, 5개의 세그먼트를 오가며 메모리에 접근해야 했죠. 비디오 메모리의 접근 세그먼트를 변경하는 것도 비디오 하드웨어의 인터럽트 펑션중 하나였습니다. 저는 당시 게임에 많이들 쓰고 있던 DOS/4GW의 정체가 이러한 제약과 관련이 있다는 것을 알아낼 수 있었습니다. 이러한 제약은 DOS가 인텔계열 CPU의 리얼모드만을 이용하는 OS이기 때문이며, 이를 보호모드로 전환하면 주소공간이 32비트로 확장되어 최대 4gb에 이르는 메모리를 세그먼트전환 없이 사용할 수 있게 되는 구조였죠. 즉, DOS에서 보호모드를 사용할 수 있게 해주는 실행환경이 바로 DOS/4GW였던 것입니다. DOS/4GW는 당시 최적화가 잘 되기로 소문이 나 있던 Watcom C++과 함께 배포되어 WC의 기본 프로젝트 세팅중 하나로 선택할 수 있었죠. 저는 '세그먼트 전환이 없는 그래픽 라이브러리'를 목표로 어렵사리 (당당하지는 못한 방법이었지만) Watcom C++ 의 한 카피를 구해서 구현 해보았죠.

위의 이야기들은 옛날 이야기고, 지금에 와서는 전혀 쓸 일이 없는 기술들이고, 제가 왜 아직까지 이런 것들을 기억하고 있는지가 신기할 지경인 일들입니다. 하지만 남은 것도 좀 있지요. 인터럽트와 보호모드는 모두 현대 CPU와 OS의 구조를 이해하는데에 결정적인 키워드입니다. 인터럽트 리스트를 뒤져가며 그래픽 라이브러리를 구현해본 것도, 개발툴 매뉴얼을 보며 보호모드 전환을 해본 것도, 모두 현대 컴퓨터의 구조를 이해하는 데에 매우 큰 도움이 된 것 같습니다.
물론, 위의 과정을 거치면서 얻은 가장 큰 소득은, 앞으로 프로그래밍이란 작업을 어떻게 해야 하는 지를 몸으로 익혔다는 점입니다. 바로, "한가지씩 해본다"는 철학이죠.


다음에 계속
나는 이렇게 게임 프로그래머가 되었다 -3-

필자 : Uhm

경력 6년차의 게임 프로그래머. geek의 화신이며 포스를 수련한다는 소문도 있습니다.
홈월드나 토탈어나힐레이션, COH 같은 RTS와 FPS를 좋아하지만 요즘은 아내와 함께 기타히어로를 하는 가정적인 남편이기도 합니다.

언제나 후배들에게  포스의 어두운면에 대한 주의를 설파하는 뼛속까지 프로그래머.
  1. bpp 는 bit per pixel의 약자로 한 점의 색을 나타나는데 사용한 데이타의 양을 나타내는 단어입니다. 8bpp라면 한 점을 나타나는데 8비트를 사용했다는 의미입니다. [본문으로]
  2. 1990년에 처음 선보인 윙커맨더 씨리즈는 이후 새 시리즈가 나올 때마다 사람들이 게임을 하기 위해 컴퓨터를 업그레이드 하는 풍속을 만들 정도로 인기 있는 우주 전투 시뮬레이션 게임이었습니다.

    from wikipidea [본문으로]
  3. 한번에 한 덩어리로 접근이 가능한 메모리의 단위. 전체 메모리에 접근하기 위해서 세그먼트란 단위로 나누어서 현재 세그먼트의 시작점을 기준으로 메모리를 접근하는 segmented memory model에서 사용한다. DOS는 16비트 주소체계를 갖고 있었으므로, 한 세그먼트의 최대크기는 2^16 = 64kb 입니다. [본문으로]
욕망.
게임을 만들기 위해서 가장 중요한 덕목입니다. 게임을 만들고 싶은 욕망이 없는 사람은 게임을 만들 수가 없죠. 저는 현재 31살의 게임프로그래머로서, (웬만한 게이머들은 이름을 대면 알 거 같은 느낌이 드는 게임의) 프로그램팀장을 하고 있습니다. 저 역시 게임을 만들고 싶은 욕망 때문에 일을 시작했죠.

게임을 접하고 좋아하는 거야 아주 어렸을 때 일이지만, 본격적으로 게임을 만들어야 겠다는 생각이 든 것은 고1때의 일입니다. 중3때 접한 듄2[각주:1]를 보고, 나중에 저런 게임을 만들면 정말 멋진 사람이 될거 같은 느낌이 들었죠. 이리저리 PC통신으로 (93년 당시) 알아본 결과, 요즘 게임은 보통 C로 만든다는 것을 알아냈고, 서점에서 찾아볼 수 있었던 책 중에서 가장 얇은 C언어 입문서를 사들고 왔습니다. 그게 94년, 고1때의 일이죠.

물론, 그 전, 초등학교(저는 국민학교를 다녔습니다만) 때 다들 하듯이 GW-BASIC[각주:2]등으로 기본적인 프로그래밍은 익혔죠. 컴퓨터학원 다니면서 심심풀이로 테트리스나 15-퍼즐이나 오목같은 간단한 게임을 만들면서 지내곤 했습니다. 하지만, 거기까지가 전부였죠. 베이직의 파일입출력을 끝끝내 이해할 수 없었기에 그보다 대규모의 프로그램은 만들 수가 없었습니다. (지금 생각해도 베이직의 파일입출력 라이브러리는 괴악하기 그지없습니다) 베이직으로는 고등학교때 컴퓨터동아리에서 '땡겨[각주:3]'내기 테트리스 짜기나, Dragon Curve[각주:4](쥬라기 공원의 각 장 앞부분에 나온 그 드래곤 커브)를 Q베이직[각주:5]으로 구현하며 논 것이 거의 마지막이었습니다.

베이직의 한계를 느낄 무렵, C라는 언어의 존재를 알게 되면서 C언어 책을 고를 때, 가장 중요한 기준은 (위에서도 썼지만) '얇은 책'이었습니다. 저는 나름 독서광이었고, 새로운 것을 접할 때는 간략하게 개괄적으로 설명한 책이 더 나에게 적합하다는 것을 알고 있었으니까요. 자신에게 무엇이 가장 적합한지를 아는 것이 중요했던 것 같습니다. 만약 C언어의 모든 면을 자세히 설명한 TCPL[각주:6]같은 책을 골랐더라면 인내심이 한없이 0에 가까운 저는 이내 포기하고 말았겠죠.

제 인내심은 욕망을 지지할 정도로 견고하지는 못하다는 점을 알고 있었습니다. 게임 제작을 하고 싶다고 하더라도, 자신의 특성을 파악해야 했던 것이죠.

(다음에 계속)
나는 이렇게 프로그래머가 되었다 -2-



필자 : Uhm

경력 6년차의 게임 프로그래머. geek의 화신이며 포스를 수련한다는 소문도 있습니다.
홈월드나 토탈어나힐레이션, COH 같은 RTS와 FPS를 좋아하지만 요즘은 기묘하게도 와우를 하는 시간이 더 많은 게이머입니다.

언제나 후배들에게  포스의 어두운면에 대한 주의를 설파하는 뼛속까지 프로그래머.

  1. Westwood Studio의 실시간 전략 시뮬레이션 게임. 이후 실시간 전략 시뮬레이션 장르의 효시가 되었다.
    [본문으로]
  2. MS에서 만든 행번호 기반의 BASIC. [본문으로]
  3. 짜먹는 펜슬형 빙과류의 상품명. [본문으로]
  4. 종이 띠를 한 방향으로 절반씩 접은 자국을 90도로 꺾으면 나타나는 형상. 간단한 프랙탈 도형의 예로 자주 소개된다.
    [본문으로]
  5. 통합 IDE를 가진 MS의 BASIC 구현. MS-DOS와 함께 배포되었다. [본문으로]
  6. The C Programming Language. C언어의 창시자인 커니건, 리치가 쓴 C언어의 바이블이라 할 수 있는 책.강컴 링크 [본문으로]
라이브러리란 것은, 도서관입니다. 네. 도서관이란 다름이 아니라 다른 사람이 써놓은 책을 가서 볼 수 있는 곳이죠. 아시겠지만, 도서관에는 지금까지 출간됐던 적이 있는 책들은 거의 모두 구비하고 있습니다. 제가 다니던 학교 도서관에는 제가 좋아하는 SF는 국내 출판됐던 책은 거의 다 장서목록에 있더군요. 그러한 고로, SF 독자인 저는 SF를 보고 싶으면 도서관에 가서 적당히 보고 싶은 책을 골라다가 보면 됩니다. 이미 출판된 SF로도 제 취향을 만족시켜줄만한 책은 (국내 사정은 좀 열악하지만) 찾아보면 있거든요. 나는 SF를 좋아하니까 내가 좋아하는 SF 소설은 모두 내 손으로 써야 되겠다고 생각하는 사람이 있다면, 글쓰기의 천재일 수도 있지만, 천재는 매우 희귀하므로, 바보일 가능성이 매우 높겠죠. 더군다나 쓰고자 하는 소설의 내용이 장르의 바이블이라고 일컬어지는 작품과 매우 유사한 소재와 주제를 갖고 있다면, 차라리 안쓰느니만 못한 결과가 나올 겁니다.

코드 라이브러리, 즉 흔히들 .lib, .a 파일로 이름붙여지는 컴파일된 코드의 집합체들은 바로 위와 똑같은 개념에서 출발했습니다. 원하는 내용이 있다면, 라이브러리를 뒤져서 적절한 부분을 떼어다가 쓰면 된다는 개념입니다. 프로그래밍의 역사가 비록 50여년밖에 안되지만, 프로그래머들은 인간중에서도 무척 부지런한 쪽에 속하는지 수백종류의 언어로 만들어진 수만가지 라이브러리가 존재합니다. 이 중에서 나의 필요에 적당히 맞는 코드가 한 두개쯤 있으리라는고 기대하는 편이 합리적이죠. 만약 자기가 쓸 코드는 모두 자기 손으로 직접 만들어야 한다고 말하는 사람이 있다면, 그 사람은 다른 사람이 해놓은 일을 자기 시간을 들여서 다시 할 생각인 것이죠.

소설에 습작이 있고, 수학엔 연습문제가 있듯이, 프로그래밍에 있어서도 남들이 다들 한번씩 풀어본 문제를 자기 손으로 한번 풀어서 구현해 보는 것은 매우 중요한 학습방법입니다. 문제는 이것이 학습방법이라는 거죠. 직업 소설가 중에 습작 팔아서 먹고 사는 사람이 있을까요? 있다면 아마 진짜 천재 작가일 겁니다. 직업 수학자들 중에 교재의 연습문제를 풀어서 연구비 받는 사람이 있을까요? 그런 사람이 있다면, 아마 수학 교사이거나 그 비슷한 직업이겠죠. 그런 사람을 수학자라고 하지는 않습니다. 프로그래머들도 남들이 다들 풀어본 문제를 다시 풀어보면서 월급을 받겠다고 한다면, 고용주 입장에서는 매우 달갑지 않은 직원이 될겁니다.

더군다나 '표준라이브러리'라 일컬어지는 것과 동일한 기능을 가진 라이브러리 조차도 자기 손으로 직접 만들겠다는 사람이 있으면, 엄청난 시간낭비일 뿐 아니라 언어를 쓰는 이유조차도 부정하는 셈이죠. 사람의 말로 치자면, 한 언어의 표준 라이브러리는 기본 어휘와 같아서, 모든 사람이 공통으로 알고 있고, 쓸수 있을 것이라고 가정하고 언어의 일부분으로 만드는 구성요소입니다. 결코 언어가 만들어진 다음에 덧붙여진 기능이 아니란 거죠. 애초에 언어의 일부로 설계되고 제작된 것이 표준라이브러리입니다. 표준라이브러리가 괜히 '표준'인 것이 아닙니다.

물론 표준 라이브러리는 만능이 아닙니다. 표준라이브러리를 어휘로 비유한다면, 순 우리말 만으로 논문을 쓰려고 할 때 봉착하게 될 문제점을 생각해 보면 비슷할 겁니다. 특정한 요구사항이 있다면 표준라이브러리만으로는 결코 해결할 수 없을 수도 있습니다. 요구사항이 너무나 특이해서 표준라이브러리뿐 아니라 기존의 어떤 라이브러리로도 꿰어맞출 수 없을 때가 있습니다. 물론 이런 경우가 생긴다면 당연히 해당 기능은 직접 구현해야 합니다. 이럴 경우에 프로그래머의 진짜 능력이 드러나죠. 프로그래밍은 문제 해결과정이며, 다른 사람이 해결해 놓은 문제의 답안을 가져다 쓰는 것과 다른 사람이 해결해 본 적이 없는 문제를 푸는 일은 매우 다른 능력을 요구합니다.

혼자서 공부할 때는 남들이 다 해본 것이라도 직접 구현하는 것은 매우 좋은 공부방법입니다. 공부할 때는 그렇게 밑바닥부터 기초를 다지는 것이 매우 중요하죠. SF에서 '인조인간의 인간성 고찰'이라는 주제로 나온 소설이 만편은 되겠지만, 자기 혼자 습작으로 이런 주제를 다뤄 보는 것은 권장할만 합니다. 'n이 3이상의 양의 정수일 때, xⁿ + yⁿ = zⁿ을 만족하는 0이 아닌 정수 x,y,z는 존재하지 않는다'는 것은 이미 증명되었지만, 연습문제로(?) 증명해 보는 것은 매우 좋은 수학적 훈련이 됩니다. 마찬가지로, '자기 자신에게 드리워지는 경계가 부드러운  그림자 구현' 같은 문제도 이미 다른 사람이 구현해 놓았지만, 공부할 때는 혼자서 구현해 봐야 합니다. '임의의 위치에서의 삭제/삽입에 상수시간이 걸리는 자료구조 구현'이라는 문제도 프로그래밍을 하는 모든 사람들이 한번씩 해 보았고, 심지어는 표준라이브러리에도 있지만, 공부할 때는 항상, 반드시, 누구나 해보아야 하는 문제인 것이죠.
이런 과정, 즉 남들이 해본 것을 자기 손으로 해보는 학습과정을 통해서 결국에는 자기 손으로 남들이 안해본 것을 할 수 있는 능력을 손에 넣는 것입니다.

아마도, 어떤 소설가가 책을 쓴다면, 누군가가 쓴 적이 없는 내용을 쓰는 것일 테고, 당연히 도서관에도 찾아볼 수 없는 내용일 겁니다. 마찬가지죠. 누군가가 직업적으로 코드를 짤때는 어떤 고유한 문제를 풀기 위해서 짜는 것일 겁니다. 대부분의 사람들이 부딪치는 평균적인 문제에 대한 적절한 해법은 거의 모두 누군가가 풀어 놨습니다. 이런 문제에 대한 해법을 제공하는 것이 라이브러리의 존재 이유입니다. 여러분의 귀중한 시간과 능력은 다른 사람들이 풀어본 적이 없는 문제를 해결하는 데에 사용하시기 바랍니다.
이왕이면 인류 발전을 위해 풀어본 결과를 다른 사람들이 볼 수 있게 해주면 좋겠지요 :)

사실은 개인적으로 C++코딩을 하는데,
gitiss에서 제공하는 자료를 보기위해 fasoodrm을 깔았더니
error PRJ0002 : 오류 결과 -1073741819이(가) 'D:\Program Files\Microsoft Visual Studio 8\VC\bin\cl.exe'에서 반환되었습니다.

라는 메세지와 함께 컴파일이 되지 않습니다. (덤으로 cmd명령 역시 먹지 않습니다.)

이런식의 에러메세지를 내는 경우 참고하시기 바랍니다.
복구방법은 아직 찾지 못했습니다.
그냥 컴퓨터 복구 외엔 답이 없는것 같군요.

일단 gitiss와 fasooDRM에 문의를 넣을 예정입니다.

혹시 visual c++ 2005 express로 컴파일 하시는 분들은 참고하시기 바랍니다.
(예전에 2003으로도 비슷한 증상을 겪은적이 있는데 아무래도 같은 원인일지도 모르겠습니다.)

정확하게 문제점을 밝히고 대처방안을 찾아내면 좋겠는데, 아무래도 깔아버리면 코딩을 할 수 없다. 라는 제약이 너무 크군요.

+ Recent posts