encall Posted February 22, 2025 Posted February 22, 2025 1 hour ago, nopse0 said: Interesting. How did you change the skin of your followers, with the NiOverride AddSkinOverride functions ? I don't understand, why combining AddSkinOverride and AddNodeOverride functions makes the frame rate drop. As far as I understand https://geek-of-all-trades.neocities.org/programming/skyrim/nioverride-textures-03-skin skin overrides directly work on the nodes of the body, e.g. something like "HIMBO - Hands" or "3BA", while node overrides are some sort of abstract layers, which don't directly modify the nodes of the skinned armor you are wearing, but instead the fleshy part (the part which isn't covered by the armor mesh) of the (skinned) armor (regardless of the concrete node names the armor has), e.g. a node override name is something like "[Ovl Body 123]". Maybe this is a engine or NiOverride problem. Sorry I mean some of my follower's fomod have an option to use player texture, so I reinstall and select that option instead. There's still problems with other followers who use their custom texture. I also run WetFunction Redux and I think it also used AddSkinOverride and AddNodeOverride and it works just fine with no FPS drops. Maybe its just my PC, if this were happening to others, it would be a big issue.
no_way Posted March 5, 2025 Posted March 5, 2025 Is this mod and the monoman BIS tweaked patch compatible with BIS renewed? https://www.nexusmods.com/skyrimspecialedition/mods/135288 It says it incorporated monomans tweak but not verbatim.
aim4it Posted March 6, 2025 Posted March 6, 2025 On 3/4/2025 at 9:12 PM, no_way said: Is this mod and the monoman BIS tweaked patch compatible with BIS renewed? https://www.nexusmods.com/skyrimspecialedition/mods/135288 It says it incorporated monomans tweak but not verbatim. Should be since it doesn't use slave and instead says this: "Apply dirt textures via Racemenu overlays specific to each body part" You'd probably just out of usable overlays depending on what you have setting in the Racemenu ini.
fkt Posted March 11, 2025 Posted March 11, 2025 Hello! How can I change applied tattoo alpha in my script without using simple_remove_tattoo & simple_add_tattoo?
nopse0 Posted March 11, 2025 Author Posted March 11, 2025 8 hours ago, fkt said: Hello! How can I change applied tattoo alpha in my script without using simple_remove_tattoo & simple_add_tattoo? You can use remove_tattoo + add_tattoo for this, because the SlaveTats functions have a flag if the change shall become immediately visible (last = True, that's the default) or not (last = False), so for example you can do a UpdateAlpha function like this: SlaveTats.simple_remove_tattoo(akTarget, "Spank That Ass", "sta_" + name, silent = true, last = False) SlaveTats.simple_add_tattoo(akTarget, "Spank That Ass", "sta_" + name, alpha = Alpha, silent = true) 1
fkt Posted March 12, 2025 Posted March 12, 2025 4 hours ago, nopse0 said: You can use remove_tattoo + add_tattoo for this, because the SlaveTats functions have a flag if the change shall become immediately visible (last = True, that's the default) or not (last = False), so for example you can do a UpdateAlpha function like this: SlaveTats.simple_remove_tattoo(akTarget, "Spank That Ass", "sta_" + name, silent = true, last = False) SlaveTats.simple_add_tattoo(akTarget, "Spank That Ass", "sta_" + name, alpha = Alpha, silent = true) thanks. I will try that
no_way Posted March 13, 2025 Posted March 13, 2025 On 3/6/2025 at 6:27 PM, aim4it said: Should be since it doesn't use slave and instead says this: "Apply dirt textures via Racemenu overlays specific to each body part" You'd probably just out of usable overlays depending on what you have setting in the Racemenu ini. It does not seem to work, overlays no longer appear on anyone. It overwrites BIS Renewed mzinOverlayUtility.pex. Removing the SlavetatsNG patch for BIS tweaked brings back the overlays.
NicholasJMoore Posted March 13, 2025 Posted March 13, 2025 (edited) Just an FYI, it looks like Lewd Marks overrides 2 of the scripts. (https://www.nexusmods.com/skyrimspecialedition/mods/83786) Seems to still work if I let this override LewsMarks though. Edited March 13, 2025 by NicholasJMoore
51offthescale Posted March 14, 2025 Posted March 14, 2025 22 hours ago, NicholasJMoore said: Just an FYI, it looks like Lewd Marks overrides 2 of the scripts. (https://www.nexusmods.com/skyrimspecialedition/mods/83786) Seems to still work if I let this override LewsMarks though. This is because you installed the optional patch from LewdMarks to increase the glow of tattoos.
sidfu1 Posted March 14, 2025 Posted March 14, 2025 does this update fix this crash? the only other mods i have adding overlays would be SCOE fade tattoo rape tatto blush when aroused diary of mine. wet funtion redux so far i removes slavetats NG and downgraded slave tats to 1.3.7 and ive not had a single crash for overlays since.
nopse0 Posted March 14, 2025 Author Posted March 14, 2025 3 hours ago, 51offthescale said: This is because you installed the optional patch from LewdMarks to increase the glow of tattoos. Yes, if LewdMarks overwrites my SlaveTats.pex (my SlaveTats.pex is just a stub, which calls global native functions), my mod isn't used at all, you have a plain Papyrus SlaveTats then (+ the LewdMark changes)
nopse0 Posted March 14, 2025 Author Posted March 14, 2025 (edited) 2 hours ago, sidfu1 said: does this update fix this crash? the only other mods i have adding overlays would be SCOE fade tattoo rape tatto blush when aroused diary of mine. wet funtion redux so far i removes slavetats NG and downgraded slave tats to 1.3.7 and ive not had a single crash for overlays since. No, my update (hopefully) doesn't change anything, I just expose a C++ interface, which can be used from other plugins. About your crashes: SCOE is critical, it often crashes/freezes the game, even without SlaveTatsNG, I would try without it (requires a new game). If this doesn't help, then this are probably racing conditions. My theory about this is, that now, when SlaveTatsNG is called (add, remove, synchronize tattoos), this leads almost immediately to a NiOverride.ApplyNodeOverrides call, while before SlaveTats was so slow, that this took minutes. I think that calling ApplyNodeOverrides, while other mods are adding or removing overrides leads to CTD's (missing synchronization). You could test, if adding a delay to the SlaveTats functions helps, e.g. change in SlaveTats.pex (must compile SlaveTats.psc for this): bool function simple_add_tattoo(Actor target, string section, string name, int color = 0, bool last = true, bool silent = false, float alpha = 1.0) global return SlaveTatsNG.simple_add_tattoo(target, section, name, color, last, silent, alpha) endfunction to: bool function simple_add_tattoo(Actor target, string section, string name, int color = 0, bool last = true, bool silent = false, float alpha = 1.0) global Util.Wait(20) ; 20 seconds delay return SlaveTatsNG.simple_add_tattoo(target, section, name, color, last, silent, alpha) endfunction Edited March 14, 2025 by nopse0
sidfu1 Posted March 14, 2025 Posted March 14, 2025 1 hour ago, nopse0 said: No, my update (hopefully) doesn't change anything, I just expose a C++ interface, which can be used from other plugins. About your crashes: SCOE is critical, it often crashes/freezes the game, even without SlaveTatsNG, I would try without it (requires a new game). If this doesn't help, then this are probably racing conditions. My theory about this is, that now, when SlaveTatsNG is called (add, remove, synchronize tattoos), this leads almost immediately to a NiOverride.ApplyNodeOverrides call, while before SlaveTats was so slow, that this took minutes. I think that calling ApplyNodeOverrides, while other mods are adding or removing overrides leads to CTD's (missing synchronization). You could test, if adding a delay to the SlaveTats functions helps, e.g. change in SlaveTats.pex (must compile SlaveTats.psc for this): bool function simple_add_tattoo(Actor target, string section, string name, int color = 0, bool last = true, bool silent = false, float alpha = 1.0) global return SlaveTatsNG.simple_add_tattoo(target, section, name, color, last, silent, alpha) endfunction to: bool function simple_add_tattoo(Actor target, string section, string name, int color = 0, bool last = true, bool silent = false, float alpha = 1.0) global Util.Wait(20) ; 20 seconds delay return SlaveTatsNG.simple_add_tattoo(target, section, name, color, last, silent, alpha) endfunction well so 1.3.7=no crashes 1.3.9= crashes 1.3.9+slave tats NG= crashes(higher rate) im thnking the issue might be that debug. cause once you open the mcm it every time for rest of the game will on load process the player and i think maybe any npc it ever applied to. 1.3.7 doesnt have that. ill try what yo posted once i get more time to screw around on the modding side of things
nopse0 Posted March 15, 2025 Author Posted March 15, 2025 (edited) 6 hours ago, sidfu1 said: well so 1.3.7=no crashes 1.3.9= crashes 1.3.9+slave tats NG= crashes(higher rate) im thnking the issue might be that debug. cause once you open the mcm it every time for rest of the game will on load process the player and i think maybe any npc it ever applied to. 1.3.7 doesnt have that. ill try what yo posted once i get more time to screw around on the modding side of things I compared 1.3.7 and 1.3.9 and the only difference in SlaveTats.psc is this: In 1.3.7 always Game.EnablePlayerControls was called at the end of synchronize_tattoos, and in 1.3.9 only if the 'silent' flag was true. I don't use the 'silent' flag at all, I never disable the player controls, regardless of if silent is true or false. That's a hint, maybe Game.EnablePlayerControls does some hidden synchronization between the NiNode tree, and what is rendered. I will add the Game.EnablePlayerControls calls (if this is possible in C++, have to look at what is done in Game.psc in EnablePlayerControls) in synchronize_tattoos as in 1.3.7, and will upload a new version if possible. There are also differences in SlaveTatsWatchCell.psc, SlaveTatsOnLoad.psc (in 1.3.9 almost everything in this two files has been commented out) and SlaveTatsMCMMenu.psc and SlaveTats.esp. Do you also have these crashes, if you install SlaveTatsNG on top of SlaveTats-1.3.7, but only replace the SlaveTats.pex file, and keep the other files from 1.3.7 ? Edited March 15, 2025 by nopse0
nopse0 Posted March 15, 2025 Author Posted March 15, 2025 (edited) 3 hours ago, nopse0 said: I compared 1.3.7 and 1.3.9 and the only difference in SlaveTats.psc is this: I uploaded a quick and dirty test. In this file I call at the end of synchronize_tattoos: Actor::SetPlayerControls(true); Not sure though, if this does the same as the Papyrus function "Game.EnablePlayerControls". Probably not, because Game.EnablePlayerControls has 11 parameters, like abMenu, abSneaking, abJournalTabs, etc, while Actor::SetPlayerControls does this: void Actor::SetPlayerControls(bool a_enable) { if (GetActorRuntimeData().movementController) { EnableAI(!a_enable); if (a_enable) { GetActorRuntimeData().movementController->EnablePlayerControls(); } else { GetActorRuntimeData().movementController->DisablePlayerControls(); } } } I am also not sure what happens, if Actor::SetPlayerControls(true) is called on an actor which isn't the player, does this crash the game, or does the npc follows the player movements then ? Try it out. Edit: Oh, "EnableAI(!a_enable)" is not so good for npc's, will stand around and do nothing then, have to check if the actor is the player ... - on the other hand, npc's probably have no movement controller. just try it out, and report what happens. Forgot to press "Save and Submit", now the new file is up, 0.6.6-test Edit: Reverted the change, and added instead a "Game.EnablePlayerControls()" after the native function call in SlaveTats.pex. This should show, if this EnablePlayerControls thing is the reason => SlaveTatsNG-0.6.6-test2. Edited March 15, 2025 by nopse0
sidfu1 Posted March 15, 2025 Posted March 15, 2025 i havent tried NG over 1.3.7 yet. ill take and try it.
nopse0 Posted March 15, 2025 Author Posted March 15, 2025 (edited) 49 minutes ago, sidfu1 said: i havent tried NG over 1.3.7 yet. ill take and try it. If this really fixes your crashes, then this is a side effect. Because that EnablePlayerControls in 1.3.9 is only done, if the 'silent' flag is false, is clearly a bug fix. Background: If 'silent' was false, SlaveTats did show a notification on screen "Please wait while SlaveTats works on ...", and called "Game.DisablePlayerControls(false, false, false, false, false, true, false, false, 0)" (this disabled, that the player could open the menu). I think, this only made sense, when the player was adding a tattoo via the MCM, because the "EnablePlayerControls()" (this enables all player controls, not only the menu control!!!) at the end, totally breaks mods which disable player controls (e.g. Devious Devices, if the players hands are bound). So almost every mod is calling SlaveTats with the parameter silent = true (they should change the default). Edited March 15, 2025 by nopse0
nopse0 Posted March 17, 2025 Author Posted March 17, 2025 (edited) Some thoughts I had about these crashes: First of all, I think it's possible that there are still undetected bugs in the override node memory mangement in the RaceMenu dll, because I saw in the Git history that there had been bugs in the memory management before, and also because I noticed, that sometimes (very rarely) I had crashes, if I don't call ApplyNodeOverrides at the end of synchronize_tattoos (normally this shouldn't be neccessary, the changes would just become visible later without this), as if the override nodes are sort of "garbage collected"/reused without calling ApplyNodeOverrides. Edited March 18, 2025 by nopse0
nopse0 Posted March 18, 2025 Author Posted March 18, 2025 (edited) I had a look at how the NiOverride OverlayInterface::AddNodeOverlay function is implemented, and I have a good idea now, what the problem is: void OverrideInterface::Impl_AddNodeOverride(TESObjectREFR * refr, bool isFemale, BSFixedString nodeName, OverrideVariant & value) { OverrideHandle handle = refr->formID; nodeData.Lock(); nodeData.m_data[handle][isFemale ? 1 : 0][g_stringTable.GetString(nodeName)].erase(value); nodeData.m_data[handle][isFemale ? 1 : 0][g_stringTable.GetString(nodeName)].insert(value); nodeData.Release(); } The problem is the line with the "erase(value)", because, and that is very strange, nodeData.m_data[handle][isFemale][nodeName] is a set of values, instead of a single value, and, since the key in this set is the value, and the value changes each time AddNodeOverride is called, nothing is erased. So this doesn't change the override value, but adds another value to the set. Edit: No, sorry, everything ok, this isn't the problem. I overlooked this: void OverrideInterface::AddNodeOverride(TESObjectREFR* refr, bool isFemale, const char* nodeName, skee_u16 key, skee_u8 index, SetVariant& value) { OverrideVariant variant; SetValueVariant(variant, key, index, value); Impl_AddNodeOverride(refr, isFemale, nodeName, variant); } and OverrideVariant (that's not the SetVariant parameter type) is defined as: class OverrideVariant { public: OverrideVariant() : type(kType_None), index(-1) { }; ~OverrideVariant() { }; bool operator<(const OverrideVariant & rhs) const { return key < rhs.key || (key == rhs.key && index < rhs.index); } bool operator==(const OverrideVariant & rhs) const { return key == rhs.key && index == rhs.index; } void Save(SKSESerializationInterface * intfc, UInt32 kVersion); bool Load(SKSESerializationInterface * intfc, UInt32 kVersion, const StringIdMap & stringTable); UInt16 key; The keys in the set are the key parameters from the function call, and that's ok. Sigh, would have been a nice solution. Edited March 18, 2025 by nopse0 1
nopse0 Posted March 18, 2025 Author Posted March 18, 2025 (edited) But now I am quite sure I know why SlaveTatsNG crashes, while the Papyrus SlaveTats doesn't. In Papyrus SlaveTats: bool function clear_overlay(Actor target, bool isFemale, string area, int slot) global string nodeName = area + " [ovl" + slot + "]" NiOverride.AddNodeOverrideString(target, isFemale, nodeName, 9, 0, PREFIX() + "blank.dds", true) (and PREFIX() = "Actors\\Character\\slavetats\\" While I were doing in clear_overlay() a: fail_t clear_overlay(RE::Actor* a_target, bool a_is_female, RE::BSFixedString a_area, int a_slot) { RE::BSFixedString nodeName = string(a_area) + " [Ovl" + to_string(a_slot) + "]"; // RE::BSFixedString blankPrefix = string(PREFIX()) + "blank.dds"; RE::BSFixedString blankPrefix = "actors\\character\\overlays\\default.dds"; In other words, Papyrus SlaveTats gives empty slots the texture name: "textures\Actors\Character\slavetats\blank.dds" while I was giving empty slots the texture name "textures\actors\character\overlays\default.dds" (that's the default empty texture name from the Racemenu.bsa). The reason for the crashes is now the following, I think: If a mod is looking for a free overlay slot, it checks if the slot has the texture name "default.dds" (the "is empty" texture name from RaceMenu), but with the Papyrus SlaveTats it doesn't find one, because all free overlay slots have the texture name "slavetats\blank.dds". So no conflicts, no racing conditions, no crashes, other mods simply are not able to manually add overlays, SlaveTats takes full control. Edit: No, sorry again, did a "skee dump overrides" and it makes no difference if using slavetats/blank.dds or default.dds, both remove the overlay, and the slot is displayed as free again in RaceMenu Edited March 18, 2025 by nopse0 1
Nymra Posted March 18, 2025 Posted March 18, 2025 just a small question: Slave Tats supports only like 4 tattoo slots per body part. Is there a setting somewhere for more? I modded the scripts for my LE to support 24 per part, I just wonder if there is a similar update for SE before I do it all over again.... (and C++ I cant :D)
Nuascura Posted March 19, 2025 Posted March 19, 2025 (edited) 5 hours ago, nopse0 said: If a mod is looking for a free overlay slot, it checks if the slot has the texture name "default.dds" (the "is empty" texture name from RaceMenu), but with the Papyrus SlaveTats it doesn't find one, because all free overlay slots have the texture name "slavetats\blank.dds". So no conflicts, no racing conditions, no crashes, other mods simply are not able to manually add overlays, SlaveTats takes full control. @sidfu1 Wasn’t this the issue you bumped into with slavetats and BISR? Blank.dds does effectively occupy the overlay slot and prevent any other overlay application from non-slavetats, nioverride interface. Edited March 19, 2025 by Nuascura
sidfu1 Posted March 19, 2025 Posted March 19, 2025 51 minutes ago, Nuascura said: @sidfu1 Wasn’t this the issue you bumped into with slavetats and BISR? Blank.dds does effectively occupy the overlay slot and prevent any other overlay application from non-slavetats, nioverride interface. kinda. what would happen is when you load the game first racemnu would check itself and have the default listed. but then slave tats would change that to the blank.dds this seemed to cause it to sometimes prevent other mods from applying their overlay at start for example bisr would sometimes miss the face or hands due to it. but i still get this with slave tats 1.3.7 and get no crash. i think 1.3.9 crashes due to it begins to go thru every npc you ever applied slave tats to(i say this as ive seen it say checking xx npc that is literally not even 3d loaded/havent been ear for litearly 20 hours or on other side of map so can only guess that) and so eventuay it hits a npc it cant change to the blank texture then crashes. this would explain why the crash is so random. you can literally one min get the crash 5 min after start and another time play 12 hours.
nopse0 Posted March 19, 2025 Author Posted March 19, 2025 6 hours ago, Nymra said: just a small question: Slave Tats supports only like 4 tattoo slots per body part. Is there a setting somewhere for more? I modded the scripts for my LE to support 24 per part, I just wonder if there is a similar update for SE before I do it all over again.... (and C++ I cant :D) This isn't neccessary in SE/AE, the number of slots per area can be configured in SKSE\plugins\skee.ini, e.g I have defined: [Overlays/Body] ; "Body [Ovl#]" and "Body [SOvl#]" ; Determines how many body overlays there should be iNumOverlays=30 ; Default[6] iSpellOverlays=0 ; Default[1] [Overlays/Hands] ; "Hands [Ovl#]" and "Hands [SOvl#]" ; Determines how many hand overlays there should be iNumOverlays=30 ; Default[3] iSpellOverlays=0 ; Default[1] [Overlays/Feet] ; "Feet [Ovl#]" and "Feet [SOvl#]" ; Determines how many feet overlays there should be iNumOverlays=30 ; Default[3] iSpellOverlays=0 ; Default[1] [Overlays/Face] ; "Face [Ovl#]" and "Face [SOvl#]" ; Determines how many face overlays there should be iNumOverlays=30 ; Default[3] iSpellOverlays=0 ; Default[1] 1
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now