BMSを読んでみよう

この記事は、BMS製作について Advent Calendar 2015 の22日目の記事です。

www.adventar.org

近年では、iBMSCをはじめとした非常に優秀なBMS譜面作成ツールを使ってBMSを制作することはもはや当たり前になってきました。 ですが、譜面作成ツールも対応していない命令は多く、特殊な譜面を作る際にはある程度手作業でBMSファイルを編集する必要があります。 今日はそんな方々に向けて、平易なBMSの読み方とおまけであなたの知らない超絶技巧BMSをご紹介します。

この記事を書くにあたって、BM98Data_format_specification および BMS command memo(JP)を参考にしました。本記事ではBMSのおおまかな記述方法に触れるだけですので、各種命令の詳細については以下を参照していただければと思います。

http://bm98.yaneu.com/bm98/bmsformat.html hitkey.nekokan.dyndns.info

ヘッダ

とりあえずBMSを開いてみましょう。ここでは、真・千年女王[yumether]を例として見ていきます。

www.youtube.com

すると、ファイルの先頭では以下のような文が見つかるはずです。

#PLAYER 1
#GENRE Hardcore
#TITLE 真・千年女王 [yumether]
#ARTIST Shiraishi / obj:夢瑠
#BPM 160
#PLAYLEVEL 22
#RANK 3
#TOTAL 500

なんとなく察しは付くと思いますが、ここでは曲および譜面の情報を指定しています。

  • #PLAYERは主にSP/DP譜面であることを示します。
  • #GENREは曲のジャンルを、#TITLEは曲名を、#ARTISTは曲の作者を示します。
  • #BPMは曲開始時のBPMを示します。
  • #PLAYLEVELは譜面の難易度を示します。
  • #RANKは判定の厳しさを示します。
  • #TOTALはノーツを全てPERFECT判定で取った時のノーマルゲージの回復量を示します。

更にBMSを読み進めていくと以下のような文が見つかるはずです。

#WAV01 Effects_01.wav
#WAV02 Effects_02.wav
#WAV03 Effects_03.wav
#WAV04 bass_01.wav
#WAV05 bass_02.wav
#WAV06 bass_03.wav
#WAV07 bass_04.wav
#WAV08 bass_05.wav
#WAV09 bass_06.wav
#WAV0A bass_07.wav
#WAV0B bass_08.wav
#WAV0C bass_09.wav
#WAV0D bass_10.wav

これはBMS中で鳴らす音を指定する命令です。#WAVxx filepathという形で、鳴らす音のファイルパスを指定していきます。
xxには00を除く36進数2桁が入ります。ですので、1つのBMSで使用できるファイルは1256個*1までということになります。
同様に、#BMPxx filepathの形でBGAを指定する命令も存在します。

これらの#XXX xxxの形で記述される命令をヘッダ(Header)と呼びます。ヘッダの多くの命令は命令の種類とその内容が1対1の対応で記述されているため、初見でもなんとなく意味を理解しやすいかと思います。

チャンネル文

ここから、譜面そのものとなるチャンネル(Channel Messages)について見ていきます。BMSファイルを読み進めていくと、このような文字列が大量に見つかるはずです。

#07411:BDBDBDBD
#07412:DCD8
#07413:D8DC000000DCDCDC000000DC
#07414:00E1DF00DFE100E1DF00DFE1
#07415:0000E3E1E3000000E3E1E300
#07416:C1
#07418:00E400E4
#07419:BFBFBFBF

不思議な文字列が並んでいます。頭が痛くなってきました。
ここでは、次の文を例として扱っていきます。

#07418:00E400E4

まずは先頭の数字5文字について見ていきましょう。

先頭の3文字の数値は、その命令の属するべき小節を表しています。
次の2文字の数値は、その命令の種類(チャンネル番号)を表しています。

例えば、LR2では11番から15番まではそれぞれ1鍵~5鍵に対応していて、18番が6鍵、19番が7鍵、16番がスクラッチに対応しています。
その他にも、BGAや譜面の停止、BPM変化などの動作もこのチャンネル番号で定義しています。

例文をもう一度見てみましょう。先頭3桁は小節番号で、後の2桁は命令の種類を表しています。
よって、この命令は74小節目の6鍵に関する命令であることが読み取れます。

それでは、コロン以降の文字列について見ていきましょう。 コロン以降の文字列は基本的に2文字区切りで扱います。したがって、ここでは00 E4 00 E4という4つの番号が記述されていることになります。

ところで、この2桁の文字列になんとなく見覚えはありませんか?

#WAV01 Effects_01.wav
#WAV02 Effects_02.wav
#WAV03 Effects_03.wav
#WAV04 bass_01.wav
#WAV05 bass_02.wav
#WAV06 bass_03.wav
#WAV07 bass_04.wav

そうです。この文字列は鳴らすべき音を指定しているのです。
E4 とは、 #WAVE4 のことを示しています。
00は欠番であり、そこでは音を鳴らさないことを示します。

コロン以降の文字列の数は命令を実行する小節の解像度を示し、それぞれの文字列の位置はいつ音を鳴らすかを示しています。
すなわち、#07418:00E400E4は「74小節目の6鍵の1/4と3/4の位置に、E4が鳴るノートを配置する」という意味になり、図にすると以下のようになります。

f:id:h1dia:20151221195107p:plain

同様に、冒頭の

#07411:BDBDBDBD
#07412:DCD8
#07413:D8DC000000DCDCDC000000DC
#07414:00E1DF00DFE100E1DF00DFE1
#07415:0000E3E1E3000000E3E1E300
#07416:C1
#07418:00E400E4
#07419:BFBFBFBF

を図にすると、以下のような譜面になります。

f:id:h1dia:20151221194813p:plain

それぞれ命令が譜面の各レーンに対応していることが確認できます。

このように、チャンネル文は主にヘッダで記述されたWAVファイルを曲として配置するために使用されます。
先に述べたようにBGAや譜面の停止、BPM変化についてもこの命令で記述することができますが、各文字列の持つ意味や記述方法が異なる場合がありますので注意して下さい。

あなたの知らない超絶技巧BMSの世界

なんとなくBMSの読み方を理解したところで、「恐らく手作業で作られたっぽいなんかすごいBMS」を一緒に読んでみましょう。
全部知ってたらごめんなさい。

U9

クソ譜面パーティー優勝曲★★7 U9です。

youtu.be

差分はInternet Archiveからダウンロードすることができます。 https://web.archive.org/web/*/http://soflan.hp.infoseek.co.jp/event/futher_u9.zip

ではBMSを開いてみましょう。まずはヘッダを読みます。

#PLAYER 1
#GENRE プログレスィブロック
#TITLE U9
#ARTIST paraoka / futher
#BPM 123
#PLAYLEVEL U2
#RANK 3
#TOTAL stand by OK

お分かり頂けただろうか…

#PLAYLEVEL U2
#TOTAL stand by OK

PLAYLEVELとTOTAL値に文字が突っ込んであります。数値が入るべき場所に文字列が突っ込んであります。
LR2はとても優秀なBMSプレーヤーなので、このような数値をうまく誤魔化して何事もなかったかのように振る舞っていますが、裏ではこのような仕打ちを受けていたことがわかりますね。

さて、U9と言えば「曲終盤でランダムでノーツが上昇していく」ギミックが有名ですね。そのギミックは1270~1288行目に記述されています。

#random 6
#if 1
#04908:01
#endif
#if 2
#04908:02
#endif
#if 3
#04908:03
#endif
#if 4
#04908:04
#endif
#if 5
#04908:05
#endif
#if 6
#04908:06
#endif

これは、譜面を再生するごとにこの中のどれかの命令をランダムで実行するような記述です。
#random nで変化パターンの数を示し、#if x から #endifの中で各パターンの動作を示しています。

この命令は先頭3文字より49小節目で実行されることがわかります。
チャンネル番号08とはBPM変化を示す命令です。これはヘッダの#BPMxxで定義されたBPMに再生中の譜面のBPMを変化させます。
U9では、455~460行目に定義されています。

#BPM01 9888
#BPM02 3390
#BPM03 -45
#BPM04 6666
#BPM05 65535
#BPM06 908

つまり「49小節目でこれらのどれかのBPMに変化する」という意味になります。この中で、たまたま #04908:03 が実行されると譜面が上にスクロールしていくというギミックになる訳です。

オートメーション工場

さて、U9では #random という命令を使用して、実行時にランダムに変わる譜面を実現していました。
この命令をふんだんに使用したBMSが「オートメーション工場」です。 http://www.comeup.info/bofoon2007/automation.zip

BMSを開いてみましょう。まずはヘッダを読みます。

#GENRE オートメーション工場
#ARTIST John "De Bello" Cage

#RANDOM 16
#IF 1
#TITLE 職権を乱用するRainbow
#ENDIF
#IF 2
#TITLE またお前らただし女性限定
#ENDIF
/* 中略 */
#IF 14
#TITLE 人生とビル・ゲイツ
#ENDIF
#IF 15
#TITLE 黒鍵の上も歩くRED
#ENDIF
#IF 16
#TITLE 風雲!寝る
#ENDIF

#BPM 128
#VOLWAV 100

// 判定
#RANDOM 4
#IF 1
#RANK 2
#ENDIF
#IF 2
...

なんということでしょう。曲名から判定まで全部ランダムで決まってしまいます。

気を取り直してチャンネル文を見ていきましょう。

#RANDOM 16
#IF 1
#00111:01
#ENDIF
#IF 2
#00111:02
#ENDIF
#IF 3
#00111:03
#ENDIF
#IF 4
#00111:04
#ENDIF
#IF 5
#00111:05
#ENDIF
...

チャンネル文も全てランダムです。この調子でチャンネル文の記述が40万行以上続いていきます。
LR2はとても優秀なBMSプレーヤなので、このようなBMSでも読み込んでしまいます。すごい。

#RANDOM命令は非常に権限の強い命令で、このようにヘッダすらランダムに変更することが出来ます。ですが、命令の動作はBMSプレーヤに依存するため、乱用することはおすすめしません。

(^^) [pseudo: ninth -forbidden story-]

Yamajet氏の(^^)http://www.yamajet.com/archives/43の差分です。 http://hitkey.nekokan.dyndns.info/foon-ninth-403-alt.zip

例によってヘッダから見ていきましょう。

#PLAYER 1
#GENRE Clockwork
#TITLE (^^) [pseudo: ninth -forbidden story-]
#ARTIST Yamajet
#SUBARTIST 403: MRYM's husbandary
#SUBARTIST BGA: cyclia
#BPM 138
#RANK 3
#VOLWAV 130
#BANNER _banner.bmp
#STAGEFILE title.bmp
#PLAYLEVEL こんばんは

PLAYLEVELに挨拶をされてしまいましたがもうこの程度では驚きませんね。むしろ挨拶を返してあげるくらいの余裕はもうみなさんにあるはずです。こんばんは。
続いてチャンネル文を読んでいきます。

#00004:03:21 (sfmddrex) 樹海の神秘03:21 (TOALair) 38人居ますか?03:21 (A-Manbow) 実写取り込み03:21 (sfmddrex) 38人のとこなつが03:21 (sfmddrex) あなたの所へだんご3兄弟は、お年寄りののどに詰まってお年寄りが死んだという逸話のあるキラーだんごで
#00104:おはようございます。五時の丸山です。
#00111:F2 Random Shuffle Ex.Random MIRROR(1P) MIRROR(2P) MIRROR(DP)切り替えF2 Random Shuffle Ex.Random MIRROR(1P) MIRROR(2P) MIRROR(DP)切り替えF2 Random Shuffle Ex.Random MIRROR(1P) MIRROR(2P) MIRROR(DP)切り替え
#00114:〜         〜
#00112:●         ●

#00113:     >           <Hello!

#00115:      ▼

おはようございます。五時の丸山です。
BMSプレーヤでは読み込めなくても、このように目で見て楽しむBMSも存在するようです。芸術ですね。

ちなみに最後の方にはかわいいAAが書いてあります。

f:id:h1dia:20151221194646p:plain

おわりに

BMSの簡単な読み方でした。基本的にチャンネル文の読み方さえ覚えれば、あとは命令の意味を逐次探すだけで簡単に読めるようになるかと思います。たぶん。
地雷ノーツやRANDOM命令に対応している譜面制作ツールは無かったような気がするので、この記事がそのような譜面を制作する際の足がかりになればと思います。

*1:362 - 1