Adding new Cvars

From The DarkMod Wiki
Jump to: navigation, search

Originally written by Ishtvan & Domarius on

To add a new console variable (cvar) the files that must be changed are /game/gamesys/syscvar.*

Let's use the example of adding a cvar to globally lower the volume of sounds that AI hear. We want to add a cvar called dm_ai_sndvol so we can adjust the volume of sounds that AI hear in realtime in the console.

Add a declaration of the cvar in game/gamesys/syscvar.cpp

idCVar cv_tdm_ai_sndvol( "tdm_ai_sndvol", "0.0", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, 
          "Modifier to the volume of suspcious sounds that AI's hear. Defaults to 0.0 dB" );

The syntax is:

idCVar <SDK variable name>( "<variable name ingame>", "<default value>", <FLAGS>, 
          "<Brief description of the variable>" );

Our naming convention for the SDK variable name is "cv_*", where the cv indicates it's a cvar. This should be followed. The name ingame can be whatever you want but it has to include the tdm_ prefix at least. I've been using the format tdm_ai_ .. for stuff having to do with the AI, etc.

Note that the default value is stored as a string. These things are parsed just like key/value pairs, so the name and default value are both strings.

Type Flags

These flags define the Cvar type. If one of them is not set on your cvar, it will default to type string.

  • CVAR_ROM (not sure what this is used for)

Other Flags

  • CVAR_GAME, CVAR_RENDERER : Identifies the CVar as having to do with the game, or having to do with the renderer. Since we can't add anything to the renderer, I'm guessing we'll always ue CVAR_GAME.
  • CVAR_GUI : Used by the GUI (the difference to "CVAR_GAME" is unclear)
  • CVAR_ARCHIVE : If set, the value of this CVAR will be stored to your Darkmod.cfg file, and saved. When you next start the game, the CVAR will have the same value, it will NOT go back to the default. (You can see what the default value was and set it back yourself by using listcvars <the cvar>).
  • CVAR_NETWORKSYNC : Probably means that in multiplayer games, this is read from the server, so individuals cannot change it to a different setting on their client. Examples include jump height, walking speed, etc.
  • CVAR_SERVERINFO : Server settings
  • CVAR_USERINFO : User settings
  • CVAR_INIT : ???
  • CVAR_NOCHEAT : ??? It's set on password and g_fov. Maybe if cheats are enabled, it still doesn't let people change it?

This is from the Id documentation on the matter:

CVars are always considered cheats except when CVAR_NOCHEAT, CVAR_INIT, CVAR_ROM, 

Adding extern declaration in game/gamesys/syscvar.h

extern idCVar cv_tdm_ai_sndvol;

This step is pretty self explanatory, just add the extern declaration in syscvar.h. (Unfortunately, changing syscvar.h requires a recompile of all the src, since it is included in game_local.h, and that is included in pretty much everything.)

Step 3. Using the CVar in the SDK

To set and read the variable: use the appropriate idCvar::Set* and idCVar::Get* functions, where the * is replaced with the CVar type that you declared before.

For example, suppose we want to use our cv_tdm_ai_sndvol in the code. Suppose we want to subtract it from some value InitialVolume.

float AdjustedVolume = InitialVolume - cv_tdm_ai_sndvol.GetFloat();

Similarly, to set it in the SDK;

cv_tdm_ai_sndvol.SetFloat( 5.0f );

Side note: Manipulating cvars ingame in the console

  • To see a list of cvars ingame, use "listcvars <your search string>"
  • To see a description of a cvar, use "listcvars -help <your search string>"
  • To see the current and default value of the cvar, just type the cvar name in the console.
  • To set the value of a cvar, use "set <cvar name> <value>"

I believe you can also omit the "set" and just type "<cvar name> <value>" to set the value.

More info can be found in: framework/cvarsystem.h. This file actually contains a lot of documentation in the form of comments.

Creating a CVAR using script

If you need to create a cvar for use with script, you're in for a much easier ride. Just use this line:

sys.setcvar("name", variable);

where name is the actual name of the cvar that the user will type in the console, and variable is a variable you have already created in your script that will change when the user enters a new value for this cvar.

The initial value of your variable will be considered the default value of the cvar when the map starts (for when you type the name of the cvar in the console and it will tell you its default value and current value).

CVARs and the GUI

It is possible to bind an input field directly to a CVAR via:

choices         "#str_07213"            // Aspect ratio
values          "0;1;4;2;3"
cvar            "r_aspectRatio"

The user is presented with the list of choices from "choices", and for each of these, the appropriate value from "values" is set into "r_aspectRatio". So when this field is changed, the value of r_aspectRatio is automatically changed, too.

Note: Choices are limited to ASCII strings and the values are limited to valid choices for this CVAR. See I18N for details and how to work around that limitation.