Gears

Read Settings in XML Patches

Call modsetting() to read your own or another mod's settings from a conditional block or inline in an attribute value.

Gears adds one function, modsetting(), to the game's XML patching. Use it to read a mod setting from your Config/*.xml patches without writing any C#.

It works in two places: inside the game's <conditional> blocks, and inline inside any attribute value. Everything else on this page — <conditional>, <if>, <else>, mod_loaded, mod_version and XPath — belongs to the game's own patching system, not to Gears.

Arguments and return value

modsetting('ModName', 'SettingsGroup', 'SettingPath')
ArgumentValue
ModNameThe <Name> from the mod's ModInfo.xml. Not the display name, and not the folder name. This may be another mod's name.
SettingsGroupGlobal or World, in any case.
SettingPathFor a global setting, TabName.CategoryName.SettingName, exactly three parts. For a world setting, CategoryName.SettingName, exactly two. The names are the name attributes from ModSettings.xml, not the display keys.

Gears matches ModName and every part of SettingPath exactly, including case. Only the function name and SettingsGroup ignore case. Gears splits SettingPath on every ., so modsetting() cannot read a tab, category or setting whose name contains a dot.

The function returns the setting's serialized value as a string, which is the same text Gears writes to the saved settings file:

  • a bool returns True or False;
  • a number uses <Formatter serialize="…"> if the setting has one, and its plain ToString() otherwise;
  • an enum returns its member name, and a Color returns R,G,B;
  • a Binding has no value and returns an empty string.

Compare the result against a quoted string: == 'True', == 'Hard', == '2'.

Read a setting in a conditional block

<configs>
	<conditional>
		<if cond="modsetting('MyMod', 'Global', 'General.Difficulty.Mode') == 'Hard'">
			<set xpath="/progression/level/@experience_multiplier">1.1</set>
		</if>
		<else>
			<set xpath="/progression/level/@experience_multiplier">1.05</set>
		</else>
	</conditional>
</configs>

A world setting uses the two-part path:

<if cond="modsetting('MyMod', 'World', 'Zombies.BiggerHordes') == 'True'">

modsetting sits alongside the game's own condition functions, such as mod_loaded, mod_version, version and game_version, and you can combine it with them in one expression.

Read a setting inline in an attribute value

After the conditional blocks of a file have been applied, Gears scans every attribute of every element in that file and replaces each modsetting(...) call it finds with the value:

<configs>
	<append xpath="/windows/window[@name='windowHUD']">
		<label depth="4" width="500" height="40"
		       text="Day of the week: modsetting('MyMod', 'Global', 'Calendar.Selectors.DayOfWeek')"
		       color="modsetting('MyMod', 'Global', 'Colors.HUD.DayColor')" />
	</append>
</configs>

This form is a plain text substitution, so it follows a few rules of its own:

  • It works in attribute values only. Gears does not substitute element text, so <set xpath="…">modsetting(...)</set> is left alone.
  • The match is case-insensitive. The arguments run up to the first ). Gears removes every ' and splits the rest on ,, so quotes are optional and an argument can contain neither a comma nor a parenthesis.
  • Gears replaces every call in an attribute, not just the first. If the resulting value itself contains the text modsetting(, Gears leaves it alone rather than expanding it again.
  • A call with no closing ) is an error, and patching of that file stops. So is any of the failures listed under Error messages.

Guard the patch for players without Gears

Without Gears installed, modsetting is an unknown function. Inside <conditional>, the condition then fails to evaluate. Inline, the game tries to use the literal text modsetting(...) as a value and logs errors. Wrap either form in a mod_loaded check.

<configs>
	<conditional>
		<if cond="mod_loaded('Gears')">
			<append xpath="/windows/window[@name='windowHUD']">
				<label depth="4" width="500" height="40"
				       text="Day of the week: modsetting('MyMod', 'Global', 'Calendar.Selectors.DayOfWeek')" />
			</append>
		</if>
		<else>
			<append xpath="/windows/window[@name='windowHUD']">
				<label depth="4" width="500" height="40" text="Day of the week: Monday" />
			</append>
		</else>
	</conditional>
</configs>

When the values are current

Gears populates settings at game start, before any XML is patched, so a global setting always holds its current value at patch time.

A world setting belongs to the world. On the host, Gears loads it when the world starts, before the world's XML is patched, so a world patch reads the right values. A client does not patch the world's config files itself. It receives them from the server already patched, so they carry the server's values.

Before the first world is loaded, a world setting reads as its defaultValue. After the host leaves a world, a world setting keeps that world's values until the next world loads.

Error messages

Gears reports every failure as an XML patch error in the log. For the inline form, Gears first logs a warning that names the file, the attribute and the position of the call:

[Gears] XML.<file> (<attribute>, line <n> at pos <m>): <message>

These messages check the arguments themselves. In the conditional form each one is prefixed Calling function ; inline it is not:

MessageCause
modsetting with invalid number of arguments (N, expected 3)wrong argument count
modsetting: Parameter ModName expected string argumentconditional: the first argument is not a quoted string. Inline: it is empty.
modsetting: Parameter SettingsGroup expected string argumentconditional: the second argument is not a quoted string. Inline: it is empty.
modsetting: Parameter SettingsGroup expected to be either 'Global or World'the second argument is something else, including an empty '' in the conditional form
modsetting: Parameter SettingName expected string argumentconditional: the third argument is not a quoted string. Inline: it is empty.
modsetting: mod <ModName> could not be foundno loaded mod has that <Name>, including an empty '' in the conditional form

In the conditional form, an empty '' third argument is a string, so it fails as a path with the wrong number of parts instead.

The inline form has one more message of its own:

MessageCause
modsetting( at position <n> has no closing ')' in "<value>"the call has no closing parenthesis

These messages come from resolving the path, and they carry the Calling function prefix in both forms:

MessageCause
Calling function modsetting: Parameter SettingName expected string argument in the format of 'TabName.CategoryName.SettingName'a global path does not have three parts
Calling function modsetting: Parameter SettingName expected string argument in the format of 'CategoryName.SettingName'a world path does not have two parts
Calling function modsetting: mod <ModName> does not have any global mod settings, or …world mod settingsthe mod has no settings in that group
Calling function modsetting: mod <ModName> does not have a mod settings tab called <t>the first part of a global path is wrong
Calling function modsetting: mod <ModName> does not have a mod settings category called <c>the category part is wrong
Calling function modsetting: mod <ModName> does not have a mod setting called <s>the setting name is wrong

A setting that exists but holds no value, which means a Binding, is not an error. It returns an empty string.

On this page