Skip to content

Configurations

Cameron Meyer edited this page Feb 27, 2024 · 24 revisions

Configurations are generated at %localappdata%\Larian Studios\Baldur's Gate 3\Script Extender\Automatic_Inventory_Manager - this contains the config.json, log.txt, and all the presets.

Available Configurations

Property Name (case sensitive) value(s) default
ENABLED 0 for disabled, 1 for enabled. Just disables the processing and tagging of items, configs will still be processed and synced (see SYNC_* properties) 1
LOG_LEVEL TRACE = 5, DEBUG = 4, INFO = 3, WARNING = 2, ERROR = 1, OFF = 0
---
HIGHLY recommended to leave at INFO or below, as writing logs is extremely performance intensive and if you have any items with stack counts in the hundreds or thousands, like gold, it will appear as though your game is frozen. Only increase this if you're actively debugging an issue for a select item.
---
Any logs above INFO level (debug/trace) will not be logged to console, and will only be sent to the log.txt, due to the sheer amount of information.
3
RESET_CONFIGS 1 if you want to completely reinitialize, as if you had deleted the folder (but doesn't wipe out mod-added filters\ files 0
SORT_ITEMS_ON_FIRST_LOAD 1 if you want to execute items when you load a campaign that hasn't had its items processed by AIM yet - once a campaign has been processed and saved, a PersistentVar will be used to prevent re-processing on every load afterwards
0 otherwise
1
SORT_ITEMS_DURING_COMBAT 1 if you want any items that you pick up while combat is active to be sorted
0 otherwise. Example of this being helpful is if you're forceably disarmed and don't want the weapon to be sorted when you pick it up
0
SORT_CONSUMABLE_ITEMS_ON_USE_DURING_COMBAT 1 if you want any items that you use while combat is active, and that have the CONSUMABLE TAG, to be sorted.
0 otherwise
0
PRESETS See Configurations#customizing-preset-loading - ACTIVE_PRESETS: {}
- FILTERS_PRESETS: {} (populated at runtime by AIM)
- PRESETS_DIR: "presets"
RECORD_APPLICABLE_ENTITY_PROPS See Configuration#entity-property-recorder
1 to enable
0 otherwise
0

Presets

Version 2.0.0 introduces the concepts of Presets - groups of ItemFilterMaps that can be selectively merged together to form your ideal configuration for whatever game you're playing.

From the Mod User's perspective, there are three categories of Presets:

  • Default Presets created by AIM
  • Presets created by third-party mods
  • Presets created by the mod user

Preset Customization

Only presets created by the user themselves can/should be customized - any presets added by mods, including the AIM defaults, are intended to be controlled entirely by the mod that added them, to ensure mod users can get the latest updates without fear of losing any customizations (as merging in these tables would be heinously complicated and destructively error-prone). AIM will reinitialize its default presets on every save load - when third-party mods reinitialize theirs is up to them.

Customizing Preset Loading

To help compensate for the lack of customizability, Mod Users are not only able to specify which presets to load, but which ItemFilterMaps from that preset to load. This is done through the following configuration properties, grouped under the PRESET configuration:

Property Name (case sensitive) Description AIM Interactions
PRESETS_DIR Represents the directory under AIM's ScriptExtender folder (%localappdata%/Larian Studios/Baldur's Gate 3/Script Extender/Automatic_Inventory_Manager) where all presets live. Can't think of a valid reason to change this, but exposing anyway. Defaults to presets. The config key and all values are case-sensitive. AIM will not overwrite this value once it's been initialized
FILTERS_PRESETS Documents the known presets and all ItemFilterMaps that are registered to that preset (corresponding to the .json files within that preset's directory). The config key and all values are case-sensitive. Any mod-added presets (including AIM defaults) can and will be completely overwritten by AIM at any point (AIM reinitializes each save load) - no customizations will be preserved. Any user-added presets will be preserved under all circumstances (unless the provided JSON is invalid and can't be read)
ACTIVE_PRESETS Documents which presets and which of their associated ItemFilterMaps to load (use value "ALL" to load all registered ItemFilterMaps) - order matters, and any presets specified earlier in the list will be given higher priority if any filters are duplicated. More info below. The config key and all values are case-sensitive. AIM will not overwrite this value after it has been initialized - will default to AIM-Migrated-Custom-Filter-Preset if a 1.x filters/ directory has been migrated, otherwise Automatic_Inventory_Manager-All-Defaults

ACTIVE_PRESET Merging Behavior

This config follows a first-come, first-serve merge model, but only at the Filter and PreFilter (lowest) level, meaning Presets specified earlier in the list will be given higher priority when resolving duplicates than those later in the list - otherwise, all ItemFilterMaps are merged together and stored in memory (reloaded on each save load).

PreFilters take a more all-or-nothing approach (as of 2.0.0), which means that any PreFilters in Preset_A will be completely ignored if Preset_B already registered a PreFilter with the same key - needs to be a more complicated merge to ensure that it supports current and future PreFilter formats, and that merging multiple ItemFilters together won't automatically result in prefiltering out everyone in the party.

Example

Say you have the following presets registered:

"FILTERS_PRESETS" : 
{
	"A_Preset" : 
	[
		"Roots",
		"Weapons",
                "Armor"
	],
	"B_Preset" : 
	[
		"Equipment",
		"Roots"
	]
}

A_Preset has the following entry in presets/A_Preset/Roots.json:

{
	"LOOT_Gold_A_1c3c9c74-34a1-4685-989e-410dc080be6f" : 
	{
		"Filters" : 
		[
                        "1": {
				"CompareStategy" : "LOWER",
				"TargetStat" : "STACK_AMOUNT"
			},
			"2": {
				"CompareStategy" : "HIGHER",
				"TargetStat" : "STACK_AMOUNT"
			},
                        "3": {
				"Target" : "originalTarget"
			}
		]
	}
}

B_Preset has the following entry in presets/B_Preset/Roots.json:

{
	"LOOT_Gold_A_1c3c9c74-34a1-4685-989e-410dc080be6f" : 
	{
		"Filters" : 
		[
			"1": {
				"CompareStategy" : "HIGHER",
				"TargetStat" : "STACK_AMOUNT"
			}
		]
	}
}

and the ACTIVE_PRESETS config set to:

"ACTIVE_PRESETS" : 
{
	"B_Preset" : 
	[
		"ALL"
	],
	"A_Preset" : 
	[
		"Roots",
		"Weapons"
	],
}

(B_Preset is set first to demonstrate that it's placement, not naming, that matters)

AIM will process B_Preset first and load all registered ItemFilterMap files into memory - in this scenario, "Equipment", "Roots"

AIM will then process A_Preset - it will load Weapons without issue, as that ItemFilterMap hasn't been registered yet, but will kick off a merge operation upon processing the Roots.json. This operation will perform the following evaluations:

  1. Compares the entries in A_Preset/Roots.json to B_Preset/Roots.json and determines that they have an identical ItemFilter key: LOOT_Gold_A_1c3c9c74-34a1-4685-989e-410dc080be6f
  2. Begins processing each Filter within Preset_A's LOOT_Gold_A_1c3c9c74-34a1-4685-989e-410dc080be6f ItemFilter
  3. Priority 1 will set to priority 2 and added to the in-memory ItemFilterMap, as there was no existing filter with the same content, but Preset_B's filter was already set to Priority 1
  4. Priority 2 will be ignored, as the CompareFilter is identical to the existing Priority 1 filter from Preset_B/Roots.json
  5. Priority 3 will be set to priority 3 as there was no existing duplicate and no other Filters set to Priority 3

Making the final result for the in-memory ItemFilterMaps being:

{
	"Weapons": {...},
	"Equipment": {...},
	"Roots:" {
		"LOOT_Gold_A_1c3c9c74-34a1-4685-989e-410dc080be6f" : 
		{
			"Filters" : 
			[
				"1": {
					"CompareStategy" : "HIGHER", -- From Preset_B
					"TargetStat" : "STACK_AMOUNT"
				},
				"2": {
					"CompareStategy" : "LOWER", -- From Preset_A
					"TargetStat" : "STACK_AMOUNT"
				},
				"3": {
					"Target" : "originalTarget" -- From Preset_A
				}
			]
		}
	}
}

Or, to use a diagram that would make railroad designers proud (or give them an aneurysm): (You can right-click -> open in new tab for a bigger image) Preset Merge Diagram

Adding Custom Presets

Third-party mods can add their own presets via AIM's API - see any of the the Sample Mod's implementations

Users can easily add their own presets by doing the following steps (order is irrelevant, just complete them all before loading a save):

  • Add a new entry to the config.json PRESETS.FILTERS_PRESETS property, specifying the name of your preset and the ItemFilterMap keys you'll be registering, which are exactly the name of the .json files you'll be creating under the {PRESETS.PRESETS_DIR}/{Your Preset Name}/ directory.
  • Create your new ItemFilterMap .json files under the {PRESETS.PRESETS_DIR}/{Your Preset Name}/ directory - for example, if your preset name is MyCustomPreset_1 and PRESETS.PRESETS_DIR is the default of presets, then you'll be using %localappdata%/Larian Studios/Baldur's Gate 3/Script Extender/Automatic_Inventory_Manager/presets/MyCustomPreset_1/ - case-sensitive (there aren't any directory traversal utilities natively available that I can find)
  • If you want to use it in a game, add it to the PRESETS.ACTIVE_PRESETS array, keeping in mind the filter merge behavior

Example (right-click -> open image in new tab for better view):

image

Blacklisting Items and Templates

An ItemBlackList.json file is generated alongside the config.json - this file allows mod users and third-party mods to add Item and RootTemplate UUIDs (partial or full) that should be ignored by AIM in all circumstances. AIM will never reset this file, and will handle merging entries created by mod users and third-party mods (removing duplicates)

Example Content:

{
	"Items" : 
	[
		"ALCH_Solution_Oil_Poison-05823919-1ffa-4e6e-a7f4-853ea76aae36"
	],
	"RootTemplates" : 
	[
		"ALCH_Solution_Oil_Combustion-bb750807-895b-468d-81e1-4378797d11ca",
                "Oil_Combustion"
	]
}

Third-party mods should refer to the Sample Mod's _ItemBlacklist.lua

Entity Property Recorder

Introduced in 2.1.0

The new Config property RECORD_APPLICABLE_ENTITY_PROPS introduces a new helper within AIM - this helper looks at a given entity (either an item or a party member) and 'records' the properties that AIM, or any third-party mods that have registered recorders, knows it can use as part of its filtering logic, and save the entry in %localappdata%\Larian Studios\Baldur's Gate 3\Script Extender\Automatic_Inventory_Manager\RecordedEntityProperties.json. This file is loaded once on startup, then is fully replaced each time an entity is processed.

AIM will run this process on each item that is eligible for processing (does not have the AIM_PROCESSED tag on it and isn't in the Blacklist) before it goes through the filtering process (e.g. was just picked up) - if you want to record an item that was already processed by AIM, simply drop the item and pick it back up again! AIM will also run this against the current party on each level load, or when a new party member is added.

Third-party mods looking to register their own PropertyRecorders should reference the SampleMod's _CustomFilters.lua

Record Structure

Each entity will have their own entry in RecordedEntityProperties.json with the following guaranteed structure:

{
	"ID" : 
	{
		"MOD" : 
		{
                    ...
		}
	},
}

ID will be the GUIDSTRING of the character (e.g. Elves_Female_High_Player_b17af403-fd62-01c1-2344-8c160c207926) or the rootTemplate GUIDSTRING of the item being processed (e.g CONS_Potion_Speed_ad9f3f24-d755-48b6-aa7b-c34da068209f).

Mod will be the name of the mod that registered the recorder function that contributed to this entry - this is done for clarity on what is natively applicable versus added by third-party mods.

The content of the MOD object is technically up to the mod that generates the entry, but AIM uses and recommends the following structure:

{
	"ID" : 
	{
		"MOD" : 
		{
			"Property" : 
			{
				"Can Be Applied To" : 
				{
					"FilterFields" : 
					[
						...
					],
					"ItemFilterFields" : 
					[
						...
					],
					"ItemFilterMaps" : 
					[
						...
					],
					"PreFilterFields" : 
					[
						...
					]
				},
				"Value" : ...
			}
		}
	},
}

Examples

(right click -> open in new tab for a bigger image)

Entity Property Recorder - Char example

Entity Property Recorder - Equipment example