Mutator Config GUI (UT2004)
Mutator configuration within UT2004 is handled very differently from that in previous games (see Mutator Config GUI (UT2003)). Rather than have a separate config window for each mutator all mutators share the same configuration.
Basic Requirements
These are the basic elements needed to include configurable options for a mutator.
Mutator GUI Functions
Each mutator has the option to add its configuration options as a separate group to an existing configuration group. This is handled by adding the following static functions to the mutator you are writing.
- static function FillPlayInfo(PlayInfo PlayInfo)
- Responsible for actually creating the GUI widgets used to configure each option.
- static event string GetDescriptionText(string PropName)
- Responsible for returning "long" descriptions of each of the options.
- static function string GetDisplayText(string PropName)
- Repsonsible for returning the displayed menu name of each of the options. This function is not strictly required but it keeps things consistent with the GameInfo configuration code.
Mutator GUI Properties
In addtion to the above functions your mutator will also have the following array properties. The number of elements within the array should equal the number of configurable items your mutator has.
For example, if your mutator has two configuration options the the following arrays should be declared. The size of the arrays should match the number of properties you are attempting to configure.
class HitAndScore extends Mutator config (MutHitAndScore); var localized string GUIDisplayText[2]; // Config property label names var localized string GUIDescText[2]; // Config property long descriptions // If you have any drop lists then you will want to add a localized array // variable whose element count matches the number of selections within the drop list. var localized string GUISelectOptions[2];
Example Code
The following is some example code of GUI support for a mutator that counts the hits taken and resets the player's score after a certain threshold is reached.
var config int HitCount; // A counter for the number of hits taken var config int MaxHits; // Number of hits beore you lose your score var localized string GUIDisplayText[2]; // Config property label names var localized string GUIDescText[2]; // Config property long descriptions // Mutator code and class definition snipped for clarity // The function used to obtain the text that will be displayed within the // config window. static function string GetDisplayText(string PropName) { // The value of PropName passed to the function should match the variable name // being configured. switch (PropName) { case "HitCount": return default.GUIDisplayText[0]; case "MaxHits": return default.GUIDisplayText[1]; } return Super.GetDisplayText(PropName); } // The function used to obtain the "hint" text that is displayed at the bottom // of the config window. static event string GetDescriptionText(string PropName) { // The value of PropName passed to the function should match the variable name // being configured. switch (PropName) { case "HitCount": return default.GUIDescText[0]; case "MaxHits": return default.GUIDescText[1]; } return Super.GetDescriptionText(PropName); } // This function is called to actually add the configuration options for the // mutator to the configuration window. static function FillPlayInfo(PlayInfo PlayInfo) { Super.FillPlayInfo(PlayInfo); // Always begin with calling parent // The following function calls actually cause the configuration options to be // added to the mutator config window. See below for a description of how to // use the PlayInfo.AddSetting() function. PlayInfo.AddSetting(default.GameGroup, "HitCount", GetDisplayText("HitCount"), 0, 2, "Text", "3;0:32", "", True, True); PlayInfo.AddSetting(default.GameGroup, "MaxHits", GetDisplayText("MaxHits"), 0, 0, "Text", "3;0:999"); // Note that the second parameter, and the value passed to the GetDisplayText() // within the calls to the AddSetting() function above matches the // name of the attribute we want to configure as declared within the class defintion } defaultproperties { HitCount=8 MaxHits=500 GUIDisplayText[0]="Hit Count" GUIDisplayText[1]="Max Hits" GUIDescText[0]="The number of hits each player can take" GUIDescText[1]="The number of hits that a player can take before their score is reset" //Group these components when other mutator components are configurable GroupName = "HitAndScore" //Display of mutator in mutator list FriendlyName = "Hit And Score" //Description of mutator appearing in GUI description = "mutator that counts the hits taken and resets the player's score after a certain threshold is reached." }
Note: If you are subclassing from an existing mutator, or from the GameInfo class then your GetDisplayText() and GetDescriptionText() functions should include a call to the method defined within the superclass. Be aware that the inclusion of a GetDisplayText() function is considered good practice rather than being mandatory so check that the function is defined within the superclass before calling it. Note that on patch 3355, GetDisplayText will cause a compile error, so you do not need this function when compiling for that environment.
The PlayInfo.AddSetting() Function
The PlayInfo.AddSetting() function is defined as shown below.
native(704) final function bool AddSetting(string Group, string PropertyName, string Description, byte SecLevel, byte Weight, string RenderType, optional string Extras, optional string ExtraPrivs, optional bool bMultiPlayerOnly, optional bool bAdvanced);
AddSetting() Function Parameters
What follows is a description of each of the parameters to the AddSetting() function.
- Group
- This is the group the setting falls into. Within the mutator config window this setting has no effect. It is used primarily to group similar properties together within the main "game" and "game rules" windows. The values used by the default UT2004 code are defined within the /Engine/Info class and are as follows:
- default.RulesGroup ("Rules")
- default.ServerGroup ("Server")
- default.BotsGroup ("Bots")
- default.GameGroup ("Game")
- default.ChatGroup ("Chat")
- default.MapVoteGroup ("Map Voting")
- default.KickVoteGroup ("Kick Voting")
- PropertyName
- This is the name of the property that this setting relates to. It must match exactly the name of the class configuration attribute that this menu setting relates to.
- Description
- This is the label that will be used when the configuration option is displayed within the GUI window.
- SecLevel
- This is the security level of the setting. Values greater than zero may require the user to be logged on (Is this used more at the Web-Admin level?). For a mutator it will generally be passed as 0.
- Weight
- This is simply an value used to order the configuration options within the group. For the purposes of the Mutator config screen it can be set to 0.
- RenderType
- This is the type of widget to be used to alter the value of the property being configured. The allowed values are listed below.
- "Check" Used when a check boxes is required.
- "Text" - Used when a standard entry field is required.
- "Select" - Used when a drop list is needed.
- "Custom" - Used when an advanced configuration page (new window) is needed. This value cannot be used within a mutator configuration setting.
- Extras
- This parameter is used in conjunction with the RenderType parameter to determine what is actually displayed. The format for the string is described below.
- Check
- Ignored.
- Text
- This parameter can be in a number of different forms
- "value" for the default value of the Text Edit box.
- "width;value" for a Text Edit box with a given width and default value.
- "width;lowest:highest" for a Ranged Edit box that allows values between the lowest and highest to be entered. If the range is a float then the values should be specified with a decimal point.
- Select
- The paramter should be a semi-colon delimited list of value and name pairs. For example "value1;name1;value2;name2;value3;name3".
- Custom
- This configuration type cannot be used in a mutator configuration. However values are of the form: "##;Package.WebHandlerClass;Package.CustomConfigPage"
The first part generally indicates an optional width. The second part allows to specify the class that should handle rendering this property in webadmin. The third part is the classname of a custom GUI page for this property. All three parts are optional.
Couple of notes:- The semi-colons are only required if you are using the second or third part of the field. So valid values could be "255", "255;;GUI2K4.MOTDConfigPage" or ";;GUI2K4.MOTDConfigPage".
- The second part (webadmin support) is currently not implemented, so any value you put here will be ignored.
- If you specify a custom config page, your property will appear in the GUI list as a button. Clicking this button opens the page you've specified. You'd normally only need to do this for more complex properties, such as structs.
- ExtraPrivs
- Used to specify any additional privileges that are required in order for an admin to modify the value of this property from e.g. webadmin. You'd only use this field if have custom privilege classes (i.e. subclasses of xPrivilegeBase), and then only in cases where you'd like the property to appear in the same group as other properties, but only for certain admins.
Expected values would be the abbreviation for the corresponding privilege type as listed in the SubPrivs value of your custom privilege class. In order to require multiple privileges for this property, use the pipe character as a delimiter.
For example, to have a property appear on the Game page, but only if the admin also has the ability to kick players, you could specify "Game" for the Group parameter, and "Kp" for this parameter. - bMultiPlayerOnly
- This parameter should be set to True if the configuration option only applies within a mutliplayer game.
- bAdvanced
- This parameter should be set to True if the configuration option should only be displayed when the "Advanced" options checkbox is checked.
Advanced Configuration Support
If you need to pass on the PlayInfo object to other Info subclasses then after the call to FillPlayInfo you should call the PlayInfo.PopClass() function. An example is given below.
// Example take from Engine/GameInfo.uc FillPlayInfo() function static function FillPlayInfo(PlayInfo PlayInfo) { Super.FillPlayInfo(PlayInfo); // Always begin with calling parent // code snipped if (default.GameReplicationInfoClass != None) { default.GameReplicationInfoClass.static.FillPlayInfo(PlayInfo); PlayInfo.PopClass(); } // code snipped }
The call to Super.FillPlayInfo() performs an AddClass(). Not popping the class off the stack will result in a different number of classes being held within the PlayInfo's class stack on function exit than on function entry.
Related Topics
Discussion
EntropicLqd: Reset discussion and added real property names.
GnaM: Maybe it's just me, but this lesson seems pretty vague on how to actually use the 'extras' parameters. After reading it, I understand that that I need to use a list of names and values for "select", but I have no idea how to use those values to actiate changes within the game. Perhaps a small simple example of how to use each type of extra in the code would help. Anyway, it's also kind of hard to find this lesson from the UScript topics page. It seems to me a link right under the other mutator tutorials would be apropriate. Thanks.
Foxpaw: Just one minor point: this tutorial would likely be hard to follow, as it is not a tutorial. It's a reference, probrably aimed at people who already have a general idea of what to do and are looking for specifics.
Geist: Remember, you need to declare your configurable vars with the config keyword. Otherwise, they wont appear in the Configure Mutator dialog, and you'll get runtime warnings in the log like " Warning: Property 'HitCount' not found in class 'Class MutHitAndScore.HitAndScore' " when opening that dialog. This was very confusing at first, since HitCount is definitely there, but it just wasn't a configurable property (slightly misleading warning message, I guess). I've made the corrections in the script above.
LionsHeart: I have a slight confusion on what I should do...I'm not sure what I should do with the PropName string. Do I set it equal to something? If would would like to give me a hand quickly, email me at LionsHeart455@hotmail.com. Thanks!
Geist: Take a look at how PropName is used the functions. PropName is used in the switch() of both GetDisplayText() and GetDescriptionText() as a key to what strings to return. These strings are then displayed in the Mutator Configuration screen in the game.
Devi: I found this pretty helpful, I managed to add a config window to my mutator in about 20 minutes with it
Sir_Brizz: Shouldn't we add the ability to create a seperate Config Page to this page as well?
SuperApe: I added the following line to the end of the GetDescriptionText() event code above...
return Super.GetDescriptionText(PropName);
...It appears to be necessary. And am I correct in assuming that while the GetDisplayText() function can be called whatever, the GetDescriptionText() event must be explicitly named so? (Please correct me if I'm wrong on any of this.) My question is this: How can I have a checkbox property enable another PlayInfo setting? IOW, a main option "Allow Foo" check box is available, but a greyed out (or non-existant) sub-option "Start with Foo" check box will not be available unless the "Allow Foo" box is checked. Is something like that possible with the UT2004 GUI system?
Wormbo: GetDisplayText() is only a helper function for this class, but GetDescriptionText() is an engine event.
SuperApe: That's what I figured. Thank you. Now, about my question of enabling/disabling Mutator config option widgets: I see an example of what I'm looking for in the standard game config for bots. If you select Bot Mode: "Specify Number" (as opposed to "Use Map Defaults"), the "Number of Bots" widget is enabled. That is what I'm looking for and it's not apparent to me, in the code, how this works. Is this functionality even available to Mutator configs?
Wormbo: This information can't be stored in PlayInfo, so the functionality is not available in PlayInfo-generated config menus like the mutator configuration.
SuperApe: Thank you for clearing that up, Wormbo.
Bitty: Added the following to GetDisplayText()...
return Super.GetDisplayText(PropName);
It's necessary to do this to prevent some of the default settings descriptions from disappearing in the UI. Also, these functions are not limited to mutators, but can also be used in custom gametype classes. Another thing you may want to mention here is if you have a lot of configurable options, you can create separate configuration sections by doing the following in FillPlayInfo()...
static function FillPlayInfo(PlayInfo PlayInfo) { local string MyGroup; Super.FillPlayInfo(PlayInfo); MyGroup="My Config Section"; PlayInfo.AddSetting(MyGroup, "bAddEffect", GetDisplayText("bAddEffect"), 0, 1, "Check"); // code snipped }
mad: Added some lines to show how to change what is displayed in the mutator list. The above code by Bitty will also pretty much do the same thing. Also, when I tried to add GetDisplayText function to my mutator, there was a compile error. I have patch 3355, so this may be the reason why I get compilation errors. I added a note about this below the main class code up top.