I got started trying to make a game for Minetest in just 4096 (4Ki) bytes yesterday. Things progressed pretty well with a texture atlas/sheet graphic file and a bunch of code golfing, but then I hit a stumbling block: sound.
If I open Audacity and save an empty file as Ogg Vorbis, it comes out at 4119 bytes, which on its own is beyond the 4 Ki limit. The thought occurred to maybe steal some sounds off the engine, but there are none to use that ship with the engine, and stealing sounds from another game would defeat the point. Maybe the game would need to be 16-32 Ki just to have a few sounds, or maybe a single sound with pitch variations or offsets would work.
My thinking then goes a few directions: generating the Ogg files myself in Lua with some kind of highly-compressed encoder, trying to Muntz the Ogg file down, or trying to push for a much smaller format to be supported in the engine. This thread is about the last of the those.
sfxr
Back in December 2007, it was the 10th Ludum Dare competition and one entrant, DrPetter, needed a tool to make sound effects quickly to meet the competition's 48 hour time limit. He named it sfxr (sfx = sound effect, r = -er suffix; it makes sound effects). It worked quite well, a lot of entrants used it, and it has seen wide popularity since.
sfxr isn't even new to Minetest. It was mentioned by Melkor in a forum thread back in 2013, and in the OP of Zoonami.
These days, you can get a lot of programs, even web apps, that can give you the same results as the original SFXR program. Debian has sfxr-qt.
The sound effects produced by SFXR are output in WAV format. SFXR-qt uses SDL to play the samples back in the preview window. You can also save the SFXR info in the original binary SFXR format or the newer JSON-based SFXJ. These files are quite small. In fact, the original binary format is so small that encoding it with a compression codec like gzip or xz will increase its size due to the fixed cost of overheads. Sizes are in bytes:
Code: Select all
1073 a.sfxj
108 a.sfxr
464 a.sfxj.xz
168 a.sfxr.xz
133 a.sfxr.gz
A rationale
With sfxr direct integration, I could drastically reduce file sizes compared to Ogg. Now, it would probably be a bit selfish to ask for it purely so my project could turn out well. I'd also like to point out a similar long-lived proposal, #3873, to add Tracker Music support to Minetest.
Minetest would not be the first game engine to directly integrate sfxr playback. "Chroma 2D" (MIT-licensed) has an integration for it: Chroma.Audio.Sfxr.
Back in the 8-bit era, computers often had audio chips that could be programmed directly, instead of having to feed samples to the sound card. This enabled games to ship with sound effects and music in an era with tiny storage requirements. We no longer have that problem with pretty much any hardware that can run Minetest, but I still like it in principle. The tracker music proposal would enable a large library of music to be played back directly, and save on server and ContentDB bandwidth. My proposal is more modest, but it definitely could save on transfers.
I can also think about two parallels in Minetest: Schematics and graphics. We have an API for serialising schematics into a binary format that are made out of Lua tables, and deserialising them back into the game world from files. We have a png texture modifier for making a whole image out of. I think it would be good to be able to specify a table of sfxr parameters and play it back. The audio system doesn't get as much love as graphics :(
Discussion questions
Have you used sfxr before? Was exporting it to Ogg a significant barrier for you? Maybe an inconvenience?
Is the large size of sound effects a concern for you? What about music?
Do you think it's possible to approach my file size problem in a different way, such as encoding an Ogg from Lua? Do you have a library in mind?