nopse0 Posted July 4, 2025 Author Posted July 4, 2025 4 hours ago, Nuascura said: This is curious. It seems we inherited this condition from BiS Tweaked 3.4. I wonder what the intention was. Wouldn't it make more sense to just check if is3DLoaded? Mostly talking to myself unless you have any additional insight. Edit: Nvm I've got it. I looked into the nioverride script. The RemoveOverlays() function only works on NPCs. That means, if anything, ApplyNodeOverrides() should be moved outside and below the IF clause. In all, this looks to be a safety function given that the BISR works a-okay so far with this IF clause in place. You must not confuse the NiOverride.RemoveOverlays function and the RemoveOverlay function in mzinOverlayUtility.psc:, they are doing totally different things, this is the mzin function: Function RemoveOverlay(Actor akTarget, Bool Gender, String Node) ;mzinUtil.LogTrace("ClearDirt(): Target: " + akTarget.GetBaseObject().GetName() + ". Node: " + Node + ". Clearing ! TexPath: " + TexPath) NiOverride.AddNodeOverrideString(akTarget, Gender, Node, 9, 0, "actors\\character\\overlays\\default.dds", true) NiOverride.RemoveNodeOverride(akTarget, Gender, Node, 9, 0) NiOverride.RemoveNodeOverride(akTarget, Gender, Node, 7, -1) NiOverride.RemoveNodeOverride(akTarget, Gender, Node, 0, -1) NiOverride.RemoveNodeOverride(akTarget, Gender, Node, 8, -1) NiOverride.RemoveNodeOverride(akTarget, Gender, Node, 2, -1) NiOverride.RemoveNodeOverride(akTarget, Gender, Node, 3, -1) EndFunction It removes NodeOverride nodes. But without calling NiOverride.ApplyNodeOverrides, this has no effect, the changes are just queued (ApplyNodeOverrides is like commit or push in Git). While the NiOverride.RemoveOverlays function removes all overlay slots (the slots themselves, not their content!) from an actor. After this, the actor doesn't have any slots, you could add node overrides to (you would have to call NiOverride.AddOverlays first, before you can add node overrides again).
Nuascura Posted July 5, 2025 Posted July 5, 2025 (edited) 6 hours ago, nopse0 said: While the NiOverride.RemoveOverlays function removes all overlay slots (the slots themselves, not their content!) from an actor. After this, the actor doesn't have any slots, you could add node overrides to (you would have to call NiOverride.AddOverlays first, before you can add node overrides again). I understand. I plan to test a change to this part. But I want to stress to you again what I previously wrote: This part of the function exists as-is/verbatim in monoman's BiS Tweaked. Additionally, NiOverride.RemoveOverlays() only affects NPCs, it does not affect the player. Edited July 5, 2025 by Nuascura
vulcan13 Posted July 9, 2025 Posted July 9, 2025 On 7/4/2025 at 1:01 PM, nopse0 said: Hi! I am reading the RaceMenu function addresses now from a Json file, they are no longer hardcoded. So, now, it's quite easy to add support for RaceMenu dll versions which aren't supported yet (like the one for Skyrim 1.6.353, or the custom skee dlls from UBE). The Json file looks like this: Reveal hidden contents { "6df8589175031c701b7fc5d2befa9f4a": { "comment": "Skyrim 1.5.97, RaceMenu v0-4-16", "offset_GetNodeOverrideInt": 778592, "offset_GetNodeOverrideFloat": 778384, "offset_GetNodeOverrideString": 778992, "offset_AddNodeOverrideInt": 776672, "offset_AddNodeOverrideFloat": 776064, "offset_AddNodeOverrideString": 777264, "offset_HasNodeOverride": 630144, "offset_RemoveNodeOverride": 631248, "offset_ApplyNodeOverrides": 630064, "offset_AddOverlays": 628576, "offset_HasOverlays": 628608, "offset_RemoveOverlays": 628640 }, "f5bd9e8f9f7a7367c95c2d005302fd03": { "comment": "Skyrim 1.4.15 (VR), RaceMenu VR v0-4-14", "offset_GetNodeOverrideInt": 762032, "offset_GetNodeOverrideFloat": 761808, "offset_GetNodeOverrideString": 762464, "offset_AddNodeOverrideInt": 760080, "offset_AddNodeOverrideFloat": 759472, "offset_AddNodeOverrideString": 760672, "offset_HasNodeOverride": 616816, "offset_RemoveNodeOverride": 617952, "offset_ApplyNodeOverrides": 616736, "offset_AddOverlays": 615248, "offset_HasOverlays": 615280, "offset_RemoveOverlays": 615312 }, "2edbd15187134395a0898d13c8372026": { "comment": "Skyrim 1.6.659 (GOG), RaceMenu v0-4-19-14 GOG", "offset_GetNodeOverrideInt": 828304, "offset_GetNodeOverrideFloat": 828096, "offset_GetNodeOverrideString": 828704, "offset_AddNodeOverrideInt": 826416, "offset_AddNodeOverrideFloat": 825792, "offset_AddNodeOverrideString": 827008, "offset_HasNodeOverride": 678560, "offset_RemoveNodeOverride": 679424, "offset_ApplyNodeOverrides": 678544, "offset_AddOverlays": 677040, "offset_HasOverlays": 677168, "offset_RemoveOverlays": 677200 }, "d28195ed035cd19604d2f0c97bad6c44": { "comment": "Skyrim 1.6.640, RaceMenu v0-4-19-14", "offset_GetNodeOverrideInt": 827952, "offset_GetNodeOverrideFloat": 827744, "offset_GetNodeOverrideString": 828352, "offset_AddNodeOverrideInt": 826064, "offset_AddNodeOverrideFloat": 825440, "offset_AddNodeOverrideString": 826656, "offset_HasNodeOverride": 678208, "offset_RemoveNodeOverride": 679072, "offset_ApplyNodeOverrides": 678192, "offset_AddOverlays": 676688, "offset_HasOverlays": 676816, "offset_RemoveOverlays": 676848 } } The first string is the MD5 hash from the skee dll (you can get this on Windows with "certutil -hashfile skee64.dll MD5"), then a comment, and then the address offsets (how to get them is described in this forum here, look for mails containing "VR"). If your skee has not a standard name (not "skee64.dll" or "skeevr.dll"), you can define it in SlaveTatsNG.ini. I just recently saw the notification for this. So I get what you're saying here is I can add compatibility myself if I add the proper addresses to a .json file? I did end up pulling out UBE, and pulled out SlavetatsNG since it was just causing problems only trying to load the MCM or when a LewdMarks Event was trying to be called. So my Game works and loads in when SlavetatsNG is installed. In all honestly I'm surprised I've gotten away with my 353 version for this long with all these new mods that are apparently mostly backwards compatible. Yours is the first NG mod to drop a wrench in my gears. But I went back and looked through the comment history and found some things on this but I'm not sure if I found what I needed, and I'm sorry to say but your description here doesn't really help me finding those addresses or where to put in or direct that "certutil -hashfile" command if that's what it is. I'm a pretty experienced modder usually figuring out and solving my own problems, but I tend not to touch .json files unless I really know what I'm there for and how to do it... which is rarely.
nopse0 Posted July 9, 2025 Author Posted July 9, 2025 (edited) 17 hours ago, vulcan13 said: I just recently saw the notification for this. So I get what you're saying here is I can add compatibility myself if I add the proper addresses to a .json file? I did end up pulling out UBE, and pulled out SlavetatsNG since it was just causing problems only trying to load the MCM or when a LewdMarks Event was trying to be called. So my Game works and loads in when SlavetatsNG is installed. In all honestly I'm surprised I've gotten away with my 353 version for this long with all these new mods that are apparently mostly backwards compatible. Yours is the first NG mod to drop a wrench in my gears. But I went back and looked through the comment history and found some things on this but I'm not sure if I found what I needed, and I'm sorry to say but your description here doesn't really help me finding those addresses or where to put in or direct that "certutil -hashfile" command if that's what it is. I'm a pretty experienced modder usually figuring out and solving my own problems, but I tend not to touch .json files unless I really know what I'm there for and how to do it... which is rarely. Ok, here a summary: First you have to set "vmHook=true" in SlaveTatsNG.ini. This hooks into the VM function, which SKSE plugins call when they register their native functions in the VM, and dumps the name and address of the functions. Then you have to look in the SlaveTatsNG.log. It will contain lines like this: [19:54:35:794] [vm_hook] object: NiOverride, name: GetNumBodyOverlays, callback: 140708481639552 [19:54:35:794] [vm_hook] object: NiOverride, name: GetNumHandOverlays, callback: 140708481639568 [19:54:35:794] [vm_hook] object: NiOverride, name: GetNumFeetOverlays, callback: 140708481639584 [19:54:35:794] [vm_hook] object: NiOverride, name: GetNumFaceOverlays, callback: 140708481639600 [19:54:35:794] [vm_hook] object: NiOverride, name: GetNumSpellBodyOverlays, callback: 140708481639616 [19:54:35:794] [vm_hook] object: NiOverride, name: GetNumSpellHandOverlays, callback: 140708481639632 [19:54:35:794] [vm_hook] object: NiOverride, name: GetNumSpellFeetOverlays, callback: 140708481639648 [19:54:35:794] [vm_hook] object: NiOverride, name: GetNumSpellFaceOverlays, callback: 140708481639664 [19:54:35:794] [vm_hook] object: NiOverride, name: AddOverlays, callback: 140708481636192 [19:54:35:794] [vm_hook] object: NiOverride, name: HasOverlays, callback: 140708481636224 So, for example, if you want to calculate the offset of the "NiOverride.HasOverlays" function, you would have to subtract from 140708481636224 the base address of the skee64.dll (where it's loaded into memory). Only problem with this is I just noticed, I don't dump the base address of the skee64.dll anymore (gone, when I changed the code, to load the function offsets from the .json file). Will upload a new version which dumps the base adddress again. But, basically, as I said, it's very simple, just enable that the function addresses are logged, and then subtract the base address of the skee dll. Edit: Ok, built a new version, which dumps the skee dll base address again. The example looks like this now: SlaveTatsNG.log: ... [20:58:57:634] [vm_hook] object: NiOverride, name: HasOverlays, callback: 140708445919104 ... [20:58:59:722] NIOverride base address: GetModuleHandleA(skee64.dll) = 140708445290496 ... So, the offset of the HasOverlays function is: 140708445919104 - 140708445290496 = 628608 About certutil: That's a Windows command line executable. Open a cmd.exe in the folder, where the skee64.dll is, and then do a Ps: I renamed the SlaveTatsNG.dll to aaSlaveTatsNG.dll, because the SlaveTats dll must be loaded before the skee64.dll, otherwise the VM hook isn't active, when skee registers it's functions. Also attached my SlaveTats.log file, I hope it makes clearer what I mean When editing the .json, you almost for sure will make errors, e.g. forget a comma or curly brace or so. This will cause a JSON parse exception, and the game will CTD. But don't worry, just install Crash Logger https://www.nexusmods.com/skyrimspecialedition/mods/59818 , and look into the crash dump, it will show the parse exception (including the line and column number from the .json file, where the parse error occurred). And, of course, the game will also crash, when you make errors when calculating the address offsets, double check the arguments and the results are right (happened to me, too, when calculating the offsets for the VR version). SlaveTatsNG.log Edited July 9, 2025 by nopse0
vulcan13 Posted July 10, 2025 Posted July 10, 2025 (edited) Okay so I've done all that but now I'm stuck... I have the two codes I need but I don't know where to put them as I can't find the Racemenu .json file or if that's even what the name is. But here are the two Codes I generated. 661824 599a32a24a9bcb72f04e1d8cce1aa942 I assume these are probably unique to version 353? Edit: Never mind I think I found it.... I'll edit again if I make headway, and I'll share the code back so you can just add it to your own for others. Edited July 10, 2025 by vulcan13
vulcan13 Posted July 10, 2025 Posted July 10, 2025 So I have good news. I managed to add the Code get into the game (it started crashing again before it reaches the main menu with your newest version) loaded into my save and got the SlaveTats MCM to work, I haven't tested LewdMarks yet but I assume (hope) it will work. As Promised above I'll share the code so you can add it to yours for compatibility. "599a32a24a9bcb72f04e1d8cce1aa942": { "comment": "Skyrim 1.6.353, RaceMenu v0-4-11", "offset_GetNodeOverrideInt": 814464, "offset_GetNodeOverrideFloat": 814256, "offset_GetNodeOverrideString": 814864, "offset_AddNodeOverrideInt": 812576, "offset_AddNodeOverrideFloat": 811968, "offset_AddNodeOverrideString": 813168, "offset_HasNodeOverride": 663136, "offset_RemoveNodeOverride": 664000, "offset_ApplyNodeOverrides": 663120, "offset_AddOverlays": 661680, "offset_HasOverlays": 661792, "offset_RemoveOverlays": 661824
nopse0 Posted July 10, 2025 Author Posted July 10, 2025 1 hour ago, vulcan13 said: So I have good news. I managed to add the Code get into the game (it started crashing again before it reaches the main menu with your newest version) loaded into my save and got the SlaveTats MCM to work, I haven't tested LewdMarks yet but I assume (hope) it will work. As Promised above I'll share the code so you can add it to yours for compatibility. "599a32a24a9bcb72f04e1d8cce1aa942": { "comment": "Skyrim 1.6.353, RaceMenu v0-4-11", "offset_GetNodeOverrideInt": 814464, "offset_GetNodeOverrideFloat": 814256, "offset_GetNodeOverrideString": 814864, "offset_AddNodeOverrideInt": 812576, "offset_AddNodeOverrideFloat": 811968, "offset_AddNodeOverrideString": 813168, "offset_HasNodeOverride": 663136, "offset_RemoveNodeOverride": 664000, "offset_ApplyNodeOverrides": 663120, "offset_AddOverlays": 661680, "offset_HasOverlays": 661792, "offset_RemoveOverlays": 661824 Super, thanks! The problem with this offsets is, that they can only be calculated on a system where the respective Skyrim and RaceMenu versions are installed, so I can't do this myself, because I don't have Skyrim 1.6.353 or UBE installed.
blackoperations Posted July 10, 2025 Posted July 10, 2025 On 8/23/2024 at 12:37 PM, duy123a said: Can you build for 1.5.97? I want to test it a bit NG mods should, if they are labelled NG, run on both SSE and AE.
nopse0 Posted July 11, 2025 Author Posted July 11, 2025 14 hours ago, blackoperations said: NG mods should, if they are labelled NG, run on both SSE and AE. It should work on Skyrim 1.5.97, doesn't it for you ? Maybe you are not using the latest RaceMenu for 1.5.97, or UBE ? The problem here is not NG (works fine with all Skyrim versions), but the RaceMenu (skee64.dll/skeevr.dll) dll, for older versions (not neccessary for 1.61130/1170) its function addresses are reverse engineered like NG does with the Skyrim binaries.
manafalls Posted July 12, 2025 Posted July 12, 2025 I know this is about modernizing and improving the function of the slavetats code, rather than adding features or mkaing add ons, but having said that... It would be a great add on to slavetats if it were possible to assign and distribute specific slavetats at runtime to specific NPCs via an ini or json file, like you can with SPID, KID, etc. As far as I know (maybe I have missed something?), this has never been done. The closest thing I can think of is that random bodypaint distribution mod.
nopse0 Posted July 12, 2025 Author Posted July 12, 2025 (edited) 5 hours ago, manafalls said: I know this is about modernizing and improving the function of the slavetats code, rather than adding features or mkaing add ons, but having said that... It would be a great add on to slavetats if it were possible to assign and distribute specific slavetats at runtime to specific NPCs via an ini or json file, like you can with SPID, KID, etc. As far as I know (maybe I have missed something?), this has never been done. The closest thing I can think of is that random bodypaint distribution mod. Yes, would be nice, like "Random Overlay Framework" for FO4. I think Invictusblade distributes keywords with SPID/Robco Patcher to actors, and then he has scripts which add overlays to the actors, depending on the keywords. I think, the easiest way to get this for SlaveTats tattoos, would be to hook into SPID. When an actor gets loaded, and SPID distributes it's stuff, would be the right moment, to add SlavetTats tattoo records to JContainers. The difficult thing is not applying tattoo records to JContainers, but the matching algorithms of SPID, and it's hooking into the actor loading stuff (there are dynamically created actors based on templates, etc.), I definitely would not want to reimplement this. Would be nice, when poweofthree would implement some plugin system for his SPID/KID. Edit: Had a look at how "Distributed Bodypaints and Overlays" is doing it's stuff. Quite simple, it distributes a spell, which adds the overlays: Edited July 12, 2025 by nopse0 1
nopse0 Posted July 12, 2025 Author Posted July 12, 2025 (edited) 10 hours ago, nopse0 said: Yes, would be nice, like "Random Overlay Framework" for FO4. I think Invictusblade distributes keywords with SPID/Robco Patcher to actors, and then he has scripts which add overlays to the actors, depending on the keywords. I think, the easiest way to get this for SlaveTats tattoos, would be to hook into SPID. When an actor gets loaded, and SPID distributes it's stuff, would be the right moment, to add SlavetTats tattoo records to JContainers. The difficult thing is not applying tattoo records to JContainers, but the matching algorithms of SPID, and it's hooking into the actor loading stuff (there are dynamically created actors based on templates, etc.), I definitely would not want to reimplement this. Would be nice, when poweofthree would implement some plugin system for his SPID/KID. Edit: Had a look at how "Distributed Bodypaints and Overlays" is doing it's stuff. Quite simple, it distributes a spell, which adds the overlays: Very good idea, one could create a magic spell/effect for each tattoo, which shall be distributed via SPID. "DPF - Dynamic Persistent Forms" https://www.nexusmods.com/skyrimspecialedition/mods/116001 would be very usefull for this purpose, because then you can create spells/effects dynamically, instead of having a giant, static .esp file with thousands of spells/effects. The script would always be the same for all these magic effects, only the properties in the magic effects would be different (SlaveTats section, area, pattern etc.). I think this would be feasible. Edit: On second thought, not sure if it really would work to create with DPF dynamically for each SlaveTats tattoo a corresponding magic spell/effect for applying it, and distribute them with SPID. Depends on if SPID is able to locate dynamically created Forms (with Form-IDs starting with "FF") or not. Maybe a better approach would just be to manually maintain an .esp flle for these spells/effects (or to write a Synthesis patcher to create such an .esp). In any way, the Editor-ID's would have to be chosen carefully, to have a bijective mapping between the tattoos and the spells for applying them. But, at least, I could provide a script, which applies a SlaveTats tattoo and can be attached to magic effects. Edited July 13, 2025 by nopse0
manafalls Posted July 13, 2025 Posted July 13, 2025 15 hours ago, nopse0 said: Very good idea, one could create a magic spell/effect for each tattoo, which shall be distributed via SPID. "DPF - Dynamic Persistent Forms" https://www.nexusmods.com/skyrimspecialedition/mods/116001 would be very usefull for this purpose, because then you can create spells/effects dynamically, instead of having a giant, static .esp file with thousands of spells/effects. The script would always be the same for all these magic effects, only the properties in the magic effects would be different (SlaveTats section, area, pattern etc.). I think this would be feasible. Edit: On second thought, not sure if it really would work to create with DPF dynamically for each SlaveTats tattoo a corresponding magic spell/effect for applying it, and distribute them with SPID. Depends on if SPID is able to locate dynamically created Forms (with Form-IDs starting with "FF") or not. Maybe a better approach would just be to manually maintain an .esp flle for these spells/effects (or to write a Synthesis patcher to create such an .esp). In any way, the Editor-ID's would have to be chosen carefully, to have a bijective mapping between the tattoos and the spells for applying them. But, at least, I could provide a script, which applies a SlaveTats tattoo and can be attached to magic effects. Yeah, I'd looked at that too, and I figured the dueling dynamic creation processes would be a stumbling block (i've already been bitten by that problem with base object swapper and container distribution stuff). I wondered if a somewhat unsatisfying partial hack would be to have a dozen "fixed" slavetats spells/magic effects in an esp, with the actual slavetat to be used and distributed stored in a changeable json, and then use spid to distribute those "fixed" tats. If I'm right, that would at least let you set up (and change) tats specific for your game and play-through to be distributed on runtime, automatically and consistently (so if you want serena to always have that tat, she will always have that tat).
nopse0 Posted July 13, 2025 Author Posted July 13, 2025 (edited) 8 hours ago, manafalls said: Yeah, I'd looked at that too, and I figured the dueling dynamic creation processes would be a stumbling block (i've already been bitten by that problem with base object swapper and container distribution stuff). I wondered if a somewhat unsatisfying partial hack would be to have a dozen "fixed" slavetats spells/magic effects in an esp, with the actual slavetat to be used and distributed stored in a changeable json, and then use spid to distribute those "fixed" tats. If I'm right, that would at least let you set up (and change) tats specific for your game and play-through to be distributed on runtime, automatically and consistently (so if you want serena to always have that tat, she will always have that tat). No, you don't need a JSON file, or so, for this. You can do this with JContainers. JContainers has a JFormDB, and SlaveTats stores in it, which tattoos actors have (a map "actor -> [tattoos]"). You could, just as well, store in the JFormDB which tattoos your magic effects shall apply (a map "magic_effect -> [tattoos]"). This map even could be maintained automatically by SlaveTats, if adding an "applied_by_magic_effect", or so, attribute to tattoos. Tthis is nothing new, they already have a form attribute anyway, i.e. the spell, which is applied via the tattoo_magic functions (the opposite direction of what you want). Edited July 13, 2025 by nopse0
DrSeptimus Posted July 15, 2025 Posted July 15, 2025 Quick question, is there anyway to save all the tattoo you setup and load it for your new game? I try MCM Recorder and it doesn't work well..
nopse0 Posted July 16, 2025 Author Posted July 16, 2025 8 hours ago, DrSeptimus said: Quick question, is there anyway to save all the tattoo you setup and load it for your new game? I try MCM Recorder and it doesn't work well.. There is a way, but nothing "ready to go". One could write a script, which writes the tattoos the player has into a file, and another script which deserializes this file again. The first script would to have be called from the old game, and the second one from the new game. Serialization: string filePath = "Data/tmp/player_tattoos.json" int tattoos = JFormDB.getObj(Game.GetPlayer(), ".SlaveTats.applied") if tattoos != 0 JValue.writeToFile(tattoos, filePath) endIf Deserialization: int tattoos = JValue.readFromFile(filePath) if tattoos != 0 JFormDB.setObj(Game.GetPlayer(), ".SlaveTats.applied", tattoos) endif Best you add a dummy tattoo to the new player first, so that everything is initialized and only the tattoo array of the player has to be replaced. I didn't test this, but I think this should work.
verydarknut Posted July 17, 2025 Posted July 17, 2025 Is it still true that Slavetats textures can not be placed into BSA on SE/AE? Ever since SE it seems to be broken.
nopse0 Posted July 18, 2025 Author Posted July 18, 2025 (edited) On 7/17/2025 at 8:02 AM, verydarknut said: Is it still true that Slavetats textures can not be placed into BSA on SE/AE? Ever since SE it seems to be broken. I assume the textures itself can be in a BSA, because this is a pure RaceMenu/Skyrim thing, SlaveTats only sets the texture paths in the NiOverride calls. But if the .json files of tattoo packages can be in BSA files, I don't know. Depends on if JContainers can read files from BSAs ("JValue::readFromDirectory()"), or not. Because SlaveTats simply calls: JValue::readFromDirectory(string(ROOT()) + string(PREFIX()), ".json") and: RE::BSFixedString ROOT() { return "Data\\Textures\\"; } RE::BSFixedString PREFIX() { return "Actors\\Character\\slavetats\\"; } Edit: I forgot, a while ago someone asked, what the "in_bsa" attribute of tattoos does, and I explained, that SlaveTats checks that the texture file exists, if not "in_bsa: 1" is set. So, probably, your in BSA tattoos don't work, because they don't have the 'in_bsa' attribute set. Edited July 18, 2025 by nopse0
verydarknut Posted July 18, 2025 Posted July 18, 2025 (edited) 15 hours ago, nopse0 said: Edit: I forgot, a while ago someone asked, what the "in_bsa" attribute of tattoos does, and I explained, that SlaveTats checks that the texture file exists, if not "in_bsa: 1" is set. So, probably, your in BSA tattoos don't work, because they don't have the 'in_bsa' attribute set. Wow it works. I could have sworn I tried the same thing a few years ago and it did not work then. Awesome ,now I can afford thousands more slavetats on my storage. To save future me or anyone else reading some time, the exact syntax is "in_bsa":1 Example with Cema's Spanked Pack: [ {"name": "spanked01", "section":"Spank", "texture":"spank\\spank01.dds", "area":"Body", "in_bsa":1}, {"name": "spanked02", "section":"Spank", "texture":"spank\\spank02.dds", "area":"Body", "in_bsa":1}, {"name": "spanked03", "section":"Spank", "texture":"spank\\spank03.dds", "area":"Body", "in_bsa":1} ] Also don't forget to enable the dummy esp that loads the bsa. I tested Alpia's Slavetats, turned 861 4k-textures from 12.8 Gb into 100 Mb with Cathedral Asset Optimizer and they show up correctly in game. Not sure what I did wrong before. For comparison, I used to have Alpia's textures scaled down to 1k as loose file and it still was 800 Mb. BSA compression is incredible. 15 hours ago, nopse0 said: I assume the textures itself can be in a BSA, because this is a pure RaceMenu/Skyrim thing, SlaveTats only sets the texture paths in the NiOverride calls. But if the .json files of tattoo packages can be in BSA files, I don't know. Cathedral Asset Optimizer did not include the .json files, they stay in their original folder. It works regardless. Thank you for your help and for making Slavetats lightning fast and fun! Edited July 18, 2025 by verydarknut
straysaint Posted July 19, 2025 Posted July 19, 2025 hi ive been battling with overlays for almost a week now. i can't get more than three to show, despite having update the skee.ini, instally OverlayFixes from Nexus, rebuilding meshes with 12, and checking that the log loads proper. i get this: [16:02:44:147] NiOverride::Init() entered [16:02:44:147] SKEE interface map found [16:02:44:147] NiOverride interface version is: 2 [16:02:44:147] Minimum supported NiOverride interface version is: 2 [16:02:44:147] Found NiOverride interface version is supported, will use interface [16:02:44:147] Using NiOverride interface [16:02:44:149] Load Data/SKSE/Plugins/skee64.ini, result = 0 [16:02:44:150] # Overlay: 24 20 20 12 any idea what could be messing this up?
nopse0 Posted July 19, 2025 Author Posted July 19, 2025 (edited) 8 hours ago, straysaint said: hi ive been battling with overlays for almost a week now. i can't get more than three to show, despite having update the skee.ini, instally OverlayFixes from Nexus, rebuilding meshes with 12, and checking that the log loads proper. i get this: [16:02:44:147] NiOverride::Init() entered [16:02:44:147] SKEE interface map found [16:02:44:147] NiOverride interface version is: 2 [16:02:44:147] Minimum supported NiOverride interface version is: 2 [16:02:44:147] Found NiOverride interface version is supported, will use interface [16:02:44:147] Using NiOverride interface [16:02:44:149] Load Data/SKSE/Plugins/skee64.ini, result = 0 [16:02:44:150] # Overlay: 24 20 20 12 any idea what could be messing this up? Are you using VR? Maybe the config file is named skeevr.ini there. Never thought about this, have to look into the code, maybe I load the wrong config file on VR. But, anyway, "24 20 20 12" is what skee64.ini contains. If this has no effect, your RaceMenu must read a different config file. Edit: No, sorry, cannot be VR, interface version 2 is 1.6.1130/1170 and above. Edited July 19, 2025 by nopse0
straysaint Posted July 19, 2025 Posted July 19, 2025 9 hours ago, nopse0 said: Are you using VR? Maybe the config file is named skeevr.ini there. Never thought about this, have to look into the code, maybe I load the wrong config file on VR. But, anyway, "24 20 20 12" is what skee64.ini contains. If this has no effect, your RaceMenu must read a different config file. Edit: No, sorry, cannot be VR, interface version 2 is 1.6.1130/1170 and above. Yeah I'm using 1.6.1170, just normal version. I'm running it through Crossover on a Mac though, not sure if that's causing an issue. Any idea how I can find the config file RaceMenu is loading up?
straysaint Posted July 19, 2025 Posted July 19, 2025 8 minutes ago, straysaint said: Yeah I'm using 1.6.1170, just normal version. I'm running it through Crossover on a Mac though, not sure if that's causing an issue. Any idea how I can find the config file RaceMenu is loading up? @nopse0 Sorry for double post but I was looking at the skee addresses file, it doesnt show a section for 1.6.1170. am i using the wrong setup?
nopse0 Posted July 19, 2025 Author Posted July 19, 2025 2 hours ago, straysaint said: @nopse0 Sorry for double post but I was looking at the skee addresses file, it doesnt show a section for 1.6.1170. am i using the wrong setup? No, that's fine. Since 1.6.1130/1.6.1170 no address tables are needed for RaceMenu. It publishes an interface containing the addresses, which can be queried with SKSE functions
nopse0 Posted July 19, 2025 Author Posted July 19, 2025 3 hours ago, straysaint said: Yeah I'm using 1.6.1170, just normal version. I'm running it through Crossover on a Mac though, not sure if that's causing an issue. Any idea how I can find the config file RaceMenu is loading up? No, but I cannot imagine, it loads a different config file on Mac, never heard of this. I don't know, what functions RaceMenu uses for parsing the config file, but I could imagine the line endings are a problem. Windows uses CRLF, Unix uses LF only, and Mac uses LFCR. I would check, if your skee64.ini has Windows line endings (maybe, you used a wrong editor - I am using NotePad++, with this you have full control over line endings, what charset is used (UTF8/16/32/Latin1/etc), and it can show hidden, non-printable characters)
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