Today’s topic is the engine configuration system; we’ll not only find out how it works, but the moral rules which govern its use. The post covers the three vital files which control the configuration: quake.rc, config.cfg and autoexec.cfg. Each one of these files belongs to a different interest, and as a mod author it is your duty to keep these interests in balance.
Most players are familiar with the .cfg files in quake. They are plain text files containing lists of console commands. The engine will read a .cfg file and play each command in sequence into the console. This allows a .cfg file to set values on cvars, bind keys and create aliases, and even execute commands like loading a map or playing a demo.
quake.rc appears to be the odd man out in our trinity of files, because it lacks this .cfg extention. Don’t let the appearance fool you, it is also a plain text list of console commands which is executed in exactly the same way. The different extension is simply a warning to players – hands off this file, it doesn’t belong to you! This begs the question – who does own that file? And who owns the other two files?
The answers are:
- quake.rc belongs to the mod designer
- config.cfg belongs to the engine
- autoexec.cfg belongs to the player
config.cfg belongs to the engine. At the end of a session, the engine will write all the key bindings and the values of selected cvars to this file, so that they can be recalled next time the game runs. The file usually gets read from and written to the mod directory. If no config.cfg exists there, it falls back to the one in the id1 folder – so the first time you run a mod you get the settings from the last time you ran vanilla quake. The rules for locating config.cfg are the same as any quake models or sounds, which makes adding config.cfg to a pak file such a grave sin! The pak file copy will always be loaded in favour of the one the engine writes, meaning cvars can’t be saved.
This system does have some limits now that there are a plethora of engines to choose from. Almost every engine offers cvars which relate to new features, and engines disagree on which cvars are worth saving from session to session. The result is that if you switch engines back and forth, you’ll lose the engine specific customisations you make to the cvars. It’s not a huge setback though, as most engines only save a small handful of cvars, and if you’re faithful to just one custom engine it works fine.
autoexec.cfg belongs to the player. It’s the right place to create your custom binds, set cvars that you always want to override or that engines don’t save. Like config.cfg, autoexec.cfg is “inherited” from the id1 directory if the mod doesn’t have one. This is much more useful though, because it lets players define they favourite macros once in id1 and benefit from them in all their mods. Packaging your own autoexec.cfg with a mod is another sin because it destroys that mechanism. If you need to execute commands, you should use…
This is the property of the mod maker. The converse to the autoexec sin above is that players should not depend on customisations they make to the id1 quake.rc, as it’s the file that mods must replace to configure the initial console environment. So lets take a look at what appears in the standard quake.rc
// load the base configuration exec default.cfg // load the last saved configuration exec config.cfg // run a user script file if present exec autoexec.cfg // stuff command line statements stuffcmds // start demos if not allready running a server startdemos demo1 demo2 demo3
It’s so carefully commented already! You’ll see the big two cfg files from above, along with a few other details. We’ll talk about default.cfg a little bit at the end. stuffcmds is simple but important: all the stuff you add to the quake command line as +commandname parameter gets added to a buffer, and the stuffcmds instruction executes that buffer just like a cfg file. startdemos is the odd one out here, as it’s a direct command, rather than an instruction to load command from elsewhere.
One thing you might have noticed is that quake.rc, the file that the mod creator controls, is responsible for making sure the big two cfg files are executed. Don’t let the power go to your head! There’s no good reason to ever remove config.cfg from the quake.rc file, all it does is break the settings saving feature. Please also think extremely carefully before removing autoexec.cfg. If you think your mod is so different to stock quake that no player would reasonably want their binds imported, you can take it out. Adding an alternative like mymod.cfg might be nice though!
It’s important to look at the order that things are run, as this determines the precedence between the various configuration sources. The player’s autoexec commands are given high priority, only exceeded by command line settings, and of course the default commands are at the bottom of the stack (files executed first can be overridden by all the later commands). I’d pretty much recommend not messing with this order at all.
So if we want to execute some commands when our mod boots up, what are the options? One decision is where to put the commands. We can create a new cfg file and execute it from quake.rc, or just add the command directly to quake.rc. It doesn’t make a lot of difference though, so for simplicity we’ll add them directly in this article. A much more interesting decision is when to add the commands, here are the broad options:
Before config.cfg is for cvar values which are “initial recommendations”. Since config.cfg can override them, as soon as the player makes a change the setting stops having an effect (unless the engine doesn’t save that cvar). Similarly if you bind a key at this point, the binding only lasts until the player assigns something else to that key. That’s probably the best way to do key binding.
Between config and autoexec is for passive settings. Your settings will always get reapplied on boot, regardless of how they changed last game. The only thing that can shake this setting is if the player actively overrides it by expressing a new value in autoexec.cfg. This is a good place for recommended values of cvars, as it still lets a player overrule you if they need to. It’s probably not a good way to set key bindings, as a player who tries to rebind the key through the menu will find their work undone each time they restart.
After autoexec is for settings that are so vital to your mod, you must strongly discourage changes to their values. Remember you can’t completely prevent changes to cvars, the player can just pull down the console once in-game. The main case is a player who set cvar defaults in their id1 autoexec, which you need to override. Some examples: “gl_flashblend 0” if your mod depends on dynamic lights for gameplay, the head bob cvars if your map abuses weapon models to display hud items.
The startdemos command from quake.rc is right at the bottom of the list, which seems to suggest it’s given extremely high priority. However, this is offset by the very quiet nature of the startdemos command itself – it doesn’t do anything if a map has been loaded, or a connection made to a server, or a demo was played by one of the previous commands.
Darkplaces has a set of cvars which disable potentially mod-breaking changes to gameplay. Suppose our mod is specially designed to take advantage of the “killable zombie” change when it’s available, but needs to disable the other changes to work correctly in both darkplaces and other engines. We can create a new quake.rc to apply these fixes.
exec default.cfg exec config.cfg exec autoexec.cfg sv_gameplayfix_blowupfallenzombies 1 sv_gameplayfix_consistentplayerprethink 0 sv_gameplayfix_delayprojectiles 0 sv_gameplayfix_downtracesupportsongroundflag 0 sv_gameplayfix_droptofloorstartsolid 0 sv_gameplayfix_droptofloorstartsolid_nudgetocorrect 0 sv_gameplayfix_easierwaterjump 0 sv_gameplayfix_findradiusdistancetobox 0 sv_gameplayfix_gravityunaffectedbyticrate 0 sv_gameplayfix_grenadebouncedownslopes 0 sv_gameplayfix_multiplethinksperframe 0 sv_gameplayfix_noairborncorpse 0 sv_gameplayfix_noairborncorpse_allowsuspendeditems 0 sv_gameplayfix_nogravityonground 0 sv_gameplayfix_nostepmoveonsteepslopes 0 sv_gameplayfix_nudgeoutofsolid 0 sv_gameplayfix_nudgeoutofsolid_separation 0 sv_gameplayfix_q1bsptracelinereportstexture 0 sv_gameplayfix_q2airaccelerate 0 sv_gameplayfix_setmodelrealbox 0 sv_gameplayfix_slidemoveprojectiles 0 sv_gameplayfix_stepdown 0 sv_gameplayfix_stepmultipletimes 0 sv_gameplayfix_stepwhilejumping 0 sv_gameplayfix_swiminbmodels 0 sv_gameplayfix_upwardvelocityclearsongroundflag 0 stuffcmds startdemos demo1 demo2 demo3
You’ll notice that we’ve made these commands high priority, but this is justified because they directly affect the gameplay of the mod, rather than the control or the visual appearance.
So that just leaves default.cfg to be discussed. I believe that this also “morally” belongs to the mod maker, although I’m not too sure about that and welcome comments below. The file is, as the name suggests, for default settings, config.cfg will be overriding it as soon as the player changes the settings from this file. Suppose you add a 9th weapon in your mod selected with “impulse 50”. Adding ‘bind “9” “impulse 50” ‘ to a copy of default.cfg is a good way to add the command for the player without disrupting anything they’ve ever bound to the 9 button previously.
The one extra thing that default.cfg offers is a special feature in the engine. When you select the “reset controls to default” option from the game menus, it resets the commands by executing default.cfg. The file traditionally opens with “unbindall” for this reason. Particularly if you’ve made a mod which differs a lot from standard quake gameplay (something like qrally or airquake), having a good default.cfg will make it much more user-friendly.