BMS command memo (draft)

  • latest update:
  • written by hitkey

  • references:

    about BMS:
    This report referred to:
    BMS Format Specification: ()
    Basic specification of BML:
    BMS extensions proposed by Sonorous: (since ) (as reference data)
    DTX file format specifications: (as reference data)
    Guide to understand BMS format: () (as reference data)
    Angolmois Internals: () (as reference data)
    about obsolete MGQ notation: () (as reference data)
    LR2 beta3 Skin csv specification revision 5: () (as reference data)
  • caution:

    • This is not what translated specifications. This is only my memo.
    • I used on-line translation service 100%.
    • Since I cannot understand English, I cannot judge whether the result of automatic translation is right.
    • The contents may lead to misunderstandings because the translation could be a bit off.
    • Moreover, my research may not be exact. (Of course, I strove not to write a mistake. But I cannot guarantee that the contents are right. )
    • From the above reason, I do not bear responsibility to this document. Please forgive me.
    • If you have any further questions, please feel free to contact me. If an error is pointed out, I am glad and will correct.
    • Font test: Segoe UI, Helvetica, Helvetica Neue, Verdana, Lucida Sans Unicode, Lucida, Arial,
  • update history:

    • : DTXCreator 026 / I added a postscript about apps which supports #VOLWAV.
    • : Sonorous 0.1.0-pre (2014-07-08)
    • : HDX v1.05
    • : BGAEncAdv v0.034
    • : BGAEncAdv v0.033 / Suspended TechnicalGroove
    • : HDX v1.04
    • : Mid2BMS / lr2_pmsview_helper
    • : PMSee-V v2.2.2
    • : HDX v1.03
    • : Feeling Pomu 2nd had #BGA, #POORBGA, #xxx0A (LAYER2)
    • : Angolmois Rust Edition () / nanasigroove2 beta (Toy Musical 3 Ver.2.2) / PMSee-V v2.2.1′
    • : Extended BPM / STOP Sequence
    • : Further retouch to RLE (bmpfmt.htm) / I added about big-video
    • : I found downloadable MacBeat.
    • : I corrected the following items: RLE / grouping by filename (*.lr) / #BGA compatibility (bemaniaDX)
    • : [old] mainori-se.sakura.ne.jp/dtxmania/ -> [new] dtxmania.net/
    • : Angolmois Rust Edition (2014-01-26) / Sonorous 0.1.0-pre (2014-01-31)
    • : HDX v1.02
    • : HDX v1.01 / bms diff tool
    • : Fixed link rot (BMS Viewer, in_bm) / LR2SkinHELP
    • : Sonorous 0.1.0-pre (2013-11-18)
    • : Sonorous 0.1.0-pre (2013-11-13) / iBMSC 3.0.5
    • : Sonorous 0.1.0-pre (2013-10-13) / multi #SUBTITLE / multi #COMMENT
    • : Sonorous 0.1.0-pre (2013-10-09)
    • : I added the TechnicalGroove column in #DEFEXRANK n. / I had overlooked PMSee-V v2.1.5a () (sorry... sorry...)
    • : I added about video rewinding.
    • : Be-Music Helper (beta 4′) / woslicerIII (2013-09-22)
    • : Be-Music Helper (beta 4) / Sonorous 0.1.0-pre (2013-09-17) / Listing of all the values of #OPTION (option.htm)
    • : Angolmois 2.0 e5cea53a2cbd (SDL 2.0.*) (fixed: #BGA compatibility)
    • : #DEFEXRANK 0 / grouping by subtitle / multi #SUBARTIST / fractional #STOP / multi #LNOBJ / #BGA compatibility
    • : [old] bit.sparcs.org/%7Etokigun/article/bmsguide.php -> [new] cosmic.mearie.org/2005/03/bmsguide/
    • : HDX v1.00 / Sonorous 0.1.0-pre / BGAEncAdv v0.032 / TechnicalGroove
    • : I realized that HDX and IIDXv was supporting “spread canvas”.
    • : I realized that Indenting of HDX/IIDXv is enhanced. (U+3000)
    • : I added ENDIF (U+FF03) into “Examples of Mistakes”.
    • : uBMplay 1.5.2 / fixed about “spread canvas” (added BM98)
    • : I added uBMplay into #PATH_WAV.
    • : uBMplay 1.5.1 / I corrected URI of woslicerII. (remove “soft/index.html”) / uBMplay 1.5.0 knew #OCT/FP
    • : I added BmDx and changed the abbreviated name of bemaniaDX.
    • : Angolmois Rust Edition
    • : woslicerIII / fixed about “spread canvas
    • : <hgroup> is gone
    • : IIDXv 2.14, PMSee-V 2.1.3a
    • : HDX 0.99 / #99902:1 / multiple #xxxA6 / fixed a mistake about default value of #RANK n
    • : PMSee-V 2.1.3
    • : uBMplay 1.5.0
    • : Angolmois 2.0 77ce3b6e2761 / I corrected the item of #ExtChr.
    • : Angolmois 2.0 798422870970 (fixed: #LNTYPE 2)
    • : Angolmois 2.0 alpha 2 9880e98d15f8
    • : Angolmois got alpha-blending
    • : I added the reference about the escape of a character string into “Comment syntax”.
    • : HDX 0.98, PMSee-V 2.1.2, nanasi2 1.0, IIDXv 2.13, PMChr-V 4.0.2, Angolmois 2.0 alpha 2 pre
    • : HDX 0.97, PMSee-V 2.0.2, nanasi2 0.4, fixed some broken links
    • : HDX 0.96, PMSee-V 2.0.1a, PMChr-V 4.0.0
    • : nanasi2 0.3
    • : iBMSC 3.0.4
    • : HDX 0.94, iBMSC 3.0.3 / I added BMSV and nBMplay into “FREE ZONE”.
    • : HDX 0.93
    • : PMSV 1.10.5, nanasi2 0.2, IIDXv 2.12, HDX 0.92, #ELSEIF, Indent style, Comment syntax, Keyup-sounding
    • : PMSV 1.10.4, PMCV 3.1.0, nanasi2 0.1, SMB 1.03
    • : ruv-it! 2.0 b5p7 test #7
    • : Be-Music Helper (beta 3)
    • : I fixed a lot of bugs about HTML of this document. Valid HTML5 Valid CSS3
    • : I corrected the item of #TOTAL. (thanks to kisama)
    • : I forgot to reflect update of iBMSC 3.0. I added about that.
    • : I set the permalink to all the headings, and also added some items.
    • : I updated this document. Since there were too many corrected parts, I cannot remember them.
    • : I Japanized this document. My gestalt collapsed.
    • : I HTMLized this document. File size swelled up fourfold.
    • : I finished writing this document. I merely wrapped the plain text in the <pre> tag only.
    • : I became feeling of writing this document. I began to write.

BMS apps:

The abbreviation which this document uses for convenience is as follows. (It may differ from a formal abbreviation. )

The name and version Abbr Description
Body (obsolete):
BM98 & BM98 kikuchan version 330 revision 42 BM98
BM98 Kikuchan Version 3.32β Drink Edition BM98de
music game quest ver2.18 MGQ
Delight Delight Reduplication Ver.0.50 beta5 DDR
rhythm-it 1.72a RDM
Mixwaver 1.6 Final & MixWaver][ 1.2 MW
BmDx Millennium Edition M6 (old document) BmDx
bemaniaDX Vision.3 APPEND Vision.4 Skin version 0.95 bemaniaDX
unofficial nazobmplay rev.798 nazo
unofficial nazobmplay rev.798 + Glasopal nazoZZ
BM2DXEmu a20 DXEmu
MacBeat 0.9.8.3 Mac
Aqua'n Beats 1.0.3 Aqua
nanasigroove ver.1.552 nanasi
forgetalia++ () fgt++ (closed)
Body (current):
LunaticRave2 LR2 (for now, the de facto standard in Japan)
ruv-it! 2.0 b5p7 test #7 () ruvit (for now, the de facto standard in South Korea)
nanasigroove2 beta (Toy Musical 3 Ver.2.2) nanasi2
forgetalia# () fgt#
Feeling Pomu Second Ver 0.8001 pomu2
charatbeatHDX VIOLET (v1.05) HDX
Angolmois 2.0 e5cea53a2cbd Angolmois
Angolmois Rust Edition () Angolmois
Sonorous 0.1.0-pre () Sonorous
Editor:
BMS Creator 2.0b1 BMSC
beditor 1.3.1 beditor
GDA Creator Professional Edition Ver.0.24 GDAC2
GDAC2 lane-script for nanasigroove-extended-command 774gsc (download is impossible now)
BMx Sequence Editor 1.3.8 BMSE
BMx Sequence Editor dttvb-1.3.8 ( ver.) BMSE (visualization of LN)
iBMS BMS Creator 3.0.5 Delta iBMSC
DTXCreator 026 () DTXC
Viewer (obsolete):
BMS Viewer 2.0 BMSV
BME(BMS) Viewer 0.04 BMEV
nBMplay v0.26a nBMplay
in_bm 1.17 (WAview) WAview (plug-in of Winamp ()
o2play o2play
Viewer (current):
uBMplay 1.5.2 uBMplay
PMSee-V v2.2.3 PMSee-V
BMIIDXView2010 v2.14 IIDXv
Others (obsolete):
otama Ver.0.991 otama (bullet curtain)
NINJA AGENT GALLI ver1.03 GALLI (action game)
BMS Printer Ver.0.01 Pre-Release bmsPRN
bms2wav 0.07b / 0.07c bms2wav (download is impossible now)
bme2wav BETA 13 bme2wav
BmsToAvi 0.03c bms2avi
BGAEncoder 0.2a BGAenc (download is impossible now)
in_bm 2.01 in_bm2 (plug-in of Winamp)
BMS/BME/EMS plugin for KbMediaPlayer version 1.0r13 bmse.kpi

KbMedia Player Version 2.63a contains this

Others (current):
bmx2wav 1.3.3 bmx2wav
PMChr-V v4.0.2 PMChr-V
woslicerII (wav-file slicer) woslicerII
woslicerII (bug-fix version? ) woslicerII
woslicerIII (requires .NET Framework 4.5 (Windows Vista or later)) woslicerIII
BMx Outliner (for now, #RANDOM / #SWITCH viewer) outliner (web apps)
Starry Music Beat ver1.03 SMB (for iOS)
BGAEncAdvance Ver0.034 BGAEncAdv
bms diff tool diff (web apps)
lr2_pmsview_helper LR2PMS
to be tested:
o2mania 1.2.0 o2mania
MyO2 MyO2 (Since it seems that I received warning, I do not indicate URI.)
D3beat ver1.1 (jubeat style / Windows7 or later) D3beat
Invisible Object to Landmine Object Converter 3-4toD-E
Sp2Dp ver_ SP2DP (download is impossible now)
BMSE ClipBoard Object Data Format to NoteDrop Converter BM-ND (web apps)
Be-Music Helper (beta 4′) (Windows Vista or later) bmhelper
Mid2BMS Mid2BMS
[tentative name] [suspended] TechnicalGroove techGrv

latest collection:


Memo about BMS Format Specification

About the minimum requirements which specification indicates:

  • The following is a summary of specification:

    • This file format was devised by Urao Yane and NBK in 1998.
    • Anyone can use this format freely.
    • The line which begins with # is the command line. All the rest are ignored (use for comments).
    • The command lines are case-insensitive.
    • The command lines have two kinds, the header sentence and the channel sentence.
    • This BMS file is compiled at runtime, so we can order any lines freely.

      • Quotation person notes: The header can be described anywhere in BMS.
      • Quotation person notes: The header is not necessarily described in front of the channel sentence.
  • However, the details of specification are implementation-dependence.

    • For example, some implementations are case-sensitive in particular cases. e.g., #LNOBJ XX
    • There are also implementations that can not recognize any lowercase <HEADER>. (O2play)

About detailed implementing which specification does not indicate:

  • The header sentence uses one half-width space as delimiter which divides the header and the value.

    • #header value = # + header + + value
    • Some implementations can also use a tab character as a delimiter.
    • Some implementations permit continuous white-space characters as one delimiter.
    • Some implementations permit the indent which used white-space characters.
    • Some implementations which do not support those features may make a mistake in the parsing of BMS.
  • The channel sentence uses one half-width colon as delimiter which divides the channel and the value.

    • #xxxCH:00112233 = # + xxx + CH + : + 00 + 11 + 22 + 33
    • xxx: number of measure [000-999]
    • CH: the channel of the target to operate
    • 00, 11, 22, 33: The index which consists of the alphanumeric character of two characters corresponding to each object.

      early: hexadecimal number16*16 (256)[0-9A-Fa-f][0-9A-Fa-f]
      pre-modern: limited base3616*36 (576)[0-9A-Fa-f][0-9A-Za-z]
      modern: base3636*36 (1296)[0-9A-Za-z][0-9A-Za-z]
    • The value which consists of some “indexes” divides a measure at an equal interval.
    • If four indexes are described, measure will be equally divided into four. It means having specified the rhythm “four quarter notes”.
    • 00 is a musical rest symbol.
    • The header corresponding to other indexes is dependent on a channel. It may be the definition of #WAVxx or #BMPxx or others.
  • The musical score file is the plain text file substantially. If the filename extension TXT is changed into BMS, BMS apps will recognize musical score files.

    • The character encoding of BMS file is not indicated by specification. This fact causes the problem on which DBCS is garbled. (mojibake)
    • Most Japanese BMS files are written by Shift_JIS.
    • Many Japanese BMS apps do not support multilingual encoding.

      • When the value of BMS command contains DBCS, the value may be garbled (mojibake).

        However, when OS is Japanese version Windows, DBCS of Shift_JIS is displayed correctly as it happens.

      • When a filename and a directory name contain DBCS, BMS apps may malfunction. But in winJP, as it happens, the DBCS path of Shift_JIS succeeds.
      • In winJP, the example with which BMS using JIS (ISO-2022-JP) or EUC-KR brought malfunction to LR2 and BMX2WAV is known.
    • The only character set safe for all implementations is ASCII (ANSI). We should not use DBCS at least to a filename and a directory name.
    • ruvit, iBMSC, IIDXv (2.13+), HDX (0.98+), Sonorous, BGAEncAdv, and TechnicalGroove are supporting multilingual encoding.

      • However, it does not guarantee that a character string is displayed correctly.
      • The garbled characters problem will not be avoided until UTF-16 becomes mainstream of BMS.
      • Even if UTF-16 spreads, this problem is not solved completely.
      • YEN-SIGN problem, WAVE-DASH problem, WON-SIGN problem, GB_18030, etc...

      #TITLE (^^)♥♡♠♤♣♧♦♢♨☀☁☃☄☊☚☠♘☲☸♩♪♫♬♭♮filename: foon♥.bms

Behavior in general implementation:

  • When the same header duplicates, the side near EOF is adopted. For example:

    remarkssample BMS code
    (line number 100)#TITLE ABC
    (line number 200)#TITLE DEF

    The value of #TITLE of this BMS is “DEF”.

    • This rule is applied to all the headers except #ExtChr, #STP, #WAVCMD, #OPTION, and control flow.
    • This rule may not be applied to #SUBTITLE, #SUBARTIST, #COMMENT, and #LNOBJ.
    • This rule is applied also to the channel #xxx02 (length of measure).
    • However if #xxx02 duplicates, ruvit (b5p3 and below) will adopt the first line. (fixed in b5p4)
  • However, the following commands are exceptions and a little complicated processing is required.

    • These can describe two or more same commands:

      • #ExtChr: [BM98] Extended Character
      • #STP: [bemaniaDX] STOP sequence
      • #WAVCMD: [MacBeat] pseudo-MOD effect (about MOD: )
      • #OPTION: [nanasigroove] forced OPTION
      • #SUBTITLE: [nanasigroove] explicit subtitle / [limited Sonorous: allowed Multiplex definition]
      • #SUBARTIST: [LunaticRave] helpers' name / [limited TechnicalGroove and Sonorous: allowed Multiplex definition]
      • #COMMENT: [feelingPomu] caption on selecting screen / [limited Sonorous: allowed Multiplex definition]
      • #LNOBJ: [Rhythm-it] Termination of LONGNOTE / [limited TechnicalGroove: allowed Multiplex definition]
    • Control flow is more special. In BMS notation, only the command shown below constitutes a block structure.

      • #RANDOM or #SETRANDOM

        • #IF
        • #ELSEIF
        • #ELSE
        • #ENDIF

        #ENDRANDOM

      • #SWITCH or #SETSWITCH

        • #CASE
        • #SKIP
        • #DEF

        #ENDSW

  • When the same channel in the same <measure> duplicates, both are compounded.

    • However, this behavior is not applied to #xxx01 (BGM channel), #xxx02 (length of <measure>), and #xxxA6 (#CHANGEOPTION).
    • The multiple BGM lines must be interpreted as multiple BGM lines. They must not be merged.
    • When two or more #xxx02 channel lines compete, the line of the side near EOF is adopted.
    • Dynamic option change channels have the same character as BGM channels, in order to enable change of two or more options simultaneously.
  • Priority is given to a side with a large line number. But 00 does not overwrite an old place. For example:

    remarkssample BMS codecomment
    (line number 100)#00113:11111111 // 1100110011001100
    (line number 200)#00113:0022332255224400 // channel 13 of #001 overlapped
    (line number 300)#00113:0066 // channel 13 of #001 overlapped
    parsing result:#00113:1122332266224400// all 3 lines are merged

    This is BM98k's behavior prepared in order to make a complicated rhythm easy to write.

    • This technique which divides and describes a line (on the assumption that it is finally merged) enables very interesting expression.
    • The work which finished it most exhaustively is オートメーション工場 ()
    • The work which finished it most unobtrusively is Netzwerkgenen ()
  • But unfortunately, the half of implementations do not meet this requirements specification. ( ... Is this really requirements specification? )

    • Implementations which do not support duplication of channel lines may not be unable to count the number of musical notes correctly.
    • pomu2 has the function to change the arrangement of a musical score automatically.

      But this function will not operate normally, when channel lines are duplicated.

      (the example which duplicated the original musical score 5 times: )

    • LR2 has a function similar to pomu2 and it has the similar bug. LR2 cannot process duplication of land-mine channels well.
  • BMS parser may have to read the file in which three kinds of line feed codes are intermingled. (CRLF, CR, LF)

  • BMS parser may need to read EOF which does not sandwich a newline character.

    • For example: #08401:ZZ[EOF]

    We will find many inline-EOF more than we expected.

  • When an unjust value is given to a channel line, specification has not defined how it should interpret.

    sample BMS coderemarks
    #00111:0011文字2233 // mixing of DBCS
    #00112:0011223 // data length which is not a multiple of 2
    #00113:+-;$%&'()/ // the special character which cannot be used for #WAV-index
    #00114:1100...(over 500000 characters)...011
    // too long a character String
    #00115:11  ;comment // DTX's inline-comment (GDAC2 cannot be parsed correctly)
    #00102:12.375f // The option flag (for explicitly specifying the floating-point type) in IIDXv and HDX
    #00121:  FFFFFF  OOOOOO  OOOOOO  NNNNNN
    #00122:  FF      OO  OO  OO  OO  NN  NN
    #00123:  FFFFFF  OO  OO  OO  OO  NN  NN
    #00124:  FF      OO  OO  OO  OO  NN  NN
    #00125:  FF      OOOOOO  OOOOOO  NN  NN
    // Shift_JIS art ()

    Some implementations (nazo, uBMplay, LR2, etc) try these interpretations. The method is unknown. The definition of an appropriate interpretation is also unknown.

  • BMS parser may have to read the following header sentences.

    sample BMS coderemarks
    #stopA 192// zero suppression of the index of a definition slot
    #stop11 -192// the value of a negative number
    #stop22// an empty definition slot with delimiter
    #stop33// the omission of the delimiter which divides a command and a value
    #if⇥   4// delimiter by a Tab character
    #bpm 2.147484e+0.9// exponential notation
    #bpm99 12.375f// The option flag in IIDXv and HDX (BMSE hangs-up)
    #WAV60 ura_63.wav

    // actual filename is ura_63..wav

    ()

    #bga01⇥ fz512␣␣256␣␣768␣␣384␣␣0␣␣␣64␣␣big.bmp // the layout which uses two or more tab characters or half-width spaces
    #bmp big.bmp // DBCS index of a definition slot
    #random 10
    ⇥   #if 1
    ⇥   ⇥   #wavZZ foo.wav
    ⇥   #else
    ⇥   ⇥   #wavZZ bar.wav
    ⇥   #endif
    #endrandom
    // the indent by two or more tab characters or half-width spaces

    Some implementations permit the above value as a valid thing.

    However, another implementation considers that these are invalid values.

    Specification has not defined what kind of value is invalid.

  • Modern implementation is supporting 1295 (1296) kinds of slots.

    The value of each header is defined to the index of [01-ZZ] (or [00-ZZ]).

  • <measure> is expressed by the 3 number of digits. General implementation is supporting [#000-#999].
  • Some exceptions and notes:

    appsremarks
    BMSV[000-511]
    DDR[000-998]
    bemaniaDX[000-399]
    GALLI[000-399]
    BGAenc[000-249]
    BMEVBMEV will be forced to terminate, if the musical score which has the contents only in #000 is opened.
    RDMRDM cannot scroll the musical score which has the contents only in #000.
    GDAC2GDAC2 is overflowed by pasting objects over #170. (fixed in Ver.0.20)
    LR2

    Supposing visible (or long-note) objects exist in the head of #000, LR2 will insert the empty <measure> of the same length as #000 just before #000.

    (This is one of the methods for avoiding “perplexing a user at the time of a game start”. )

    Although this function is convenient, if an object exists in #000 and #999, a musical score does not finish normally.

    pomu2

    As long as sound (key-sound) is sounded, pomu2 does not make a musical score finish.

    However, if sound is still sounded even if a musical score passes over #999, pomu2 will do forced termination.

    otama

    The document about otama () has the following description: Measure's maximum number is 1024.

    However, this description is mysterious. #1024xx will cause a bug.

    MyO2

    382. [ニコニコ動画] 組曲 is done forced termination, before a musical score finishes. Is this unrelated to <measure>?

    The following is quotation of an error message. Since character was garbled partially, it omitted.

    TypeError: Error #1010: A term is undefined and has no properties.
            at ::scorenum/()[E:\popstage_5key\com\scorenum.as:44]
            at ::scorenum/setNum()
            at ::o2jam/()[E:\popstage_5key\com\o2jam.as:2951]
            at ::o2jam/()[E:\popstage_5key\com\o2jam.as:2630]
            at ::o2jam/()[E:\popstage_5key\com\o2jam.as:3056]

About filename extensions of musical score file of BMS Format

Outline:

  • Typical filename extensions are as follows.

    caution: Since there are various views about the origin of these filename extensions, I cannot have responsibility. These are trivial names rather than abbreviations.

  • In recent years, these filename extensions only exist mostly for backward compatibility.
  • Implementations without the channels which a musical score needs is filtered by a filename extension.
  • Since modern implementation was supporting all this, the necessity for filtering faded.
  • If it is modern implementation, we may change the filename extension of all the musical scores into BMS.

    (But in 9KEYS, we have to change the suffix into PMS (*.pms).

    fgt++/fgt# will display a musical score as BMS-DP (10KEYS), when not doing so. Similarly, LR2 will only display BME-SP type 9KEYS as BME-SP. )

  • However, the filename extension is useful when searching musical score files in Windows Explorer.

    • 5K is BMS.”
    • 7K is BME.”
    • LN is BML.”
    • 9K is PMS.”

    For those who know the context of BMS, it is easy to understand this naming.

    (These are intelligible summaries although these include misunderstanding. )

  • There is a format derived from BMS besides these. Please refer to for details.

    • MGQ: 24KEYS BMS which uses LONG-NOTE channel. “Music Game Quest” came up with pseudo-KEYBOARDMANIA.
    • MBM: MacBeat MOD. The BMS musical score using the #WAVCMD must change a filename extension into MBM.
    • EMS: 24KEYS BMS based on AngelicPianizm type. KbMediaPlayer (bmse.kpi) is supporting this format still now.
    • KMS: 24KEYS BMS based on KeyMani type.
    • BAS: BMS-2 Format (BM-A4 & beat arranger extension)
    • PHX: PHOENIX type (unknown for details)
    • MGF: beatmaster [standard] type (unknown for details)
    • BMB: beatmaster [bms] type (unknown for details)
    • PMB: beatmaster [pms(Do-Re-Mi Mania)] type (unknown for details)
    • D2B: beatmaster [D2R] type (unknown for details)
    • DEE: (unknown for details)

    Seeing of almost all these were lost in recent years.

    However, the following formats accomplish original evolution and still in the process of evolution now.

    • DTX: DTXMania (the developed type of DrumMania)
    • GDA: BandJam (like GuitarFreaks & DrumMania)
    • G2D: SessionStream (extended GDA)
    • GFS: Guitar Friends 98

    Please refer to official site for the details of DTX series:

  • The details of typical filename extensions of musical score file are described in the following sections.

BMS:

The origin of BMS was started as imitation of beatmania. ()

It had five keys (x2) and one turntable (x2).

historical circumstances:

: beatmania started operation.

: Urao Yane showed the draft of “Be-Music Data Format” to NBK. This is the foundation of today's BMS format.

: NBK created the musical score file of HOUSE-music based on the Urao Yane's draft, and submitted it to Urao Yane.

: At the offline gathering held in the penny arcade “CIRCO PORTO”, Urao Yane exhibited BM98 ver 1.00.

: Urao Yane created his own homepage, and BM98 ver 1.03 was released on the World Wide Web.

: Kazutoshi Takata released BMS Viewer Version0.8.

: Urao Yane stopped public release of BM98 temporarily.

: TIX released BMS Creator v0.02.02. (update history) ... We were able to be released from the text-editor at last.

: Urao Yane exhibited BMS Format Specification.

originBM98
supportall the implementations of BMS
header #PLAYER n, #GENRE string, #TITLE string, #ARTIST string, #BPM n, #MIDIFILE midiFilename, #PLAYLEVEL n, #RANK n, #VOLWAV n, #WAVxx audioFilename, #BMPxx imageFilename, #TOTAL n, #RANDOM n, #IF n, #ENDIF, #ExtChr SpriteNum BMPNum startX startY endX endY [offsetX offsetY [x y]]
channel #xxx01-06, #xxx11-17, #xxx21-27, #xxx31-36, #xxx41-46

The details about headers are in another section.

about the details of channels:
numberobject to changeremarks
#xxx01 BGM

The file defined as #WAVxx is placed as audio-objects which should sound automatically.

Only this channel can describe multiple lines to the same measure. #xxx01 is not merged.

#xxx02 MEASURE-LENGTH

#xxx02 operates Meter.

  • The length of measure is specified with an integer or a floating-point.

    • The value 1 is 4/4 meter. #xxx01:11223344 Length is equivalent to four quarter-notes.
    • The value 2 is 8/4 meter. #xxx01:1122334411223344 Length is equivalent to eight quarter-notes.
    • The value 0.75 is 3/4 meter. #xxx01:112233 Length is equivalent to three quarter-notes.
    • The value 0.015625 is 1/64 meter. Length is equivalent to only one hemidemisemiquaver.

      1/64 is the minimum length that BMSE can edit.

    • The value 0.01 is the length equivalent to 1% of usual quadruple measure.

      BMSE rounds this value 0.01, because BMSE handles the length as multiples of 0.01625.

      BMSE rounds a value 0.01 and changes it into 0.01625

    • Since BMSE and beditor relates length with a musical note and handles it, it is easy to write a musical score by a musical view. That is, BMSE and beditor are good at edit of unusual time signatures.
    • Since BMSC and GDAC2 handles length as simple length, they are easy to write a musical score by the percentage. That is, they are good at edit of a scroll speed change unrelated to music.

      BPMlength of measureratio = afterBPM / standardBPM
      1211.008333333333333121/120 (BMSE cannot interpret correctly)
      1201120/120 (BMSE can interpret correctly)
      1190.991666666666666119/120 (BMSE cannot interpret correctly)

      In the situation which does not change actual BPM of music, the stage effects which change only the scroll speed of a musical score are commonly called ソフラン (soft landing) in Japan. The joke BMS about this can download at a joke site.

    • iBMSC (3.0 or later) is a hybrid of both. The rhythm which we cannot edit does not exist any longer theoretically.
  • In BMS, the value of #xxx02 acts only on the #xxx.

    If music is triple measure completely, it is necessary to specify #xxx02 to all the measures.

  • In DTX, the value of #xxx02 becomes effective until another #yyy02 appears.

    If music is triple measure completely, what is necessary is to specify #00002:0.75 only once.

  • In BMS, the default value 1 is implicitly applied to the <measure> on which this channel was omitted.
  • If #99902 exists, nazo will not finish a musical score until scroll reaches #999.

    • If #xxx02 is described behind the end point of music even if music has already finished, nazo will have misunderstanding as if the object which has not been processed yet remained.
    • In BMSE, the “Beat” tab's “All” button Selects all #000-#999.
    • If 3/4 is specified from this state, all #000-#999 will be changed into 3/4 meter.
    • For example, this function must be very convenient when editing the musical score of triple measure.
    • However, because nazo is foolish, we cannot entrust work to this function.
    #TITLE test Apps which continue for 33 minutes
    #BPM 120
    #00111:01
    #99902:1
    nBMplay, BMEV, DDR, RDM, nazo, IIDXv, HDX, Angolmois
  • Although BM98 was implementing this channel, it was not shown in specifications.

    Probably owing to it, the concept of Meter did not spread to some games.

#xxx03 BPM [01-FF] placed as an object is interpreted as the integer BPM of [1-255]. 00 is a musical rest symbol.
#xxx04 BGA-BASE The file defined as #BMPxx is placed as image-objects which will be displayed during the usual play.
#xxx05 Extended Object The object defined by #ExtChr is placed. Only BM98 supports this.
#xxx06 BGA-POOR The file defined as #BMPxx is placed as image-objects which will be displayed if note is overlooked.
#xxx11 1P-side KEY1 The file defined as #WAVxx is placed as audio-objects which should be performed by player.
#xxx12 1P-side KEY2 ditto. That is, #xxx1n is a lane for musical note symbols which should be performed.
#xxx13 1P-side KEY3 ditto. The musical score for 1P is displayed on the left-hand side of a screen.
#xxx14 1P-side KEY4 ditto. KEYs are five buttons which a keyboard type input device has.
#xxx15 1P-side KEY5 ditto. The player must hit the KEY corresponding to directions of a musical score.
#xxx16 1P-side SCRATCH ditto. #xxx16 is a lane for notes which should be performed by rotating a turntable.
#xxx17 1P-side FREE-ZONE
  • #xxx17 sets the section which can scratch a turntable freely.

    • The section from “the position which placed the object” to “the length of one quarter note” becomes one FREE-ZONE.
    • If a new object is placed in #xxx17 before a FREE-ZONE closes, the length of the FREE-ZONE will be extended.
    • If the section set by #xxx17 contains the SCRATCH objects of #xxx16, SCRATCH objects will be displayed overlying a FREE-ZONE.

      #00611:0011000000000000
      #00614:1400001400000000
      #00616:0000000000160000
      #00617:0000000017000000

      “u gotta groove” #006 (from beatmania 2ndMIX)

    • Whatever the length, one FREE-ZONE is counted as one note which should be performed.
    • Whatever the number, the turntable objects in a FREE-ZONE are not counted to the note which should be performed.
    • When there are one or more turntable objects in one FREE-ZONE, the judgment branches to three kinds.

      1. When they are all performed to the best timing, “the best score to one note” is obtained.
      2. When a turntable is not once scratched in the FREE-ZONE section, a score is not obtained.
      3. Other case means one note was performed to the timing which is not bad. A so-so score is obtained.
    • When a turntable object does not exist in one FREE-ZONE, the judgment branches to two kinds.

      1. When a turntable is not once scratched in the FREE-ZONE section, a score is not obtained.
      2. Other case means one note was performed to the timing which is not bad. A so-so score is obtained.

      When FREE-ZONE without turntables exists in a musical score, “a perfect result” is not obtained by any means.

    • How are they related about the sound assigned to #xxx16, the sound assigned to #xxx17, and the sound actually sounded? Although I must have investigated about the affair before, I cannot remember the result.
    • The same rendering as beatmania is expected in implementation which supports the FREE-ZONE.
    • Only BM98, BMSC, BMSV, nBMplay, Aqua (?), and fgt (the first version) are supporting this specification.

      • Too complicated specification requires extremely hard work of programmers.
      • It is difficult to make FREE-ZONE live together with the concept of score.
      • FREE-ZONE was removed in beatmania 3rdMIX:
    • I am interested in modern FREE-ZONE. What kind of specification should it define?

      • It has channels about itself like long-note, and will set the section by the starting point and the end point.
      • FREE-ZONE must be applicable also to the line of not only turntables but keys.
      • FREE-ZONE must be separated as objects unrelated to the count of the score and notes.

      However, the better format will appear. Because all the objects should be able to have not a point but the section.

  • In recent years, the channel #xxx17 is hardly used as FREE-ZONE.

    • nanasi and Angolmois use this channel for FOOT-PEDAL objects.
    • nanasi, pomu2, and Angolmois use this channel as one of the buttons of 18KEYS (PMS-DP).
    • LR2, PMSee-V, pomu2, and Angolmois use this channel as one of the buttons of 9KEYS (BME-type-PMS).
#xxx21-27 2P-side Visible object

Musical note symbols which a right-hand side player should perform.

21-25 are keyboard controls, 26 is a turntable, and 27 corresponds to a FREE-ZONE.

#xxx31-36 1P-side Invisible object

The invisible object is not displayed, is not judged and is not added to a score.

This is for changing into another sound the sound assigned to the key.

  • For the ad lib performance by a player.
  • For Easter eggs.
  • If two invisible objects sandwich one visible object, it can jeer, when the timing of a player is out of order.
  • By placing empty invisible objects, it is possible to make a player mute. For example, in a quiet scene, it is useful.
  • In Angolmois, the explosion sound which cannot usually be changed can be changed to some extent by putting an Invisible object and a landmine object on the same position.
#xxx41-46 2P-side Invisible object
  • Because of the property, the FREE-ZONE cannot have invisible objects.
  • Therefore, the channels #xxx37 and #xxx47 are not supported. (In BM98, it becomes compile error)
  • But implementation which supports #xxx17 as one of the keys instead of FREE-ZONE is supporting #xxx37.
  • nanasi and pomu2 which support 18KEYS are supporting #xxx47 as invisible objects.
  • Angolmois can customize all the #xxx[1-6][1-Z] by the “--key-spec” option as playable lane. Therefore, Angolmois supports all the #xxx[30-4Z] as Invisible objects.
  • Some implementations have bugs about invisible objects.

    • pomu2: When the LIGHT option of a DOUBLE series is applied, the score can exceed theoretical perfect one.
    • ditto: Application of the AutoPlay mode will sound invisible objects.
    • RDM and the old version of ruvit: Invisible objects are ignored.
    • ditto: If a player performs ad lib in the position where invisible objects exist, it will be judged as if it was not able to process visible objects. That is, the groove gauge will decrease.

BME:

beatmaniaIIDX had seven keys (x2) and one turntable (x2). ()

historical circumstances:

: beatmaniaIIDX started operation.

In order to support 7KEYS, Project2DX which is an extended format of BMS was proposed by Urami.

  • This format uses channel #xxx21 as “1P-side KEY6 in 7KEYS mode”.
  • This format uses channel #xxx22 as “1P-side KEY7 in 7KEYS mode”.
  • By using the #ExtChr, musical scores change the visual item of BM98 directly. That is, 5K-DP is displayed like 7K-SP.
  • This is pseudo-7KEYS by which the musical score side changes the display of the client side. Substantially, it is completely the same as BMS.

Project2DX had many problems.

  • #ExtChr is a BM98 proprietary extension. When BMS apps other than BM98 appeared one after another, this format faced the problem of portability.
  • The musical score of each needed to have the information for Sevenize, respectively. Although this is fit for customization, it is only a stopgap.
  • The specification of #ExtChr was only a minimum memo. The way to Sevenize was prepared only for the programmers.
  • This format cannot support the musical score for the Double Play of 7KEYS.

    Although it was a fact that DP was supported, I failed in finding the details about it.

FlashTerminal which is an extended format of BMS was proposed by Tomohiro Fujii.

  • The method of using the reservation channels of BMS for 7KEYS was devised. (#xxx18-19, #xxx28-29)
  • I do not know the other details about this format.

In order to support 7KEYS completely, BME which is an extended format of BMS was proposed by TIX.

  • BME is the format which made it possible to unify the channel of FlashTerminal and BMS, and to edit it by BMSC.
  • If the conventional implementation supports extended channels, it is necessary to newly change a design.
  • The rule which changes a filename extension into BME was specified so that implementation which does not change a design might not read “the musical score file which is using the extended channels”.
originally:

Strict BME does not include the feature which BMSC does not support. (via )

When the musical score contains the command which cannot be edited by BMSC, it is unsuitable to use BME as a filename extension.

For example: #STOPxx n, #BPMxx n, #WAV01-FZ, #BMP00-FZ, #BGA00-ZZ, #xxx51-69, etc.

However, BME is less unsatisfactory than BMS. Because the above-mentioned command is an “extended” command in a broad sense.

supplement by a quotation person:

The conclusion of a previous column is: “The act which forces sharp distinction of BMS and BME is no longer meaningful.”

I agree with his opinion. It is because the extended command is already natural.

And it is because implementation which does not support an extended command is no longer used.

Furthermore, BMSC did not support #RANDOM which is a fundamental command.

“Strict BME” does not have the perfect upward compatibility to BMS. I judged that the adherence to the origin and strictness was meaningless.

By the way, I am not opposed to using BME properly as a pronoun of 7KEYS. Although it is not strict, it is more useful than “strict BME”.

originBMSC
supportall the BMS implementations other than BM98, BM98k, BMSV
header

In addition to the commands of BMS, most implementations are supporting the following extended commands.

(It is unrelated to regulation of BME that these are supported.)

name & valuesummaryBMSCorigin
#STAGEFILE imageFilenamesplash screen 640x480YesBM98k extend
#BPMxx nover255 and/or decimal fractionNobemaniaDX extend
#BGAxx BMPnum x1 y1 x2 y2 dx dy partial trim & display No BM98de extend

Since many implementations did not support #MIDIFILE and #ExtChr, they became a de facto non-standard command.

channel

In addition to the channels of BMS, most implementations are supporting KEY6 and KEY7.

numberobject to changeBMSCorigin
#xxx07BGA-LAYERYesBM98k extend: image objects overlying #xxx04
#xxx08Extended BPMNobemaniaDX extend: real number BPM objects defined by #BPMxx
#xxx18-191P-side Visible KEY6 / KEY7YesFlashTerminal extend
#xxx28-292P-side Visible KEY6 / KEY7YesFlashTerminal extend
#xxx38-391P-side Invisible KEY6 / KEY7YesFlashTerminal extend
#xxx48-492P-side Invisible KEY6 / KEY7YesFlashTerminal extend

Since many implementations did not support #xxx[1-4]7, they became a de facto non-standard command.

BML:

EZ2DJ had five keys (x2), one turntable (x2), two effector-buttons (x2), one footpedal (x2), and the feature of Long-Note. ()

about Long-Note:

On BMS scene of Japan, generally the Long-Note is abbreviated as LN. This document follows that custom.

LN is a note which needs to hold an input state for a definite period of time which was specified. For example, press and hold the key.

The start point and the end point are set to each LN. In many games, each LN is displayed just like a long stick as a variable-length note.

Action required of a player is dependent on the context of the game which a musical score imitates.

Although LN is the operations which hold an input state, another game may require the operation which repeats an input at high speed.

The another name and the feature about LN may be given in the original game. Some typical kinds are as follows:

formal namethe first appearanceremarks
Long Notes : Ez2DJ THE 1st TRACKS

Do keydown at starting point and hold it.

Keyup at end point is unnecessary. was needed at first, but no longer needed.

Long Notes : KEYBOARDMANIA Do keydown at starting point and hold it. Keyup at end point is necessary.
Keep-kun (キープ君) : pop'n music MICKEY TUNES

Not variable-length note but fixed-length note is displayed.

Pushed note is displayed like a Progress-bar. This is a required time gauge.

(Name unknown) : Taiko no Tatsujin

All the objects that have length are objects which should be hit repeatedly.

This is not a symbol which divides one action into keydown-keep-keyup.

This is a symbol of countless keydown action. This is like a cookie-cutter.

(Probably since this time, about each long obj, names correspond to natures.)

freeze arrows : DDRMAX -DDR 6thMIX-

Hold treading on a panel. Putting leg up at end point is unnecessary.

While it is less than quarter note, even if we change step, freeze arrows don't break off.

Probably, the judgment is eased in consideration of the operation of “treading on a panel”.

(In a sense, this is the combination of press&hold and continuous-hits.)

one rotating scratch : beatmania 7thMIX

Rotating 360 degrees of turntables, by the time it reaches an end point must be completed.

The more the angle turned in the section is close to 360 degrees, the more a score.

Stopping rotation exactly at end point is unnecessary.

Analog Notes : DJMAX Portable

Continue turning the analog pad of PSP. While the input continues, a combo increases.

It is necessary to continue an input until it arrives at end point.

Holding Long Note : DJMAX TECHNICA Hold finger on the circular note until the time line passes the blue line at the end of the note.
Dragging Long Note : DJMAX TECHNICA Drag the circular note along the path while keeping it on the time line.
Chain Note : DJMAX TECHNICA Hit all notes in the path when time line passes over them.
Repeat Note : DJMAX TECHNICA Keep pressing the circular note each time the time line is on a little purple line that is part of this note.
Charge Notes : beatmaniaIIDX 17 SIRIUS Do keydown at starting point and hold it. Keyup at end point is necessary.
Backspin Scratch : beatmaniaIIDX 17 SIRIUS Do rotating at starting point and keep it. Backspin at end point is necessary.
---- touch-device series under investigation

BMS apps other than [nanasi, HDX, Angolmois] are not judged an end point of LN. That is, keyup at end point is unnecessary.

  • However, I think that this behavior is not suitable to UI of “expressing a rhythm as a point and relating a point with action”.
  • In my personal opinion, if a game system does not force keyup, LN should not display an end point explicitly --- the appearance contrary to intuition should avoid.

LN brings about confusion about how to count notes. This is troublesome for programmers and noters and musical score collectors.

  • In some games, LN is counted as one note. That is, LN section (the pair which consists of a start point and an end point) is one note.
  • In some games, a start point and an end point are counted as a respectively separate note.
historical circumstances:

: beatmania started operation. ()

: pop'n music started operation. ()

: Dance Dance Revolution Internet Ranking Version started operation. ()

: GUITARFREAKS started operation. ()

: beatmaniaIIDX started operation. ()

: Ez2DJ THE 1st TRACKS -R U Ready to Insida DJ Box?- started operation. ()

: drummania started operation. ()

: pop'n stage started operation. ()

: KEYBOARDMANIA started operation. ()

: Dance Maniax started operation. ()

: ParaParaParadise started operation. ()

: 太鼓の達人 started operation. ()

Many formats derived from BMS appeared and disappeared at this time. Probably, the idea which imitates LN was also contained in those some.

In order to express the musical score of all the above games comprehensively, MGQ which is an extended format of BMS was proposed by quest in 2001.

  • This format extended the channel number to the hexadecimal number. It is because KEYBOARDMANIA has 24KEYS (x2).
  • This format newly reserved the channels for LN. It is because some games featured LN.
  • This format defined the notation of LN. However, LN of MGQ form was un-intuitive and difficult to write.

: In order to solve the problem of MGQ, NvyU proposed LN of RDM form. Moreover, it was implemented to RDM 1.21.

  • This became a de-facto standard of LN in the present. This is notation which simplified MGQ.
  • This notation uses #xxx51-69 among the channels which MGQ proposed.
  • All the implementations that support LN are implementing this notation.
  • RDM in those days needed to specify 1 or 2 to #LNTYPE, in order to distinguish notation of RDM-LN and MGQ-LN.

: RDM 1.61 also supported the notation of #LNOBJ xx as RDM type #2.

  • #LNOBJ xx is the command which simplified LN of RDM form further. #LNOBJ xx does not need the channel #xxx51-69 any longer.
  • The object of the index specified as #LNOBJ is defined as an end point symbol of LN.
  • The object which is just before that by putting an end point on the channel #xxx11-29 is interpreted as a LN start point.
  • Implementation which does not support #LNOBJ xx interprets LN end point as a usual note. The file name extension BML was prepared as a filter so that implementation which does not support #LNOBJ xx might not misread a musical score.
  • It is recommended that the musical score which uses #LNOBJ xx changes a filename extension into BML.
  • Strict BML means the musical score which contains only #LNOBJ xx as LN.

    LN of the channel #xxx51-69 of a RDM notation is not included in definition of BML.

  • If the filename extension is changed into BMS or BME, strict BML can be edited by BMSC. (If all the indexes are hexadecimal numbers. )

    Originally, BML is the format defined in order to edit LN by BMSC. Therefore, strict BML can become a subset of BME.

: RDM 1.7 defined #LNTYPE 1 as a default value.

  • Thereby, the #LNTYPE declaration became unnecessary any longer. #LNTYPE 2 is required only when using MGQ-LN.
  • Only the BMS implementation which supports both MGQ-LN and RDM-LN needs the #LNTYPE command in a real meaning.

    (For now: RDM, MGQ, WAview, in_bm2, ruvit, Angolmois)

  • Quotation from ruv-it! | support page (free translation by a quotation person):

    RDM and ruvit are continuing support of MGQ-LN for two reasons.

    1. Because MGQ is a pioneer of LN.
    2. Because RDM (1.2 and below) was temporarily using it.

    Most implementations do not support MGQ-LN any longer. If possible, please do not use MGQ-LN any longer.

Some of implementations which do not support #LNOBJ xx read the musical score whose filename extension is BML.

  • This is strictly a violation of the BML specification, but useful to the implementations which do not know the channel #xxx51-69.
  • #LNOBJ is BML --- it is strictly right. However, that rightness is not so useful any longer nowadays.
  • LN is BML --- it is misunderstanding. But it is simple and intelligible and practical.
strict BML:
originRDM
supportRDM, nazo, nazoZZ, bme2wav, LR2, nanasi, ruvit, fgt++, fgt#, pomu2, uBMplay, PMSee-V, bmx2wav, iBMSC (3.0 or later), Angolmois
channelsame as BME
header
name & valuesummaryoriginremarks
#LNOBJ xx using #WAVxx as LN end point symbol RDM extend we should specify index by uppercase. (for compatibility)
loose BML:
originWAview
support

RDM, nazo, nazoZZ, bme2wav, LR2, nanasi, ruvit, fgt++, fgt#, pomu2, uBMplay, PMSee-V, bmx2wav, iBMSC, Angolmois

DDR (only DDR mode), WAview, in_bm2, BMSE, IIDXv, HDX, O2play, Aqua (?)

  • DDR is supporting not #LNOBJ xx but RDM-notation #xxx51-69 in ARROW mode.
  • Since DDR does not meet requirements specification of BML, DDR does not support the filename extension BML. (= DDR is strictly based on regulation)
channel

In addition to the channels of BME.

numberobject to changeoriginremarks
#xxx51-59 1P-side LN Object MGQ extend It is implementation-dependent whether #xxx57 and #xxx67 are supported.
#xxx61-69 2P-side LN Object MGQ extend
#LNTYPE 1:: RDM-notation:

It will be a LN start point if the index which is not 00 is found.

It will be a LN end point if the index which is not 00 is found next.

#LNTYPE 2:: MGQ-notation:

LN section will be opened when indexes other than 00 are found.

LN section will be filled up with indexes other than 00.

LN section will be closed when the next 00 is found.

headersame as BME

PMS:

pop'n music had nine colorful buttons, and dancing characters. ()

historical circumstances:

: pop'n music started operation.

: doremimania was released by Koutaro Izumi as a trainer which imitated KEYBOARDMANIA.

  • This software proposed and implemented the suffix PMS as proprietary extension.
  • In my guess, this PMS is an abbreviation of Piano-Music-Script. This notation completely differs from BMS. They are separate formats.
  • Therefore, compatibility is not between “PMS which doremimania supports” and “PMS which is the subsets of BMS”.
  • We are not concerned here with doremimania-PMS. (proxy for distribution of doremimania: )

: In order to support 9-buttons (9KEYS), Nekomi released feeling pomu 1.41 Test5. (ふぃーりんぐぽみゅ)

  • This software specializes in 9BUTTONS. The musical score of BMS or BME is automatically spread on nine lines at the time of a game start.
  • This software proposed and implemented PMS which is the subsets of BMS format. PMS is a musical score which specializes in 9BUTTONS.
  • PMS is the filename extension for displaying the channel #xxx11-15 and #xxx22-25 of BMS as pseudo-pop'n-music.
  • Although the suffix PMS had already existed as proprietary extension of doremimania, it is unrelated to pomu-PMS.

: feeling pomu second Ver 0.60 was released as an upgrade version of feeling pomu. (ふぃーりんぐぽみゅせかんど)

  • On the support page, Nekomi is abbreviating “feeling pomu” as “ぽみゅ” and “feeling pomu second” as “みゅに”.
  • pomu2 supported LN of both RDM-notation #xxx51-69 and #LNOBJ xx, and supported the filename extension BML.
  • More than PMS is a filter, it is required in order to force 9BUTTONS mode. It is because 9KEYS is BMS-DP substantially.

    • The method of distinguishing between BMS-DP and 9KEYS does not exist other than the filename extension.
    • Therefore, as for the musical score which specializes in 9KEYS, filename extension must be changed into PMS.
    • Furthermore, implementation which supports PMS must be able to interpret LN, even if a filename extension is not BML.
  • pomu2 also proposed and implemented 18BUTTONS (PMS-DP). This is the original feature which does not exist in the arcade versions.

    • 18KEYS uses all the channels #xxx11-29 as objects which should be hit. 18KEYS is BME-DP substantially.
    • Therefore, as for the musical score which specializes in 18KEYS, filename extension must be changed into PMS.

: LR2 beta3 090916 extended “the channels which should be interpreted when the filename extension of a musical score is PMS”.

  • In short, LR2 interprets not only BMS-DP but BME-SP as appropriate PMS.
  • pomu2 is supporting this mapping from the beginning. nanasi interprets this mapping as foot pedal mode.
  • LR2 (beta3 090916 and above) can be called from editor-apps. But when 9KEYS musical score under edit is previewed, LR2 does not apply the 9KEYS display.

    : The method of solving this problem was proposed by Misty.ls04. ()

    : “lr2_pmsview_helper” for solving this problem was released by Misty.ls04. See my article.

originpomu
support
9KEYS (BMS-DP):pomu2, WAview, in_bm2, LR2, nanasi, fgt++, fgt#, GDAC2, BMSE, uBMplay, PMSee-V, bmx2wav, iBMSC (3.0+), Angolmois (2.0a2 or later)
9KEYS (BME-SP):pomu2, LR2, GDAC2 (774gsc), PMSee-V, bmx2wav, Angolmois (2.0a2 or later)
18KEYS (BME-DP):pomu2, nanasi, GDAC2 (774gsc), bmx2wav, Angolmois (2.0a2 or later, by --key-spec)
header In order to maintain compatibility, specifying #PLAYER 3 to PMS is recommended.
channel
1 2 3 4 5 6 7 8 9 remarks
9KEYS (BMS-DP): 1112131415 22232425standard PMS
9KEYS (BME-SP): 1112131415 18191617not known or well known
18KEYS (BME-DP): 1112131415 181916171P-side (left)
2122232425 282926272P-side (right)
  • Invisible #xxx31-49 and LN #xxx51-69 and Landmine #xxxD1-E9 follow mapping of visible-object channels.
  • #xxxX7 which was channels for FREE ZONE is used.


<CONTROL FLOW>

origin: BM98 ()
support:

BM98, BM98de, DDR, RDM, MW, bemaniaDX, nazo, Mac, Aqua, WAview, in_BM2, bms2wav, bms2avi,

LR2, ruvit, nanasi, fgt++, fgt#, pomu2, nazoZZ, uBMplay, PMSee-V, IIDXv, HDX, bmx2wav, outliner, Angolmois,

BMSE (partial), iBMSC (3.0+ / partial), Sonorous, BGAEncAdv, TechnicalGroove

one level:RDM, bemaniaDX, nazo, nazoZZ, WAview, in_BM2, LR2, ruvit, fgt++, fgt#, uBMplay (1.4.6 or earlier), PMSee-V, bmx2wav
nestable:

BM98, BM98de, DDR, MW, nanasi, Aqua, pomu2, BMSE (partial),

IIDXv, HDX, outliner, Angolmois, uBMplay (1.5.0 or later), Sonorous, BGAEncAdv, TechnicalGroove

  • #RANDOM generates one of the natural numbers from 1 to n. Needless to say, n should specify a natural number.
  • The section from #IF to #ENDIF is a block statement.
  • The contents of the block with the same label as the value which generated by #RANDOM are applied.
  • The contents of all blocks that do not agree with the generated value are ignored.
  • That is, this syntax makes it possible to make “BMS which differ each time we play”.

    • : BM98 implemented #RANDOM. (earlier than #PLAYER 3 (DP), #TOTAL, #xxx07 (BGA LAYER), etc.)
    • This feature was proposed in order to emulate DJ BATTLE of beatmania.
    • The randomized BMS oldest in the range which I know is FANKS "Anthology" COLLECTION. (cranky, )
    • Even now, randomized BMS is continuing being released. e.g. DJ BATTLE 2011 (2106, )
    • See also: [#RANDOM BMS list]
  • An important point is that all the contents of the musical score are randomizable.

    • Play-option RANDOM cannot randomize the rhythm of a note.
    • Command #RANDOM is more dynamic and more powerful.
  • Basic example:

    BMS code:when 1 is generated:when 2 is generated:
    #00111:11000000
    
    #RANDOM 2
    
    #IF 1
    #00112:00220000
    #ENDIF
    
    #IF 2
    #00113:00003300
    #ENDIF
    
    #00114:00000044

    #00111:11000000, #00112:00220000, #00114:00000044

    #00111:11000000
    #00112:00220000
    #00114:00000044

    #00111:11000000, #00113:00003300, #00114:00000044

    #00111:11000000
    #00113:00003300
    #00114:00000044
    • This example has two lines and one #RANDOM block at a top level.
    • #00111:11000000 and #00114:00000044 are written to the outside of #RANDOM. (top level)

      Therefore, whatever the value which #RANDOM generated, these two lines are always parsed.

    • This #RANDOM sentence is written to the top level. Therefore, a random number is always generated.

      • When 1 is generated, #00112:00220000 is applied and #00113:00003300 is ignored.
      • When 2 is generated, #00112:00220000 is ignored and #00113:00003300 is applied.
    • Implementation which is not supporting #RANDOM will display four musical notes.
  • Bad example Unrecommended example: orphanized common part

    BMS code:when 1 is generated:when 2 is generated:
    #RANDOM 2
    #00111:11000000
    #00114:00000044
    
    #IF 1
    #00112:00220000
    #ENDIF
    
    #IF 2
    #00113:00003300
    #ENDIF

    #00112:00220000

    #00112:00220000

    #00113:00003300

    #00113:00003300
    • Noter expects that this example will bring the same result as the first example. But this is syntax violation not recommended.
    • It is because the #RANDOM block contains the line which is not contained in #IF section.
    • The note 11 and the note 44 are not written to the top level. Therefore, it is not guaranteed that these orphans are displayed.
    • In BM98, ruvit, or uBMplay, the same result as the first example is brought. But in nazo, LR2, or BMSE, these orphans are ignored.
    • We should describe it on the outside of a #RANDOM block, if it is a “common part”.
  • Example of nested #RANDOM:

    #RANDOM 2 is nested to two levels: when 1 is generated » when 1 is generated: when 1 is generated » when 2 is generated: when 2 is generated:
    #00111:11000000
    
    #RANDOM 2                 
                              
      #IF 1                   
        #00112:00220000       
                              
        #RANDOM 2             
                              
          #IF 1               
            #00115:00550000   
          #ENDIF              
                              
          #IF 2               
            #00116:00006600   
          #ENDIF              
                              
        #ENDRANDOM            
                              
      #ENDIF                  
                              
      #IF 2                   
        #00113:00003300       
      #ENDIF                  
                              
    #ENDRANDOM                
    
    #00114:00000044

    #00111:11000000, #00112:00220000, #00115:00550000, #00114:00000044

    (pattern A)

    #00111:11000000
    #00112:00220000
    #00115:00550000
    #00114:00000044

    #00111:11000000, #00112:00220000, #00116:00006600, #00114:00000044

    (pattern B)

    #00111:11000000
    #00112:00220000
    #00116:00006600
    #00114:00000044

    #00111:11000000, #00113:00003300, #00114:00000044

    (pattern C)

    #00111:11000000
    #00113:00003300
    #00114:00000044
    • There is not much implementation which can interpret nested #RANDOM correctly. Be careful.
    • In order to make a code easy to read, I used an indent and #ENDRANDOM in the above-mentioned example.

      When actually using nested #RANDOM, we should unindent. We should also trim the spaces of the end-of-lines.

      #ENDRANDOM must not omit. It is because nanasi requires this when using nested #RANDOM.

    • The lines in a top level are always interpreted: #00111:11000000, #RANDOM 2, #00114:00000044

      • When top-level #RANDOM generates the value 1, #00112:00220000 is interpreted.

        Furthermore, the #RANDOM sentence of a second level is interpreted.

        • When #RANDOM of a second level generates the value 1, #00115:00550000 is interpreted.
        • When #RANDOM of a second level generates the value 2, #00116:00006600 is interpreted.
      • When top-level #RANDOM generates the value 2, #00113:00003300 is interpreted.
    • Although this example branches to 3 patterns, the probability that each pattern will be chosen is not 1 in 3.

      • The probability that #00115:00550000 will be chosen is 1 in 4.
      • The probability that #00116:00006600 will be chosen is 1 in 4.
      • The probability that #00113:00003300 will be chosen is 1 in 2.
    • For example, if #RANDOM 2 is nested to six levels, the pattern of a sixth level will be chosen by the probability of 1 in 64. (64 is 6th power of 2)

      In order to realize the same thing, we may write 64 #IF blocks. Most implementations can be interpreted although that is inefficient.

  • The implementation which does not support #RANDOM will interpret all commandline as a top-level sentence, and will bring about fault as the result.

    For example: Declinin' (sta, ) (download: 低級言語を労わる会)
    BMSE (partial support):
    BMSC (does not support):
    iBMSC 3.0 (partial support):

    Isolation to the “Expansion Code” tab is performed correctly. This tab can store at least 700,000 or more characters surely.

    But, the present isolation is imperfect and will also display flow control expression on “Edit Panel”.

    • This BMS randomizes the rhythm of the musical note using 40 #RANDOM sentences in #026-033.
    • Conceptual diagram:
    • BMSE can parse the section of #RANDOM and can isolate it in an Expand tab.

      However, since this BMS has too many #RANDOM blocks, those will exceed the capacity of the Expand tab of BMSE.

      By this BMS, I discovered that the Expand tab was a maximum of 65535 characters.

  • Control flow needs to be parsed ahead of all other commands.
  • Control flow has the capability to change all commands also including a header.

    • e.g. オートメーション工場 (automation factory) (John "De Bello" Cage, ) ()
    • This BMS generates music automatically at random.
    • All #TITLE, #RANK, and #BPM[01-ZZ] are controlled by this statement.
    • And the section of the line numbers 347781-409539 is a child of the #IF 14 (347780-409542).
    • 6177 #RANDOM sentences are used for this musical score. 1260 of them are children of #IF 14 of the 347780th line.
    • This BMS is a good sample of “unlimited sibling”. This is a typical example of kusofumen called a benchmark BMS.
    • It was fortunate for many implementations that this BMS did not contain the element of “unlimited descendant”.
  • Almost all implementations cannot parse “unlimited control flow”.
  • In almost all cases, the randomizable header is restricted or the number of statements is restricted.
  • For example, in nestable implementation, a semi-permanent deep nesting is theoretically possible.

    • However, whatever the depth of a nest, we are obliged to always describe the block termination command #ENDRANDOM.
    • It is because nanasi will do forced-termination if a #RANDOM statement without #ENDRANDOM appears 47 times or more.
    • (Although it seems that this is a bug of nanasi, possibly it may be my misapprehension. )
  • IIDXv and HDX and BGAEncAdv and TechnicalGroove apply the default value 1, when #RANDOM n is not found.

    • This is one of the methods for coping with the simple violation of syntax originating in a hand code.
    • (e.g. #random5 (without delimiter), #rondam 5 (typo))

#RONDAM n

origin:uBMplay
support:uBMplay, outliner, Sonorous, BGAEncAdv, TechnicalGroove
  • In order to cope with typo.
  • e.g. 20,november "club edit" [random ver.] (cranky, )

    • It is written to the 366th line as #rondam 5. When this line is ignored, the difficult problems about syntax occur.
    • How should they be treated although this #RONDAM has five #IF blocks?

      • Almost all implementations refer to the value generated by previous #RANDOM.
      • However, since this behavior is not specified by specification, it is implementation-dependent.
    • How is the range of #RANDOM decided? Doesn't such a thing exist but does only the section of #IF-#ENDIF merely exist?

      doubtful coderemarks
      #00111:11
      
      #RANDOM 2
        #IF 1
          #00212:22
        #ENDIF
        #IF 2
          #00313:33
        #ENDIF
        
      #00414:44
      #00515:55
        
      #RONDAM 3
        #IF 1
          #00616:66
        #ENDIF
        #IF 2
          #00717:77
        #ENDIF
        #IF 3
          #00818:88
        #ENDIF
      
      #00919:99
      Since this line is a top level, it is always interpreted.
      
      ┐
      │
      │
      │
      │
      │
      ┆ It is doubtful whether #RANDOM is closed at this position.
        
      ┐ These lines are top levels if it is the usual case.
      ┘ But in #RONDAM, that may not be right. It may become an orphan block here.
        
      ] This line is commented out.
      ┐
      │ This block is also applied if the result of previous #RANDOM is 1.
      ┘
      ┐
      │ This block is also applied if the result of previous #RANDOM is 2.
      ┘
      ┐
      │ This block is also applied if the result of previous #RANDOM is 3.
      ┘ Since it is not materialized, this block is not applied by any means.
      
      ] Is this line a top level ? Is this on the outside of #RANDOM ? Really ?
    • If #RANDOM 2 of the beginning does not exist, what will happen in the above-mentioned example?

      • nanasi does not recognize #IF block as #IF block.

        That is, the contents of #IF block are processed with the same priority as “the command lines written to the outside of a #RANDOM”.

      • LR2 and uBMplay ignore all the contents of orphan #IF. (discard: #00616:66, #00717:77, #00818:88)
      • PMSee-V warns as follows: #IF written before the first #RANDOM or #SETRANDOM
  • The problem of a control flow is being able to generate a syntax error very easily.
  • Although the method of uBMplay may be ad hoc, it is an unavoidable thing because specification has defined no details.

#END IF

origin:uBMplay (1.5.0)
ad hoc support:Angolmois (#END), outliner (#END), Sonorous (#END), BGAEncAdv, TechnicalGroove
interpreted by chance:nazo, rdm, ruvit, fgt++, fgt#, LR2, uBMplay, PMSee-V
only when the first #IF agrees:BM98k, BM98de, DDR, MW (hung up), pomu2, IIDXv, HDX
only when the last #IF agrees:nanasi
  • In order to cope with typo.
  • e.g. Velocity Magic 3 [Aren't you lucky?] (Speed Magician / Transfero, ) () (download is impossible now)

    • Please change the filename extension of lovetricks.ogg into bms, bme, or bml.
    • #END IF is typo by a misapprehension. Or although this may be an intentional trick, I am uninterested about it.
    • The usual implementations ignore this line. That is, this is problem about #IF without #ENDIF.
    • Implementation which does not support nested #RANDOM can cope with this example easily.

      • In #IF block, if another #IF is found before #ENDIF is found, it will be not a nested line but an adjacent sibling #IF block.
    • This problem is troublesome for nestable implementations. It is because a possibility of nest cannot be disregarded, either.

      • I remember HTML without end tag. HTML parser must finish work more difficult than XML parser.
      • Should BMS parser gain ability like HTML parser? I think that XMLized BMS is better than doing so.

Examples of Mistakes

  • #RONDAM n
  • #END IF
  • #IF n without #ENDIF
  • ENDIF
  • #RANDOMn
  • #IFn
  • #IFEND

See also: [#RANDOM BMS list]

All the patterns mentioned above are supported: uBMplay 1.5.2+, Sonorous (if UTF-8), BGAEncAdv, TechnicalGroove

#SETRANDOM n

origin:pomu2
support: pomu2, WAview, in_bm2, nanasi, Aqua, PMSee-V, IIDXv, HDX, outliner, iBMSC (3.0+ / partial), Angolmois, Sonorous, BGAEncAdv, TechnicalGroove
similar:bms2avi (“SEED” menu), bmx2wav (RandomConstantValue in bmx2wav.ini)
  • The constant value n will be generated if #SETRANDOM n is described instead of #RANDOM n.

    For exampleremarks
    // #RANDOM 3
    #SETRANDOM 2
      #IF 1
        #WAV01 a.wav
      #ENDIF
      #IF 2
        #WAV01 b.wav
      #ENDIF
      #IF 3
        #WAV01 c.wav
      #ENDIF
    #ENDRANDOM
    • This sample comments out an original #RANDOM sentence.
    • Since there is little implementation which supports an indent, use of an indent is still premature now.

      In order to make a sample code easy to read, this document uses an indent.

    • Since this #SETRANDOM always generates 2, the statement block with a label “2” is always chosen.
    • As a result, #WAV01 b.wav is always applied.
    • As long as #SETRANDOM 2 is specified, #IF 1 and #IF 3 are never chosen.
    • The statement block which was not chosen is only ignored.
  • Probably, it seems that #SETRANDOM is the prepared command in order to test nested control syntax.

#ELSEIF n

origin:IIDXv
support:IIDXv, HDX, outliner, Angolmois, Sonorous, BGAEncAdv, TechnicalGroove
  • #ELSEIF n sentences can be written one or more to somewhere between #IF sentence and a #ENDIF sentence.
  • #ELSEIF n sentences can be written in front of #ELSE, supposing #ELSE exists.
  • Supposing there is no necessity, we need not write #ELSEIF.
  • The contents of “the first block among the blocks whose generated value and labels correspond” are applied. For example:

    #RANDOM 5
    
      #IF 1
                #00111:UU
      #ELSEIF 2
                #00112:VV
      #ELSEIF 3
                #00113:WW
      #ELSE
                #00115:ZZ
      #ENDIF
    
      #IF 2
                #00121:AA
      #ELSEIF 2
                #00123:BB
      #ELSEIF 5
                #00125:CC
      #ELSE
                #00126:DD
      #ENDIF
    
    #ENDRANDOM
    • When the value 1 is generated, the following command lines are applied: #00111:UU + #00126:DD
    • When the value 2 is generated, the following command lines are applied: #00112:VV + #00121:AA
    • When the value 3 is generated, the following command lines are applied: #00113:WW + #00126:DD
    • When the value 4 is generated, the following command lines are applied: #00115:ZZ + #00126:DD
    • When the value 5 is generated, the following command lines are applied: #00115:ZZ + #00125:CC

    In IIDXv and HDX, each block of #IF-#ELSEIF-#ELSE becomes a group of an exclusive choice.

    When the choice which agrees with a generated value is found, subsequent choices are skipped from there.

    • Therefore, whatever the generated value, #00123:BB in this example is not applied.
    • outliner cannot yet be simulating this exclusive action.

#ELSE

origin:nanasi
support:nanasi, IIDXv, HDX, outliner, iBMSC (3.0+ / partial), Angolmois, Sonorous, BGAEncAdv, TechnicalGroove
  • An #ELSE sentence can be written only once to somewhere between #IF sentence and a #ENDIF sentence.
  • An #ELSE sentence can be written in the rear of #ELSEIF, supposing #ELSEIF exists.
  • Supposing there is no necessity, we need not write #ELSE.
  • When #ELSE exists, the statement block of #IF-#ENDIF is divided into two sections, #IF-#ELSE and #ELSE-#ENDIF.
  • When #ELSE exists during a statement block, the following processings are performed.

    • If the label of block agrees with “the generated value”, the contents of #IF-#ELSE will be applied.
    • If the label of block does not agree with “the generated value”, the contents of #ELSE-#ENDIF will be applied.
  • When #ELSE does not exist during a statement block, the usual processing is performed.

    • If the label of block agrees with “the generated value”, the contents of #IF-#ENDIF will be applied.
    • If the label of block does not agree with “the generated value”, the contents of #IF-#ENDIF will be ignored.
  • For example:

    #RANDOM 4
      #IF 1
            #00111:UU
      #ELSE
            #00112:VV
      #ENDIF
      #IF 2
            #00113:WW
      #ELSE
            #00114:XX
      #ENDIF
      #IF 3
            #00115:YY
      #ELSE
            #00116:ZZ
      #ENDIF
    #ENDRANDOM
    // 1
    
     UU 
    
        
    
    
        
    
     XX 
    
    
        
    
     ZZ 
    
    
    
    // 2
    
        
    
     VV 
    
    
     WW 
    
        
    
    
        
    
     ZZ 
    
    
    
    // 3
    
        
    
     VV 
    
    
        
    
     XX 
    
    
     YY 
    
        
    
    
    
    // 4
    
        
    
     VV 
    
    
        
    
     XX 
    
    
        
    
     ZZ 
    
    
    
    
    ┐
    │
    │ IF-1 block
    │
    ┘
    ┐
    │
    │ IF-2 block
    │
    ┘
    ┐
    │
    │ IF-3 block
    │
    ┘
    
    • When the value 1 is generated, the following command lines are applied: #00111:UU + #00114:XX + #00116:ZZ
    • When the value 2 is generated, the following command lines are applied: #00112:VV + #00113:WW + #00116:ZZ
    • When the value 3 is generated, the following command lines are applied: #00112:VV + #00114:XX + #00115:YY
    • When the value 4 is generated, the following command lines are applied: #00112:VV + #00114:XX + #00116:ZZ
  • Another example (the musical score in which a special pattern is applied by the probability of 1/64):

    #RANDOM 64
      #IF 1
           // special pattern
      #ELSE
           // default pattern
      #ENDIF
    #ENDRANDOM
    • When the value 1 is generated, a special pattern is applied.
    • When values other than 1 are generated, a default pattern is applied.
    • When not using #ELSE, it is necessary to describe 1 special pattern and 63 default patterns.
  • When #RANDOM n is specified, we have to describe all the patterns from 1 to n is written to nanasigroove specification.

    • Therefore, the two above-mentioned examples do not meet nanasi specification.
    • However, nanasi can parse the two above-mentioned examples correctly.
    • IIDXv and outliner can parse the two above-mentioned examples correctly.
    • But we should use not #ELSE but #SWITCH to perform such a flow control.

#ENDRANDOM

origin:nanasi
support:nanasi, IIDXv, HDX, outliner, iBMSC (3.0+ / partial), Angolmois, Sonorous
  • The command for expressing the termination of #RANDOM block clearly.
  • A certain #RANDOM block is started by one #RANDOM sentence, and it is closed by one #ENDRANDOM sentence.
  • Implementation which does not support #ENDRANDOM disregards #ENDRANDOM simply.

    • Probably, programmers' work was slightly easier than the present, supposing #ENDRANDOM was contained in the specification of BMS from the beginning.
    • However, since that was not so, the parsing of nested #RANDOM is troublesome work.
  • #ENDRANDOM is indispensable when it nests control flow is written to nanasigroove specification.

    • However, in fact, even if #RANDOM is not nested, we should always write #ENDRANDOM.
    • It is because nanasi will do forced-termination if a #RANDOM statement without #ENDRANDOM appears 47 times or more.
  • In all the implementations which support nested #RANDOM other than nanasi, #ENDRANDOM is omissible.

    • Therefore, for the moment, #ENDRANDOM is needed only for the purpose of making #RANDOM interpret exactly to nanasi.
    • However, I recommend always writing #ENDRANDOM. It is because it becomes easier for us to read BMS codes.
  • IIDXv and HDX will reset the value of #RANDOM in current scope to 1, if #ENDRANDOM is found.

    • Unless post-processing by #ENDRANDOM will be performed, the value of former #RANDOM is inherited.
origin:nanasi
support: nanasi, IIDXv, HDX, outliner, iBMSC (3.0+ / partial), Sonorous (parsing-only), BGAEncAdv, TechnicalGroove
  • These are almost the same as the SWITCH statement of a programming language.
  • #SWITCH generates one of the natural numbers from 1 to n. Needless to say, n should specify a natural number.
  • The constant value n will be generated if #SETSWITCH n is described instead of #SWITCH n. This is useful in the case of a test play.
  • It is evaluated whether the label n of #CASE agrees with the value which #SWITCH generated.

    Needless to say, BMS parser evaluates in sequence each line which exists after SWITCH in order of a line number.

    The contents of the section from #CASE desired value to #ENDSW are applied.

  • When #SKIP exists between #CASE desired value and the next #CASE, parsing is skipped from #SKIP to #ENDSW.
  • When #SKIP does not exist between current #CASE and next CASE, even if the label of next #CASE does not agree with desired value, the contents of next #CASE are applied. That is, nanasigroove specification has allowed fallthrough.
  • #ENDSW terminates a #SWITCH block. Unlike the case of #ENDRANDOM, noter is not allowed to omit #ENDSW.
  • #DEF can also be used instead of #CASE. When #CASE does not yet agree with desired value, the contents of #DEF are applied.

    It is written to nanasigroove specification as follows: それまでの #CASE が不一致であった場合実行される。

    However, #DEF will also be applied by fallthrough, if #SKIP is omitted even when #CASE has already agreed with desired value.

    • #DEF is the command prepared as a default choice which should be applied when all #CASE is unmatch. (at least in nanasi. )
    • Therefore, noter must not write two or more #DEF to one #SWITCH.
    • Moreover, if #DEF is required, noter should write #DEF after all other #CASE.

      • Although this rule is not written to nanasigroove specification, we have to follow this rule.
      • It is because #CASE / #SKIP / #DEF from #DEF to #ENDSW loses a function, when nanasi finds #DEF.

        That is, nanasi will apply #DEF-#ENDSW as one section.

      • IIDXv, and HDX and outliner interpret correctly #DEF written before #CASE.

        Fallthrough is also effective.

        If #SKIP does not exist between #DEF and next #CASE, parsing flows into next #CASE.

    • I think that styles, such as “DEF before CASE” and fallthrough, are ill-mannered. However, since I am ignorant about programming, I cannot decide an attitude.
  • For example:

    BMS coderemarks
    #SWITCH 5
      #CASE 1
        #00111:XX
      #CASE 2
        #00112:YY
        #SKIP
      #CASE 3
        #00113:ZZ
      #DEF
        #00114:AA
        #00115:BB
    #ENDSW
    1. When the value 1 is generated, the following lines are applied: #00111:XX + #00112:YY
    2. When the value 2 is generated, the following line is applied: #00112:YY
    3. When the value 3 is generated, the following lines are applied: #00113:ZZ + #00114:AA + #00115:BB
    4. When the value 4 is generated, the following lines are applied: #00114:AA + #00115:BB
    5. When the value 5 is generated, the following lines are applied: #00114:AA + #00115:BB
    • Italic expresses that it is the line applied by the omission of #SKIP. (That is, fallthrough. )
    • When actually using #SWITCH, we should unindent. (nanasi will ignore all #SWITCH block, if we do not do so. )
  • #SWITCH may be able to express the same contents as #RANDOM more skillfully. For example:

    a special pattern is applied by the probability of 1/64:
    In the case of #RANDOM: When #ELSE is used: In the case of #SWITCH: 1/65535:
    #RANDOM 64
      #IF 1
        // special pattern
      #ENDIF
      #IF 2
        // default pattern
      #ENDIF
        ...
      #IF 64
        // default pattern
      #ENDIF
    #ENDRANDOM
    #RANDOM 64
      #IF 1
        // special
      #ELSE
        // default
      #ENDIF
    #ENDRANDOM

    Note: violation of nanasi specification

    #SWITCH 64
      #CASE 1
        // special
        #SKIP
      #DEF
        // default
        #SKIP
    #ENDSW
    #SWITCH 65535
      #CASE 1
        // special
        #SKIP
      #DEF
        // default
        #SKIP
    #ENDSW
    • In #RANDOM, noter must describe all the choices. In this example, noter must write 63 default patterns.

      • All implementations that support #RANDOM can interpret this way. The portability of this way is the highest.
      • However, this way is the most troublesome, and the file size of a musical score becomes the maximum.
    • #ELSE is the smartest way. However, although there is no actual harm, since it is violation specification, it is not suitable.
    • #SWITCH is the 2nd best way. It can describe very briefly and can also adjust probability easily.
  • Contents expressible by #SWITCH are expressible also by #RANDOM. But I do not desire to write 65534 #IF.
  • I think that #RANDOM is good to use when the same pattern does not exist.
  • That the following rules are not written to specification makes me uneasy:

    • Noter must describe each label in ascending order.
    • Noter must describe each label only once.

    It is the same also about #RANDOM. Some implementations can interpret ill-mannered control statements. But all are not so.

  • The command lines which BMSE does not support are isolated in the Expand tab of BMSE.

    • BMSE can parse the section of #IF-#ENDIF and can isolate it in an Expand tab. This is a very wonderful feature.
    • However, the sectioning contents which #SWITCH has will be interpreted as a code of a mere top level, since BMSE is not supporting #SWITCH.
    • That is, the same result as the case where BMSC opens randomized BMS is brought. ()
  • BMS editor which can edit control flow itself does not yet exist.

    If it may exist, I surmise that it will become a form like an outline processor.

  • According to nanasigroove specification:

    • #SWITCH blocks can be written into #RANDOM blocks.
    • #RANDOM blocks can be written into #SWITCH blocks.
    • #RANDOM and #SWITCH are unlimitedly nestable.
  • However, control flows implemented of nanasi are mysterious.

    • If #RANDOM is nested to 90 levels or more, nanasi will do forced termination. (when #SWITCH is not mixed )
    • If #SETSWITCH is nested to 47 levels or more, nanasi will do forced termination. (when #RANDOM is not mixed )
    • nanasi can realize about 100 or more levels by nesting #RANDOM and #SWITCH by turns.
  • The number of maximal levels of the nest in outliner is dependent on each web browser.
  • The performance of IIDXv and HDX about a control flow is the best.

Indent style

origin:IIDXv
support:
Apps Tabulation (U+0009) Space (U+0020) Ideographic Space (U+3000)
fgt, fgt++, fgt#YesYesYes
IIDXv, HDXYesYesYes
iBMSCYesYesYes
outlinerYesYesYes
PMSee-V (v1.10.5+)YesYesYes
BGAEncoder (HEADERs only)YesYesYes
BGAEncAdv, TechnicalGrooveYesYesYes
Sonorous (UTF-8)YesYesYes
uBMplayNoYesYes
bemaniaDXNoYesYes
LR2YesYesNo
BMS List Sorter, BME2WAV, BMX2WAVYesYesNo
Angolmois, Sonorous (non-UTF8)YesYesNo
  • The indenting by tab characters or half-width spaces. (In IIDXv support page, this is called “paragraphization”.)
  • I think that this is very useful for noter. I cannot write a control flow without an indent any longer.
  • All characters other than “#” are set to indentation in fgt, fgt++, fgt#, BGAEncoder (HEADER lines only), BGAEncAdv, and TechnicalGroove.

    • forgetalia series cannot comment command lines out.
    • BGAEncoder cannot comment header lines out.
    • BGAEncAdv and TechnicalGroove cannot comment command lines out except “//”.
    • Several BMS lose compatibility by this specification. (E.g. FANKS "RANDOM" COLLECTION comments #random out by “/”)

Comment syntax

origin:IIDXv
support:IIDXv, HDX, outliner (except escape sequences), BGAEncAdv (“//” only), TechnicalGroove (“//” only)
  • These are the explicit comment syntax for debugging musical scores.
  • Comment syntax is interpreted more preferentially than control syntax.
  • ; : The start symbol of a single-line comment. The section from a semicolon to a newline character is commented out.

    • This is the same as that of the single-line comment syntax of a DTX format.
  • // : The start symbol of a single-line comment. The section from two slashes to a newline character is commented out.

    • This is the same as that of the single-line comment syntax of C-like programming languages.
  • /* - */ : The start symbol and end symbol of multiline comment. The section from /* to */ is commented out.

    • Although this resembles multiline comment syntax of C-like programming languages,
    • All the newline characters in comment blocks are parsed.
    • A block comment can not be nesting.
  • For example:

    before parsingafter parsingremarks
    #TITLE foo-/*bar-*/baz; :)
    #RANDOM 23
      #IF 1
        #00111:XX
      #ELSEIF 2/*
        #00112:YY
      #ELSEIF ; */3
        #00113:ZZ
      #ELSE//IF 4
        #00114:AA
      #ENDIF
    //*
    #ARTIST foon
    /*/
    #ARTIST asso
    //*/
    #BPM 130
    #TITLE foo-baz
    #RANDOM 23
      #IF 1
        #00111:XX
      #ELSEIF 2
    
    3
        #00113:ZZ
      #ELSE
        #00114:AA
      #ENDIF
    
    #ARTIST foon
    
    
    
    #BPM 130
    • Unlike programming languages, a result of #ELSEIF 23 is not brought.

      • Because it is based on the specification of the BMS “one command per line”.
      • As a commented-out result, only the character 3 remains in this line.
      • On the specification of BMS, since this line is interpreted as an implicit comment, it is only ignored.
    • If one slash of the head of “//*” is deleted,

      • This part will be commented out as follows:

        /*
        #ARTIST foon
        /*/
        #ARTIST asso
        //*/
        /* (another solution)
        #ARTIST foon
        /*/
        #ARTIST asso
        /**/
      • Thus, the scope of each comment block can be changed easily.
  • In IIDXv and HDX, a means to cancel comment syntax does not exist.

    • When using comment symbols as character string values, the method of changing them into full-width characters is proposed by the document of IIDXv.
    • For example, “#ARTIST audio: foo // video: bar” is changed into “#ARTIST audio: foo // video: bar”.
    • When music scores cannot be corrected, IIDXv and HDX only interpret it as “#ARTIST audio: foo ”.
  • IIDXv 2.13+ and HDX 0.98+ provide the escape sequence of strings. (This will not disable the comment syntax)

    • Any command that accepts a string value can be enclosed in values with U+0022 QUOTATION MARKs.
    • The comment mark in the character string surrounded by quotation marks is parsed as a mere character string.
    • Moreover, one character which follows U+005C REVERSE SOLIDUS is parsed as a mere character.
    e.g. 1: #ARTIST C:\usr the "DPer" (http://hitkey.nekokan.dyndns.info/)

    Display of IIDXv and HDX: C:usr the DPer (http:

    Display of another apps: C:\usr the "DPer" (https://hitkey.nekokan.dyndns.info/)

    e.g. 2: #ARTIST C:\\usr the \"DPer\" (http:\//hitkey.nekokan.dyndns.info/)

    Display of IIDXv and HDX: C:\usr the "DPer" (https://hitkey.nekokan.dyndns.info/)

    Display of another apps: C:\\usr the \"DPer\" (http:\//hitkey.nekokan.dyndns.info/)

    e.g. 3: #ARTIST "C:\usr the "DPer" (http://hitkey.nekokan.dyndns.info/)"

    Display of IIDXv and HDX: C:usr the DPer (https://hitkey.nekokan.dyndns.info/)

    Display of another apps: "C:\usr the "DPer" (https://hitkey.nekokan.dyndns.info/)"

    e.g. 4: #ARTIST "C:\\usr the \"DPer\" (http://hitkey.nekokan.dyndns.info/)"

    Display of IIDXv and HDX: C:\usr the "DPer" (https://hitkey.nekokan.dyndns.info/)

    Display of another apps: "C:\\usr the \"DPer\" (https://hitkey.nekokan.dyndns.info/)"

  • In HDX 0.99 and above, without being escaped, “\” (U+005C) which is not surrounded by U+0022 was changed so that it might be outputted as it is.

test cases

  1. from BMIIDXView2010.txt:

    BMS coderemarks
    #SWITCH 5
        #DEF
            #00013:0055
            #SKIP
        #CASE 1
            #00013:0100000000000000
            #RANDOM 2
                #IF 1
                    #00014:04
                #ELSE
                    #00014:05
                #ENDIF
        #CASE 2
            #00013:0200000000000000
            #SKIP
        #CASE 3
            #00013:0300000000000000
            #SWITCH 2
                #CASE 1
                    #00016:1111
                    #SKIP
                #CASE 2
                    #00016:2222
                    #SKIP
            #ENDSW
            #SKIP
    #ENDSW
    • indent
    • #DEF before #CASE
    • nested #RANDOM without #ENDRANDOM
    • desired value which is greater than the number of prepared #IF statement

      (Note: violation of nanasigroove specification)

    • fallthrough by omission of #SKIP
    • not nesting #RANDOM and #SWITCH by turns
    which passes this test:
    IIDXv, HDX, outliner
    passing test partial (but failed isolation ):
    iBMSC (3.0+)
  2. automation factory ()

    • 6177 #RANDOM sentences / 147723 #IF sentences (unlimited sibling)
    • the statement blocks containing even headers
    • the huge nested #RANDOM exceeding 60,000 lines (347781-409539)
    • too many desired values which are greater than the number of prepared #IF statement
    • randomized #TITLE (Probably, implementation which uses #TITLE for a song selection list or IR will suffer troubles.)
    which passes this test:
    pomu2, IIDXv, HDX, outliner, Angolmois, uBMplay (1.5.0 or later), Sonorous, BGAEncAdv, TechnicalGroove
    passing test partial (but nested level is interpreted as 1 ):
    uBMplay (1.4.6 or earlier), LR2, fgt++, ruvit, bmx2wav

    If #ENDRANDOM is supplemented to this musical score, nanasi will also pass. ()

  3. 20,november "club edit" [random ver.] (cranky, )

    • #RONDAM is typo
    • pass: uBMplay, BMSE, outliner, Sonorous, BGAEncAdv, TechnicalGroove
  4. Velocity Magic 3 [Aren't you lucky?] (Speed Magician / Transfero, ) () (download is impossible now)

    • lovetricks.ogg » lovetricks.bms
    • #END IF is typo
    • pass: nazoZZ, RDM, ruvit, fgt++, fgt#, LR2, uBMplay, PMSee-V, outliner, Angolmois, Sonorous, BGAEncAdv, TechnicalGroove
  5. kitchen twies (Orange Strophe, ) ()

    beforeafterremarks
    #RANDOM 2
    
    #00002:0.5
    #00003:4F
    #IF 1
    #00004:01
    #00006:03
    #ENDIF
    #IF 2
    #00004:02
    #00006:04
    #ENDIF
    #00002:0.5
    #00003:4F
    #RANDOM 2
    #IF 1
    #00004:01
    #00006:03
    #ENDIF
    #IF 2
    #00004:02
    #00006:04
    #ENDIF
    • Unjust branch containing the line which does not belong to #IF
    • : This bug was fixed by the patch.
    • (I do not understand the necessity of solving this problem. Should it pass? )

      Of course, passing in this test is desirable. BM98 implemented #RANDOM as such.

    • pass: RDM, ruvit, nanasi, uBMplay, PMSee-V, bmx2wav, IIDXv, HDX, Angolmois, Sonorous, BGAEncAdv, TechnicalGroove, ... (uninvestigated)

<CHANNEL>

Channel Mapping Table

numsummaryremarksorigin
00 Retired number In some implementations: BPM change in the forefront of #xxx (removed) -
01 BGM #WAVxx (multiline) BM98
02 Length of #xxx (1 corresponds to 4/4 meter) // specify integer or decimal fraction BM98
03 Change of BPM BPM 1 « [01-FF] » BPM 255 BM98
04 BGA BASE #BMPxx (BASE is displayed under LAYER) BM98
05 Extended Object #ExtChr (BM98 only) BM98
05 SEEK Object #SEEKxx n (LR only) LR
06 BGA POOR #BMPxx (POOR is displayed when a mistake is made) BM98
07 BGA LAYER #BMPxx (LAYER is layered over BASE) BM98k
08 exBPM #BPMxx n | #EXBPMxx n (real number) bemaniaDX
09 STOP #STOPxx n (1 corresponds to 192nd note) DDR
0A BGA LAYER2 #BMPxx (LAYER2 is layered over LAYER) nanasi
0B Opacity of BGA BASE transparent « [01-FF] » opaque nanasi
0C Opacity of BGA LAYER transparent « [01-FF] » opaque nanasi
0D Opacity of BGA LAYER2 transparent « [01-FF] » opaque nanasi
0E Opacity of BGA POOR transparent « [01-FF] » opaque nanasi
11-1Z 1P Visible { BM98: 11-17, FlashTerminal: 18-19, MGQ: 1A-1F, pomu: 1G-1Z } BM98/FT/MGQ/pomu
21-2Z 2P Visible { BM98: 21-27, FlashTerminal: 28-29, MGQ: 2A-2F, pomu: 2G-2Z } BM98/FT/MGQ/pomu
31-3Z 1P Invisible { BM98: 31-36, FlashTerminal: 38-39, MGQ: 3A-3F, pomu: 3G-3Z } BM98/FT/MGQ/pomu
41-4Z 2P Invisible { BM98: 41-46, FlashTerminal: 48-49, MGQ: 4A-4F, pomu: 4G-4Z } BM98/FT/MGQ/pomu
51-5Z 1P Longnote { MGQ: 51-5F, pomu: 5G-5Z } MGQ/pomu
61-6Z 2P Longnote { MGQ: 61-6F, pomu: 6G-6Z } MGQ/pomu
70-96 reserved channel [ 10, 20, 30, 40, 50, 60 ] also reserved -
97 BGM volume min 1 « [01-FF] » max 255 (= original sound) // fgt only forgetalia
98 KEY volume min 1 « [01-FF] » max 255 (= original sound) // fgt only forgetalia
99 TEXT #TEXTxx "string" pomu
A0 JUDGE #EXRANKxx n (100 corresponds to RANK:NORMAL. integer or decimal fraction) nanasi
A1 BGA BASE aRGB #ARGBxx a,r,g,b (each [0-255]) nanasi
A2 BGA LAYER aRGB #ARGBxx nanasi
A3 BGA LAYER2 aRGB #ARGBxx nanasi
A4 BGA POOR aRGB #ARGBxx nanasi
A5 BGA KEYBOUND #SWBGAxx nanasi
A6 OPTION #CHANGEOPTIONxx (multiline) nanasi
D1-D9 1P Landmine #WAV00 // specify a damage by [01-ZZ] (decimalize/2) ZZ: instantly gameover nanasi
E1-E9 2P Landmine #WAV00 // specify a damage by [01-ZZ] (decimalize/2) ZZ: instantly gameover nanasi

KEYMAP Table

formatVisible Object Channel Mapping
BMS
KEY1 KEY2 KEY3 KEY4 KEY5 SCRATCH (FREE ZONE)
11 12 13 14 15 16 17
KEY1 KEY2 KEY3 KEY4 KEY5 SCRATCH (FREE ZONE)
21 22 23 24 25 26 27
BMS (nanasi-FP)
KEY1 KEY2 KEY3 KEY4 KEY5 SCRATCH
11 12 13 14 15 16
FOOT PEDAL: #xxx17
KEY1 KEY2 KEY3 KEY4 KEY5 SCRATCH
21 22 23 24 25 26
FOOT PEDAL: #xxx27
BMS (Angolmois-FP)
SCRATCH KEY1 KEY2 KEY3 KEY4 KEY5
16 11 12 13 14 15
FOOT PEDAL: #xxx17
KEY1 KEY2 KEY3 KEY4 KEY5 SCRATCH
21 22 23 24 25 26
FOOT PEDAL: #xxx27
縦連打測定器 (WayBack)
SCRATCH KEY1 KEY2
? ? ?
DDR Arrow 6
11 12 13 14 15 16
DDR Arrow 4/8
11 13 15 16
21 23 25 26
Project2DX
SCRATCH KEY1 KEY2 KEY3 KEY4 KEY5 KEY6 KEY7
16 11 12 13 14 15 21 22
BME
SCRATCH KEY1 KEY2 KEY3 KEY4 KEY5 KEY6 KEY7
16 11 12 13 14 15 18 19
KEY1 KEY2 KEY3 KEY4 KEY5 KEY6 KEY7 SCRATCH
21 22 23 24 25 28 29 26
BME (nanasi-FP)
SCRATCH KEY1 KEY2 KEY3 KEY4 KEY5 KEY6 KEY7
16 11 12 13 14 15 18 19
FOOT PEDAL: #xxx17
BME (Angolmois-FP)
SCRATCH KEY1 KEY2 KEY3 KEY4 KEY5 KEY6 KEY7
16 11 12 13 14 15 18 19
FOOT PEDAL: #xxx17
KEY1 KEY2 KEY3 KEY4 KEY5 KEY8 KEY9 SCRATCH
21 22 23 24 25 28 29 26
FOOT PEDAL: #xxx27
DSC / FPP
SCRATCH KEY1 KEY2 KEY3 KEY4 KEY5 KEY6 KEY7 SCRATCH
16 11 12 13 14 15 18 19 26
OCT/FP
SCRATCH KEY1 KEY2 KEY3 KEY4 KEY5 KEY6 KEY7 KEY8 KEY9 KEY10 KEY11 KEY12 KEY13 SCRATCH
16 11 12 13 14 15 18 19 22 23 24 25 28 29 26
FOOT PEDAL: #xxx21
PMS
KEY1 KEY2 KEY3 KEY4 KEY5 KEY6 KEY7 KEY8 KEY9
11 12 13 14 15 22 23 24 25
PMS (BME-type)
KEY1 KEY2 KEY3 KEY4 KEY5 KEY6 KEY7 KEY8 KEY9
11 12 13 14 15 18 19 16 17
KEY1 KEY2 KEY3 KEY4 KEY5 KEY6 KEY7 KEY8 KEY9
21 22 23 24 25 28 29 26 27
PMS (5button)
KEY1 KEY2 KEY3 KEY4 KEY5 KEY6 KEY7 KEY8 KEY9
13 14 15 22 23
PMS (pomu-battle)
KEY1 KEY2 KEY3
11 12 13
O2mania (?)
KEY1 KEY2 KEY3 KEY4 KEY5 KEY6 KEY7 (KEY8)
16 11 12 13 14 15 18 19
MyO2 (?)
KEY1 KEY2 KEY3 KEY4 (KEY5) (KEY6) (KEY7) (KEY8)
16 11 12 13 14 15 18 19
Uninvestigated:

GDA 9btn (feeling Pomu second),

16panel (D3beat),