Another Star 2 Dev Log #12: FM Synthesis

“I think the next big hurdle to tackle is scripting,” I wrote in my last dev log. Well, that was the plan, anyway. But shortly after writing that I decided to make a quick addition to the game’s room code. With just a little work, the game could automatically switch door tiles between “open” and “closed” variations as the player approached. It worked quite well and right away, despite being such a minor thing, really made the tiny world inside the game feel all that more grounded.

Another Star 2 in-game footage of doors opening and closing.

I’d imagine in real life, she’d just leave a bunch of open doors behind her with all the lights turned on.

This is done programmatically, by the way. No scripting is involved, which makes it really easy to throw doors into a room. The game simply caches all the door tiles after loading up a room and then the entities moving around the map ping their location as they move. But as I tested it out, I couldn’t help but realize how empty it felt because everything was so quiet. The doors needed a satisfying audio cue as they changed state. To do that, I’d need to implement a proper sound engine, the only major core engine task left other than scripting.

Being a child of the 1980s, I really love FM synthesis. Especially the early, somewhat cheap sounding little FM synth chips that Yamaha liked to develop. The first Another Star played prerecorded music composed in FL Studio using samples from (and a VST that emulated) a Yamaha YM2413, a chip used in the Japanese version of the Sega Master System. Most game soundtracks flock to the more traditional chip tunes of the NES or Commodore 64, so working with early FM synth sounds instead was a real treat for me. For those who never played Another Star, here’s an unused track from the original game to give an idea of how it sounded:

As I’ve noted in past dev logs, I’ve always planned for Another Star 2 to have a similar soundtrack that emulates early FM synth chiptunes. But I wanted it to sound more unique instead of being almost entirely limited to the preset instrument selection of the YM2413. Instead of just choosing a different emulated chip VST to record, I decided to go a step further and actually write a software FM synthesizer of my own to run in-game in real-time. Not the brightest solution, perhaps, but I’ve written a few before as experiments and I really had my heart set on doing this. To justify going through all the trouble of making it work, I decided I would create ways for the game to dynamically react to what’s happening on-screen. While far from impossible, that’s a lot harder to do with your usual pre-recorded tracks.

It took a month and a half of work—time I really probably should have spent elsewhere—but I finally accomplished it. Most of my time was spent writing the tool to actually get the music into the game. I thought about writing a simple General MIDI file importer, but even then I would need a custom tool to be able to do things like place event triggers and create song variations by enabling or disabling individual tracks.

FM Pipe Organ editor screenshot

Up to four operator FM is supported in the editor, but in-game only operators one and two are enabled. This is partially for optimization on older systems, and also to stick closer to the simpler, “cheaper” sound of the earlier FM chips used before the 16-bit era.

Most of my tools are written in C# with WinForms because it’s really quick to get things up and running, and afterwards I rarely need to rewrite any code in C++ for the game other than the routines for importing files, which usually doesn’t take very long. But a software synthesizer is a much different beast, and I didn’t feel like writing it or the playback code twice, once in each language. So I ended up writing the composing tool in straight C++, something I don’t normally care to do. As you can see, I wasted a lot more time trying to make it look pretty than I should have.

FM Pipe Organ editor screenshot

Because I wasn’t using WinForms, I even had to write custom interfaces for normally trivial things like picking where to save a file.

The playback format is similar to MOD music in that it’s pattern based, although each pattern is a variable-sized list of single-byte commands for a single monophonic channel instead of a table having something for all the channels together. Notes and other commands are inserted in the piano roll for each pattern, and then patterns can be assigned to tracks down below the piano roll.

FM Pipe Organ editor screenshot

The little board at the top is displaying volume in this screenshot, but it can also be used for editing stereo panning, assigning instruments, and more.

Finally, the variation editor is used to decide which tracks will be used on which channel. Internally all the tracks advance together and there can be any number of them, but only the assigned tracks send their notes to a channel to play. Originally, there were going to be only four channels of FM synthesis, and then there would be two other channels limited to just noise generation and low-fidelity PCM samples that could be used primarily for percussion. But this would require actually programming special channels for noise generation and low-fidelity PCM samples instead of, you know, just telling the computer to make six FM channels instead of four. The FM channels can already switch from sine waves to noise generation anyway.

In the end I think I won’t limit any channel to any ability the others don’t have and just continue to use all six FM channels as proper FM channels. I really need to get back to making a game instead of messing around with this anyway. (The editor actually supports eight channels, but that’s an awful lot for a simple 8-bit system, so the game only uses six.)

FM Pipe Organ editor screenshot

Notice that by this point I stopped caring about fixing visual bugs in the editor.

Now, here’s that same track from before, recreated using the new software synthesizer and playing back in the editor:

And, since the game and the editor use the same synthesis and playback code, it only took literally an afternoon to get the audio into the game itself. It’s still rough around the edges, but here’s some actual footage I recorded this morning:

Notice how the music switches between variations when going from one room to the next. You’ll probably also notice that sound effects cut out parts of the music so they can play. This was common back in the day, and makes me feel nostalgic, but I may break down and add a couple of channels that are reserved just for playing sound effects.

And now I really do need to get to work on that scripting engine!