FamiTone: A Music Engine for the NES
The creator of FamiTone recounts building a lightweight, high-performance music driver for NES homebrew games — from analyzing CPU costs of commercial game sound engines to designing an optimally constrained library that became the standard for hundreds of fan-made titles.
Today I've decided to share with the world another story from my many 8-bit exploits of days long past. This is simultaneously a review and a sort of "postmortem" of a fairly successful project, albeit one that's about a decade and a half late. It's never too late to bask in the glory of past successes!
This is the story of a library I once created — a music "driver" or engine called "FamiTone," designed for creating sound in homebrew games for the 8-bit Famicom game console, also known as the NES, also known as the "Dendy." Along the way, we'll figure out what it is, how it works, who could possibly need it, and whether it ended up being useful. Spoiler: yes.
Official Game Development
The approach to developing games for third-generation consoles, which include the Famicom and NES, was vastly different from what has long been standard today. Not only were there no ready-made universal game "engines" like today's Unity and Unreal, but there was no operating system, no files, and no standard formats. Just bare hardware, hardcore: memory, device registers, a processor, and assembly code. And no "devkits," SDKs, or even technical documentation!
This seems strange now, but those were different times. The video game industry was just being born, and the market had different rules. Nintendo didn't welcome third-party developers on its platform, seeing them as competitors and a threat to its own business, and was unwilling to help them develop games. On the contrary, even the choice of the then-unpopular MOS 6502 processor for the console was motivated by the hope that Japanese competitors wouldn't be able to quickly figure it out. And the specifics of the game development process within Nintendo itself were deliberately hidden, which is why very few historical records survive of how it was actually done.
This strange situation persisted throughout the console's entire lifecycle, from 1983 to 1994. Even when the console launched in the US and European markets, strict licensing policies were introduced, and game publishing was put under Nintendo's tight control, local developers were essentially left to their own devices — figure out how to make your games however you want.
As a result, each individual developer was forced to first study the hardware through reverse engineering, then adapt commercial cross-assemblers, create their own in-house development tools and engines. In short, reinvent their own wheels. And of course, this applied to sound as well.
Music Drivers
While the format of graphical data in games was at least partially determined by the video system design and was similar across games, no standard for music data existed. Essentially, the console only had a sound synthesizer capable of producing the simplest sounds, knowing nothing about music. Therefore, contrary to common modern assumptions based on contemporary experience, there was no ready-made music format like MIDI on game consoles of that era. Combining individual sounds into something resembling music had to be accomplished through programmers' efforts, purely by software means.
This task was solved by code that modern researchers call a "music driver" or "sound engine." Despite the name, this driver has nothing in common with modern device drivers, such as those for sound cards, and implements a different function. Here we mean a set of procedures that parse a script of encoded events — which note should sound when — and also form more complex, time-varying sounds to create the semblance of different "instruments."
In the absence of standard solutions, each developer invented their own driver with its own features and capabilities, and as a result there are a good hundred of them. Of course, drivers could later be reused within one company or the works of the same hired composer, who was often also the author of his own custom driver, and they could evolve over time, which meant the code and data format in each subsequent game could differ.
While the character of the sound is largely determined by the sound chip's capabilities, the driver determines how fully and efficiently those capabilities are exploited. Sometimes the difference can be very radical, from the simple timbres of Super Mario Bros. to the dense, rich arrangement of Super Spy Hunter. Different drivers have a quite recognizable, easily distinguishable character of sound. Confirmation of this thesis is the sound in games from Capcom, Konami, Sunsoft, Natsume, and Software Creations — the same set of sound chip capabilities is revealed in very different facets.
From a technical standpoint, drivers differ not only in their feature sets but also in less noticeable parameters that nonetheless affect the games themselves. First and foremost is CPU time consumption, main RAM usage, and data compactness. The more efficiently a sound driver's code is designed, the more system resources remain for the game itself. This is quite important, as there are known examples where an inefficient driver consumed up to one-tenth of CPU time. Not so little, considering how modest the Famicom/NES's resources are.
It's worth mentioning separately how music was created for commercial games. This is actually a subject for a separate long conversation that could be quite fascinating for geeks, and someday I'll tell you about it in much more detail.
For now, in a nutshell: no special music editors existed. Each developer invented their own solution. As a rule, music was composed in one's head and then encoded manually in hex or assembly, or entered in MML (a script similar to the PLAY statement syntax in BASIC). Late Western developments occasionally used MIDI sequencers or trackers, but not specialized ones — regular ones — and then the data was somehow converted by custom utilities.
The main consequence of this approach was that you couldn't hear the music in its final sound during composition, and the process of achieving the desired result was very labor-intensive and uncomfortable, and not every developer had the patience or other resources to achieve truly quality sound from their drivers and music.
Homebrew Games
The release of The Lion King in May 1995 marked the end of the platform's commercial life. No more games with the legitimate "Licensed by Nintendo" inscription would ever be released for it. However, the platform's story didn't end there. Next, unlicensed specialists took over — commercial developers who didn't make it onto the last train, Chinese software pirates, and soon enough, ordinary enthusiasts.
Amateur games for obsolete game consoles are known by the collective name "homebrew," which previously referred to home-brewed beer. Essentially, a kind of "moonshine" from the world of video games. Given the passage of time and blurry definitions, it's probably no longer possible to determine when and how the first amateur game appeared. The enthusiast movement was born in the 1990s, leading to the emergence of emulators, fan translations, game replicas, and eventually original developments. Notably, among the earliest examples of this activity, there are quite a few products with domestic roots. But I'll definitely tell that story another time — today our agenda is music.
Hobbyists created their first games using roughly the same approach as commercial developers of the past: they studied the hardware themselves, adapted existing development tools, and invented their own. Although initially there were few enthusiasts, the power of community and free exchange of experience through the Internet allowed the process to be accelerated and avoided reinventing the wheel many times over: unlike commercial development, a solution once created by hobbyists had a chance of becoming available for use by a wider circle of enthusiasts.
Over the decades of its existence, the homebrew development scene has grown enormously, especially in the recent decade. If in the 2010s only a handful of games came out, usually very simple ones, the most successful being Battle Kid at the time, now hundreds of people are creating homebrew, dozens of games are released annually, including absolutely mind-blowing developments like the game Former Dawn.
And of course, homebrew games also needed music. For its creation and playback, some solutions were also developed.
Music for Homebrew
Of course, initially amateur developers followed in the footsteps of their commercial brethren: they invented their own sound procedures, typed music as sequences of bytes in assembly source files, and didn't share their procedures. Perhaps it was fun, but it slowed overall progress.
The first ready-made solution created by enthusiasts for adding sound to their developments appeared quite early, way back in 1999. This was the program Nerd Tracker II, created, however, for the already-outdated MS-DOS operating system.
The next ready-made solution was the now-famous FamiTracker editor, whose development began in 2005.
In 2010, a third ready-made solution appeared, also for Windows, originally bearing the name PornoTracker. Later the author renamed the project to MuseTracker.
All of them are, in modern terminology, "hyper-trackers" that squeeze the best possible sound from the system regardless of resource costs. Their driver procedures weren't optimized for use in games. And the main problem was the lack of support for sound effects played simultaneously with music — a feature critically necessary in any game.
That's where I entered the game.
The Path of FamiTone
I came to homebrew NES game development at the end of 2010 through an enthusiasm for the ZX Spectrum and various game consoles in the 1990s and early 2000s.
I wrote the source code of my driver for NESASM, and then using a converter, versions for Asm6 and CA65 were automatically generated. The name FamiTone was suggested by one of the most active homebrew enthusiasts of those years, Memblers, in the #nesdev IRC chat.
The Benefit of Constraints
To achieve maximum engine performance, I decided to limit its capabilities to an absolutely minimal necessary set. I measured CPU cycles of commercial game music drivers:
| Game | Location | Average | Peak |
|---|---|---|---|
| Batman | first level | 1085 | 3780 |
| Battletoads | title screen | 482 | 1820 |
| Contra | first level | 1090 | 4554 |
| Mega Man | Cutman level | 2311 | 7639 |
Comparison of track data sizes (bytes):
| Track | FT 0.3.7 | FT 0.4.6 | FamiTone | FamiTone2 |
|---|---|---|---|---|
| After The Rain | 7847 | 6059 | 6315 | 4676 |
| Danger Streets | 4825 | 4840 | 5522 | 4354 |
RAM and code size (bytes):
| Driver | RAM | ZP | ROM |
|---|---|---|---|
| FT 0.3.7 | 241 | 21 | 5128 |
| FamiTone | 183 | 7 | 1493 |
| FamiTone2 | 186 | 3 | 1636 |
APU Capabilities
The APU is a fairly typical synthesizer of its era with five heterogeneous channels: two Pulse channels, one Triangle, one Noise, and one DMC (Delta Modulation Channel).
Engine Architecture
The driver is a single source file of about 1,000 lines of assembly, divided into music and sound effects components.
Envelopes
FamiTone implements 11 envelopes total across all channels, using a simple RLE-encoded format for maximum speed.
Sound Effects
Sound effects are stored as pre-calculated register dumps, overlaid on music via volume priority.
Legacy
FamiTone was used in hundreds of homebrew games. The original was released as Public Domain, spawning forks including FamiTone3-5 by nesdoug and a Game Boy port. While GGSound (via NESMaker) may now be more popular, FamiTone's influence on the NES homebrew scene remains significant.