GUI Scripting: User Variables

From The DarkMod Wiki
Revision as of 20:46, 15 November 2022 by Geep (talk | contribs) (→‎Declared in Property List: Non-zero initialization of float)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigationJump to search

This page is part of a series. See GUI Scripting Language for overview.


Optional user variables may be defined as part of (and conventionally at the end of) a guiDef's property list. There are 3 forms:

  • float name
  • definefloat name // same as "float name". No examples of this alias found in TDM.
  • definevec4 name // Not used in core. Nor was an example in a sample of FMs found.


A user variable is directly known only to the guiDef in which it is defined and NOT its child guiDefs. However, it can be referenced elsewhere in the file by using the appropriate "guiDef_name::" prefix.

Float User Variable

Float and definefloat variables are the same thing. Reportedly, keyword "definefloat" was designed first by id Studio, then shortened to "float". Let’s refer to just "float" in what follows. Such a variable can serve as a decimal, integer, or boolean value. Boolean is the most frequent usage.

Declared in Property List

Declaration syntax is:

float myvar 0  // recommended form, matching syntax style of properties.
float myvar; // alternate form with semi-colon, initialized to 0.
float myvar // BAD. Parser may or may not recover from this, depending on what follows.

As for the value to assign, traditional best-practice guidance is:

  • A float user variable is ALWAYS initialized to zero. Attempting to use any other number (before TDM 2.11) is often ignored and replaced by 0.
  • It must be ended in either ";" or " 0".
  • This is because, although initialization with a non-zero value was intended with Doom 3, buggy implementation made that unreliable.

However, code refactoring in TDM 2.11 may now make non-zero initialization reliable. Too early to tell, but hopeful.

float myvar 1 // ALLOWED IN 2.11, WITHOUT WARNING. MISLEADING BEFORE 2.11, because variable is still initialized to 0.

Used to Affect Properties

Occasionally of interest. See Example #2 below.

Used in Event Blocks

  • Typically used within event handler if(...) statements, e.g., to transfer local state info between event handler blocks.
  • Changed with "set", or less commonly, "transition".

In the main menu system, user variables are important for crouch management, e.g., of lightgem height. "float exit" is common as well, as shown in the next example.

Menu Button Example #1

After mission success, the "button" to bring up game statistics is styled with mouse-over glows. Once the button is pressed (triggering the onAction block), it is no longer desirable for the glow transition of the onMouseExit block to operate. User variable "exit" controls that.

windowDef statistics_select
	visible	1
	float	exit;

		set "exit" 0;
		transition "Statistics::forecolor" SWHITE_COLOR SGLOW_WHITE_COLOR "200";
		transition "StatisticsH::forecolor" SINVISIBLE SGLOW_YELLOW_COLOR "200";
		set "cmd" "play sound/meta/menu/mnu_hover";

	onMouseExit {
		if ( "exit" == 0 )
			transition "Statistics::forecolor" SGLOW_WHITE_COLOR SWHITE_COLOR "200";
			transition "StatisticsH::forecolor" SGLOW_YELLOW_COLOR SINVISIBLE "200";

		transition "Statistics::forecolor" SGLOW_WHITE_COLOR SWHITE_COLOR "200";
		transition "StatisticsH::forecolor" SGLOW_YELLOW_COLOR SINVISIBLE "200";
		set "exit" 1;

Menu Button Example #2

Here’s another "button", styled with a different type of mouse-over recoloring. Float user variables bgCol and fgCol (i.e., background color and foreground text color) are bound as individual but identical R, G, B values. At the outset (and ignoring the winAlpha value), the button is gray with black type. On mouse-over, the type brightens to white, reversibly. When the button is hit, the background jumps to light gray, then reverts to dark gray.

windowDef GammaResetButton {
	rect			20, 168, 80, 16
	backcolor		"bgCol","bgCol","bgCol","GammaStandardPicture::winAlpha"
	forecolor		"fgCol","fgCol","fgCol","GammaStandardPicture::winAlpha"
	bordersize		1
	bordercolor		0.5, 0.5, 0.5, "GammaStandardPicture::winAlpha"
	textalign		1

	text			"#str_02277"		// Reset
	textscale		0.2

	noevents		1

	float bgCol 0
	float fgCol 0

	onTime 0 {
		set "bgCol" "0.3"
		set "fgCol" "0"
		transition "fgCol" "0" "1" "50";
		transition "fgCol" "1" "0" "50";
	onAction {
		transition "bgCol" "0.5" "0.3" "200";
		set "cmd" "resetBrightness";
		set "cmd" "resetGamma";

DefineVec4 User Variable

If you thought the float user variable was squirrelly, the definevec4 is even worse. Which may be why it's not used in the core. If you want to use it, here's a suggestion.

Define it in the property list with exactly this syntax:

definevec4 show_it 1,1,1,1 
definevec4 hide_it 1,1,1,0

Use it only in event blocks, like so:

transition "my_image::matcolor" "$show_it" "$hide_it" "2000";

If the event block is associated with a different guiDef than where the definevec4 is defined, you can add the proper prefix, e.g.:

transition "my_image::matcolor" "$desktop::show_it" "$desktop::hide_it" "2000";

DON’T try to use it to give a value to a property, e.g., in a property list:

matcolor show_it  // Doesn’t work no matter what form you use

As a synonym for "definevec4", keyword "vec4" is available in some other id-family games, and has been proposed for TDM 2.12. See New features in GUI engine.