Exclusive Groups
available in SPID 7.0.0+
Changelog
- Dec 6, 2024
- Cleaned all the invisible characters that caused issues when trying to copy code examples.
Summary
Exclusive Groups define sets of distributable forms where only one from the set can be distributed at any time.
Ordering and other distribution rules are unaffected by Exclusive Group. The entry that is distributed first according to default ordering will prevent all other entries from the same Exclusive Group to be distributed to the same NPC.
Note, that Exclusive Groups also affect Linked Distribution and On Death Distribution.
Syntax
ExclusiveGroup = GroupName|FormsList
required required requiredwhere:
- ExclusiveGroup - a special key that define an Exclusive Group.
- GroupName - any text that will be used as group's name. (separator | not allowed in the name)
- FormsList* - a comma separated list of FormIDs or EditorIDs similar to default FormFilters in regular SPID entries. These forms will be added to the Exclusive Group.
*Combining modifier (+) doesn't make sense in FormsList, thus is not supported.
Examples
- Defining Exclusive Group
ExclusiveGroup = Only One Sword|IronSword,SteelSword,DaedricSword
Now there will be an Exclusive Group named Only One Sword with 3 mutually exclusive swords.- Modifying existing Exclusive Group
You can also reference existing Exclusive Group by name and modify it by either adding or removing forms to it:
ExclusiveGroup = Only One Sword|SteelBattleaxe,-SteelSword
Only One Sword now doesn't contain SteelSword, but instead contains SteelBattleaxe.When to use
Typical scenario when ExclusiveGroups could be helpful is when you find yourself creating tons of keywords just to ensure that you pick only one entry.
If you find the following setup familiar, you should adopt Exclusive Groups:
Keyword = GetsCoolSword|...|50
Keyword = GetsDecentAxe|-GetsCoolSword,...|50
Keyword = GetsOPBow|-GetsCoolSword,-GetsDecentAxe,...|50
; List goes on :)
Item = CoolSword|GetsCoolSword
Item = DecentAxe|GetsDecentAxe
Item = OPBow|GetsOPBow
Instead, you should be able to express your intent clearer and more efficiently:
Item = CoolSword|...|50
Item = DecentAxe|...|50
Item = OPBow|...|50
ExclusiveGroup = Primary Weapon|CoolSword,DecentAxe,OPBow
36 comments
ExclusiveGroup = myskinname|myWNAM1,myWNAM2,myWNAM3
and tried to distribute them as below:
Skin = myskinname|*dododo,*rerere,*mimimi|myracename
But it doesn't seem to work. I want to distribute these skins to any NPC containing "dododo", "rerere", or "mimimi" in their Editor IDs who also are from race "myracename".
The log says:
(myskinname) FAIL - editorID doesn't exist
It also reads that "Adding 'myskinname' exclusive group", followed by the corresponding ARMO records (myWNAM1,myWNAM2,myWNAM3)
What does it mean? Which EDID is it referring to as absent? "myskinname"? But it's made as an ExclusiveGroup... Then how am I to distribute this group?
I have SPID v7.2.0.RC11. What am I missing?
As for your question, ExclusiveGroup is not a Form by itself. It's just a place where you can tell SPID which forms you don't want to appear on the same NPC. I'm guessing what you want to achieve is this:
ExclusiveGroup = CoolSkins|myWNAM1,myWNAM2,myWNAM3
Keyword = DoReMi|*dododo,*rerere,*mimimi|myraceEDID
Skin = myWNAM1|DoReMi|....|33
Skin = myWNAM2|DoReMi|....|50
Skin = myWNAM3|DoReMi|....|100
A couple notes on the code above:
Hope that clarifies everything
But I think I'm facing another problem with template NPCs which I'm too darn tired to comprehend the tricks related to them with SPID. I'll give another chance later, haha!
Thank you so much for your patience and your detailed explanation!
Spell = 0x800~Myplugin.esp|ActorTypeNPC|NONE|NONE|NONE|NONE|33
SPID behaves like the ExclusiveGroup line was not in the config.Spell = 0x801~Myplugin.esp|ActorTypeNPC|NONE|NONE|NONE|NONE|50
Spell = 0x802~Myplugin.esp|ActorTypeNPC|NONE|NONE|NONE|NONE|100
ExclusiveGroup = MySpells|0x800~Myplugin.esp,0x801~Myplugin.esp,0x802~Myplugin.esp
[19:55:19:462] po3_SpellPerkItemDistributor v7.1.3.0
[19:55:19:462] Game version : 1-5-97-0
[19:55:20:115] *******************DEPENDENCIES*******************
[19:55:20:115] powerofthree's Tweaks (po3_tweaks) detected : true
[19:55:20:115] ***********************INI************************
[19:55:20:163] 1 matching inis found
[19:55:20:163] INI : Data\MySpells_DISTR.ini
[19:55:20:165] **********************HOOKS***********************
[19:55:20:166] Installed actor load hooks
[19:55:20:184] **********************MERGES**********************
[19:55:20:184] Failed to dispatch message to MergeMapper
[19:55:20:184] INFO - MergeMapper not detected
[19:56:03:713] ********************PROCESSING********************
[19:56:03:713] Registered 3/3 Spells
[19:56:03:713] *****************EXCLUSIVE GROUPS*****************
[19:56:03:713] Adding 'MySpells' exclusive group
[19:56:03:713] [SPEL:000ED099]
[19:56:03:713] [SPEL:000ED09D]
[19:56:03:713] [SPEL:000ED09E]
[19:56:03:714] **********************EVENTS**********************
[19:56:03:714] Registered for struct RE::TESFormDeleteEvent
[19:56:03:715] Registered class PCLevelMult::Manager
[19:56:03:715] Registered for struct RE::TESDeathEvent
[19:56:03:759] **************MAIN MENU DISTRIBUTION**************
[19:56:03:759] Spell
[19:56:03:759] [0xED099~Skyrim.esm] added to 509/2796 NPCs
[19:56:03:759] [0xED09D~Skyrim.esm] added to 747/2796 NPCs
[19:56:03:759] [0xED09E~Skyrim.esm] added to 1475/2796 NPCs
[21:14:15:489] [0xED099~Skyrim.esm] added to 948/2796 NPCs
0xED09E Form was added to every actor, that means that there is at least one actor that have more than one of the forms which is not exclusive.[21:14:15:489] [0xED09D~Skyrim.esm] added to 1382/2796 NPCs
[21:14:15:489] [0xED09E~Skyrim.esm] added to 2796/2796 NPCs
This is the log when I remove the ExclusiveGroup line.
[21:18:06:996] [0xED099~Skyrim.esm] added to 930/2796 NPCs
I am probably missing something if you are saying its working as intended.[21:18:06:996] [0xED09D~Skyrim.esm] added to 1391/2796 NPCs
[21:18:06:996] [0xED09E~Skyrim.esm] added to 2796/2796 NPCs
EDIT: The distributions are basically the same if we take randomness into accout, thats why I am saying that SPID is behaving like the ExclusiveGroup line was not defined.
EDIT2: If I use keywords in the ExclusiveGroup then it distributes the keywords uniformly 33/33/33%
Spell = 0xED099~Skyrim.esm|NONE|NONE|NONE|NONE|NONE|33
Spell = 0xED09E~Skyrim.esm|NONE|-0xED099|NONE|NONE|NONE|100
[0xED099~Skyrim.esm] added to 892/2796 NPC
[0xED09E~Skyrim.esm] added to 2796/2796 NPCs
If you're curious why it happened, it's because SPID doesn't actually add spells one-by-one, but instead it collects all the spells that should be distributed to given NPC and after that adds them all at once. This was done for performance reasons, but what this means is that when other spell distribution's filter tries to check previously distributed spell it looks for spells that NPC already has, and at this point in time NPC has none of the distributed spells yet, hence all the filters/ExclusiveGroups essentially don't see other spells.
Basically I have:
Skin = rooster1||mihailcock_race||||10
Skin = rooster2||mihailcock_race||||15
Skin = rooster3||mihailcock_race||||15
ExclusiveGroup = rooster1,rooster2,rooster3
and when I check the log, the group is correct and a few of each skin are said to be distributed. But their skins aren't being changed when I spawn a bunch via console. With the old method which uses a distributed spell to apply the skin, they would wear their new skins even when spawned. Would assigning a keyword in an exclusive group and then distributing the proper skin to the proper keywork make any difference? Or just make it messier. :D
Thank you so much for your advice!
EDIT: I think I see what I was getting wrong. The skins aren't random per NPC rooster: if the skin is distributed to one of the base formids of a rooster then *all* of the roosters with that base formid will have that skin. I just happened to be spawning the baseid that didn't get distributed to. I guess I still need the skin changer spell to truly randomize them. :/ (I was also playing around with Stray Dog skins and each time I entered the game, all the stray dogs I spawned would be the same skin, but different each login, helped me to understand what was going on)
I was kind of hoping this could be something similar to Base Object Swapper, but I misunderstood the mechanics. Sorry to trouble you!
Another option is to use SPID to distribute the spell
EDIT: Actually, you know what
One thing that sparked my interest was an auto-strip area that altered my stray dog companion. The way the spell works is by giving the animal a random skin outfit to wear, which can technically be removed by either the unequip console command or by such scripts that make you naked when bathing, etc. Having an actual skin assigned seemed better in general, it wouldn't be removeable. Plus I'm looking into applying size differences and being able to have a linked spell to certain skins seemed like a cool way to do it.
Another thing I was trying to see if I could get to work is I have a mod that uses that spell to distribute horker skins, and someone wanted a patch so the skin of their carcass from one of those hunting mods would match the skin of the animal they killed. I thought maybe I could achieve that by having SPID assign a keyword based on what outfit they are wearing, and then make textures to apply based on that keyword, but unfortunately that did not work either, it didn't recognize the ones added by the spell. The only keywords were assigned to animals who were given the skins in a patch. I think it may be due to the order of distribution, since keywords are assigned before spells?
Thanks again for taking the time to reply <3
If you don't mind please create an Exclusive group for these item below for me to understand:
In your case the group is this:
ExclusiveGroup = MyItems|0x801~Kemper's Weapon Collection II.esp,0x802~Kemper's Weapon Collection II.esp,0x803~Kemper's Weapon Collection II.esp
Expectations: Mihail's Skeleton Colossus, is both a Draugr and a Skeleton type. It should receive only one of either perks below.
Result: It received both perks
Perk = BonyPerk||SkeletonFaction|NONE|NONE|NONE
Perk = FleshyPerk||DraugrFaction|NONE|NONE|NONE|NONE
Exclusivegroup = MihailColossusPickOne|BonyPerk,FleshyPerk
Also, all trailing NONEs can be omitted.
I couldn't get exclusion groups to work with perks somehow, i had better success using keywords for exclusion groups, then distributing perks to those keywords.
i think there's a bug with exclusive groups, in my SPID file I have 4 different exclusive groups for keywords.
in the log file it says they're all being processed, but I notice that the keywords in some of the groups aren't consistently being applied.
for example:
Keyword = keyword_a|-custom_keyword|||-C||33
Keyword = keyword_b|-custom_keyword|||-C||34
Keyword = keyword_c|-custom_keyword|||-C||33
ExclusiveGroup = My Group|keyword_a,keyword_b,keyword_c
My understanding is this should be uniformly applied to every NPC that does not have the custom_keyword, where everyone has either keyword_a, keyword_b, or keyword_c since the chances all add up to 100 (33 + 34 +33), as defined since it is an ExclusiveGroup.
However, during testing I will notice that not all the NPCs have a keyword applied from the group.
In fact, when I look at the logs, i see this:
[21:10:54:272] Keyword_a [0xF43~my_plugin.esp] added to 894/2738 NPCs
[21:10:54:272] Keyword_b [0xF44~my_plugin.esp] added to 582/2738 NPCs
[21:10:54:272] Keyword_c [0xF45~my_plugin.esp] added to 378/2738 NPCs
The total here does not add up to even close to the total amount of NPCs,. I know i have a trait filter -C that excludes children, but theres no way 1851/2738 are excluding just children lol
So your config actually has the following probabilities:
Pa = 33%
which can be confirmed by the numbers in log output. (P0 - chance where actually none of 3 would be given, which explains why number in the log don't add up to the total NPCs count)Pb = (100 - 33)% * 34% = 67% * 34% = 22.78%
Pc = 67% * (100 - 34)% * 33% = 14.5926%
P0 = 67% * 66% * 67% = 29.6274%
What you want to do is:
Pa = 33%
Pb = 50% (this will make 67% * 50% to give 33.5% probability overall)
Pc = 100% (to cover the rest 67% * (100 - 50)% * 100% = 33.5%
Item = CoolSword|...|33
Item = DecentAxe|...|50
Item = OPBow|...|
ExclusiveGroup = Primary Weapon|CoolSword,DecentAxe,OPBow
What determines what is evaluated first in the exclusive group? Because I want coolsword to get 33% distribution, and then decent axe to be half of 67%, and the rest to be OPBow.
But that's not really what I'm observing.
I feel seen :D
Thanks for this great update & explainer!