Guide to understand BMS format

version 1.2.2 (2005.3.22)

이 글은 토끼군 강 성훈이 정리한 한국어 버전의 BMS 포맷 스펙이다. 이 글은 GNU GFDL에 의해 무료로 배포되고 수정될 수 있다.

이 글의 고유 링크는 http://zenith.sparcs.net/article/bmsguide.phphttp://cosmic.mearie.org/2005/03/bmsguide이며 자유롭게 링크할 수 있다.

2013년 7월 5일: 이 문서는 매우 오래되었으며, 현재의 BMS 포맷을 제대로 반영하지 못 하고 있다. 보다 자세하고 최신의 문서는 BMS command memo(영문)를 참고하길 권한다.

차례

  1. 돌아가기
  2. BMS 포맷이란?
  3. 플레이 방법
  4. BMS 파일 포맷
  5. 부록

BMS 포맷이란?

BMS 포맷은, 원래 코나미 사의 비트매니아(beatmania)의 연습용으로 개발된 일종의 에뮬레이터인 BM98에서 사용되던 게임 데이터 포맷이다. 따라서 이 포맷의 원작자는 BM98의 개발자인 Yane Urao 씨이다. 나중에 BM98이 비트매니아의 곡 뿐만 아니라 자작곡을 비롯한 다른 곡을 플레이하기 위해서도 사용되면서 BM98과 그 뒤를 잇는 프로그램들은 더 이상 에뮬레이터가 아니게 되었으며, BMS 포맷도 필요에 따라 확장되었다. 기원이 기원이다 보니까 게임 방법은 비슷하지만, 그 이상의 유사점은 없다고 볼 수 있다.

BMS 포맷을 지원한다고 해서 현존하는 모든 BMS 포맷 확장을 지원하는 건 아니다. 하지만 최근에 나온 대부분의 프로그램들은 적어도 다음과 같은 세 종류의 서로 다른 BMS 파일 확장자를 지원한다.

플레이 방법

BMS 포맷을 사용하는 프로그램을 비롯한 많은 리듬 게임(DDR이나 Pump It Up 같은 댄스 게임도 포함)의 플레이 방법은, 건반을 누르거나 턴테이블을 돌린다던지 하는 동작을 해서 판정선을 향해 접근하는 오브젝트들을 없애는 것이다. 판정선이 위에 있고 오브젝트들이 그 쪽으로 올라 오는지, 아니면 서로 반대의 위치에 있는 지는 게임에 따라 다르지만, 일반적으로 건반을 사용하는 게임은 판정선이 아랫쪽, 발판을 사용하는 게임은 윗쪽에 있다.

보통 오브젝트들은 각기 다른 입력에 반응해서 사라진다. 예를 들어서 어떤 특정한 건반을 눌러서 입력해야 하는 오브젝트는, 다른 건반을 아무리 눌러도 사라지지 않는다. 따라서 이들을 구분하기 위해서 각각의 오브젝트들은 판정선의 서로 다른 부분으로 접근하고, 판정선을 지나치기 전에 사용자의 입력으로 오브젝트가 사라지지 않았다면 그대로 판정선을 지나쳐서 사라진다.

다음 이미지는 이러한 종류의 게임의 화면을 갈무리한 것이다. 빨간색/파란색/흰색의 선들이 오브젝트들(정확히는, 빨간색은 턴테이블, 파란색/흰색은 건반으로 입력하는 오브젝트)이며, 아랫쪽으로 접근한다. 아래의 검붉은 선은 판정선이다. 그리고 오른쪽에 나오는 커다란 화면은 배경 동영상(BackGround Animation; BGA)이다.

BMS 포맷을 사용하는 게임의 일반적인 화면

아무렇게나 입력한다고 모든 오브젝트가 사라지는 건 아니다. 판정선 위아래로 얼마 정도의 간격 안에 오브젝트가 있을 때 입력(건반을 누르거나 턴테이블을 돌리거나)해야 비로소 그 오브젝트가 사라진다. 보통 판정선에 가까울 수록 더 많은 점수가 주어지며, 멀어질 수록 점수가 적어지거나 아예 입력이 무시될 수도 있다. (판정선이라는 이름이 나온 이유이다) 이러한 것을 판정이라 하는데, 판정 방법이나 그 정도는 프로그램에 따라 다르다. 리듬 게임에 나오는 거의 모든 곡들은 그 곡의 박자에 맞도록 오브젝트의 위치가 조정되어 있으므로, 보통 박자를 잘 맞춰야 좋은 점수가 나온다. 비트매니아/EZ2DJ 계열의 리듬 게임이나 BMS 포맷 같은 경우 오브젝트를 없앨 때 특정한 소리가 재생되도록 하는 것도 가능한데, 이 때 재생되는 음을 "키음"이라고 부른다.

보통 대부분의 오브젝트는 한 번의 입력으로 바로 사라지지만, 위의 화면에서 볼 수 있듯이 긴 오브젝트가 나올 경우도 있다. 이들을 롱노트 오브젝트(혹은 그냥 롱노트)라고 부르는데, 이들은 오브젝트의 앞부분이 판정 간격 안에 들어 갔을 때 입력이 시작해서 뒷부분이 판정 간격 안에 들어 갔을 때 입력을 끝내야 제대로 입력한 것으로 처리된다. (좀 더 간단하게 말하면, 오브젝트가 판정선을 통과하는 동안 입력을 계속 해야 한다는 것이다. 예를 들어서 건반이나 발판을 계속 누르고 있거나, 턴테이블을 계속 돌리거나 하는 것이 해당된다.)

오브젝트들이 내려 오는 속도는 BPM(Beat Per Minute)으로 표시한다. 이는 음악에서 사용되던 용어를 따 온 것으로, 원래는 1분에 몇 개의 4분 음표가 재생되느냐를 뜻하는 것이었으나 리듬 게임에서는 보통 "4분 동안 곡의 몇 마디가 재생되느냐"로 정의한다. (위의 화면에서 가로로 그어진 회색 선이 이 "마디"를 구분하는 선이다. 게임에 따라 나오지 않는 경우도 있다.) BPM이 높을 수록 오브젝트들이 빠르게 나왔다가 빠르게 사라지기 때문에 더 어려워지지만, 거꾸로 BPM이 너무 낮으며 오브젝트들을 구분하기 힘들어져서 오히려 어려워지는 경우도 있다. 이런 이유로 대부분의 리듬 게임이나 BMS 포맷을 지원하는 프로그램들은 배속이라는 개념을 가지고 있다. 예를 들어서 3배속이라고 할 경우, 오브젝트 사이의 간격이 원래의 3배로 늘어 나고 내려 오는 속도가 3배가 된다는 것을 의미한다. (곡 자체의 속도에는 영향을 주지 않는다.)

항상 존재하는 것은 아니지만, 배경에 깔리는 이미지 혹은 동영상이 있는 경우도 있다. (대부분의 리듬 게임들이 이를 지원하며, BMS 포맷도 이 기능을 지원한다.) 일반적으로 이들은 게임에 거의 영향을 주거나 받지 않으나, BMS 포맷의 경우 오브젝트를 입력하지 못 해서 판정선 너머로 사라져 버릴 때 나타날 배경 동영상을 따로 선택할 수 있다.

마지막으로 대부분의 리듬 게임에는 게이지(Gauge)라는 개념이 있다. 게이지는 사용자의 입력으로 오브젝트가 사라질 때 그 판정에 따라 차등적으로 올라 가며, 입력을 하지 못 해서 오브젝트가 판정선을 지나쳐 버릴 때 내려 간다. 많은 프로그램들은 이 게이지가 모두 깎여서 내려 갈 경우 게임을 중단하고 "GAME OVER" 표시를 보이게 하는데, 이를 보통 폭사라고 부른다. 게이지가 올라 가거나 점수가 올라 갈 때 그 정도는 판정 뿐만 아니라 얼마나 많은 오브젝트를 연속으로 없앴는 지에도 영향을 받는데, 연속으로 없앤 오브젝트의 수를 콤보(Combo)수라고 부르며, 모든 오브젝트를 없애서 콤보수가 오브젝트의 수와 같을 때 올콤(All Combo)이라고 부른다.

BMS 파일 포맷

이 장에서는 BMS 포맷을 비롯한 관련된 파일들의 포맷을 살펴 본다.

파일 구성

BMS 파일에는 다음과 같은 정보가 들어 있다:

BMS 파일만으로는 오브젝트의 배열만 알 수 있기 때문에, 실제로는 BMS 파일과 함께 사용할 키음 및 배경음, 그리고 BGA에 사용할 이미지 파일 등이 함께 배포된다. (꼭 필요하지는 않다) 다음은 실제로 BMS 포맷으로 만들어진 곡을 받았을 때 나올 수 있는 파일들의 종류이다.

BMS 파일 (.bms, .bme, .bml)
이들은 평범한 텍스트 파일이며, 일반적인 텍스트 에디터로 만들거나 고칠 수도 있지만, 일반적으로는 BMS Creator와 같은 편집기를 사용해서 만든다.
이미지 파일 (.bmp, .jpg, ...)
BGA에 사용할 이미지 파일들이다. 처음에는 윈도우즈의 bmp 파일만이 지원되었지만 최근의 프로그램들은 다른 파일 포맷을 지원하는 경우도 있다. BGA 화면의 원래 크기는 256x256픽셀이었기 때문에, 이보다 큰 이미지는 왼쪽 윗부분만 잘려서 보이게 되고, 작은 이미지는 왼쪽 위에 표시되고 남는 부분은 검은 색으로 채워진다. (실제로 보여 줄 때는 2배 혹은 전체 화면으로 확대해서 보여 줄 경우도 있다.) 검은색(HTML 형식으로 #000000)은 투명색을 나타내기 때문에, 의도하지 않는 경우 이 색 대신 검은색에 가까운 색깔(#000001 같은 것)을 사용하는 것이 좋다.
사운드 파일 (.wav, .mp3, ...)
배경음 및 키음으로 사용할 사운드 파일들이다. 처음에는 윈도우즈의 wav 파일(RIFF 형식)만이 지원되었지만 최근의 프로그램들은 다른 파일 포맷을 지원하기도 한다. 같은 파일이 배경음 및 키음에 모두 사용될 수도 있으며, 그 외에 별다른 제한은 없다.
동영상 파일 (.avi, .mpg)
몇몇 프로그램들은 이미지 데이터 대신에 진짜 동영상 파일을 BGA로 쓸 수 있게 하는 경우도 있다. 보통 이 경우 동영상 파일에는 사운드 데이터가 포함되어 있지 않으며, 화면 크기는 256x256이어야 한다.

모든 프로그램에서 똑같이 동작하는 BMS 파일을 만드려면 bmp/wav 파일만을 사용해야 한다. 대부분의 프로그램들은 기본으로 지원하지 않는 jpg 등의 다른 포맷들을 Susie32 플러그인이나 Windows Media 등의 외부 라이브러리를 사용해서 처리하지만, 별도의 라이브러리 없이 자체적으로 이러한 파일 포맷들을 지원하는 경우도 있다.

기본 구조

다시 말하지만, BMS 파일은 일반적인 텍스트 파일이다. 개행 문자는 보통 윈도우즈의 개행 문자인 0D 0A(C 형식으로 표시하면 "\r\n")를 사용한다.

BMS 파일에서 실제로 인식되는 줄은 #로 시작하는 줄 뿐이다. 명령 이름이나 파일 이름 등은 대소문자를 구별하지 않는다. #로 시작하지 않는 줄은 모두 무시되며, 일반적으로 제작자의 주석이나 BMS 파일을 만드는 데 쓴 프로그램의 정보 혹은 데이터가 들어 간다. #로 시작하는 줄들은 그 줄에 들어 있는 데이터의 종류에 따라서 헤더 섹션과 데이터 섹션으로 나뉜다. 보통 헤더 섹션이 데이터 섹션 앞에 나오는 경우가 많지만 항상 그렇지는 않으며, 두 섹션이 섞여 나오거나 위치가 바뀌어도 같은 뜻을 가져야 한다.

실제로 BMS 파일을 읽을 때는 보통 다음과 같은 과정을 거친다. 마지막 두 과정에서는 항상 먼저 나오는 줄부터 먼저 처리해야 한다. (기술적인 용어를 동원하면, 줄들을 정렬할 때 사용하는 알고리즘이 Stable해야 한다는 것이다.)

  1. 파일 시스템에서 BMS 파일을 읽어 들인다.
  2. 전처리(preprocess) 과정을 거친다. 이 장의 마지막 절을 참고하여라.
  3. 전처리를 거친 줄들 중 헤더 섹션만을 읽어 들여서 기본적인 정보를 알아 낸다.
  4. 헤더 섹션에서 알아 낸 정보를 바탕으로 이미지/사운드 파일 등등을 불러 온다.
  5. 나머지 줄들(데이터 섹션)을 정렬한다.
  6. 순서대로 읽어 가면서 오브젝트 배치와 같은 정보들을 마저 읽어 들인다.

포맷의 특성 상, 사운드 파일과 이미지 파일들은 특정 명령으로 각 파일을 일정한 키값에 배당한 후 그 키값을 나중에 쓰는 방식을 사용한다. 예를 들어서 3F라는 키값에 특정 이미지 파일을 지정했다면, BGA를 표시할 때 3F가 나오면 이 이미지를 가리키게 된다. 이 때 똑같은 3F라는 키값에 다른 사운드 파일을 지정할 수도 있다. (이미지 파일과 사운드 파일 등은 키값을 지정하는 방법과 그 키값을 사용하는 방법이 서로 다르기 때문에 같은 키값에 다른 종류의 파일을 함께 배당할 수도 있다.) 키값은 0부터 9까지, A부터 Z까지의 36개의 문자를 사용하는 36진법 숫자 두 자리로 이루어지며, 각 종류 별로 1296개의 키값까지 사용할 수 있다. 하지만 옛날 프로그램들에서도 동작하게 하려면 0부터 9까지, A부터 F까지의 16개의 문자를 사용하는 16진법 숫자를 사용하는 것이 좋다. (이 때는 256개의 키값까지 사용할 수 있다)

헤더 섹션

헤더 섹션은 곡의 메타 데이터나 기본적인 정보, 그리고 사용할 사운드/이미지 파일들을 지정한다. 대부분의 프로그램에서 일반적으로 지원되는 명령들은 다음과 같다.

#PLAYER 정수
해당 BMS 파일의 플레이 방법을 의미한다. 정수 부분에는 다음과 같은 값들이 들어 갈 수 있다.몇몇 프로그램들은 2, 3, 4를 모두 3의 뜻으로 받아 들이기도 한다.
#TITLE 문자열
곡의 제목을 지정한다.
#ARTIST 문자열
곡의 제작자를 지정한다.
#GENRE 문자열
곡의 장르를 지정한다.
#BPM 실수
BPM 값을 지정한다. 기본값은 130이다. 중간에 BPM 값이 바뀔 경우, 이 값은 처음으로 BPM 값이 바뀌기 직전까지 적용된다.
#PLAYLEVEL 정수
패턴의 난이도를 지정한다. 상대적인 수치로 실제 플레이에 영향을 주지는 않는다.
#RANK 정수
플레이어의 입력을 얼마나 엄격하게 판정할 것인지(즉, 판정 난이도를) 지정한다. 이 역시 상대적인 수치로, 프로그램에 따라서 무시할 수도 있다. 정수에 들어 갈 수 있는 값은 다음과 같다. (기본값은 2이다.)
#TOTAL 정수
전체 오브젝트 수를 수동으로 지정한다. 이 값은 판정 난이도를 조정하는 데 사용하며, 프로그램에 따라서 무시할 수도 있다. (실제 오브젝트 수보다 많게 설정할 수록 어려워진다.)
#VOLWAV 정수
사운드 파일의 소리 크기(볼륨)를 지정한다. 100에 대한 상대값으로 지정하며, 기본값은 100(그대로 유지)이다. 프로그램에 따라서 무시될 때도 있다.
#MIDIFILE 파일명
배경음으로 재생될 미디 파일을 지정한다. 현재는 거의 사용되지 않는다.
#WAVxx 파일명
지정한 사운드 파일을 지정된 키값(xx)에 지정한다.
#BMPxx 파일명
지정한 이미지 파일을 지정된 키값(xx)에 지정한다. 특별하게, 00번 키값에 지정한 이미지는 사용자가 오브젝트를 입력하지 못 했을 때 보여지는 기본 이미지로 사용된다. (이 이미지는 다음 절에서 설명할 데이터 섹션의 channel #06에서 바꿀 수 있다.) 지정되지 않은 이미지를 사용하려 할 경우 보통 검은색(#000000, 즉 투명색)으로 채워진 이미지로 초기화된다.
#STAGEFILE 파일명
곡의 데이터를 읽어 들일 때 보여 줄 이미지 파일을 지정한다. 이 이미지는 전체 화면으로 보여진다.
#VIDEOFILE 파일명
BGA 대신에 재생될 동영상 파일을 지정한다. 이 명령이 지정되면 다른 BGA 관련 명령들은 모두 무시된다.
#BGAxx bmpno x1 y1 x2 y2 targetx targety
지정한 키값(bmpno)에 배당되어 있는 이미지 파일에서 (x1, y1)부터 (x2-1, y2-1)까지의 직사각형 영역(두 경계점을 포함함. (0,0)은 이미지의 왼쪽 위 끝)을 다른 키값(xx)에 배당되어 있는 이미지의 (targetx, targety) 위치에 복사한다. x1과 x2가 0보다 작을 경우 각각 0으로 조정되며, 지정된 영역이 256x256보다 크면 256x256 크기에 맞게 x2와 y2가 조정된다. 지정되지 않은 키값을 사용할 경우 검은색(#000000)으로 채워진 이미지가 있는 것으로 가정한다.
#BPMxx 실수
지정한 키값(xx)에 확장 BPM 채널(channel #08)에서 사용할 BPM을 지정한다.
#STOPxx 정수
지정한 키값(xx)에 시퀀스 정지 채널(channel #09)에서 사용할 정지할 시간을 지정한다. 정지할 시간은 1/192 마디 단위로 표시한다. (예를 들어 96은 반 마디를 의미한다)
#STPxxx.yyy 정수
xxx번 마디의 yyy 지점(마디의 시작은 0, 마디의 끝은 1000)에서 지정된 시간(1/1000초 단위) 만큼 시퀀스를 정지시킨다.
#LNTYPE 1
#LNTYPE 2
#LNOBJ xx
롱노트 지원을 위한 옵션으로, 에서 자세히 설명한다.

다음은 몇몇 프로그램에서만 지원하는 명령이다.

#EXTCHR sprno bmpno x1 y2 y1 y2 [ox oy [x y]]
BM98에서만 지원하며, [...]로 묶은 것은 생략할 수 있음을 나타낸다. 지정된 스프라이트 번호(sprno)에, 지정된 키값(bmpno)에 지정된 이미지의 (x1, y1)부터 (x2, y2)까지의 직사각형 영역을 복사하고, 그 스프라이트의 상대 위치(offset)을 (ox, oy)로 지정한 후, 만약 x와 y가 존재한다면 전체 화면 위의 (x, y) 위치에 그 스프라이트를 출력한다. ox와 oy의 기본값은 0이다.

#BGA 채널을 제외한 모든 중복되는 명령은 마지막 명령만 인식한다. (예를 들어서 #TITLE이 여러 개 있다면 마지막에 나온 #TITLE만이 적용된다.)

데이터 섹션

데이터 섹션은 실제로 지정된 이미지/사운드가 어떤 순서로 재생되는 지를 결정하고 오브젝트의 배치를 지정한다. 데이터 섹션에 해당하는 모든 줄은 다음과 같은 형태로 되어 있다.

#xxxyy:aabbccdd...

또는,

#xxxyy:(데이터)

이 줄은 콜론(:)을 기준으로 두 부분으로 나뉜다. 각각의 부분은 다음과 같은 의미를 가진다.

xxx
샾(#) 뒤의 3자리 10진법 숫자는 마디 번호를 나타낸다. 첫째 마디는 0, 둘째 마디는 1, ...과 같은 방법으로 지정한다. 따라서 BMS 포맷으로는 1000개의 마디까지 수용할 수 있다.
yy
콜론(:) 앞의 2자리 16진법 숫자는 채널 번호를 나타낸다. 이 번호는 뒤에 따라 오는 데이터가 어떤 내용을 가리키는 지 나타내는 역할을 한다.
aabbccdd...
대부분의 경우 콜론 뒤에 나오는 데이터는 두 글자 단위로 해석하게 된다. (글자 수가 홀수이면 에러로 처리하거나 마지막 글자를 무시한다.) 이 두 글자는 채널에 따라서 키값이나 16진법 숫자로 해석될 수 있다. 이 때 데이터의 갯수가 n이라고 하면, 마디는 n 조각으로 나뉘게 되고 첫째 데이터는 해당 마디의 0/n 위치(즉, 마디의 시작), 둘째 데이터는 1/n 위치, ..., n번째 데이터는 (n-1)/n 위치에 들어 가게 된다. "00"이 들어 왔을 경우 데이터가 없는 것으로 간주하고 무시한다.
(데이터)
일부 채널의 경우 앞과 같은 방법으로 데이터를 나타내지 않고 다른 방법으로 나타내는 경우도 있다. 기본적으로는 channel #02에서만 사용한다.

채널은 그 종류에 따라서 다시 두 종류, 즉 이벤트 채널과 오브젝트 채널로 나뉜다.

이벤트 채널

이벤트 채널은 실제로 오브젝트를 배치하지는 않지만 곡이 재생될 때 발생하는 이벤트(BGA 변경, 배경음 재생 등)를 지정하는 데 사용한다.

channel #01: 배경음 채널
지정한 키값을 배경음으로 재생한다. 이 배경음은 어떤 경우에라도 항상 재생된다. 존재하지 않는 키값은 무시한다.
channel #02: 마디 단축
이 채널은 다른 채널과는 다르게 데이터로 숫자를 받는다. 지정한 실수 배로 해당 마디의 길이를 줄이거나 늘린다. (0.5일 경우 원래 길이의 반으로, 2.0일 경우 원래 길이의 두 배로) 이는 BPM의 조정과 다르며, 해당 마디가 재생되는 시간 자체가 그만큼 짧아지거나 길어지는 것을 의미한다.
channel #03: BPM 채널
해당하는 위치에서, BPM을 지정한 16진수 숫자(1부터 255까지)로 바꾼다. 예를 들어서 78은 BPM 120을 의미한다.
channel #04: BGA 채널
현재 표시되고 있는 배경 이미지 파일을 해당하는 키값에 지정된 이미지 파일로 바꾼다. 지정된 이미지는 다른 이미지가 이 채널에서 지정될 때까지 계속 보여진다.
channel #05: BM98 확장 채널
이 채널은 BM98에서만 사용할 수 있다. 따라 오는 데이터들을 순서대로 해당 마디의 에 넣는다. 그리고 오브젝트 채널에서 명령을 내릴 때, 해당 마디의 큐가 비어 있지 않으면 나오는 순서대로 00이 아닌 키값에 큐에서 키값을 꺼내서 그 키값에 대응하는 스프라이트를 기본 오브젝트 모양 대신 출력한다. 키값에 대응하는 스프라이트 번호는 미리 지정되어 있으며 부록에 그 목록이 있다.
channel #06: Poor BGA 채널
사용자가 오브젝트를 입력하지 못 했을 때 표시될 배경 이미지를 해당 키값의 이미지로 바꾼다. 일반적인 BGA 채널과는 달리 Poor BGA 채널은 하나 뿐이며, 투명색 등은 모두 무시된다.
channel #07: BGA 레이어 채널
현재 표시되고 있는 배경 이미지 파일을 해당하는 키값에 지정된 이미지 파일로 바꾼다. channel #04와 다른 점은 이 이미지는 channel #04에서 지정한 이미지 위에 표시된다는 것이다. (검은색, 즉 투명색으로 되어 있는 부분은 아래의 일반 BGA 이미지가 비쳐 보이게 된다.) 그래픽 편집 툴의 레이어 기능과 흡사하다.
channel #08: 확장 BPM 채널
해당하는 위치에서, BPM을 지정한 키값에 지정된 BPM 값(#BPMxx 명령으로 지정한 값)으로 변경한다.
channel #09: 시퀀스 정지 채널
해당하는 위치에서, 지정한 키값에 지정된 시간(#STOPxx 명령으로 지정한 값) 만큼 오브젝트가 움직이는 것을 멈춘다. 이미 재생되던 배경음은 그대로 재생되지만 다른 모든 것은 해당하는 시간만큼 멈춰 있게 된다.

오브젝트 채널

오브젝트 채널은 실제로 사용자가 입력할 수 있는 오브젝트들의 배치를 지정하는 데 사용한다. 채널 번호에서 뒤의 글자("3F"에서 "F")는 오브젝트의 종류를 나타내기 위해 사용하며, 각각 다음과 같은 의미를 가진다.

여기서 프리존 영역은, 스크래치에 어떤 입력을 해도 판정에 영향을 주지 않는 영역이다. (영역은 해당 채널의 오브젝트 주변에 지정되며 실제로는 보이지 않는다.) BM98 시절에는 판정 영역에 아무 것도 없을 때 입력을 하면 틀린 것으로 간주했는데, 스크래치에서 자유롭게 입력을 할 수 있도록 하기 위해 만들어진 명령이다. 현재는 대부분의 프로그램들이 판정 영역에 아무 것도 없을 때 입력을 해도 틀린 걸로 처리하지 않으므로 더 이상 사용되지 않는다.

채널 번호의 앞의 글자("3F"에서 "3")는 오브젝트 그룹을 나타내기 위해 사용하며, 각각 다음과 같은 의미를 가진다.

참고로, 판정선 근처에 아무 오브젝트도 없을 때는 판정선에서 가장 가까운 오브젝트의 키음을 재생하게 되는데, 투명 오브젝트는 실제로는 보이지 않고 판정이나 점수에도 영향을 주지 않지만, 이와 같은 경우에만 오브젝트로 인식하는 오브젝트를 의미한다. (투명 오브젝트가 더 가까이 있을 경우 이 오브젝트의 키음을 재생하게 된다. 실제로는 더 많은 노력을 필요로 하므로 많이 사용되지 않는다.)

롱노트 오브젝트에 대해서는 다음 절을 참고하여라.

롱노트의 구현

롱노트를 구현하는 방법에는 세 가지, 즉 #LNTYPE 1, #LNTYPE 2, #LNOBJ 명령을 사용하는 방법이 있다. 최근에 만들어진 많은 프로그램은 이 세 가지 방법을 모두 지원하지만 보통 #LNTYPE 1이나 #LNOBJ 명령을 많이 사용한다.

#LNTYPE 1

이 명령이 지정되었을 경우, RDM 타입이라 불리는 방법으로 롱노트를 구현한다. 이 경우 롱노트 채널(channel #5x#6x)을 사용하며, 롱노트 채널에 나타나는 키값은 다음과 같이 처리한다.

예를 들어서 "#00251:00AA00FF"는 2번 마디의 1/4 지점부터 3/4 지점까지 롱노트를 지정한다. 이 롱노트를 누를 때는 키값 AA에 배당된 사운드가 재생된다.

#LNTYPE 2

이 명령이 지정되었을 경우, MGQ 타입이라 불리는 방법으로 롱노트를 구현한다. 이 방법은 처음에 제안되었던 롱노트 구현 방법으로 당시 프로그램들은 이 명령이 없어도 자동으로 MGQ 타입으로 처리하도록 되어 있었다. 현재 많은 프로그램들은 기본적으로 RDM 타입으로 처리하게 되어 있다. 이 경우에도 롱노트 채널(channel #5x#6x)을 사용하며, 롱노트 채널에 나타나는 키값은 다음과 같이 처리한다.

예를 들어서 "#00251:00AAAAAABBBB00CC"는 2번 마디의 1/8 지점부터 4/8 지점까지, 4/8 지점부터 6/8 지점까지, 그리고 마지막으로 7/8 지점부터 8/8 지점까지 세 개의 롱노트를 지정한다. 이 롱노트를 누를 때는 각각 순서대로 키값 AA, BB, CC에 배당된 키음이 재생된다.

#LNOBJ xx

이 명령이 지정되었을 경우, RDM 타입 2라고 불리는 방법으로 롱노트를 구현한다. 이 때 xx는 사운드를 나타내는 키값이다. 이 방법은 롱노트 채널 없이 일반 오브젝트 채널(channel #1x#2x)을 사용하며, 다음과 같이 처리한다.

예를 들어서 "#LNOBJ FF"가 지정되어 있을 때, "#00211:00AA00FFBBCCFF00"는 2번 마디의 4/8 지점에 한 개의 일반 오브젝트를 지정하고 1/8 지점부터 3/8 지점까지, 5/8 지점부터 6/8 지점까지 두 개의 롱노트 오브젝트를 지정한다. 이 오브젝트를 입력할 때는 순서대로 BB, AA, CC에 배당된 키음이 재생되며, FF에 배당된 사운드가 있다면 3/8 지점과 6/8 지점에서 그 사운드를 배경음으로 재생한다.

전처리 과정

다음은 전처리 과정에서 인식하는 명령들로, 다른 어떤 명령들보다도 먼저 실행된다.

#RANDOM 숫자
1부터 해당 숫자까지의 범위 안에 있는 난수를 생성한다.
#IF 숫자
마지막으로 생성된 난수가 해당 숫자가 아니면, #ENDIF(또는 #ELSE)가 나오기 직전까지의 모든 줄들을 무시한다. #IF-#ENDIF는 중첩될 수 없다.
#ELSE
마지막 #IF 명령으로 앞의 줄들이 무시되고 있다면 이 명령 다음 줄부터는 무시하지 않고, 거꾸로 앞의 줄들이 무시되고 있지 않았다면 이 명령 다음부터 #ENDIF가 나올 때까지의 모든 줄을 무시한다. 이 명령은 프로그램에 따라 지원하지 않을 수도 있다.
#ENDIF
#IF로 무시하는 부분의 끝을 나타낸다.

부록

수정 사항

문서에서 추가할 사항이나 수정할 사항은 이 글 맨 위에 있는 메일 주소로 메일을 보내 주시면 감사하겠습니다.

version 1.0 (2005.3.15)
첫 문서.
version 1.1 (2005.3.18)
BM98 확장들(#EXTCHR, channel #05)을 소개함.
version 1.2 (2005.3.20)
HTML 형식으로 변경. 글의 구조를 바꾸고 불명확한 부분을 바로잡음. #BACKBMP 명령 추가.
version 1.2.1 (2005.3.21)
설명 순서를 거꾸로 넣은 것 수정 -_-;
version 1.2.2 (2005.3.22)
EXTCHR 테이블을 표 형식으로 변경

참고할 곳

한국에서 만든 BMS 포맷을 사용하는 몇몇 프로그램들의 목록은 다음과 같다. (대부분의 프로그램은 Windows 환경만을 지원한다.)

다른 곳들은 잘 정리된 곳이 있으니 이 쪽을 참고하는 것이 좋겠다.

EXTCHR 테이블

다음은 #EXTCHR 명령을 사용하지 않았을 때 기본적으로 지정되어 있는 스프라이트 번호들이다. 자세한 사항은 Yane Urao 씨의 글을 참고하여라.

x0x1x2x3x4x5x6x7x8x9xAxBxCxDxExF
0x0961962963964965966967968969970971972973974975
1x976977978979980981982983984985986987988989990991
2x99299399499599699799899910001001100210031004100510061007
3x1008100910101011101210131014101510161017101810191020102110221023
4x0000000000000000
5x0000000000000000
6x94194294394494594694794894995095100000
7x730731732733734735736737738739740741742743744745
8x746747748749750751752753754755760761762763764765
9x766767768769770771772773774775776777778779780781
Ax782783784785790791792793794795000000
Bx80080180580680780881081181291091191291394000
Cx850851852853854855856857858859860861862863864865
Dx866867868869870871872873874875876877878879890891
Ex720721722723724725726727728729000000
Fx880881882883884885886887888889000000

여기서 961부터 1023까지의 스프라이트는 사용자 지정으로 남겨진 부분이다. 나머지는 글자, 기호와 같은 스프라이트가 기본으로 배당되어 있다.

Copyright © 2005, Kang Seonghoon <tokigun@gmail.com>