bcsp Posted September 2, 2018 Share Posted September 2, 2018 (edited) Hi all, I posted this over on LL but I feel the need to post it here as well to 'cover more ground'.There appears to be an issue with Bethesdas/SKSEs code when 2 mods make a soft dependency check to the same resource but that resource is not installed. To demonstrate I've created 3 tiny mods. One 'master' mod that contains the resource we want to access and two 'soft link' mods that try to access a function in the master mod. Test yourself with mod organizer. 1. Install and enable all mods2. Start a new game, save and reload it. Quit and check your logs. Both mods should be running ok. 3. Disable the master mod in the left hand side of MO (IE. remove the scripts). Start a new game and save a reload. Quit and check your log. Only one mod will be running even though they are essentially identical. Here's the code: Master: Scriptname _TM_MasterScript extends Quest String Function _TM_MasterFunction() Return "Master String" EndFunction SoftLink Mod A Scriptname _TM_SoftLinkA_Script extends ReferenceAlias Event OnInit() RegisterForSingleUpdate(1.0) EndEvent Event OnPlayerLoadGame() _TM_MasterScript Master = Game.GetFormFromFile(0x00000d62, "_TM_Master.esp") as _TM_MasterScript If Master Debug.MessageBox("_TM_: Soft Link A - " + Master._TM_MasterFunction()) Debug.Trace("_TM_: Soft Link A - " + Master._TM_MasterFunction()) Else Debug.MessageBox("_TM_: Soft Link A - Master esp not found") Debug.Trace("_TM_: Soft Link A - Master esp not found") EndIf EndEvent Event OnUpdate() Debug.Trace("_TM_: Soft Link A: Mod A running ok") RegisterForSingleUpdate(1.0) EndEvent SoftLink Mod B Scriptname _TM_SoftLinkB_Script extends ReferenceAlias Event OnInit() RegisterForSingleUpdate(1.0) EndEvent Event OnPlayerLoadGame() _TM_MasterScript Master = Game.GetFormFromFile(0x00000d62, "_TM_Master.esp") as _TM_MasterScript If Master Debug.MessageBox("_TM_: Soft Link B - " + Master._TM_MasterFunction()) Debug.Trace("_TM_: Soft Link B - " + Master._TM_MasterFunction()) Else Debug.MessageBox("_TM_: Soft Link B - Master esp not found") Debug.Trace("_TM_: Soft Link B - Master esp not found") EndIf EndEvent Event OnUpdate() Debug.Trace("_TM_: Soft Link B: Mod B running ok") RegisterForSingleUpdate(1.0) EndEvent Here's a papyrus log with all mods active and installed:The same is true if the masters scripts are installed but the esp is not active.Line 814: [09/01/2018 - 11:10:07AM] _TM_: Soft Link B: Mod B running ok Line 815: [09/01/2018 - 11:10:07AM] _TM_: Soft Link A: Mod A running ok Line 1258: [09/01/2018 - 11:10:08AM] _TM_: Soft Link B: Mod B running ok Line 1259: [09/01/2018 - 11:10:08AM] _TM_: Soft Link A: Mod A running ok Line 1321: [09/01/2018 - 11:10:10AM] _TM_: Soft Link B: Mod B running ok Line 1322: [09/01/2018 - 11:10:10AM] _TM_: Soft Link A: Mod A running ok Line 1383: [09/01/2018 - 11:10:11AM] _TM_: Soft Link B: Mod B running ok Line 1384: [09/01/2018 - 11:10:11AM] _TM_: Soft Link A: Mod A running ok Line 1524: [09/01/2018 - 11:10:12AM] _TM_: Soft Link A: Mod A running ok Line 1525: [09/01/2018 - 11:10:12AM] _TM_: Soft Link B: Mod B running ok Line 1580: [09/01/2018 - 11:10:13AM] _TM_: Soft Link B: Mod B running ok Line 1581: [09/01/2018 - 11:10:13AM] _TM_: Soft Link A: Mod A running ok Line 1897: [09/01/2018 - 11:10:16AM] _TM_: Soft Link B - Master String Line 1898: [09/01/2018 - 11:10:16AM] _TM_: Soft Link A - Master String Line 2597: [09/01/2018 - 11:10:18AM] _TM_: Soft Link B: Mod B running ok Line 2637: [09/01/2018 - 11:10:19AM] _TM_: Soft Link A: Mod A running ok Line 2639: [09/01/2018 - 11:10:19AM] _TM_: Soft Link B: Mod B running ok Line 2700: [09/01/2018 - 11:10:20AM] _TM_: Soft Link A: Mod A running ok Line 2714: [09/01/2018 - 11:10:20AM] _TM_: Soft Link B: Mod B running ok Line 2844: [09/01/2018 - 11:10:21AM] _TM_: Soft Link A: Mod A running ok Line 2863: [09/01/2018 - 11:10:21AM] _TM_: Soft Link B: Mod B running ok Here's a papyrus log when the master is not installed but both soft link mods are installed:Line 30: [09/01/2018 - 11:12:46AM] Cannot open store for class "_tm_masterscript", missing file? Line 31: [09/01/2018 - 11:12:46AM] Error: Unable to link types associated with function "OnPlayerLoadGame" in state "" on object "_TM_SoftLinkB_Script". Line 1614: [09/01/2018 - 11:13:08AM] _TM_: Soft Link A: Mod A running ok Line 1687: [09/01/2018 - 11:13:09AM] _TM_: Soft Link A: Mod A running ok Line 1735: [09/01/2018 - 11:13:11AM] _TM_: Soft Link A: Mod A running ok Line 1788: [09/01/2018 - 11:13:12AM] _TM_: Soft Link A: Mod A running ok Line 1857: [09/01/2018 - 11:13:13AM] _TM_: Soft Link A: Mod A running ok Line 1911: [09/01/2018 - 11:13:14AM] _TM_: Soft Link A: Mod A running ok Line 2046: [09/01/2018 - 11:13:17AM] warning: Unable to get type _TM_SoftLinkB_Script referenced by the save game. Objects of this type will not be loaded. Line 2048: [09/01/2018 - 11:13:17AM] warning: Could not find type _TM_SoftLinkB_Script in the type table in save Line 2070: [09/01/2018 - 11:13:17AM] ERROR: File "_TM_Master.esp" does not exist or is not currently loaded. Line 2073: [alias PlayerAlias on quest _TM_SoftLinkA_Quest (41000D62)]._TM_SoftLinkA_Script.OnPlayerLoadGame() - "_TM_SoftLinkA_Script.psc" Line 8 Line 2073: [alias PlayerAlias on quest _TM_SoftLinkA_Quest (41000D62)]._TM_SoftLinkA_Script.OnPlayerLoadGame() - "_TM_SoftLinkA_Script.psc" Line 8 Line 2073: [alias PlayerAlias on quest _TM_SoftLinkA_Quest (41000D62)]._TM_SoftLinkA_Script.OnPlayerLoadGame() - "_TM_SoftLinkA_Script.psc" Line 8 Line 2109: [09/01/2018 - 11:13:17AM] _TM_: Soft Link A - Master esp not found Line 2513: [09/01/2018 - 11:13:19AM] _TM_: Soft Link A: Mod A running ok Line 2774: [09/01/2018 - 11:13:20AM] _TM_: Soft Link A: Mod A running ok Line 2819: [09/01/2018 - 11:13:21AM] _TM_: Soft Link A: Mod A running ok Line 2901: [09/01/2018 - 11:13:22AM] _TM_: Soft Link A: Mod A running okThe first mod in the load order 'wins' and continues running as expected. The mod lower in the load order has it's scripts dumped and stops working entirely. I'm a guy that likes to bring mods together where I can and have mods as more than 'a collection of islands' but with this issue I not only need to account for my own mod but every other mod and load order out there and it's just too much hassle. So questions:1. First. Is my implementation ok? Maybe I've got something wrong. 2. Why the heck does this happen and what exactly is causing it? http://www.filedropper.com/testmod-masterhttp://www.filedropper.com/testmod-softlinkahttp://www.filedropper.com/testmod-softlinkb Not being able to upload 7z files is a bit of a PITA. Here's the thread on LL if people are allergic to filedropper: https://www.loverslab.com/topic/106848-multiple-mods-with-soft-dependency-to-the-same-resource/ Edited September 2, 2018 by bcsp Link to comment Share on other sites More sharing options...
cdcooley Posted September 2, 2018 Share Posted September 2, 2018 You don't need separate mods to trigger that case. That same basic thing happens even if it's just two different scripts in the same mod. Basically it's always unsafe to use an external, potentially non-existent script as a variable type in any script. If that external script doesn't exist the game will almost always flag that as a critical error and refuse to process that script. I'm surprised that your Mod A script is running because from my experience it should be having the same problem as Mod B. From your case I now assume that in some situations the very first script which tries to reference the non-existent script can continue to work (because whatever tagging that blocks the scripts happens after it had already started running). Or alternately it's because you skip straight to the OnUpodate from the OnInit block and you loaded Mod A for the first time in that test case? You could try this variation to see if it makes a different (but I doubt it). Scriptname _TM_SoftLinkB_Script extends ReferenceAlias Event OnInit() OnPlayerLoadGame() EndEvent Event OnPlayerLoadGame() Quest Master = Game.GetFormFromFile(0x00000d62, "_TM_Master.esp") as Quest If Master Debug.MessageBox("_TM_: Soft Link B - " + (Master as _TM_MasterScript)._TM_MasterFunction()) Debug.Trace("_TM_: Soft Link B - " + (Master as _TM_MasterScript)._TM_MasterFunction()) Else Debug.MessageBox("_TM_: Soft Link B - Master esp not found") Debug.Trace("_TM_: Soft Link B - Master esp not found") EndIf EndEvent Event OnUpdate() Debug.Trace("_TM_: Soft Link B: Mod B running ok") RegisterForSingleUpdate(1.0) EndEvent In my own mods I avoid referencing external scripts (from other mods) by their unique name whenever possible. In the rare cases where I can't do that I always keep things related to that other mod's script isolated into a unique script in my mod and then handle the "fallback" case if the mod isn't loaded in a completely different script. So to implement your idea I would have used a pair of scripts on that object: Scriptname _TM_SoftLinkAMasterFound_Script extends ReferenceAlias Event OnInit() OnPlayerLoadGame() EndEvent Event OnPlayerLoadGame() _TM_MasterScript Master = Game.GetFormFromFile(0x00000d62, "_TM_Master.esp") as _TM_MasterScript If Master Debug.MessageBox("_TM_: Soft Link A - " + Master._TM_MasterFunction()) Debug.Trace("_TM_: Soft Link A - " + Master._TM_MasterFunction()) EndIf EndEvent Event OnUpdate() Debug.Trace("_TM_: Soft Link A: Mod A running ok and Master is loaded") RegisterForSingleUpdate(1.0) EndEvent Scriptname _TM_SoftLinkAMasterMissing_Script extends ReferenceAlias Event OnInit() OnPlayerLoadGame() EndEvent Event OnPlayerLoadGame() Quest Master = Game.GetFormFromFile(0x00000d62, "_TM_Master.esp") as Quest If !Master Debug.MessageBox("_TM_: Soft Link A - Master esp not found") Debug.Trace("_TM_: Soft Link A - Master esp not found") EndIf EndEvent Event OnUpdate() Debug.Trace("_TM_: Soft Link A: Mod A running but Master not loaded") RegisterForSingleUpdate(1.0) EndEvent Of course, I would always avoid OnUpdate checks whenever possible, but the same logic applies if you're adding checks for any other type of event. Link to comment Share on other sites More sharing options...
bcsp Posted September 3, 2018 Author Share Posted September 3, 2018 Thank you for taking the time to reply. Ok, the fact that it was working for one mod but not both mods was really throwing me off. I'm trying to get my head around what you've said. So based on my new-found understanding: I can run preliminary checks if mods exist with Game.GetFormFromFile(x) as any built in type - Quest, Actor, etc- from the main 'bulk' of a script without causing it to stop. But if I want to access a script attached to the object then the attempt to access the external script should be isolated into a script of it's own. Each soft dependency that tries to access an external script would each need their own separated script. If there was say 2 external functions I wanted to use from the same mod they could both be put into the same isolated script. IE. One isolated script per external mod. Here's a modified version I came up with: Master (Not changed): Scriptname _TM_MasterScript extends Quest String Function _TM_MasterFunction() Return "Master String" EndFunctionSoftLink Mod A: Scriptname _TM_SoftLinkA_Script extends ReferenceAlias _TM_SoftLinkMaster Property SoftLinkMaster Auto Event OnInit() RegisterForSingleUpdate(1.0) EndEvent Event OnPlayerLoadGame() Quest Master = Game.GetFormFromFile(0x00000d62, "_TM_Master.esp") as Quest If Master Debug.MessageBox("_TM_: Soft Link A - " + SoftLinkMaster.GetString(Master)) Debug.Trace("_TM_: Soft Link A - " + SoftLinkMaster.GetString(Master)) Else Debug.MessageBox("_TM_: Soft Link A - Master esp not found") Debug.Trace("_TM_: Soft Link A - Master esp not found") EndIf EndEvent Event OnUpdate() Debug.Trace("_TM_: Soft Link A: Mod A running ok") RegisterForSingleUpdate(1.0) EndEvent SoftLink Mod B: Scriptname _TM_SoftLinkB_Script extends ReferenceAlias _TM_SoftLinkMaster Property SoftLinkMaster Auto Event OnInit() RegisterForSingleUpdate(1.0) EndEvent Event OnPlayerLoadGame() Quest Master = Game.GetFormFromFile(0x00000d62, "_TM_Master.esp") as Quest If Master Debug.MessageBox("_TM_: Soft Link B - " + SoftLinkMaster.GetString(Master)) Debug.Trace("_TM_: Soft Link B - " + SoftLinkMaster.GetString(Master)) Else Debug.MessageBox("_TM_: Soft Link B - Master esp not found") Debug.Trace("_TM_: Soft Link B - Master esp not found") EndIf EndEvent Event OnUpdate() Debug.Trace("_TM_: Soft Link B: Mod B running ok") RegisterForSingleUpdate(1.0) EndEvent Interface Script. Both mod A & B use this: ScriptName _TM_SoftLinkMaster extends Quest String Function GetString(Quest Master) _TM_MasterScript MasterScript = Master as _TM_MasterScript Return MasterScript._TM_MasterFunction() EndFunction Seems to work fine. The updates from both mods continue ok with and without the master mod installed.Logs:With Master mod installed: Line 803: [09/03/2018 - 04:24:38PM] _TM_: Soft Link A: Mod A running okLine 805: [09/03/2018 - 04:24:38PM] _TM_: Soft Link B: Mod B running okLine 1260: [09/03/2018 - 04:24:39PM] _TM_: Soft Link A: Mod A running okLine 1261: [09/03/2018 - 04:24:39PM] _TM_: Soft Link B: Mod B running okLine 1336: [09/03/2018 - 04:24:40PM] _TM_: Soft Link A: Mod A running okLine 1337: [09/03/2018 - 04:24:40PM] _TM_: Soft Link B: Mod B running okLine 1392: [09/03/2018 - 04:24:41PM] _TM_: Soft Link A: Mod A running okLine 1393: [09/03/2018 - 04:24:41PM] _TM_: Soft Link B: Mod B running okLine 1530: [09/03/2018 - 04:24:42PM] _TM_: Soft Link A: Mod A running okLine 1531: [09/03/2018 - 04:24:42PM] _TM_: Soft Link B: Mod B running okLine 1588: [09/03/2018 - 04:24:43PM] _TM_: Soft Link B: Mod B running okLine 1590: [09/03/2018 - 04:24:43PM] _TM_: Soft Link A: Mod A running okLine 2217: [09/03/2018 - 04:24:49PM] _TM_: Soft Link A - Master StringLine 2218: [09/03/2018 - 04:24:49PM] _TM_: Soft Link B - Master StringLine 2502: [09/03/2018 - 04:24:50PM] _TM_: Soft Link B: Mod B running okLine 2503: [09/03/2018 - 04:24:50PM] _TM_: Soft Link A: Mod A running okLine 2570: [09/03/2018 - 04:24:51PM] _TM_: Soft Link B: Mod B running okLine 2571: [09/03/2018 - 04:24:51PM] _TM_: Soft Link A: Mod A running okLine 2628: [09/03/2018 - 04:24:52PM] _TM_: Soft Link B: Mod B running okLine 2629: [09/03/2018 - 04:24:52PM] _TM_: Soft Link A: Mod A running ok Without master mod installed: Line 30: [09/03/2018 - 04:05:23PM] Cannot open store for class "_tm_masterscript", missing file?Line 988: [09/03/2018 - 04:06:26PM] _TM_: Soft Link B: Mod B running okLine 990: [09/03/2018 - 04:06:26PM] _TM_: Soft Link A: Mod A running okLine 1655: [09/03/2018 - 04:06:27PM] _TM_: Soft Link A: Mod A running okLine 1656: [09/03/2018 - 04:06:27PM] _TM_: Soft Link B: Mod B running okLine 1903: [09/03/2018 - 04:06:28PM] _TM_: Soft Link A: Mod A running okLine 1904: [09/03/2018 - 04:06:28PM] _TM_: Soft Link B: Mod B running okLine 2017: [09/03/2018 - 04:06:29PM] _TM_: Soft Link A: Mod A running okLine 2019: [09/03/2018 - 04:06:29PM] _TM_: Soft Link B: Mod B running okLine 2090: [09/03/2018 - 04:06:30PM] _TM_: Soft Link B: Mod B running okLine 2091: [09/03/2018 - 04:06:30PM] _TM_: Soft Link A: Mod A running okLine 2137: [09/03/2018 - 04:06:31PM] _TM_: Soft Link A: Mod A running okLine 2139: [09/03/2018 - 04:06:31PM] _TM_: Soft Link B: Mod B running okLine 2341: [09/03/2018 - 04:06:36PM] ERROR: File "_TM_Master.esp" does not exist or is not currently loaded.Line 2344: [alias PlayerAlias on quest _TM_SoftLinkB_Quest (42000D62)]._TM_SoftLinkB_Script.OnPlayerLoadGame() - "_TM_SoftLinkB_Script.psc" Line 10Line 2344: [alias PlayerAlias on quest _TM_SoftLinkB_Quest (42000D62)]._TM_SoftLinkB_Script.OnPlayerLoadGame() - "_TM_SoftLinkB_Script.psc" Line 10Line 2344: [alias PlayerAlias on quest _TM_SoftLinkB_Quest (42000D62)]._TM_SoftLinkB_Script.OnPlayerLoadGame() - "_TM_SoftLinkB_Script.psc" Line 10Line 2345: [09/03/2018 - 04:06:36PM] ERROR: File "_TM_Master.esp" does not exist or is not currently loaded.Line 2348: [alias PlayerAlias on quest _TM_SoftLinkA_Quest (41000D62)]._TM_SoftLinkA_Script.OnPlayerLoadGame() - "_TM_SoftLinkA_Script.psc" Line 10Line 2348: [alias PlayerAlias on quest _TM_SoftLinkA_Quest (41000D62)]._TM_SoftLinkA_Script.OnPlayerLoadGame() - "_TM_SoftLinkA_Script.psc" Line 10Line 2348: [alias PlayerAlias on quest _TM_SoftLinkA_Quest (41000D62)]._TM_SoftLinkA_Script.OnPlayerLoadGame() - "_TM_SoftLinkA_Script.psc" Line 10Line 2384: [09/03/2018 - 04:06:36PM] _TM_: Soft Link B - Master esp not foundLine 2385: [09/03/2018 - 04:06:36PM] _TM_: Soft Link A - Master esp not foundLine 3043: [09/03/2018 - 04:06:39PM] _TM_: Soft Link A: Mod A running okLine 3044: [09/03/2018 - 04:06:39PM] _TM_: Soft Link B: Mod B running okLine 3113: [09/03/2018 - 04:06:40PM] _TM_: Soft Link A: Mod A running okLine 3114: [09/03/2018 - 04:06:40PM] _TM_: Soft Link B: Mod B running okLine 3315: [09/03/2018 - 04:06:41PM] _TM_: Soft Link B: Mod B running okLine 3316: [09/03/2018 - 04:06:41PM] _TM_: Soft Link A: Mod A running okLine 3512: [09/03/2018 - 04:06:42PM] _TM_: Soft Link B: Mod B running okLine 3513: [09/03/2018 - 04:06:42PM] _TM_: Soft Link A: Mod A running ok It also appears to work if the master mod was not initially installed but then is installed mid-game which is great.Does this look ok to you? Thanks again for the help. I really appreciate it. Link to comment Share on other sites More sharing options...
cdcooley Posted September 4, 2018 Share Posted September 4, 2018 Yes, that's actuall what I usually implement when I run into these situations but it somehow seemed more complicated to explain doing it that way working from your example. So I'm glad you not only realized that would work but posted the example I couldn't quite create when I responded. And I agree it's a very quirky thing that isn't well documented. Hopefully other people will find this thread in the future when they run into this problem. Link to comment Share on other sites More sharing options...
Recommended Posts