338 lines
11 KiB
Plaintext
338 lines
11 KiB
Plaintext
The "Dance" Format
|
|
------------------
|
|
The goals of this format are easy parsability, easy human readability,
|
|
brevity, and disambiguity.
|
|
|
|
Generic Information
|
|
-------------------
|
|
All strings are case-sensitive. Filenames are case-sensitive. The
|
|
directory separator is '/' regardless of the platform. All text
|
|
is encoded in UTF-8. Byte-order marking is not allowed.
|
|
|
|
Enhanced Backus-Naur Form (ENBF) Specification
|
|
----------------------------------------------
|
|
This is purely the grammar. A semantic explanation is below.
|
|
|
|
Although this is given as a CFG specification, .dance is designed to be
|
|
parsed by a table-based DFA (as in pydance's fileparsers.py)
|
|
|
|
Primitives:
|
|
<String> ::= a sequence of characters
|
|
<Float> ::= 0.0 to Inf, decimal value
|
|
<NegInt> ::= 0 | -1 | -2 | -3 ...
|
|
<PosInt> ::= 0 | 1 | 2 | 3 ...
|
|
|
|
Almost primitives:
|
|
<Whitespace> ::= (" " | "\t")+
|
|
<Newline> ::= "\n" | "\r\n" | "\r"
|
|
<LongString> ::= <String> (<Whitespace> <String>)*
|
|
<EndToken> ::= "end" <Newline>
|
|
<Int> ::= <NegInt> | <PosInt>
|
|
<Comment> ::= [("#" <LongString>) | <Whitespace>] <Newline>
|
|
|
|
Basic Structure:
|
|
<File> ::= <Metadata> [<TextSection>+] <StepSection>+
|
|
|
|
Metadata Storage:
|
|
<Metadata> ::= (<Comment> | <MetadataLine>)+ <EndToken>
|
|
<MetadataLine> ::= (<Filename> | <Title> | <Subtitle> | <Artist> | <Mix> |
|
|
<BPM> | <Offset> | <BG> | <Banner> | <Preview> |
|
|
<Checksum> | <StartAt> | <EndAt> | <Author> | <CDTitle> |
|
|
<RevisionDate> | <Valid> | <Movie>) <Newline>
|
|
<Filename> ::= "filename" <Whitespace> <LongString>
|
|
<Title> ::= "title" <Whitespace> <LongString>
|
|
<Subtitle> ::= "subtitle" <Whitespace> <LongString>
|
|
<Artist> ::= "artist" <Whitespace> <LongString>
|
|
<Mix> ::= "mix" <Whitespace> <LongString>
|
|
<BPM> ::= "bpm" <Whitespace> <Float>
|
|
<BPMDisplay> :: "bpmdisplay" ((<Whitespace> <Float>)+ | "*")
|
|
<Gap> ::= "gap" <Whitespace> <Int>
|
|
<StartAt> ::= "startat" <Whitespace> <Float>
|
|
<EndAt> ::= "endat" <Whitespace> <Float>
|
|
<BG> ::= "background" <Whitespace> <LongString>
|
|
<Banner> ::= "banner" <Whitespace> <LongString>
|
|
<Banner> ::= "cdtitle" <Whitespace> <LongString>
|
|
<Preview> :: "preview" <Whitespace> <Float> <Whitespace> <Float>
|
|
<Checksum> ::= "md5sum" <Whitespace> <String>
|
|
<Author> ::= "author" <Whitespace> <LongString>
|
|
<Movie> ::= "movie" <Whitespace> <LongString>
|
|
<RevisionDate> ::= "revision" <Whitespace> <LongString>
|
|
<Valid> ::= "valid" <Whitespace> 1 | 0
|
|
|
|
Text Sections:
|
|
<TextSection> ::= [<Description>] [<Lyrics>]
|
|
<Lyrics> ::= "LYRICS" <Newline> (<LyricLine>)+ <EndToken>
|
|
<LyricLine> ::= <Float> <Whitespace> <PosInt> <Whitespace> <LongString> <Newline>
|
|
<Description> ::= "DESCRIPTION" <Newline> (<LongString> <Newline>)+ <EndToken>
|
|
|
|
Step Sections:
|
|
<StepSection> ::= <GameMode> <Difficulty> <Sequence>+ <EndToken>
|
|
<GameMode> ::= <String> <Newline>
|
|
<Difficulty> ::= <String> <Whitespace> <PosInt> <Newline>
|
|
<Sequence> ::= (<Comment> | <Buttons> | <Command>) <Newline>
|
|
|
|
Note Sequences:
|
|
<Buttons> ::= <NoteType> (<Whitespace> <ButtonPresses>)+
|
|
<NoteType> ::= "u" | "n" | "x" | "t" | "f" | "s" | "w" | "e" | "q" | "h" | "o"
|
|
<ButtonPresses> ::= (0 | 1 | 3 | 5 | 7)+
|
|
|
|
Song Commands:
|
|
<Command> ::= <ChangeBPM> | <Ready> | <Wait> | <Stop> | <Delay> | <Lyric>
|
|
<ChangeBPM> ::= "B" <Whitespace> <Float>
|
|
<Ready> ::= "R"
|
|
<Wait> ::= "W" <Whitespace> <Float>
|
|
<Stop> ::= "S" <Whitespace> <Float>
|
|
<Delay> ::= "D" <Whitespace> <Float>
|
|
<Lyric> ::= "L" <Whitespace> <Float> <Whitespace> <PosInt> <Whitespace>
|
|
<LongString>
|
|
|
|
Informal & Semantic Description
|
|
-------------------------------
|
|
The dance format is basically the step format, but generalized, smaller,
|
|
and more readable. A script to convert .step files to .dance files is
|
|
forthcoming.
|
|
|
|
A simple file might look like:
|
|
|
|
filename asong.ogg
|
|
title A Song
|
|
subtitle Crazy Mix
|
|
artist Someone
|
|
# This is a comment
|
|
end
|
|
DESCRIPTION
|
|
This is an example song.
|
|
It's pretty uninteresting.
|
|
end
|
|
SINGLE
|
|
BASIC 0
|
|
q 1010
|
|
# This is another comment.
|
|
q 0101
|
|
q 3030
|
|
q 1010
|
|
end
|
|
|
|
Metadata Section:
|
|
|
|
The metadata section of the song is the first section, and contains
|
|
important data about the file. An explanation of the keys follow:
|
|
|
|
'filename': The filename of the audio file to play.
|
|
|
|
'title': The name of the song. This should not include "Foo Mix".
|
|
|
|
'subtitle': "Foo Mix", "Crazy Version", whatever. Default none.
|
|
|
|
'artist': The name of the artist(s) and any remixers.
|
|
|
|
'bpm': The beats per minute of the song.
|
|
|
|
'gap': The millisecond offset into the song at which the arrows should
|
|
start. If the first beat is 0.3 seconds into the song, for example,
|
|
this should be -300. This can be negative. Default 0.
|
|
|
|
'bpmdisplay': A whitespace-separated list of floats, which will be
|
|
cycled through on the song selector's BPM display. If
|
|
not present this defaults to the BPM if the song. If "*",
|
|
the BPM is displayed as constantly changing.
|
|
|
|
'background': A background image (to display while the song is playing).
|
|
Default none.
|
|
|
|
'banner': A banner for the song (to display in the song select). Default none.
|
|
|
|
'cdtitle': A small (64x40) image to use as a CD title. Default none. This
|
|
path should either be relative to a special CD title directory,
|
|
or to the directory the file is in.
|
|
|
|
'preview': An offset to seconds to start a song preview at, and a length to
|
|
play the preview. Default 45.0 and 10.0.
|
|
|
|
'startat', 'endat': Start and end the music at these positions in seconds.
|
|
offset and the steps are then relative to the startat
|
|
position. Default 0.0 and the length of the song.
|
|
|
|
'md5sum': If present, the MD5 checksum of the 'filename' file. If it's
|
|
present and the file doesn't match, a warning can be issued.
|
|
|
|
'author': The person who wrote this file. Default none.
|
|
|
|
'revision': The date of the last revision of this file, in YYYY.MM.DD format.
|
|
Defaults to "1970.01.01".
|
|
|
|
'movie': The filename of a background movie; defaults to none.
|
|
|
|
'valid': If not true, this song should be not selected using in random play
|
|
modes (e.g., it's not finished, hasn't been timed, etc). Default 1.
|
|
|
|
The 'filename', 'title', 'artist', and 'bpm' keys are mandatory.
|
|
|
|
Note that songs in this format will *NOT* have any files autodetected. If
|
|
you want them to be found, explicitly state them in the file.
|
|
|
|
The metadata section, like all sections, must end with "end" on a line
|
|
by itself.
|
|
|
|
Text Sections:
|
|
|
|
There are two "text" sections in dance files; these are essentially
|
|
extended metadata sections.
|
|
|
|
The DESCRIPTION section contains a description of the song. The format
|
|
roughly follows the DPKG description format: All lines of text start
|
|
with a space. Whitespace, including newlines, is ignored. A period ('.')
|
|
on a line by itself (with a space before it!) is to be interpreted as a
|
|
paragraph separator. An 'end' token on a single line, with no space before
|
|
it, ends the description.
|
|
|
|
The LYRICS section contains lyric timing information. The format
|
|
of each line is, an integer, a float, and then a string. The integer
|
|
specifies the lyric "channel"; lyrics in the same channel should overwrite
|
|
each other, appear in the same place on the screen, etc. The float is the
|
|
time into the song during which the lyric should appear, irrespective
|
|
of the 'gap' value.
|
|
|
|
Step Sections:
|
|
|
|
The meat of the file is in the step sections, which actually describe
|
|
the game-related stuff. A step section is started as soon as an unknown
|
|
section token is encounter (i.e. currently not LYRICS or DESCRIPTION).
|
|
This first token is then taken as the "game mode". The two tokens on the
|
|
next line are the difficulty name and rating number.
|
|
|
|
Then, until the "end" token, there are lines describing the steps. These
|
|
may be either a command, or a set of buttons to press. The "base" is 'q',
|
|
the quarter note, which represents one beat in the song.
|
|
|
|
o Whole note (4 on-beat arrows)
|
|
h 1/2 note
|
|
q 1/4 note
|
|
e 1/8 note
|
|
w 1/12 note
|
|
s 1/16 note
|
|
f 1/24 note
|
|
t 1/32 note
|
|
u 1/48 note
|
|
x 1/64 note
|
|
n 1/192 note
|
|
|
|
After the note comes a string of buttons. All these strings should be
|
|
the same length across game modes. Example strings might "1001" or "0030".
|
|
|
|
0 No button at this time
|
|
1 A regular press at this time
|
|
3 This button must be pressed here and held down until a 1 is encounted
|
|
5 A secret step at this time.
|
|
7 A secret step and hold at this time.
|
|
|
|
(Note - With bitwise &,
|
|
num & 1 => pressed here,
|
|
num & 2 => hold here,
|
|
num & 4 => this is a secret note.
|
|
|
|
This correspondance is not necesarily guaranateed to be true for all
|
|
future additions to the .dance format, but will be maintained if possible.)
|
|
|
|
Possible commands are:
|
|
|
|
B <Float> Change the BPM of the song to this number at this point.
|
|
R "Ready? Go!" graphics/sound, if any.
|
|
W <Float> Wait this many seconds before the next event.
|
|
S <Float> Stop scrolling for this many seconds before the next event.
|
|
D <Float> The same as a sequence of 0 note strings for this many beats.
|
|
L <PosInt> <LongString> Display some lyrics at this point.
|
|
|
|
Failing Gracefully
|
|
------------------
|
|
Often, your parsers may come across tokens they don't know; maybe because
|
|
someone made an invalid file, or because the parser doesn't support all
|
|
of this format (or an old version of this format). If this is a section
|
|
token, this isn't a big problem; jump to the next end token and keep
|
|
going. Metadata tokens are equally easy to skip.
|
|
|
|
Tokens in steps are more complicated. In general, you should treat
|
|
them as comments, treat unknown note types as 0s, and hope for the
|
|
best.
|
|
|
|
Bad files shouldn't make your parser crash. It should return an error to
|
|
the program, which behaves accordingly.
|
|
|
|
Future Extensions
|
|
-----------------
|
|
If this format is found to be inadaquate, the following extensions
|
|
may be added:
|
|
|
|
New metadata keys. This would be a new line in the metadata section.
|
|
It is unlikely such a line would be mandatory, since current songs
|
|
work fine without them.
|
|
|
|
New note types and commands. These would be new lowercase or uppercase
|
|
single characters in the song section.
|
|
|
|
Standard Game Modes
|
|
-------------------
|
|
SINGLE - Normal single player with up, down, left, and right, or versus
|
|
mode, if no VERSUS is found.
|
|
VERSUS - Two players, both with the same steps.
|
|
COUPLE - Two players with different steps.
|
|
DOUBLE - Doubles, one player on both pads.
|
|
|
|
5PANEL - Diagonal directions, and the center, for one player.
|
|
5VERSUS, 5COUPLE, 5DOUBLE - Similar to the 4 panel relationships.
|
|
|
|
6PANEL, 6VERSUS, 6DOUBLE, 6COUPLE: Up left, up right, up, down, left,
|
|
and right.
|
|
8PANEL, etc: All directions except center.
|
|
9PANEL, etc: All directions including center.
|
|
3PANEL, etc: Up left, down, and up right.
|
|
|
|
Changes:
|
|
--------
|
|
2004.03.01
|
|
- Version 1.2, released with pydance 1.0.
|
|
- Add 9 panel game mode.
|
|
|
|
2004.01.16
|
|
- Include comments in the example.
|
|
|
|
2003.12.23
|
|
- 3 panel modes.
|
|
- bpmdisplay metadata key.
|
|
|
|
2003.12.22
|
|
- 'cdtitle' metadata line.
|
|
|
|
2003.08.15
|
|
- Specify note types more exactly.
|
|
- Fix the broken DESCRIPTION in the example.
|
|
- Remove obsolete notes about the pydance implementation.
|
|
- Add more game modes to the list (especially of note is VERSUS).
|
|
|
|
2003.07.30
|
|
- Fix example of 'gap' attribute (-300 instead of 300).
|
|
- Fix nonsensical hold arrow example.
|
|
|
|
2003.06.29
|
|
- Fix a typo ("::" => "::=").
|
|
|
|
2003.06.27
|
|
- Add EBNF for COUPLE-style modes (spaces in Buttons)
|
|
|
|
2003.06.26
|
|
- Add a missing newline to LyricLine.
|
|
- Add (currently unexplained) BACKGROUNDS section.
|
|
|
|
2003.06.03
|
|
- Version 1.1
|
|
- Add 192nd notes with 'n', 48th with 'u'.
|
|
|
|
2003.06.01
|
|
- Version 1.0
|
|
- No more I command.
|
|
|
|
2003.05.23:
|
|
- Started changes.
|
|
- v1.0 draft preparation.
|
|
- Need to explain the I command.
|