March 12, 2005

RSEngine: Cvars

My renderer was being a pain in the ass, so I decided to finish up work on my Cvar handling routines.

Cvars, for those who don't know, are variables that can be accessed by the console and the game. These variables may be updated by either source at any time. They're usually used for global settings mnagement.

Cvars are a bit of a challenge to do efficiently. They need to be able to be declared by the code as well as by the user. Some can be strings or numbers. Others can only be numbers. Of those that are numbers, they can be either integers or floating-point numbers. They need to be extremely efficient to retrieve their values. If it's a numeric Cvar and a string value is placed in there, the string value need to be rejected and the Cvar needs to go to a neutral value, usually 0. Finally, the values need to be live, so if they're changed, they're immediately changed for everyone who has access to the Cvar object.

Well, here is my implementation (source, VB.NET 2003, 1.68Kb ZIP). Cvar.vb is an all-in-one class, including Cvar management, storage and lookup.

Instantiation of your cvar's is fairly easy. Let's say you want a Quake-style cvar, r_fullscreen. In your VB.NET code, you'd do the following:

Dim r_fullscreen As New Cvar("r_fullscreen", 0)

That creates the cvar, sets the starting value (which is 0 in this example), and because a numeric argument has been passed, this cvar will now only accept numeric arguments.

For something like a player name, you can put in:

Dim player_name As New Cvar("player_name", "Player")

This cvar can now accept anything as a value (except lines that contain carriage returns or newline characters, more on that in a second.)

Saving and loading your cvar's is also easy. The shared methods Cvar.Save(filename) and Cvar.Load(filename) take care of that. These save and load Quake-style cvar lists, with the variable name and value on the same line, hence the reason for denying some characters in the set values. While I could have used XML, I was aiming for lightweight, and this type of setting file is currently accepted by gamers. The code uses a tilde (~) to prefix saved strings. If the cvar is declared in code, the tilde isn't necessary for it to be loaded as a string.

You have multiple ways to write to the value of a cvar, and regardless of your choice, the change will affect all instances of that cvar globally.

You can set the value in code, by saying r_fullscreen.Value = 1.

You can get an instance of the cvar by calling Cvar.GetCvar("r_fullscreen"), and then set the value in that instance.

You can set the value by name, with Cvar.SetValue("r_fullscreen", 1).

For retrieving the values, you have similar choices. You can query the object directly, get an instance and query it, or you can query it by name and ask for the result as either a string, integer, or single-precision floating point value.

Check it out, and let me know if you see any bugs. Thanks.

No comments: