A then-11-year-old boy I’m friends with approached me several year ago:
Hey Jan if you can can you show me how to mod ydkj game files with my own music and stuff?
Well how could I say no! And so began my quest to reverse-engineer files for You Don’t Know Jack Vol. 3 — a game that came out the year I was born. A game that will only run with a resolution of 640 x 480 x 16 colors (This is the VGA standard). A game where the internal volume slider is broken on my machine. But I did it! And in this post I will explain how.
You Don’t Know Jack is a franchise of trivia video games that have a very quirky presentation. Particularly intriguing to him are the question segues, which announce the question number in an, um, humorous way:
I bought YDKJ3 through a Humble Bundle and installed it through Steam and after getting creamed by a few “Impossible Question”s I went looking for the files. The install was in the default location for Steam games C:\Program Files (x86)\Steam\steamapps\common\YDKJ_VOL3 and the media file for question segues/numbers was J3Items\QNUMBERS.SRF. “SRF”, huh? In essence modding is as easy as replacing the game’s audio and video files with your own, using copy-paste. But this unknown format presented an extra hurdle — it’s an archive file. Games frequently glue all their assets into a single (or a few) archive files, in the hope that it will speed up reading them from disk.
My next step was online research. Topping my search results was “SRFExtra", a software which extracts SRF archives and gives you the individual files, but does not create a new archive from your custom files. This page and this forum posts have done the detective work and figured how the format was structured exactly (Something you can do yourself with tools like hexdump using common sense reasoning, pattern recognition, and A LOT of patience). The whole SRF file is structured like this (“” indicates a repeating set of items):
LONG magicno srf1 -- it's an ".SRF" file
LONG filelen -- file length INCLUDING header, in bytes
LONG headerlen -- length of REMAINING header EXCLUDING the 3 already-seen longsLONG 'off4' -- constant indicating graphics section begins
LONG numgraphics -- length of the following array of graphics
[LONG name LONG offset LONG size] -- pointers into the RAW dataLONG 'snd ' -- constant indicating audio section begins
LONG numsounds -- length of the following array of audio clips
[LONG name LONG offset LONG size] -- pointers into the RAW dataRAW data
A little technicality is that the extracted audio clips have a garbage header. This other forum post by a fellow German clued me in on what to replace it with to get a playable file. Not really knowing the reason for the bad headers I grumblingly added a section to my Python extractor script after some trial-and-error. I finally have the graphics and AIFC files which — who else — VLC can play.
But since we know the format now, we could just prepare a battery of audio files and construct an SRF archive from them, right? Yes and no. The extracted files are AIFC files, which stands for Audio Interchange File Format (Compressed), and is an obscure Apple-specific file format. In fact Python plans to remove support for AIFC soon (PEP 594).
So the files we feed in also need to be AIFC. I first tried Audacity, but Audacity can only export to (uncompressed) AIFF files, so the command-line tool ffmpeg came to the rescue. Run the conversion, build the SRF file, replace the original, start the game, navigate to the first question, and… silence.
Turns out the AIFC files are “ima4-encoded” which is where I hit a roadblock and asked this question on StackExchange, perhaps the greatest set of sites on the internet. Turns out we need to specify an ima4 codec by passing the -c:a adpcm_ima_qt flag to ffmpeg, fine.
I asked my friend for some voice clips of him “covering” the question segues, ran the script, and there we go, YDKJ3 My Friend Edition!
Below is a demo. For privacy reasons, I replaced the clips with meme songs:
I’ve uploaded all my code (sans voice clips) to this GitHub repository here: https://github.com/xjcl/ydkj_audio
PS: An additional protip — In case the game starts as a small window in the center of your screen, right-click on the .EXE in C:\Program Files (x86)\Steam\steamapps\common\YDKJ_VOL3 and select “Run in 640x480 screen resolution” to enable fullscreen!