Because Joel's development is interesting, whether you think so or not.

If you get an error message, just refresh. Usually, that works.

Day 3 and AGI Voice Packs

I've gotten the skeleton day 3 implementation finished and have started on to day 4. Of course, I can't emphasize enough that this is framework stuff - putting the stuff into the game that I know for a fact needs to be there without fully developing it until later, but nevertheless I'm getting into parts of the game that seemed a long way off not that long ago. As I hoped, that is keeping my interest in working on the game going, because I'm not getting blocked by temporary problems. I've also been adding a few improvements to earlier parts of the game.

It occurred to me today while I was working on the game that it should be fairly easy to create optional voice packs for AGI games with some adjustments to NAGI - I don't really remember why I was thinking about that, but I was. Supporting voice does require interpreter changes, of course, so it can never be done with the original DOS interpreters, but it does not require changing the meaning of any AGI commands. The way most interpreter extensions created to date have worked is that some rarely-used command is replaced with the extended functionality. This is how both the mouse and palette hacks worked.

To do a voice pack, though, all you need is a separate voice resource file and something telling the voice-aware interpreter to look for it. This is a key point because it means that you can actually do voice packs for games that have already been released without modifying the game at all. A game with a voice pack would run fine on a voice-unaware interpreter - it would just be a text-only version of the game. The game itself would never know the difference.

The way it works is fairly straightforward...you modify the interpreter's implementation of the print command (and its variants, like print.v and print.at) so that when it prints a message it looks up a corresponding audio file and plays it. You could even set up the interpreter to play the audio file and not print the text at all.

I went ahead and created a proof-of-concept implementation of this in less than an hour, and a good portion of that near-hour was spent downloading the NAGI source code, getting the SDL and unixem libraries that it uses off the Internet, and downloading and installing the ~450 MB DirectX SDK so that the SDL library would compile in Visual C++ Express, then setting up the Visual C++ environment just so I could build NAGI without modifying it.

Once I had the code up and buildable, it didn't take long to find what I was looking for: NAGI's implementation of the print command. I went with a simple scheme. To print a message, you have to know the logic number of the message and the message number within that logic. So, I used a basic naming convention...the audio file for a given message would take the form "MsglogicNumber_messageNumber.wav". So the audio file for message 4 from logic 30 would be named Msg30_4.wav.

I then put in some code so that every time a print command was issued, NAGI would check to see if a corresponding WAV file existed in the folder and, if so, it would play it. I was surprised at how easily I succeeded here, for a few reasons - including the fact that I'm not very familiar with the NAGI code and that I was using a Windows API call to play the sound instead of using the SDL library like the rest of NAGI, so conflicts could have happened easily (in fact, the first few runs I was afraid it wasn't going to work, because NAGI exited immediately after playing the audio file, but it turned out that I had passed the parameters to the Windows PlaySound function wrong and some startup thing in NAGI wasn't running the way it was supposed to).

I recorded about 50 WAV files, most of them short messages like "You're not close enough.", and they all played without problems exactly when they were supposed to. The text "You're not close enough." would appear on the screen and you would simultaneously hear my voice say "You're not close enough."

If anybody is interested in this, I might release a reference demo, but I have no plans at the moment to release the code that I wrote today, because it really is not fit for use until somebody comes along and writes a proper SDL implementation and does a lot of testing to find out all the little problems that might arise.

I did learn some interesting things, though: recording voice stuff for a game is really tedious. Those 50 messages that I recorded were select messages from about 3 Chimera Angel rooms - I recorded most of the narrator lines from rooms 2, 3, and 6, but because it would have just sounded silly, I didn't record any lines that I have Jennifer speaking, which is quite a few. And this says nothing of Jennifer and her parents, or the dozens of other logics in the game.

These short 50 messages also wound up taking about 40 megabytes of disk space as WAV files, so anybody who wants to create voice pack ability for AGI will need to provide some support for lossy audio like MP3, just to keep the data down to a reasonable size (it's pretty easy to envision all recorded messages for my game reaching over 1 GB).

However, the fact of the matter is that if anyone were interested in the ability, it is definitely possible to have optional voice packs for AGI games, and you don't have to modify your code to do it. You just have to record lots of lines, perhaps find some voice actors, and find out all the message numbers that you're recording so you can name your files appropriately :)

(More blogging gripes: I put my &lt; code to do a < symbol and it still got ripped out when I was looking at it. I don't feel like explaining that for anyone who doesn't have any idea what I'm talking about. This has been a pretty technical entry anyway, so I'll leave it at that. To top it off, the stupid "edit" function doesn't work, either. If I make an error in an entry, I have to delete it and repost it in its entirety. What a freakin' pain).

2007-03-19 02:37:51 GMT
Add to My Yahoo! RSS


Joel's Development Journal