NML 강좌(NewGRF 제작) / 1강 : 시작하기

NML 강좌(NewGRF 제작) / 1강 : 시작하기
팁 > OpenTTD 2012.08.28 23:11
TELK 관리자

[#첨부파일]
NewGRF을 제작하기 위해서는 기본적인 제작 프로그램이 있어야 합니다.

크게 GRFMaker를 이용하는 방법과 NML, NFO 방식으로 프로그래밍하는 방법 등이 있습니다.
하지만 GRFMaker는 TTD 시절에 이용되던 프로그램이라
OpenTTD 최신 버전과는 잘 맞지 않는 단점이 있고,

NFO 방식은 저급 프로그래밍 언어(사람이 이해하기 난해한 소스 코드를 가진 프로그래밍 언어. 어셈블리어가 대표적인 예)라 배우기가 어렵습니다.

그래서 제 경우에는 (배우기는 그래도 어렵지만)
고급 프로그래밍 언어(사람이 이해하기 비교적 쉬운 소스 코드를 가진 프로그래밍 언어. Perl, PHP, ASP, JSP, Java 등)인 NML 방식을 이용해서 NewGRF을 제작하고 있습니다.


이번 기회에 부족한 실력이지만 제가 배운 NML을 알려드리고자 팁을 작성합니다.


* 읽기 전에

하늘색 부분은 여러분이 마음대로 이름을 정할 수 있는 부분입니다.
분홍색 부분은 정해진 문자열이나 값을 찾아서 지정해주어야 하는 부분입니다.


1. NML 컴파일러 준비하기

NML 방식은 NewGRF을 '프로그래밍'하는 방식입니다.
따라서 소스 코드인 *.nml 파일을 *.grf 파일로 변환하기 위한 '컴파일러'가 필요합니다.
이 컴파일러가 바로 nmlc.exe 파일입니다.

http://bundles.openttdcoop.org/nml/nightlies/LATEST에서 다운로드할 수 있습니다.
(들어가서 파일 이름이 nml-XXXXX-windows-win32.zip 으로 되어있는 것 다운로드)


압축을 풀면 여러 개의 파일이 뜨지만,
우리가 사용할 것은 nmlc.exe 실행파일 단 하나입니다.

nmlc.exe 파일이 있는 폴더 경로를 잘 기억하십시오.

[시작]-[실행]을 눌러 입력창에 cmd (XP 기준)를 입력하고 엔터를 치면
옛날에 본 듯한 도스창(명령 프롬포트)이 뜹니다.

방금 전에 nmlc.exe 파일이 있는 폴더로 이동(cd 폴더명)한 뒤,
명령창에 nmlc 를 입력하면 다음과 같이 안내문이 뜹니다.
Usage: nmlc [options] <filename>
Where <filename> is the nml file to parse

Options:
        --version                                 show program's version number and exit
        -h, --help                                 show this help message and exit
        -d, --debug                                 write the AST to stdout
        -s, --stack                                 Dump stack when an error occurs
        --grf=<file>                                 write the resulting grf to <file>
        --md5=<file>                                 Write an md5sum        of the resulting grf to <file>
        --nfo=<file>                                 write nfo output to <file>
        -M                                         output a rule suitable for make describing the
                                                graphics dependencies of the main grf file (requires
                                                input file or --grf)
        --MF=<file>                                 When used with -M, specifies a file to write the
                                                dependencies to
        --MT=<file>                                 target of the rule emitted by dependency generation
                                                (requires -M)
        -c                                         crop extraneous transparent blue from real sprites
        -u                                         save uncompressed data in the grf file
        --nml=<file>                                 write optimized nml to <file>
        -o <file>, --output=<file>                write output(nfo/grf) to <file>
        -t <file>, --custom-tags=<file>                Load custom tags from <file> [default: custom_tags.txt]
        -l <dir>, --lang-dir=<dir>                Load language files from directory <dir> [default: lang]
        -a <dir>, --sprites-dir=<dir>                Store 32bpp sprites in directory <dir> [default: sprites]
        --default-lang=<file>                        The default language is stored in <file> [default: english.lng]
        --start-sprite=<num>                        Set the first sprite number to write (do not use except when
                                                you output nfo that you want to include in other files)
        -p <palette>, --palette=<palette>        Force nml to use the palette <pal> [default: ANY].
                                                Valid values are 'DOS', 'WIN', 'ANY'
        --quiet                                 Disable all warnings. Errors will be printed normally.


영어로 되어있어 무슨 소리인지 모르겠지만 일단은 그러려니 하고 넘어갑니다.
어차피 우리가 사용할 명령어는 몇 개 없습니다.



2. 프로젝트 폴더 만들기

이제 NewGRF을 만들기 위해 프로젝트 폴더를 하나 만듭니다.
nmlc.exe 파일이 있는 폴더 안에 아래와 같이 적당히 폴더를 하나 만듭니다.
이번 강좌에서는 my_newgrf 이라고 해보겠습니다.
그 폴더 안에 또다시 lang 이라는 폴더를 만듭니다.
최종적으로 아래와 같은 구조가 될 것입니다. (폴더는 기울임 표시하였습니다.)
(...)
└nmlc.exe
 └ my_newgrf
  ├ lang
  └ (본체 파일이 들어갈 곳)


3. 가장 기초적인 NewGRF 만들기 : 언어파일

NML의 가장 큰 장점 중 하나가 바로 '번역을 손쉽게 지원할 수 있다'는 점입니다.
방금 만드신 lang 폴더에 언어 파일(*.lng)을 제작해서 넣으시면 됩니다.
하지만 기본적으로 영어 언어 파일(english.lng)은 반드시 있어야 합니다.



만약 한국어 번역을 지원하고 싶다면
english.lng 파일과 korean.lng 파일을 만들어서
아래와 같이 위치시키시면 됩니다. (굵은 글씨)
(...)
└nmlc.exe
 └my_newgrf
  ├lang
  │├ english.lng
  │└ korean.lng
  └ (본체 파일)

언어 파일은 다음과 같이 작성합니다.
##grflangid <number>

<string-name>                        :<text>
<string-name>                        :<text>
...



하나 하나 설명하겠습니다.

##grflangid <number>

##grflangid 는 이 언어 파일이 어떤 언어를 나타내는지 알려주는 부분입니다.
<number> 부분에 언어에 대한 코드값을 입력해주어야 합니다.
영어는 00, 한국어는 3A 입니다.
단, 이 코드값은 16진수값이므로, 입력시 앞에 0x 를 붙여주어야 합니다.

ex) 영어: ##grflangid 0x00
한국어: ##grflangid 0x3A

다른 언어의 코드값은 http://newgrf-specs.tt-wiki.net/wiki/NML:Language_files의 가장 하단에 있는 표에서 참고할 수 있습니다.


<string-name>: <text>

<string-name>은 문자열 이름입니다.

아래 소스 코드 본체에서 사용될 부분입니다.
<text>는 그 문자열 이름에 해당하는 문자열입니다.
이 둘을 콜론(:)으로 구분하여 입력하면 됩니다.
<string-name>은 <text> 이다 라고 생각하시면 편하겠네요.


백번 설명하는 것보다 직접 보여드리는 게 낫겠지요.
이번에 만들 NewGRF에서 쓸 언어 파일 코드입니다.
따라해보세요.


[영어 언어 파일 (english.lng)]
##grflangid 0x00

STR_MY_NEWGRF_NAME :My First NewGRF
STR_MY_NEWGRF_DESC :This is my first NewGRF. This is a description.




[한국어 언어 파일 (korean.lng)]
##grflangid 0x3A

STR_MY_NEWGRF_NAME :내 첫 번째 NewGRF
STR_MY_NEWGRF_DESC :내가 만든 첫 번째 NewGRF입니다. 이건 설명입니다.







4. 가장 기초적인 NewGRF 만들기 : 소스 코드 본체

이제 정말 기초적인 NewGRF을 만들어보겠습니다.
지금 만들 NewGRF은 어떤 기능도 하지 않고,
그저 NewGRF 목록에 이름만 올리는 용도입니다.
하지만 내가 만든 GRF이 게임 상에서 그 이름을 표시한다는 게 꽤 뿌듯하답니다.



본체 파일은 확장자가 .nml 이며,
여기에 코드를 작성하여 컴파일하는 방식입니다.
메모장이나 기타 텍스트 편집 프로그램을 열고 다음과 같이 코드를 작성합니다.

NML은 C 계열의 프로그래밍 언어처럼 줄 끝에 항상 세미콜론(;)을 붙여야 합니다.

(참고: 주석도 C 계열을 따라갑니다. //, /* */ 사용 가능)
grf {
        grfid: "ABCD";
        name: string(STR_MY_NEWGRF_NAME);
        desc: string(STR_MY_NEWGRF_DESC);
        version: 0;
        min_compatible_version: 0;
}





하나 하나 설명을 해보겠습니다.

grf { ~ }

중괄호로 묶인 하나의 영역을 블록이라고 합니다.
grf 블록은 NewGRF의 기본적인 정보를 선언해줍니다.
중괄호 안에 있는 grfid, name 같은 것들은 속성값입니다.


grfid: "ABCD";

grfid 속성은 NewGRF의 고유한 ID를 지정하는 부분입니다.
4바이트 고정 문자열로 되어있습니다. (더도말고 덜도말고 딱 4글자라는 말입니다.)

ABCD 부분을 고치시면 됩니다. 숫자를 써도 괜찮습니다.

하지만 이럴 경우 다른 NewGRF과 중복될 수도 있기 때문에,
이를 피하기 위해 16진수 방식으로도 입력할 수 있습니다.

1글자(1바이트)는 2글자의 16진수로 되어있습니다.
뒤에 오는 숫자가 16진수임을 표시하기 위해 자를 앞에 덧붙입니다.

예를 들면 A = 65, 0 = 48 등입니다. (ASCII 코드표 참조)



예를 들어 자기 이름이 '홍길동'이고 1번째로 만드는 NewGRF이라면
grfid 속성을 'HGD1' 이라고 지정하는 습관을 들이는 것도 좋습니다.
(1이 1글자임)


name: string(STR_MY_NEWGRF_NAME);

name 속성은 게임 상에서 나타날 NewGRF의 이름입니다.

string(STR_MY_NEWGRF_NAME) 은 위 '언어 파일' 부분에서 나온 <string-name>입니다.
STR_MY_NEWGRF_NAME 이라는 문자열을 읽어오겠다는 뜻입니다.
나중에 STR_MY_NEWGRF_NAME에 '나의 첫번째 NewGRF' 등의 문자열을 넣으면 됩니다.


desc: string(STR_MY_NEWGRF_DESC);

desc 속성은 이 NewGRF의 설명(description) 부분을 지정합니다.
마찬가지로 STR_MY_NEWGRF_DESC?라는 문자열을 지정합니다.




version: 0;

version 속성은 이 NewGRF의 버전을 나타냅니다.
숫자 0부터 시작하여 NewGRF을 수정할 때마다 1씩 올리는 방식입니다.(소숫점 불가)
0을 포함한 자연수로 값을 입력하셔야 합니다. (마지막에 세미콜론 붙이는 것도 잊지 마세요.)




min_compatible_version: 0;

min_compatible_version 속성은 처음 만들 때에는 version과 같이 값이 0입니다.
하지만 NewGRF을 수정하고 수정하다 구 버전과 호환이 안되게 될 경우,
이 min_compatible_version 속성을 수정하면 됩니다.

호환이 가능한 가장 낮은 version 값을 지정해주면 됩니다.









백문이불여일견이라고 실제 이번 강좌에서 만들 NewGRF의 NML 소스를 확인해봅시다.
샘플 소스에서는 주석을 어떻게 사용하는 지에 대해서도 적어두었습니다.
이 소스 파일을 my_newgrf.nml 이라고 저장하겠습니다.

아래와 같은 위치에 만드시면 됩니다.(굵은 글씨)
(...)

└nmlc.exe
 └my_newgrf
  ├lang
  │├english.lng
  │└korean.lng
  └ my_newgrf.nml





/*
이런 형태로 주석을 사용할 수 있습니다.
이 형식의 주석은 여러 줄의 설명을 달 수 있습니다.
*/

// 이런 형태의 주석도 사용 가능합니다.

// NewGRF 기본 정보 선언
grf {
        grfid : "HGD1"; // 홍길동(HGD)의 첫 번째(1) NewGRF
        name : string(STR_MY_NEWGRF_NAME);
        desc : string(STR_MY_NEWGRF_DESC);
        version : 0;
        min_compatible_version : 0;
}











5. 컴파일하여 .grf 파일로 만들기

이제 모든 준비가 끝났습니다.
최종적으로 다음과 같은 파일/폴더 구조가 되어야 합니다.
(...)
└nmlc.exe
 └my_newgrf
  ├lang
  │├english.lng
  │└korean.lng
  └ my_newgrf.nml




이제 [시작]-[실행]을 누릅니다.
입력창에 cmd (XP기준)를 입력하면 명령 프롬프트(도스창)가 뜹니다.
'dir' (폴더 목록 나열/검색)과 'cd' (폴더 이동)명령어를 이용해

nmlc.exe 파일이 있는 폴더까지 들어갑니다.

입력줄에 nmlc를 쳐봤을 때 아까 봤던 긴 영어 안내문이 나오면 됩니다.
이제 입력줄에 다음과 같이 입력합니다.
nmlc -l ./my_newgrf/lang/ ./my_newgrf/my_newgrf.nml




명령어를 해석하자면 이렇게 되겠네요.
nmlc : 컴파일해주세요.
-l ./my_newgrf/lang/ : 언어 파일은 ./my_newgrf/lang/ 폴더에 있어요.
./my_newgrf/my_newgrf.nml : 본체 소스 파일은 ./my_newgrf/my_newgrf.nml 입니다.







이제 my_newgrf 폴더로 들어가보면 전에 없던 my_newgrf.grf 파일이 생성된 것을 볼 수 있습니다.
이제 이 파일을 OpenTTD가 설치된 폴더 내에 있는 newgrf 폴더에 넣어볼까요?





와우! 게임에 내가 만든 NewGRF이 뜨는군요!
아까 언어파일에서 입력한 문자열도 잘 뜹니다.


게임 전체 언어를 영어로 바꾸어도 잘 뜨네요.











* 마치며
이번에 만든 NewGRF은 추가해서 적용해도 게임 상에 아무런 영향을 끼치지 않는 것입니다.
grf 블록으로 NewGRF의 기본적인 정보만 지정해주었을 뿐,
그 이후에 아무 것도 코딩하지 않았기 때문입니다.
이후 자동차, 전차, 기차 등을 만들기 위해서는 추가적인 문법을 더 공부해야 합니다.
일단은 오늘은 여기서 만족하도록 하지요. :)

이 게시물이 마음에 드시면 추천을, 마음에 들지 않으시면 비추천을 눌러주세요

추천 추천 비추천 비추천

IP Address : 119.xxx.220.217 / 게시물 신고 / 글쓴이 신고
댓글

목록 보기 정렬 글쓰기


↑TOP