ModSettings.xml Reference
The complete V2 schema for ModSettings.xml as the parser reads it — every element, every attribute, and what happens when something is wrong.
Use this page to look up any element or attribute of the V2 ModSettings.xml schema. Where the
parser drops or ignores something, the page says so and gives the log line to search for. Every log
line is prefixed [Gears] [XmlSettingsParserV2] unless stated otherwise.
New to Gears? Start with Getting Started instead.
A dropped setting is silent in the game
One bad setting does not stop the rest of the file from loading. The parser logs the problem, skips that element, and carries on. Nothing in the game tells you a setting went missing, so read the log when something does not appear. See Troubleshooting.
File location and root element
| Rule | Detail |
|---|---|
| Location | <mod folder>\ModSettings.xml, beside ModInfo.xml. Gears tries no other path or name. It skips a mod without one and logs nothing. |
| Root | <ModSettings version="2">. |
version | Required, and must be 2. A root with no version is a V1 file and is rejected, and so is any other value. Both log an error from [ModSettingsFromXml] naming the mod, and the whole file is skipped. |
| Malformed XML | The whole file is skipped: Mod <Name> ModSettings Failed parsing <folder>: followed by the exception. |
| Wrong root name or no child elements | The whole file is skipped with an error. |
| When it is read | Once, at game start (GameAwake), for every loaded mod in the game's load order. |
A skipped file removes your players' saved values
When Gears skips the whole file and your mod creates no global settings from C#, the mod has no
global settings that startup. Gears then removes the mod's section from each player's saved
settings file, so every saved global value for your mod is lost and cannot be recovered. This
keeps the saved file from growing with entries for settings that no longer load. Test your
ModSettings.xml in the game before you release it.
Document structure
<ModSettings version="2">
<Global>
<Tab name="" displayKey="" tooltipKey="">
<Category name="" displayKey="">
<!-- Selector | Slider | Switch | Color | Binding -->
</Category>
</Tab>
</Global>
<World>
<Category name="" displayKey="">
<!-- Selector | Slider | Switch -->
</Category>
</World>
</ModSettings><Global> holds the player's settings and <World> holds one world's settings. Both are optional,
and Gears reads only the first of each.
<Global> reads only its <Tab> children, and <World> reads only its <Category> children.
Gears ignores anything else directly under them and logs nothing.
<Tab>, global only
| Attribute | Required | Notes |
|---|---|---|
name | yes | Identity within Global. Gears merges two tabs with the same name into one. |
displayKey | no | Localization key for the tab label. An empty value falls back to name. |
tooltipKey | no | Localization key for the hover text. Tab is the only element that still uses tooltipKey. Everywhere else it became <Description>. |
A tab is not a setting, so it takes no <Caption>, <Description>, <Preview> or
<RestartScope>. Gears reads only its <Category> children and drops a setting placed directly
under a tab, without a log line. A tab with no categories still exists.
<Category>
Categories have the same shape under Global and World.
| Attribute | Required | Notes |
|---|---|---|
name | yes | Identity within its tab, for a global setting, or within World. See How duplicate names merge. |
displayKey | no | Falls back to name. |
A category counts as a setting for display purposes, so it accepts <Caption>, <Description> and
a single value-less <Preview><Image path=""/></Preview>. It does not accept tooltipKey or
<RestartScope>. Gears tries every child element as a setting and drops unknown element names
without a log line.
Setting elements
| Element | Global | World | Value types |
|---|---|---|---|
<Selector> | yes | yes | int, float, string, any enum |
<Slider> | yes | yes | int, float only |
<Switch> | yes | yes | bool, string, any enum |
<Color> | yes | no | always a color; type is accepted and ignored |
<Binding> | yes | no | none; a key binding has no value |
These five are the only elements a <Category> accepts. Gears drops a Color or Binding under
<World> without a log line, and drops any other element name the same way. When constructing a
setting throws for any reason, Gears drops it with
Failed to parse global <Element> '<name>': <message>, or world in place of global.
The rules below apply to every one of them. Each element's own subsection follows, and the child elements they take are described under Child elements.
Attributes every setting takes
| Attribute | Required | Notes |
|---|---|---|
name | yes | Identity within its category, and the key the player's saved value is stored under. See How duplicate names merge. Renaming a setting after release discards the saved value, so treat a released name as fixed; see Troubleshooting. A world setting's name must also be unique across every world category of the mod. Gears restores saved world values by name alone, into the first setting with that name. When two categories share a setting name, the first category's setting takes the value saved last, and the second one goes back to its default every time the world loads. |
displayKey | no | Falls back to name. |
type | yes, except on Color and Binding | See Value types. |
defaultValue | yes, except on Binding | See defaultValue. |
Value types
Gears trims type and matches it case-insensitively.
| Write | Meaning |
|---|---|
int, Int32, integer | 32-bit integer |
float, Single | single-precision float. Accepts a % suffix, so 50% is stored as 0.5. This applies wherever a float is parsed: defaultValue, increment, minValue, maxValue, List entries and Image value. |
string | text |
bool, boolean | true or false |
Color, Color32 | resolves, but no Selector or Switch exists for it, so the setting is dropped. Use the <Color> element instead, which ignores type. |
double | resolves, but no Selector, Slider or Switch exists for it, so the setting is dropped |
| anything else | treated as a type name and looked up in every loaded assembly, case-insensitively. Write the full name (MyMod.Difficulty), the assembly-qualified name (MyMod.Difficulty, MyMod), or the bare name (Difficulty). For an enum declared inside a class, separate the class from the enum with a plus sign (MyMod.PlayerController+Difficulty); a dot does not resolve. The type must be an enum or have a registered parser. See Use Custom Value Types. |
Each of these failures drops the setting:
| Log line | Cause |
|---|---|
<Element> '<name>' has no type. | type is missing or whitespace |
<Element> '<name>' has unknown type '<raw>'. Use one of int, float, string, bool, Color, or the name of an enum type such as 'MyMod.Difficulty, MyMod'. | not an alias and not a resolvable type name |
<Element> '<name>' uses type '<raw>', which is neither an enum nor a type with a registered parser. | resolves to a real type Gears cannot read |
Slider '<name>' has unsupported type '<type>'; sliders support int and float only. | a Slider with anything but int or float |
Setting '<name>' of type '<Type>' could not be created: <message> | an enum or custom type with no setting implementation for that element |
An enum Selector starts with every declared member as its allowed values, in declaration order,
so it needs no <List>. An enum Switch takes the first two declared members as left and right
unless <Buttons> says otherwise.
defaultValue
defaultValue is required on Selector, Slider, Switch and Color. It seeds three things at once:
the setting's default value, its applied value and its selected value. The player's saved value, if
there is one, replaces the last two after the file has loaded.
| Case | Result |
|---|---|
| Missing or whitespace | Setting dropped: <Element> '<name>' has no defaultValue; defaultValue is required, skipping. |
| Present but unparseable | Setting kept at default(T): 0, false, empty, or black. [GlobalModValueSetting] or [WorldModValueSetting] logs Setting '<name>': could not parse defaultValue '<raw>' as <Type> - <message>, then the same line twice more with value and selectedValue in place of defaultValue |
Outside the List, the Incremental range or the Buttons values | Not checked. The setting loads with the value you gave. |
<Selector>
One value at a time, with arrows on either side to step through the allowed values. Global and world.
Set the allowed values one of three ways:
<List allowedValues="a,b,c" />names them outright.<Incremental increment="" minValue="" maxValue="" />gives a numeric range, which Gears expands into every step.intandfloatonly.- Naming an enum as the
typeuses its declared members, in declaration order, and needs neither child element.
A Selector also takes <Formatter>, <LocalizationPrefix> and <Wrap>, and it is one of the three
elements that accept a per-value <Preview> image. See Child elements.
<Selector name="Units" displayKey="myModUnits" type="string" defaultValue="metric">
<List allowedValues="metric,imperial" />
<LocalizationPrefix prefix="myModUnits_" />
</Selector><Slider>
A bar the player drags, with arrows that nudge it one step. Global and world.
type must be int or float, and anything else drops the setting. <Incremental> sets the range,
and a Slider without one has a range of 0 to 0. <Formatter> controls both the text drawn over the
bar and the value written to disk. A float Slider accepts % notation, so 50% is stored as 0.5.
Gears reads no <List>, <Wrap> or <LocalizationPrefix> on a Slider.
<Slider name="Fov" displayKey="myModFov" type="int" defaultValue="65">
<Incremental increment="5" minValue="45" maxValue="120" />
</Slider><Switch>
Two buttons side by side, and the lit one is the current value. Global and world.
type may be bool, string or any enum. <Buttons left="" right="" /> names the two sides. A
bool Switch is false on the left and true on the right, an enum Switch takes its first two
declared members, and a string Switch has no sides at all until <Buttons> gives it some.
<LocalizationPrefix> turns both labels into localization keys.
Gears ignores <Formatter> on a Switch.
<Switch name="ShowHints" displayKey="myModShowHints" type="bool" defaultValue="true">
<LocalizationPrefix prefix="myModOnOff_" />
</Switch><Color>
Global only.
<Color name="Crosshair" displayKey="myModCrosshair" defaultValue="255,0,0" />A Color setting has a fixed type, so type is accepted and ignored. It takes defaultValue, which
is required, plus <Caption>, <Description>, <RestartScope> and a value-less <Preview>.
Write defaultValue as R,G,B or R,G,B,A, each 0–255. Gears serializes the value as R,G,B
only, so an alpha value is not kept once the player's value has been saved.
<Binding>
Global only.
<Binding name="Boost" displayKey="myModBoost">
<Description key="myModBoostDesc" />
</Binding>A Binding takes only name, displayKey, <Caption>, <Description>, <RestartScope> and a
value-less <Preview>. It has no type, no defaultValue and no valued previews.
Declaring the binding in XML gives it a row in the menu. You must attach the actual key binding from
C# through IControlBindingSetting.PlayerAction.
See Use Global Settings in C#.
Child elements
Gears matches each child by name among the setting's direct children. Unless noted, the order in the file does not matter.
<Incremental increment="" minValue="" maxValue="" /> on Selector and Slider
Gears parses all three attributes with the setting's value type. All three must parse or Gears
applies none of them. Each failure logs
Setting '<name>': could not parse <increment|minValue|maxValue> '<raw>' as <Type> - <message>.
- On a Slider, the three values become the slider's range. A slider with no
<Incremental>has a range of 0 to 0. - On an int or float Selector, Gears expands the range into the list
min, min+increment, …up to and includingmax.incrementmust be greater than 0 andminno greater thanmax. Otherwise Gears ignores the range and[SelectorSetting]or[SelectorWorldSetting]logsSetting:'<name>', SetAllowedValues(increment, min, max) requires increment > 0 and min <= max; … - On a string or enum Selector, Gears ignores the range and logs
Setting:'<name>', SetAllowedValues(increment, min, max) requires a numeric type; '<Type>' is not supported.
<List allowedValues="a,b,c" /> on Selector only
Gears splits the value on commas, then trims and parses each entry. One bad entry drops the whole
list, logging Setting '<name>': could not parse allowedValues entry '<raw>' as <Type> - <message>.
The setting survives with no allowed values, except that an enum Selector keeps its declared
members. There is no way to include a literal comma in a value.
When a Selector declares both <List> and <Incremental>, Gears applies the list first and the
range second, whatever order they appear in, so the range wins.
<Formatter ui="" serialize="" /> on Selector and Slider
Both attributes are optional, and Gears applies each one only if it is non-empty.
uiis what the player sees.serializeis what Gears writes to the saved settings file and whatmodsetting()returns.
Each is a .NET numeric format string, such as "0.0", "000" or "0%", handed to the value's
formatter. They take effect on int, float and double. bool, string, Color and enums
ignore the format string, and Gears ignores <Formatter> entirely on Switch, Color and
Binding.
<LocalizationPrefix prefix="" /> on Selector and Switch
Gears joins the prefix to the formatted value with no separator and looks the result up as a
localization key. A prefix of myModUnits_ and a value of metric display whatever
myModUnits_metric says in Localization.csv.
The prefix applies to each allowed value, to both Switch buttons, and to the current and selected value. Gears ignores it on Slider, Color and Binding.
<Wrap wrap="true" /> on Selector only
Write true or false, in any case. Gears ignores anything else and leaves wrapping off. Wrapping
controls whether stepping past the last value returns to the first.
<Buttons left="" right="" /> on Switch only
Both attributes must be present and both must parse as the value type. Otherwise Gears applies neither and these defaults stand:
| Type | Left | Right |
|---|---|---|
bool | false | true |
| enum | first declared member | second declared member |
string | none | none, so set <Buttons> |
The lit button follows the selected value. It is Right when the value equals the right side and not the left, and Left in every other case.
<Caption key="" /> and <Description key="" /> on every setting and category, but not Tab
Both take a localization key, and Gears applies each one only if key is non-empty. Writing
<Caption /> or <Caption key="" /> leaves the property unset.
- The caption is the short heading in the description pane. Unset, it falls back to the display name.
- The description is the body text. Unset, nothing is shown. This is the V2 replacement for the V1
tooltipKeyon settings and categories.
<RestartScope scope="" /> on global settings only
Write None, Reload or Restart, in any case. Gears shows the player a warning that a change
needs a world reload or a game restart. An unrecognized value leaves the scope at None, and an
empty one is ignored.
Gears ignores <RestartScope> on a world setting and on a category, without a log line. A world
setting is applied along with the world it belongs to, so there is nothing to ask the player to
restart.
<Preview> with <Image path="" value="" />
A preview is an image shown beside the setting. There are two forms:
<Image path="…" />with novalueis the setting's own image. It is allowed on every setting and on a category. With several, the last one wins.<Image value="…" path="…" />is shown while that value is selected, on Selector, Slider and Switch only. Gears parsesvalueas the setting's type and skips an unparseable one withSetting '<name>': could not parse preview value '<raw>' as <Type> - <message>. With two images for the same value, the first one wins.
Color accepts only the value-less form. Gears skips a valued <Image> on a Color with the warning
Setting '<name>': Color settings do not support per-value previews, ignoring <Image value="…">.
Binding and Category also take the value-less form only. Gears ignores an <Image> with no
path, and one placed outside a <Preview>.
Gears passes path to the game's texture loader untouched, so use the game's own mod-folder form:
<Image path="@modfolder(MyMod)://Textures/low.png" />Here MyMod is the <Name> from ModInfo.xml.
How duplicate names merge
Whether a repeated name merges or is dropped depends on where the repeat is:
| Repeat | Result |
|---|---|
Two <Tab> elements with the same name under <Global> | Merged into one tab. Their categories merge by the same rules. |
Two <Category> elements with the same name under <World> | Merged into one category. |
A category with the same name as one in a separate <Tab> element of the same name | Merged, along with the settings inside it. |
Two settings with the same name in categories that merge | Merged into one setting, as described below. |
Two <Category> elements with the same name inside one <Tab> element | The second category and every setting in it are dropped, without a log line. |
Two settings with the same name inside one <Category> element | The second setting is dropped, without a log line. |
When two settings merge, the later default, applied and selected values overwrite the earlier
ones. A Selector's allowed values, formatters and prefix are taken only when the earlier one had
none. Wrap is true if either one set it.
To keep the file predictable, give every tab, category and setting a unique name in its parent.
Two world settings in different categories never merge, but they still need different names; see
Attributes every setting takes.
What gets dropped and what survives
| Problem | Outcome |
|---|---|
No version, wrong version, malformed XML, wrong root | Whole file skipped. With no global settings from C#, the mod's saved global values are also removed. |
A category name repeated inside one <Tab> element | Second category and its settings dropped, no log line |
A setting name repeated inside one <Category> element | Second setting dropped, no log line |
Setting with no type, an unknown type, or a type with no implementation for that element | Setting dropped |
Selector, Slider, Switch or Color with no defaultValue | Setting dropped |
string or bool on a Slider | Setting dropped |
Color or Binding under <World> | Setting dropped, no log line |
Setting element directly under <Tab> | Setting dropped, no log line |
Unparseable defaultValue | Setting kept at default(T) |
One bad allowedValues entry | Whole list dropped, setting kept |
One bad increment, minValue or maxValue | Whole range dropped, setting kept |
increment of 0 or less, or min above max | Range dropped, setting kept |
<Buttons> with one side missing or unparseable | Neither side applied, setting kept |
Non-boolean Wrap | Ignored |
Unknown RestartScope | Ignored |
RestartScope on a world setting or a category | Ignored |
<Formatter> on Switch, Color or Binding | Ignored |
<Image> with no path, outside <Preview>, or with an unparseable value | Image skipped |
Blank template
Every element in one place. Copy it and delete what you do not need. Remember that type and
defaultValue must be filled in on every Selector, Slider, Switch and Color.
<?xml version="1.0" encoding="utf-8"?>
<ModSettings version="2">
<Global>
<Tab name="" displayKey="" tooltipKey="">
<Category name="" displayKey="">
<Caption key="" />
<Description key="" />
<Preview>
<Image path=""/>
</Preview>
<Selector name="" displayKey="" type="(int,float,string,enum)" defaultValue="">
<Incremental increment="" minValue="" maxValue="" />
<Formatter ui="" serialize="" />
<List allowedValues="" />
<LocalizationPrefix prefix=""/>
<Wrap wrap="true" />
<Caption key="" />
<Description key="" />
<RestartScope scope="(none/reload/restart)" />
<Preview>
<Image path="" value=""/>
</Preview>
</Selector>
<Slider name="" displayKey="" type="(int,float)" defaultValue="">
<Incremental increment="" minValue="" maxValue="" />
<Formatter ui="" serialize="" />
<Caption key="" />
<Description key="" />
<RestartScope scope="(none/reload/restart)" />
<Preview>
<Image path="" value=""/>
</Preview>
</Slider>
<Switch name="" displayKey="" type="(bool,string,enum)" defaultValue="">
<Buttons left="" right="" />
<LocalizationPrefix prefix=""/>
<Caption key="" />
<Description key="" />
<RestartScope scope="(none/reload/restart)" />
<Preview>
<Image path="" value=""/>
</Preview>
</Switch>
<Color name="" displayKey="" defaultValue="">
<Caption key="" />
<Description key="" />
<RestartScope scope="(none/reload/restart)" />
<Preview>
<Image path=""/>
</Preview>
</Color>
<Binding name="" displayKey="">
<Caption key="" />
<Description key="" />
<RestartScope scope="(none/reload/restart)" />
<Preview>
<Image path=""/>
</Preview>
</Binding>
</Category>
</Tab>
</Global>
<World>
<Category name="" displayKey="">
<Caption key="" />
<Description key="" />
<Preview>
<Image path=""/>
</Preview>
<Selector name="" displayKey="" type="(int,float,string,enum)" defaultValue="">
<Incremental increment="" minValue="" maxValue="" />
<Formatter ui="" serialize="" />
<List allowedValues="" />
<LocalizationPrefix prefix=""/>
<Wrap wrap="true" />
<Caption key="" />
<Description key="" />
<Preview>
<Image path="" value=""/>
</Preview>
</Selector>
<Slider name="" displayKey="" type="(int,float)" defaultValue="">
<Incremental increment="" minValue="" maxValue="" />
<Formatter ui="" serialize="" />
<Caption key="" />
<Description key="" />
<Preview>
<Image path="" value=""/>
</Preview>
</Slider>
<Switch name="" displayKey="" type="(bool,string,enum)" defaultValue="">
<Buttons left="" right="" />
<LocalizationPrefix prefix=""/>
<Caption key="" />
<Description key="" />
<Preview>
<Image path="" value=""/>
</Preview>
</Switch>
</Category>
</World>
</ModSettings>Make One Setting Depend on Another
Use Enabled to gray out the settings another setting has taken over, and avoid the trap that stops a grayed setting ever being saved.
Localize Your Settings
Every localization key Gears asks your mod for, where you declare each one, and what the player sees when a key is missing.