• Register

Highly evolved engine based on id Software technology, available under dual license (GPL, proprietary licensing for commercial use available).

Post tutorial Report RSS Quake c - create and use custom server variables

Quake one custom server variables - how to code them in quake-c (under darkplaces engines) and how to code them in any quake engine source.

Posted by on - Intermediate Server Side Coding

Some adherents of Painkeep ( Moddb.com ), Chaos Archon ( Moddb.com ) and generations w-d-q (during its very short run) may have noticed I use a lot of custom server vars.

For instance - sv_botmatch. Open the console on one of the mods set that to 1 and get 3 frikbots and 3 pk*bots when you load the next map. Or set it to the number of bots you want.

There are 2 ways to get a console variable.

Darkplaces (and derivatives):

In your quake-c code, say in world.qc:

void () worldspawn =
{
...

// create the cvar, with default value 0

registercvar("sv_botmatch", "0"); // load bots without admin

// this sample code would go in other functions
// read cvar

float bcnt;

bcnt = cvar("sv_botmatch");

// bot start code

// zero value when done
cvar_set("sv_botmatch", "0");

// NOTES:
// cvars are read as float, and set as a string
// but you can only store numerical data
// to store a float variable:
// ftos() is a float to string conversion - uses string temp space

cvar_set("sv_botmatch", ftos(bcnt));

// This MAY NOT work on all qcc compilers! on the original qcc you had to:

string tmp1;

tmp1 = ftos(bcnt);
cvar_set("sv_botmatch", tmp1);

// when using strings it is very important to know how the compiler you use handles string data

};

There is one caveat - if you set these vars in a .cfg file (such as autoexec.cfg) the first map you load will not be able to read them. Because they are not created until the first worldspawn() call is executed!


Quake engines:

To have permanent variables in an engine, get the source code (this is from glquake source) and open pr_edict.qc

Somewhere near the top with the rest of these defines put:

// create cvar, set initial value and state whether it gets saved in config.cfg

cvar_t sv_botmatch = {"sv_botmatch", "0", true };

// near the bottom with these defines - register the cvar

Cvar_RegisterVariable (&sv_botmatch);

Accessing the cvars in quake-c is exactly the same as the darkplaces sample code above.

Now you can create custom server variables for your mods and games. With a bit of imagination there are all sorts of possibilities.

Post comment Comments
LordHavoc
LordHavoc - - 11 comments

It's better to put this in default.cfg:
set sv_botmatch 0 "enable bot match"

This creates a cvar if it does not exist, sets the value and the description text of the cvar so the user can see a comment when they tab complete it, additionally all cvars are saved to default values at the end of default.cfg so the user will see this value as default in the cvar description.

You also might want to use this in the qc:
float autocvar_sv_botmatch;

An autocvar variable will automatically mirror (for reading) the value of the corresponding cvar at all times (immediately updates if you use cvar_set), so you can monitor the value with no additional code, note that it is read-only mirroring (cvar_set must still be used to change it).

Reply Good karma Bad karma+2 votes
numbersix Author
numbersix - - 2,244 comments

Thanks!

I recently discovered autocvar_* after switching to fteqcc...because my main mod broke frikqcc - ouch.

I like the default.cfg concept, I'm going to swap out to that.

Reply Good karma+1 vote
Rivarez
Rivarez - - 314 comments

Thank you very much for your tutorial! Now i can easily disable self player shadow in my torch code. Its impossible to disable and enable the shadow in .cfg file cause for pushing and releasing the torch key a same "code" called:
------------------------------------------
alias +torch "impulse 30"
alias -torch ""
------------------------------------------

But now in my torch code i wrote:
------------------------------------------
void () flash_toggle =
{
if (self.flash_flag == FALSE)
{
self.flash_flag = TRUE;
flash_on();
cvar_set("cl_noplayershadow","1"); //disable self shadow
}
else
{
self.flash_flag = FALSE;
W_SetCurrentAmmo ();
self.flash.think = SUB_Remove;
self.flash.nextthink = time + 0.1;
cvar_set("cl_noplayershadow","0"); //enable self shadow
}
}

Reply Good karma Bad karma+1 vote
Rivarez
Rivarez - - 314 comments

Initially i tried to use the "autocvar_" method, mentioned above by LordHavoc, but it not works. Only "cvar_set" works right with existing variables.

Reply Good karma Bad karma+1 vote
Post a comment

Your comment will be anonymous unless you join the community. Or sign in with your social account: