Writing Maintainable autoexec.cfg Files for Quake2

by Cy Edmunds ("Cycho")


  "Maintainability" of software is the ease with which changes and corrections can be made. Ideally you should be able to change at least some things by editing in precisely one place. Over the years the design of programming languages has evolved to support better maintainability with such innovations as named variables (although that's going back pretty far!), subroutines, structured programming, and object oriented programming. The purpose of this article is to suggest some ways to improve the maintainability of your Quake2 config files.

  If you are like most players you play several different mods with a folder for each. In each folder you must place an autoexec.cfg file to express your preferences. Experienced players often have sophisticated preferences making for lengthy autoexec.cfg files. You may wind up with half a dozen autoexec.cfg files on your system, each of which is lengthy and only slightly different. This is an excellent prescription for maintainability problems.

  Let's say you decide to change your zoom control from

// press and hold version
alias +zoom "fov 45"
alias -zoom "fov 90"
set fov "90"
bind e "+zoom"

  to

// toggle version
alias zoom_in "fov 45;alias zoom zoom_out"
alias zoom_out "fov 90;alias zoom zoom_in"
alias zoom "zoom_in"
set fov "90"
bind e "zoom"

  You make the change in your baseq2/autoexec.cfg and play a little single player to check it out. You decide you like it and now you want all of your mods to work the same way. You have to remember where all your autoexec.cfg files are and make the same change in each of them.

  At this point you might well wonder if there isn't a better way. After all, a boring, repetitive job like this is a good job for a computer but a bad job for a human being. Operator fatigue being what it is you may well make some sort of mistake such as replacing the wrong segment of text which may result in some nasty surprises the next time you play that mod. Clearly it would be better if you could make the change in only one place and have it automatically update all of your mods at once. If you structure your config files correctly that is an easy goal to achieve.

  In object oriented programming you are often called upon to abstract common elements of code into a class. This improves maintainability by isolating and hiding as much of the implementation as possible. You can do something similar here by finding all the lines in your autoexec.cfg files which are exactly the same. Put these common lines in a file called (for the sake of argument) "common.cfg" in the Quake2 directory. Then go through each of your autoexec.cfg files and delete the common parts leaving only the unique parts. (You may be surprised at how little is left. My baseq2/autoexec.cfg file has only one command and my Lithum/autoexec.cfg has only three.) Finally, add the following line to the top of each autoexec.cfg file:

exec "../common.cfg"

  The ".." indicates the next higher directory which should always be Quake2. We put common.cfg in the Quake2 directory so this command would be the same for all mods.

  Going back to our example, now that we have changed the way the zoom works and tested it in single player mode, what remains to be done? Nothing! Because all the other mods refer to common.cfg indirectly they have already been updated and are guaranteed to work the same as the single player version. That's good maintainability.

  However, we could still do better. Let's say that you decide to try a larger field of view. Now that your .cfg files are structured correctly you can make a single change to your common.cfg file:

set fov "110"
which affects all mods at once. Let's say you try it and like it. Unfortunately the first time you zoom in and back out your field of view set back to 90. The problem is that the alias "zoom_out" resets the field of view. You should have changed it to:
alias zoom_out "fov 110;alias zoom zoom_in"

  Again though, there is a better way. This bug crept in because the same constant ("90") appeared twice in the file. This is another prescription for maintainability problems and is also easy to fix. This time we will use $ variables:

// maintainable toggle version
set default_fov "90"
alias zoom_in "fov 45;alias zoom zoom_out"
alias zoom_out "fov $default_fov;alias zoom zoom_in"
alias zoom "zoom_in"
set fov $default_fov
bind e "zoom"

  Or course there is no built-in variable named "default_fov". The example shows how you can create your own variable using the same syntax you use to set a built-in variable. When it comes time to use the variable you prepend a dollar sign to its name as shown. Going back to our example we can make the following change:

set default_fov "110"
and the field of view will be updated in both the zoom_out alias and the initial fov assignment.

  In summary, make your autoexec.cfg files more maintainable by:

1. putting all common commands in a single file, and

2. making sure no constants appear more than once by using $ variables.

  Naturally, you should back up your current autoexec.cfg files before trying any of these ideas. They might not be as maintainable as they should be but at least they work!

  That's it. Happy hunting.

Cycho

Acknowledgement:
Many of these ideas came out of discussions on my favorite newsgroup: alt.games.quake2.