Valkyrie Dev Blog #1 – Welcome

Back around May of this year I began working on my own indie game, codenamed Valkyrie. I previously put out one (really bad) game in 2009, but I’d like this one to be something I can try to sell. Since I’m not putting much other content on this blog, why not do weekly dev blog updates? Hell, it’ll encourage me to be more active with the development, at least.

Anyway, not sure I want to divulge a ton of the details of the game yet. But here’s what I’ll say: It’s a rhythm game that has a lot of feature overlap with Dance Dance Revolution. As such, the goal is to make it compatible with StepMania simfiles, and that’s what I’ll talk about in this post. Oh, and I’m making it with GameMaker: Studio, so I can’t use any of the StepMania codebase.

On May 13 I made my first real commit to a project called libsm. This repository was started by me, and it’s going to be an extension for GM:S that allows you to easily read and write simfiles. Currently I’m aiming for full support of .sm files, but I’m going to try to get support for .ssc afterward, and then maybe .dwi

So the tricky part here has been figuring out how the simfiles are set up. The StepMania website has some documentation on it but it’s…not great. Particularly the #NOTES section. The site sums up the note data as this:

Note data itself is a bit more complex; there’s one character for every possible playable column in a chart type. Note types (e.g. 4th, 8th, etc.) are determined by how many rows exist before the comma (which separates measures).

But it doesn’t go into detail about how exactly the note values are determined. This has turned out to be my biggest hurdle so far. After many hours of examining the files and testing them out in StepMania itself, I have figured it out. Here’s an explanation of how it works.

StepMania has the following possible note values: 4th, 8th, 12th, 16th, 24th, 32nd, 48th, 64th, and 192nd. My initial assumption was that it only had powers of two (4, 8, 16, 32, and 64) but that turned out to be wrong and invalidated a bunch of code I had written for Valkyrie (yay!). The 192 seemed a bit odd considering how large the jump is from 64 to 192 compared to the jumps between the other values. However, there’s a good reason for this: If you examine all of these numbers, you’ll find that they are all factors of 192. 192 is simply the least common multiple of all of the other note values. And here’s the reason why that’s important.

A measure in a simfile can look something like this:

1000
0100
0010
0001

That is a representation of a measure that contains four 4th notes.

0000 <- would be 4th note
0100 <- 8th note
0110 <- 4th note
1000 <- 8th note
0000
0001
0001
0000

This is a measure that has a combination of 4th and 8th notes. Maybe you've noticed the pattern here already.

Basically a measure is represented in terms of a single note type, be it 4th notes, 8th notes, etc. If I place a 192nd note in my simfile, all notes are represented as 192nd notes, which is possible since they are all factors of 192. The number of lines in a measure is equal to the level of note used to represent it; a measure of 4th notes only is 4 lines long, and a measure that's represented as 192nd notes is 192 lines long. So I can say that the length of the measure is equal to its "precision" as I've taken to calling it.

Here's another example:

0000
0000
1000 <- 64th note
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
(imagine this repeated 3 more times)

That is an excerpt of a measure represented as 64th notes. The 1 there represents an arrow. It's on line 1 (we start counting at zero), which is a beat offset 1 * (1/64). But if we add, say, a 192nd note to this measure it's going to look like this:

0000
0000
0001 <- 192nd note
0000
1000 <- 64th note
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
(again, imagine it repeated 3 more times)

Our 64th note is still there, but now it's represented in terms of 192nd notes. It's now on line 3 (again, counting from zero), which is beat offset 3 * (1/192) which you will notice is exactly equal to our earlier 1 * (1/64).

So uh, yeah. Kind of a long-ish post, but it was a difficult problem for me to solve, and it's kind of difficult to explain. Right now in the game I'm working on getting some working arrow generation using my newfound knowledge. At some point I plan on writing up some formal documentation of the note data setup and contributing that to the StepMania project so others don't have to struggle as I did. Anyway, hopefully next week I'll be able to show a screenshot or even a video.

You May Also Like

One thought on “Valkyrie Dev Blog #1 – Welcome

Leave a Reply

Your email address will not be published. Required fields are marked *