instrument-generator/readme.md
2025-08-23 12:15:08 -04:00

48 lines
6.4 KiB
Markdown

# How to Use
`python3 generate_instrument.py`
# Origins
I had an idea: Dwarf Fortress generates musical instruments as part of its worldbuilding. I like imagining those. What if I challenged myself to draw them?
So I set out doing so! And rapidly discovered that there are only pretty limited variations in the Dwarf Fortress generator. I mean, no shade to it! It works wonderfully. But it didn't provide the variety I was looking for.
So I decided to build a musical instrument generator of my own!
# Hornbostel-Sachs
On various wikipedia trawls I have come across the [Hornbostel-Sachs classification system](https://en.wikipedia.org/wiki/Hornbostel%E2%80%93Sachs). I knew it classified musical instruments, so I figured it might be a good place to start. And indeed, it does! It is similar to and inspired by the [Dewey decimal system](https://en.wikipedia.org/wiki/Dewey_Decimal_Classification). Here's the basics:
* An instrument is catalogued as a string of digits. Starting from the left, you choose digits to describe the instrument.
* Each digit narrows down the category of instruments described.
* A `.` separates groups of three digits for readability.
* It categorizes instruments according to the mechanism by which they make sound; thus the first digit determines whether it's an idiophone (the material of the thing itself vibrates), membranophone (stretched drum head membrane), chordophone (strings), or aerophone (column or body of air).
It was designed for cataloguing instruments in collections; everyone loves it and it's doing a great job.
I figured, it'll be easy to generate a random Hornbostel-Sachs code, and then I can draw it, and then I've accomplished my goal! I have a generator with a wide variety of instruments (given that the Hornbostel-Sachs system is supposed to classify all known instruments). So I set about building it.
# Generator 1
The first thing I did was download the latest widely-accepted version of Hornbostel-Sachs, available from Musical Instruments Museum Online [as a pdf](https://cimcim.mini.icom.museum/wp-content/uploads/sites/7/2019/01/H-S_20classification_20final_20version_20_282013_29_20without_20editorial_20markings-2.pdf) showing the meaning of all the codes. I basically copy-pasted the actual data section, did a little bit of REPL wrangling to get it into a vaguely usable line-by-line format, and saved it as the file `Hornbostel-Sachs` in this repository. You're fine by me to use that, by the way.
I wanted something a little more fancy than just grabbing a random code from the list, so I wrote some python (`generate_instrument.py`) to select a random starting digit, then a random next digit, and so on, so the output is evenly distributed across each level of categories, rather than evenly distributed across all the codes together. Thus, even though there are ~150 aerophone categories and less than 100 chordophones, it is as likely to generate an aerophone as a chordophone. It then prints out the meaning of all the digits in order, thus providing a full description of an instrument. Hooray!
# Generator 2
Then I got bored and built a second one. This is not the best python I've ever written and I've always found tree-type structures very difficult to write on the seat of your pants, but I resolutely refused to plan this out. However! This builds a whole data structure representing the tree of categories Hornbostel-Sachs describes. Thus this is able to do the same evenly-spread generation as in generator 1, but it's *also* capable of effectively using suffixes.
Suffixes are supplemental information that cuts across many categories; for example, "played with a keyboard" is a suffix, because essentially any mechanism can be played with some kind of keyboard. Each suffix is "scoped", in that some suffixes apply to all chordophones, some to all aerophones, etc.. For example, any aerophone may have the suffix `-7` to indicate that it has fingerholes which can be covered. `-71` indicates that the holes are covered by keys, and `-72` means it has some kind of mechanism like a perforated roll or sheet (think a [crank-powered organ](https://en.wikipedia.org/wiki/Street_organ)).
I've been toying with the idea of making modifications to the system (the original authors envisioned the system being updated and extended over the years!) to account for some things I consider mistakes - for example, the suffixes for membranophones include `-8` and `-9` as membranophone-specific categories, whereas all other categories allow for `-8` meaning "with keyboard" and `-9` meaning "with mechanism". This means you couldn't have a set of drums actuated by a keyboard - I've never heard of such a thing, but there's certainly no reason it can't be. I think we should get to generate - I mean classify - such things!
Anyway, generator 2 (`generate_instrument_2.py`) is another script that reads in the file, builds a tree, and then walks that tree to generate instruments. I threw in a couple extra bits of information like a shape hint, a material hint, and sometimes a descriptor, to spice it up. The big differences between generators 2 and 1 are that it can generate compound instruments (for when an instrument has multiple differently-coded parts) and it can make use of suffixes.
# Generator 3
I'm working on generator 3 now. I had a lot of fun exploring Hornbostel-Sachs, but I'm not convinced I actually need it for what I'm envisioning. So I'm going to try making a generator in the "traditional" style - essentially, a template string with a bunch of stand-ins for elements or phrases randomly selected from a list. Like mad-libs! I'm heavily inspired by [Nora Reed's generators](https://nora.zone/) in this. We'll see how it goes! The plan is to build it around a set of components that can be randomly selected to go together. I'm embracing the possibility that they clash; I want to generate weird instruments so I'm forced to imagine and draw them!
# Oh Yeah, Drawing Them
Oh right, that was the original point. No matter, I had fun, which is the real point of all this. But I do want to try to do drawings! I'm posting them on the [fediverse](https://beach.city/tags/musicalMenagerie) and [bluesky](https://bsky.app/hashtag/musicalMenagerie) under the tag `#musicalMenagerie` which is maybe the fancy name for this project... Although there seem to be a couple other people using that name on the internet. If they come calling I'll change this to something else. It's fun and challenging!