Documentation: Processing rules
The processing rules are the heart of Complex Sorter. All actions are defined and customizable by processing rules.
This article describes the textual ini syntax for processing rules and how they are processed. The integrated rules editor GUI in Complex Sorter allow you to edit those ini files in a more easy graphical way and with many assistant tools. The GUI rules editor display the rules mostly in their ini syntax, so the information in this article is still very useful for the understanding of the system even if you only use the graphical editor.
Tip: If you're going to making a lot of rules, then the ini files are a much faster way to do this.
Basics
The basics are simple though. Basically the rules are a list of "When CONDITIONS then TAG" statements.
Here are two examples:EFFECTS contains RestoreHealthFood = food
EDID contains SkillMag = skillmag[/i]
When the item has the effect "RestoreHealthFood", then apply TagIdent "food". When the items EDID property contains the text "SkillMag", then apply TagIdent "skillmag".
The TagIdent (e.g. "food") will then (accordingly to your chosen output tag set) converted to the final tag (e.g. "[Food]" for FallUI or "(Food)" for Ruddy88).
Then you just have to put that lines in the section, so Complex Sorter knows where to apply it. For a food item, it would be [ALCH] (INI section, not a tag).
That's the basics. With that simple knowledge you already know how to read, understand and write the most content.
Example How To - Add [Setting] tag to a mod holotape
Easiest way without deep knowledge of FO4Edit is to add a "Rules (User)\{Mod ESP without .esp extension}.ini" file in the Complex Sorter folder with this lines:[NOTE]
"Full - Name" equals "{Item name}" = holotape_custom_mod
Generate again and the holotape will now have the name "[Settings] {Item name}" in game. The tag can now be shown as icon in your interface mod.
More complex rules
As the processing rules are extremely mighty, the details can be a bit more complex. But one step after the other!
For simple adjustments you only need some basic knowledge. (Just remember that you can match much more, like keywords, effects, properties, body
slots etc. You can also modify records, add keywords, add/remove/change INNRs and so on.)
Processing rule set file
Basic format of a processing ruleset file
- The file format is INI.
- The [section] is the target record type, e.g. [WEAP] for weapons. - See Section
- Each section line represents one rule. - See Rules
- The part before "=" are the conditions of the rule - See Conditions
- The part after "=" is the target TagIdent of the rule - See TagIdent
- Lines beginning with ";" are comments. So you can write notes or just make a rule inactive.
Section
Defines the target record type to which the rules apply.
There are two types of possible section types: Prefilter rules and normal rules. Define the prefilter sections with a prepended "prefilter:" in the name, e.g: "[prefilter:WEAP]". The normal sections are defined just by the record type, e.g. "[WEAP]".
Rules
Defined one per line in a [section]. A rule can have one or many conditions and have one resulting [TagIdent].
Syntax of a rule line
[Condition 1], [Condition 2],... = [TagIdent]
Conditions
The conditions can be used for matching nearly everything available in FO4Edit.
Syntax of a [Condition]
The syntax is pretty simple, it's always the same structure:
(not) [Property] [CompareType] [Value]
- (not) - (Optional) Negates the rule condition.
- Any rule can optionally be negated.
- Any rule can optionally be negated.
- [Property] - The record field for the match. Look at FO4Edit records to see the names.
- Examples: KEYWORDS, EFFECTS, EDID, "Full - Name", "ENIT\Sound - Consume"...
- Remember to "quote" record field names with white spaces in it
- KEYWORDS and EFFECTS are special properties for easy checking of contained keywords. (But no partial text match here!)
- You can also use most special conditions here (see later section for special conditions)
- [CompareType] - The compare type
- Possible compares: equals, contains, beginsWith, endsWith, exists, numEquals, greaterThan, lessThan, hasFlag, hasOnlyFlags, hasKeyword
- Compare type "exists" have no third parameter "[Value]".
- [value] - The value to which the record field is compared to.
- Examples: "Item name", ObjectTypeWater, Newspaper, "Props\NoteRipped_LowPoly.nif", 0, 42, "", ....
- You can type in multiple values separated by "|". The [Condition] is true, if any of its values matches (note: also for operation "equals").
- Remember to "quote" values with white spaces in it.
Example:
KEYWORDS contains ObjectTypeWater = drink
If the item has the keyword ObjectTypeWater, it gets the TagIdent "drink".
Tips and hints
- You can use multiple conditions in AND-logic separated by comma. (Note: OR isn't possible at this layer)
- Many property names in FO4Edit have a short form. So "PTRN" is the same as "PTRN - Preview Transform".
- Sometimes FO4Edit has inconsequential naming, like the "Model\MODL - FileName" can only access by "Model\MODL". You just have to try to find the correct identifier...
- Some compare types only work on correct record field types, e.g. "hasFlag" only works for the "flags" typed fields.
Special conditions
Special condition keywords to be used for advanced matching rules. Most of those will work like normal fields for processing rules.
- SPECIAL:MasterESP - Allows you to apply rules based on the source Master-ESP file.
- SPECIAL:WinningOverrideESP - Allows you to apply rules based on the winning ESP file.
- SPECIAL:ContainedInESP - Allows you to apply rules based on an involved ESP file (So either winning, master, or anything between). Specify the plugin as basename, so NO trailing ".esp", ".esm" etc. Note: this special condition doesn't have a [CompareType]. You specify the ESP directly after the keyword, e.g. SPECIAL:ContainedInESP "Fallout4".
- SPECIAL:TagIdent - Get the found TagIdent for matching (Only make sense if used in an "AfterMatch" rule in a plugin)
- SPECIAL:LeveledItemReference:[Field name] - Get a value from the referenced item in a leveled item record. (Always works on the target master). Use "LeveledItemReferenceOverride" if you want to target the winning override.
- SPECIAL:PluginSetting:[Plugin ID]:[Setting name] - Retrieves a user plugin setting.
Example:
"SPECIAL:LeveledItemReference:Record Header\Signature" equals ARMO = SPECIAL:FindCustomTagLVLI:_custom_LeveledItemArmoTagger
Special condition constructs
- [Field name]:link:[Field name in linked record] - Retrieves a field value from the referenced record in [Field name]. E.g.: INRD:link:EDID.
- [Field name]:keywordsCount - Get the count of keywords in this field. Also works for most other "array"-like structures.
- BP:flagsCount - Get the count of used biped body slots.
Example:
BP:flagsCount numEquals 1, BP hasFlag "47 - Eyes" = eyes
The following special conditions have no [CompareType] or [Value], they stand for themselves:
- * - Match anything, so it gets applied always. Good for the last rule to match any remaining item.
- SPECIAL:IsArmor - Is true for apparel that is classified as armor by Complex Sorter.
- SPECIAL:recordHasHumanRace - Is true for human apparels.
Example:
* = other
TagIdent (used in pre-filter rules)
The TagIdent for pre-filters are quite simple, there are only two:
- IGNORE - Filter the item. (So it don't get modified)
- KEEP - Prevent the item from filtered by later rules (If you want to modify it)
Example:
[prefilter:MESG]
not "FULL - Name" exists = IGNORE
EDID equals MS16FahrenheitGunName = KEEP
Description:
The section define that the rule is applied to MESG record types as pre-filter. The first rule tests if the record field for the main item name ("FULL - Name") exists. And the not negates the result. So every record without a name will be IGNORED.
The second rule test for a specific EditorID. If it matches, the record will be processed.
TagIdent (used in normal processing rules)
The TagIdent refers to tags.ini or a [TagSet:...] section of a CS plugin, which will determine the final [Tag].
Example: The TagIdent "HuntingRifle" will be converted the tag "[HuntingRifle]" for the TagSet FIS. For the TagSet Ruddy88 Original Set it will be converted to the tag "[Ranged]".
Example:
[BOOK]
EDID contains "Password" = password
This section defines to look in all BOOK records. The rule will look in the Editor-ID record field (EDID) and check if it contains the word "Password". If that is true, the rule match and will assign the record to the TagIdent password. The TagIdent password will then (dependent on your selected output tag set and your tags.ini) converted to the final tag [Password].
So all items with "Password" in their EditorId will named like "[Password] {Item name}".
Special TagIdents ("processing functions")
These TagIdents execute special functions. The most of them execute one action and let the rule chain continue (so it won't end like when a Tag is found).
- SPECIAL:FindCustomTag:{dynamic naming ruleset}
- Starts a sub-call to the naming rules, searching for a more precise item tag. Rules continue if nothing is found.
- Starts a sub-call to the naming rules, searching for a more precise item tag. Rules continue if nothing is found.
- SPECIAL:FindCustomTagLVLI:{dynamic naming ruleset}
- Works like FindCustomTag, but retrieves the base item for a LVLI record first. Always works on the target master. To work on the winning override use "LeveledItemReferenceOverride".
- Works like FindCustomTag, but retrieves the base item for a LVLI record first. Always works on the target master. To work on the winning override use "LeveledItemReferenceOverride".
- SPECIAL:AddKeyword:{keyword} or SPECIAL:AddKeyword:{field}:{keyword}
- Adds {keyword} to the record. If no {field} is specified, the keyword will be added to "Keywords".
- Adds {keyword} to the record. If no {field} is specified, the keyword will be added to "Keywords".
- SPECIAL:RemoveKeyword:{keyword} or SPECIAL:RemoveKeyword:{field}:{keyword}
- Removes {keyword} from the record. If no {Field} is specified, the keyword will be removed from "Keywords".
- Removes {keyword} from the record. If no {Field} is specified, the keyword will be removed from "Keywords".
- SPECIAL:RemoveINRD
- Removes the INRD entry from this record. This will allow direct tagging/naming. (Caution: This will prevent any automatic naming in game)
- Removes the INRD entry from this record. This will allow direct tagging/naming. (Caution: This will prevent any automatic naming in game)
- SPECIAL:RecordScript:{Record script}
- Executes an advanced record script on the current record (See article RecordScript more info)
- Executes an advanced record script on the current record (See article RecordScript more info)
- SPECIAL:PregReplace:{field}:{Preg}:{string}
- Perform a {Preg} replace on the records field {field} to {String}. Insert (matches) via \1, \2 etc. Example.: SPECIAL:PregReplace:FULL:"(\s*\{\{\{[^{}]*\}\}\})":""
- Perform a {Preg} replace on the records field {field} to {String}. Insert (matches) via \1, \2 etc. Example.: SPECIAL:PregReplace:FULL:"(\s*\{\{\{[^{}]*\}\}\})":""
- SPECIAL:SetFieldValue:{field}:{value}
- Set {Field} to {Value} (via fo4edit function SetElementEditValues)
- Set {Field} to {Value} (via fo4edit function SetElementEditValues)
- SPECIAL:SetFieldRecRef:{field}:{keyword signature}:{Keyword EditorId}
- Set the field to the reference to some other records. Example: SPECIAL:SetFieldRecRef:BNAM:KYWD:AEC_ck_AmmunitionCraftingKey
- Set the field to the reference to some other records. Example: SPECIAL:SetFieldRecRef:BNAM:KYWD:AEC_ck_AmmunitionCraftingKey
- SPECIAL:SetVar:{var name}:{content}
- Set a temporary internal variable for usage in a later processing rule condition by "SPECIAL:GetVar:{var name}".
- Set a temporary internal variable for usage in a later processing rule condition by "SPECIAL:GetVar:{var name}".
- SPECIAL:EndRuleset
- Skip the processing of THIS rule set (Processing continues at the next rule set)
- Skip the processing of THIS rule set (Processing continues at the next rule set)
Tip: You can add multiple SPECIAL TagIdents separated by "," to a rule.
Rules priority
Pre-filter is always first
The pre-filter rules will always be checked before any other processing rules.
If the record is excluded by a pre-filter-rule (by IGNORE), then it will never be processed by normal processing rules.
Priority inside the rulesets (for pre-filter and normal processing rules)
The rules are processed in this order. Once a "final" rule is applied (typically a rule setting a [Tag]), the processing skip all further rules and jump to step 7 "PluginRulesAfterMatch".
- User rules for a mod (from "Rules (User)\[Mod].ini")
- Plugin "PluginRulesBeforeAll" rules (from "Plugins\[Plugin].ini")
- Main/default rules for mods (from "Rules (Mods)\[Mod].ini" or the section [Mod.{plugin file}.Rules...] of a cs plugin)
- User main rules (from "Rules (User)\rules-processing.ini")
- Plugin "PluginRulesBeforeMain" rules (from "Plugins\[Plugin].ini")
- Main/default rules (from "Rules (Default)\rules-processing.ini")
- (Always last) Plugin "PluginRulesAfterMatch" rules (applied after TagIdent is found) (from "Plugins\[Plugin].ini")
TIPS
- For quick testing select only one or two record type(s) in the GUI - This just updates the selected records and leave the others as they are.
- Try the Ctrl+Y hotkey for quick starting Complex Sorter in FO4Edit. - After the GUI is visible, the "Generate"-button is focused, so you can start the generation instantly by pressing ENTER
- If you want to share your rules with other players, make them language-independent (just don't use "Full - Name") and as specific as possible (EDID is for example unique for a item, while matching a keyword can match many other items).
11 comments
I have question about the process priority of plug-ins . If there are two plugins and they both process a same record (Both under “PluginRulesBeforeMain”), so which one will take priority?
For example, plug-in A gives Amor_RobotLArm “Robot” tag, while plug-in B gives it “Armor” tag. Which tag should be the final one?
You can easily see the final ordering with the "Test rules" function in CS, where all matching rulesets will be listed orderey by priority
For example, in [ARMO] section of a mod there are both LeftArm and leftArm. I tried [Ll]eftArm or (L|l)eftArm, but neither works.
To checking both you can add both like with "EDID beginsWith "leftArm|LeftArm"
I got edid Wrench01, it is includes two components entries Steel & Gears.
For example, i need smth like:
"CVPA - Components" exists=???
what do i need to write to "???" to get result: {Scrap} Wrench{{{(Resource) Steel, (Resource) Gears}}} ?
Or give your own example please!
And second question!
If i dont need this teg {Scrap} Wrench{{{(Resource) Steel, (Resource) Gears}}}
How can i change this default format to {Scrap} Wrench{{{Steel, Gears}}} ?
EDID equals Wrench = scrap
The second part (red in your post) is added by the "Add component tags" plugin. You can look at the plugin file and create your own version if you like to make advanced modifications.
If you simply want to remove the tagged scrap components in the curly braces, you can also use the latest CS beta 1.11. The "Add component tags" plugin have been extended to remove those existing tags that part.
How-To: Tag (Create Own Rules)
Changing leveled item names (so levels items which have own unique names) is a bit more complicated. And currently there exists no article for that topic.