» Sat Dec 04, 2010 1:43 am
There's nothing special about Cobl Main.esm & Cobl Races TNR.esp. They're just examples that I had handy. Cobl Races TNR.esp simply uses hairs and eyes defined in Cobl Main.esm.
Let's start over. You're getting too caught up in the particulars and aren't looking at it in a general sense.
The basic question is simple. When the patch is being made, should non-active masters be unconditionally added to the patch if an imported formID requires it?
Right now, this means the face patcher, but it doesn't only apply to the face patcher. In the future, other import patchers may be written that need to work with imported formIDs. One example would be extending the graphics patcher to import magic effect shaders, enchantment effects, and lights. Any proposed answer should be generic enough to work with any potential future patcher.
Pros:
1) Any formID can be imported.
2) Simpler code.
Cons:
1) The patch can become dependent on a master that isn't present.
2) The patch can become dependent on a master that the user didn't actually want active.
3) If the load order is already full and a non-active master is added, the patch is unusable.
This is a subjective call, but I don't believe in general that the advantage outweighs the disadvantages. The patch should not be trying to activate masters that the user didn't select. The user should be in charge, not Bash. That said, the disadvantages can be worked around if the user is savvy enough to realize what importers are pulling in the unwanted masters. They just have to deselect the problematic imports. In my experience though, there are many users who can't figure this out very easily.
If we work from the premise that the patch shouldn't add non-active masters (or at least should be able to decide it on a case-by-case basis), we come to the conclusion that formIDs referring to non-active masters have to be handled in some manner. Either filtering them out, or marking them so that Bash can decide what to do.
Pros:
1) The patch won't depend on missing or unwanted masters.
2) The patch won't accidentally try to make more than 255 mods active.
3) Patchers can make more complicated decisions when importing formIDs.
Cons:
1) Slightly more complicated code.
2) The patch might not add any non-active masters even if that's what the user actually wanted.
There are several possible implementations:
1) Just don't import formIDs. This is the simplest, most fool-proof, yet most restrictive method. As long as the master is active (which is most of the time), formIDs are perfectly safe to import, but this method still prevents it. The underlying issue still exists, but it never comes to light.
2) Have CBash somehow mark formIDs that reference a non-active master. For example, when CBash loads a record, set any formID that references a non-active master to a special value (such as 0xFFFFFFFF). When Bash tries to import the formID, it can check for this special value to decide what to do (skip the entire record, just skip that formID as appropriate, add the missing master, etc).
3) When CBash loads a record, discard the entire record if any formID in it references a non-active master. Any records left over are safe to use, but a lot of information is lost. Additionally, this may break other records in the mod that refer to the discarded record. A decision would have to be made whether to also remove any records that reference the discarded record, and much of the mod may unravel. Otherwise, any formIDs would have to be tested to see if they're still valid.
4) Rather than change CBash, just have Bash look for and handle any formIDs that aren't safe on its own.
For both Bash and CBash, all import patchers except faces follow #1. It works, but it limits what the patchers are allowed to do.
#3 is much simpler to implement than #2 or #4. It also guarantees that any record that survives the pruning process is completely safe to work with in any manner, so no special attention has to be given when writing new patchers or maintaining old ones. It provides consistency in behavior at the expense of flexibility. A patcher may only be interested in the non-formID fields of a record, but loses access to the entire record with this method. Csv files and filter mods are already filtered like this.
#2 and #4 are almost identical, #2 just offloads some of the work to CBash where it can be done more quickly. Both of them require the coder of each patcher to determine the "best" way to handle any potentially unsafe formIDs, and this would be handled on a patcher by patcher case. Over time, this could become confusingly inconsistent as some patchers drop only the formID, other patchers drop the entire record, and other patchers go ahead and add the missing master to the patch. It makes maintaining patchers more work, but it gives the most flexibility too.
I lean towards #2 even though it means more work. I think the flexibility is worth more than the consistency that #3 gives.
For the face patcher specifically, #1 means that all the face data except the hair and eyes are imported even if the hair and eyes happen to be safe. #3 means that none of the face data will be imported if the hair and/or eyes require a non-active master, but all of the face data will be imported otherwise. #2 & #4 mean that the decision still has to be made, but it can be made more intelligently. For example, if the hair and eyes are in an active mod, all face data including hair and eyes can be imported. If the hair and/or eyes are from non-active mods they can be skipped (or be randomly replaced from existing hair / eye records, or be set to a predetermined default, etc) while still importing the rest of the face data. Or, if there's room in the load order, masters can be added if needed.