내 팁 공유 : NML 강좌(NewGRF 제작) / 1강 : 시작하기

NML 강좌(NewGRF 제작) / 1강 : 시작하기 | OpenTTD
2012.08.28 23:11

텔크 관리자

첨부파일1: my_newgrf.zip my_newgrf.zip (1.3 KB / 0 hits)
첨부파일2: my_newgrf_img01.png my_newgrf_img01.png (187.9 KB / 0 hits)
첨부파일3: my_newgrf_img02.png my_newgrf_img02.png (239.0 KB / 0 hits)
NewGRF을 제작하기 위해서는 기본적인 제작 프로그램이 있어야 합니다.

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

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

그래서 제 경우에는 (배우기는 그래도 어렵지만)
고급 프로그래밍 언어[fn](사람이 이해하기 비교적 쉬운 소스 코드를 가진 프로그래밍 언어. Perl, PHP, ASP, JSP, Java 등)[/fn]인 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의 기본적인 정보만 지정해주었을 뿐,
그 이후에 아무 것도 코딩하지 않았기 때문입니다.
이후 자동차, 전차, 기차 등을 만들기 위해서는 추가적인 문법을 더 공부해야 합니다.
일단은 오늘은 여기서 만족하도록 하지요. :)

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

추천 추천 비추천 비추천

banner.png
- OpenTTD & OpenRCT2 한국어 번역자
- TELKLAND 운영자 (telk.kr)
IP Address : 175.xxx.228.97 / 게시물 신고 / 글쓴이 신고
댓글

내 팁 공유

번호 제목 작성자 조회 작성 시각 F
30 [OpenTTD] 프로그램 신호기로 간단한 완행/급행 구현하기 1 ▲1 YJSoft 47 2016.11.08 sav
29 [OpenRCT2] OpenRCT2 서버에서 동기화되지 않는 것들 YJSoft 47 2016.10.21
28 [OpenRCT2] 내 서버가 다른 사람에게 보이지 않는 경우 2 평점5 텔크 194 2016.06.29 png
27 [OpenTTD] 수익률 높이기 상식 - 트타 운임 산정방법 1 ▲1 트레인맨 177 2016.05.25
26 [OpenRCT2] macOS에서 OpenRCT2 설치 및 실행하기 YJSoft 150 2016.05.24 ini
25 [OpenRCT2] OpenRCT2에서 사용하는 폰트 바꾸기! 2 ▲1 YJSoft 354 2016.05.12
24 [OpenTTD] 복선 철도 건설 및 신호기 설치 강의 (동영상) 텔크 146 2016.04.16
23 [OpenTTD] 단선 철도 건설 강의 (동영상) 텔크 118 2016.04.16
22 [OpenTTD] 경로 신호기로 간단히 복선 철도 구성하기 YJSoft 293 2016.01.11 sav
21 [OpenTTD] 좌표 보는 법 / 좌표로 이동하는 법 텔크 324 2015.12.25 png
20 [OpenTTD] 모바일 OpenTTD 사전 설정창 목록 (작성중) 텔크 236 2015.12.23 png
19 [OpenTTD] 모바일에서 치트 창을 여는 방법 텔크 394 2015.12.23 png
18 [OpenTTD] NewGRF의 매개변수 조정 방법 (한국 열차 세트 속도/가격/수송량 등 조정하기) 1 ▲1 텔크 834 2015.04.01 png
17 [OpenTTD] 인공지능 목록 6 LOOK! 텔크 2,115 2014.12.13 xlsx
16 [OpenTTD] 도시 평판 올리기 (도시의 회사 성취도 올리기) 6 평점5 LOOK! 텔크 4,666 2014.01.15 png
목록 보기 검색 글쓰기

↑TOP