Python script to convert, in bulk, NPCs to use proficiency 2 and passives instead of 5e's scaled proficiency system.
Mostly distributed for the purpose of evidencing the accuracy of the mod PR, but perhaps it would also be useful if anyone else finds they need to make a lot of changes to a BG3 stats file.
Note that as this is not intended for production, it contains the path to my clone of the repo, and should be updated to your needs if used.
Inheritance is the primary issue to work around, particularly as, once changes are made, we lose what value was previously being inherited. Sometimes this is useful, and sometimes it hinders us.
We start out by iterating through all characters and determining what their proficiency value is, handling inheritance recursively. We check for errors such as not having any value defined and skip those characters. We also skip any characters whose proficiency value is lower than that from which they inherit (a process which makes the script significantly slower) as this is likely to mean they'll also inherit passives incorrectly and need manual intervention.
We then proceed to read out their Passives and DefaultBoosts strings, again accounting for inheritance.
If the proficiency value was less than 3, we will not be giving the character any passives or changing their proficiency, so we skip these.
We then populate a list of all the characters we intend to change, along with their strings, and sort by how many layers deep they inherited their strings from. This allows us to determine which characters were base stats, and update those first, allowing us to preserve inheritance.
From there, we iterate through our list to check what value proficiency was at, grant appropriate passives (if they did not already have them), and then set the proficiency to 2. Because we do base classes first, and are carrying this out in a second pass, we can avoid updating passives in cases where the base class would have already done so.
Skill expertise is, annoyingly, a boost, so that has some extra handling.
The script prints out the name of any character it skips to be manually reviewed afterwards.