Tuning XML
XML Nodes
Section titled “XML Nodes”When writing tuning XML, nodes are written as a single letter based on their type. There are 2 top level node types and 6 regular node types.
Top Level Nodes
Section titled “Top Level Nodes”I - Instance - Add new features
M - Module - Define values of global variables
Most mods will add or update Instance tuning, but overriding Module tuning is possible. Since it is not possible to partially override tuning, a mod that overrides a Module tuning will need to set all values.
Regular Nodes
Section titled “Regular Nodes”T - Tunable - A single value
E - Enum - An enum value
L - List - A lists of values
U - Tuple - An object with key->value pairs
V - Variant - A single value with multiple valid types
C - Class - Used when defining enums, not seen often
Tunable Node Types
Section titled “Tunable Node Types”Multiple field types use the same node letter, so their usage is defined as a type. For example in a trait tuning, both display_name and icon are single values, so they use the T tag, but they store different data types. display_name is a TunableLocalizedString and stores a string key, while icon is a TunableReference and stores a resource key for an icon.
Almost all nodes will have an n node defining the name, which is used to map nodes between tuning XML and tuning description.
Python Module Optional
Section titled “Python Module ”A tuning file’s root node (I or M) contains an attribute i that points to a python module. Let’s take a look using a Trait tuning using the disable_aging node. Here’s what the description says:
disable_aging- If enabled, aging out of specific ages can be disabled.disable_aginghas anenabledchild node, which in turn has anallowed_agesnode.allowed_ages- A list of ages that the Sim CAN age out of.
Using that information, let’s create a “ForeverYoung” trait that would disable aging once a sim becomes a Young Adult.
<?xml version="1.0" encoding="utf-8"?><I c="Trait" i="trait" m="traits.traits" n="ZMilla:ForeverYoung" s="3678950568"> <V n="disable_aging" t="enabled"> <U n="enabled"> <L n="allowed_ages"> <E>BABY</E> <E>TODDLER</E> <E>CHILD</E> </L> </U> </V></I>Can we verify this is set up correctly? The i node is traits.traits. If we resolve that to the python script traits/traits.py, then search for the disable_aging node from earlier, we find a function called can_age_up.
Comments have been added to explain the code if you aren’t familiar with python.
# Can a sim age up when they are 'current_age'?def can_age_up(cls, current_age): # If 'disable_aging' is not defined, yes if not cls.disable_aging: return True # If 'disable_aging' is defined, only allow aging # if the 'allowed_ages' list contains 'current_age'. return current_age in cls.disable_aging.allowed_agesAlas, proof! Young Adult is not in the allowed_ages list and thus, youth is eternal.
This should really solidify the big picture though. Tuning files are XML that defines data for use in a corresponding python file. We can use tuning descriptions to know the exact XML structure, as well as understand how the fields will be used without needing to look at the python code. However, we can still look at the code with some extra work if we’re curious.