Jump to content

Recommended Posts

After few run I notice the problem is bigger than it seem. Every times another mod try to equip devices on the player, which remove a gear, chances are mimic trigger at the same time for the same slot DD. Result in waiting for a whole minutes for the conflict script resolve. 

Also sexlab arouse trigger mastubate when high aroused or any sex animation also remove/equip all clothing, result trigger mimic. 

Link to comment
12 hours ago, hungvipbcsok said:

So this is my first try in SE version and I got hit with DCL damsel in distress quest. I had waiting for about 5 minute for the script to work but still no control of the pc. At some point I notice Mimic transform animation running and my item got drop out then disappear. So I assume that when the Damsel quest trigger it unequip all my gear and trigger Mimic at the same time, which cause script conflict, thus making me wait forever. Sad that it is my first SE run so I am not active papyrus yet.

 

Edit: Waiting 5 more minute and the armbinder got swapped into elbowbinder. I got mimic message that when uneuiping my gautlet, it is turned into elbowbinder. The armbinder from DCUR damsel quest is disappear though, thus making the quest stuck here.

 

10 hours ago, hungvipbcsok said:

After few run I notice the problem is bigger than it seem. Every times another mod try to equip devices on the player, which remove a gear, chances are mimic trigger at the same time for the same slot DD. Result in waiting for a whole minutes for the conflict script resolve. 

Also sexlab arouse trigger mastubate when high aroused or any sex animation also remove/equip all clothing, result trigger mimic. 

 

TL;DR: That's one of the big (if not the biggest) remaining issues I'm aware of - and there's no real way to fix it unfortunately.

 

Long version:

As both variants, LE and SE, share the same source code (they just were ran through the associated compiler of that versoin), both technically have the same issue.

The problem is, that it's just not feasible to know what item unequips another. When a Devious Devices unequips a worn item - in your example armbinders remove gauntlets - the mod receives two separate events: one unequip event for the gauntlets and after that an equip event for the armbinder. Now, as they are separate and can't share any information (due to Papyrus and the engine they don't know of each other), the gauntlets will run successfully through the Mimic check, leading to a potential trigger, the armbinder will fail (as it's DD)

 

Now, MOST OF THE TIME, that's not a big deal, as there's a check built in to search for worn DD items, too. If it finds one, it tries to use an alternative, so MOST OF THE TIME, no second armbinder will equip above the first one. DMC also refuses to equip anything at all, if a DD quest item is worn for not interfering with quests.

The thing is, SOMETIMES, my mod finishes its checks "too fast", so it knows which DD item to use before the other could equip the one it wanted, then the DMC item could get equipped first..

Another thing: some mods first unequip every worn item, with each triggering Mimic events. After that, it starts to equip the DD items, one after another. Until the other mod came to the point where a certain DD item shold get equipped, DMC already could have used the slot though due to a trigger, if the other mod was "too slow".

 

Some mods (like the SL Framework, and DCUR theoretically, too) use events to signal that something important is happening, as does mine. Eg, a sex event, started by the SL Framework will never trigger a mimic with its un- and redressing, as the SLF events block my mod temporarily until the sex is finished.

But not every mod sends events, some don't use the quasi-standard of the Deviously Helpless events, and some don't send events for eveything they do but just for bigger things.

BTW, it's interesting that DCUR doesn't send a block event, when it receives one to start a quest. For this specific issue, I can try and use a DMC-internal block switch to keep other mimics from triggering while DCUR sets up it's quest, but this only will work for DMC, and not other mods that don't send events.

 

So, the "easiest" thing to do is: saving often and if you come across that issue again, just reload the last save and hope that it won't trigger the next time :(

Link to comment
19 hours ago, Mister X said:

 

 

TL;DR: That's one of the big (if not the biggest) remaining issues I'm aware of - and there's no real way to fix it unfortunately.

 

Long version:

As both variants, LE and SE, share the same source code (they just were ran through the associated compiler of that versoin), both technically have the same issue.

The problem is, that it's just not feasible to know what item unequips another. When a Devious Devices unequips a worn item - in your example armbinders remove gauntlets - the mod receives two separate events: one unequip event for the gauntlets and after that an equip event for the armbinder. Now, as they are separate and can't share any information (due to Papyrus and the engine they don't know of each other), the gauntlets will run successfully through the Mimic check, leading to a potential trigger, the armbinder will fail (as it's DD)

 

Now, MOST OF THE TIME, that's not a big deal, as there's a check built in to search for worn DD items, too. If it finds one, it tries to use an alternative, so MOST OF THE TIME, no second armbinder will equip above the first one. DMC also refuses to equip anything at all, if a DD quest item is worn for not interfering with quests.

The thing is, SOMETIMES, my mod finishes its checks "too fast", so it knows which DD item to use before the other could equip the one it wanted, then the DMC item could get equipped first..

Another thing: some mods first unequip every worn item, with each triggering Mimic events. After that, it starts to equip the DD items, one after another. Until the other mod came to the point where a certain DD item shold get equipped, DMC already could have used the slot though due to a trigger, if the other mod was "too slow".

 

Some mods (like the SL Framework, and DCUR theoretically, too) use events to signal that something important is happening, as does mine. Eg, a sex event, started by the SL Framework will never trigger a mimic with its un- and redressing, as the SLF events block my mod temporarily until the sex is finished.

But not every mod sends events, some don't use the quasi-standard of the Deviously Helpless events, and some don't send events for eveything they do but just for bigger things.

BTW, it's interesting that DCUR doesn't send a block event, when it receives one to start a quest. For this specific issue, I can try and use a DMC-internal block switch to keep other mimics from triggering while DCUR sets up it's quest, but this only will work for DMC, and not other mods that don't send events.

 

So, the "easiest" thing to do is: saving often and if you come across that issue again, just reload the last save and hope that it won't trigger the next time :(

 

Just recently @hungvipbcsok has contacted me about a incompatibility between your mod DMC and my mod DS. This is because my mod has a function that transfers all devices from one actor to another after a certain amounts of hits. While they transfer, your mod supposedly steps in and also triggers its own functions. He asked me if there is a way to solve this incompatibility. 

After reading through your explanation of the problem it sounds like there actually is something that could help to solve this: 

19 hours ago, Mister X said:

Some mods (like the SL Framework, and DCUR theoretically, too) use events to signal that something important is happening, as does mine. Eg, a sex event, started by the SL Framework will never trigger a mimic with its un- and redressing, as the SLF events block my mod temporarily until the sex is finished.

But not every mod sends events, some don't use the quasi-standard of the Deviously Helpless events, and some don't send events for eveything they do but just for bigger things.

But i have no clue on how to send a mod event so other mods can recognize whats going on. Could you tell me what exactly i need to do for our mods to become compatible? 

would really be shame if it wasn't possible.

Link to comment
16 hours ago, CrymH said:

But i have no clue on how to send a mod event so other mods can recognize whats going on. Could you tell me what exactly i need to do for our mods to become compatible? 

would really be shame if it wasn't possible.

 

Heyho, that's not too complicated, you just need three code snippets for that:

1) You actually have your mod listen for those events, best would be within an Init function, that's called on game load, one example:

; call this with OnInit() and OnPlayerLoadGame(), or put the registrations directly in those functions
Function LoadGameInit()
	RegisterForModEvent("dhlp-Suspend", "OnDhlpSuspend") ; first one is the event name, second one the function that gets called
	RegisterForModEvent("dhlp-Resume", "OnDhlpResume")
EndFunction

 

2) You need something, that blocks your mod from running, while it gets suspended, I used a simple flag variable

While this block flag is true, my mod aborts any mimic trigger, thus nothing gets changed or removed

The event variables are irrelevant, but they must be present, else it would throw Papyrus errors, at least for me it did that

Bool bBlockedDHLP = false ; public variable, could be a property, too, you just need a way to get its state

; notice, those two have the same names as the second strings of the registration, that is important
Event OnDhlpSuspend(String eventName, String strArg, Float numArg, Form sender)
	bBlockedDHLP = true
EndEvent

Event OnDhlpResume(String eventName, String strArg, Float numArg, Form sender)
	bBlockedDHLP = false
EndEvent

 

3) You have to send the events when your mod does things, so others can catch it, that are simply two one-liners.

That's the important part for compatibility, basically you could decide to ignore the events, as long as you put those two lines at the start and end of your action. Then, my mod won't do anything as long as yours is running.

; at the beginning of your mod's action
SendModEvent("dhlp-Suspend")

; [your code that does nasty things :P]

; when your mod is done
SendModEvent("dhlp-Resume")

 

 

If you want to see these examples in action, I always put the Papyrus source in my mod, so you can have a look at it ;) 

Edited by Mister X
Link to comment
8 hours ago, Mister X said:

 

Heyho, that's not too complicated, you just need three code snippets for that:

1) You actually have your mod listen for those events, best would be within an Init function, that's called on game load, one example:

; call this with OnInit() and OnPlayerLoadGame(), or put the registrations directly in those functions
Function LoadGameInit()
	RegisterForModEvent("dhlp-Suspend", "OnDhlpSuspend") ; first one is the event name, second one the function that gets called
	RegisterForModEvent("dhlp-Resume", "OnDhlpResume")
EndFunction

 

2) You need something, that blocks your mod from running, while it gets suspended, I used a simple flag variable

While this block flag is true, my mod aborts any mimic trigger, thus nothing gets changed or removed

The event variables are irrelevant, but they must be present, else it would throw Papyrus errors, at least for me it did that

Bool bBlockedDHLP = false ; public variable, could be a property, too, you just need a way to get its state

; notice, those two have the same names as the second strings of the registration, that is important
Event OnDhlpSuspend(String eventName, String strArg, Float numArg, Form sender)
	bBlockedDHLP = true
EndEvent

Event OnDhlpResume(String eventName, String strArg, Float numArg, Form sender)
	bBlockedDHLP = false
EndEvent

 

3) You have to send the events when your mod does things, so others can catch it, that are simply two one-liners.

That's the important part for compatibility, basically you could decide to ignore the events, as long as you put those two lines at the start and end of your action. Then, my mod won't do anything as long as yours is running.

; at the beginning of your mod's action
SendModEvent("dhlp-Suspend")

; [your code that does nasty things :P]

; when your mod is done
SendModEvent("dhlp-Resume")

 

 

If you want to see these examples in action, I always put the Papyrus source in my mod, so you can have a look at it ;) 

 

Thank you very much for the detailed explanation! I will implement it right away and test if it is working or not.

Link to comment

Hi, I know you're working on this. FYI, I set random to 0 and that didn't do anything. I unequipped a few devices and equipped armor and clothing, but no mimic events occurred.  My Papyrus log has 3,043,401 lines in slightly over an hour's playing time.

[07/17/2021 - 11:05:45AM] Error: Cannot call GetNthForm() on a None object, aborting function call
stack:
    [zadxQuest (0F00CA01)].zadDeviceLists.GetRandomDevice() - "zadDeviceLists.psc" Line 116
    [dmcMainQuest (22005901)].dmcarmorthreadscript.OnInternalThreadStart() - "dmcArmorThreadScript.psc" Line 152

I have no idea how far back the issue goes, so loading a prev. save isn't a practical option. I removed mod, made save, cleaned it, saved, reinstalled mod. Maintained load order. So far, so good. Going forward I'll check my p.log more often so I can easily go back to a prev. save.

I copied this for Resaver before cleaing, don't know if this info will be helpful or not, but better to have it and not need it, right?

Spoiler

Skyrim Special Edition (16)
Script Instances (16)
0 (10)
#dmcactorthreadscript#: *FORMIDX:000000 (00000143ec2867d0)
#dmcarmorthreadscript#: *FORMIDX:000000 (00000143ec286770)
#dmcconfigmenu#: *FORMIDX:000000 (00000143ec2867a0)
#dmcgoldthreadscript#: *FORMIDX:000000 (00000143ec286740)
#dmclibs#: *FORMIDX:000000 (00000143ec286830)
#dmcLoadGameAlias#: FORMIDX:000000 (00000143d8be3e20)
#dmcMaintenance#: *FORMIDX:000000 (00000143ec286860)
#dmcMainTrigger#: *FORMIDX:000000 (00000143ec286800)
#dmcNoTriggerChestScript#: *FORMIDX:000000 (00000143ec26afb0)
#dmcTriggerEvents#: FORMIDX:000000 (00000143d8be3df0)
A (1)
Activator: *FORMIDX:000000 (00000143ec26b340)
F (1)
FormList: *FORMIDX:000000 (00000143d8b82ce0)
G (1)
GlobalVariable: *FORMIDX:000000 (00000143ec231330)
L (1)
LeveledItem: *FORMIDX:000000 (00000143d8b45fc0)
O (1)
ObjectReference: *FORMIDX:000000 (00000143d8b877f0)
S (1)
SKI_PlayerLoadGameAlias: FORMIDX:000000 (00000143d8be3e50)

 

Link to comment
18 hours ago, Seeker999 said:

Hi, I know you're working on this. FYI, I set random to 0 and that didn't do anything. I unequipped a few devices and equipped armor and clothing, but no mimic events occurred.  My Papyrus log has 3,043,401 lines in slightly over an hour's playing time.

[07/17/2021 - 11:05:45AM] Error: Cannot call GetNthForm() on a None object, aborting function call
stack:
    [zadxQuest (0F00CA01)].zadDeviceLists.GetRandomDevice() - "zadDeviceLists.psc" Line 116
    [dmcMainQuest (22005901)].dmcarmorthreadscript.OnInternalThreadStart() - "dmcArmorThreadScript.psc" Line 152

I have no idea how far back the issue goes, so loading a prev. save isn't a practical option. I removed mod, made save, cleaned it, saved, reinstalled mod. Maintained load order. So far, so good. Going forward I'll check my p.log more often so I can easily go back to a prev. save.

I copied this for Resaver before cleaing, don't know if this info will be helpful or not, but better to have it and not need it, right?

  Reveal hidden contents

Skyrim Special Edition (16)
Script Instances (16)
0 (10)
#dmcactorthreadscript#: *FORMIDX:000000 (00000143ec2867d0)
#dmcarmorthreadscript#: *FORMIDX:000000 (00000143ec286770)
#dmcconfigmenu#: *FORMIDX:000000 (00000143ec2867a0)
#dmcgoldthreadscript#: *FORMIDX:000000 (00000143ec286740)
#dmclibs#: *FORMIDX:000000 (00000143ec286830)
#dmcLoadGameAlias#: FORMIDX:000000 (00000143d8be3e20)
#dmcMaintenance#: *FORMIDX:000000 (00000143ec286860)
#dmcMainTrigger#: *FORMIDX:000000 (00000143ec286800)
#dmcNoTriggerChestScript#: *FORMIDX:000000 (00000143ec26afb0)
#dmcTriggerEvents#: FORMIDX:000000 (00000143d8be3df0)
A (1)
Activator: *FORMIDX:000000 (00000143ec26b340)
F (1)
FormList: *FORMIDX:000000 (00000143d8b82ce0)
G (1)
GlobalVariable: *FORMIDX:000000 (00000143ec231330)
L (1)
LeveledItem: *FORMIDX:000000 (00000143d8b45fc0)
O (1)
ObjectReference: *FORMIDX:000000 (00000143d8b877f0)
S (1)
SKI_PlayerLoadGameAlias: FORMIDX:000000 (00000143d8be3e50)

 

 

Heyho, yes, that issue already has been reported and I came across it by myself, too. The thing is, I never was able to find a good solution, as the problem isn't in my code but in the one of the DD framework or in the game engine itself.

For some reason, sometimes my LeveledItem I fill with the allowed and usable DD items, doesn't get transferred or read properly to the framework code.

The log spam is a result of that: the framework has only a sanity check for the first iteration, after that it will try until the end of time. It always get's past that first check, which tells me that my stuff got filled properly, but then the framework gets stuck in a loop forever.

 

On my end though, anything seems to be fine, even two other coders couldn't find an error in the scripting. So I absolutely have no idea, how to get rid of this :/ 

I even asked Kimy some time ago but didn't get an answer for this.

Link to comment

New version 2.4.0 is up!

 

With this one comes the chance to find Protector Charms throughout chests in the world, that can protect against nasty Mimics (yes, this idea totally is stolen from DCUR ?)

 

There now is an experimental feature to support a follower, too!

For this to happen, you have to enable debugging though, as it's not yet meant for a normal playthrough. It will affect only one follower at a time, but this one then can get hit by Mimics on the same events and with the same chances as the player.

Link to comment
21 hours ago, Mister X said:

New version 2.4.0 is up!

 

With this one comes the chance to find Protector Charms throughout chests in the world, that can protect against nasty Mimics (yes, this idea totally is stolen from DCUR ?)

 

There now is an experimental feature to support a follower, too!

For this to happen, you have to enable debugging though, as it's not yet meant for a normal playthrough. It will affect only one follower at a time, but this one then can get hit by Mimics on the same events and with the same chances as the player.

 

Is a clean install needed?

Link to comment
  • 2 weeks later...
On 7/30/2021 at 12:32 PM, forsythia_vahl said:

Hi!

I need help since I cant get it work at all!

 

The papyrus.log only shows:

...
[Mimic Clothes] Equip event attempts triggering - 
[Mimic Clothes] Unequip event attempts triggering - 
...
But nothing happened.
 

 

After the "-" there should be the name of the item that triggered. As nothing's there I assume some technical item or helper tried to trigger a mimic. Those will get filtered, they can't trigger anything.

 

Try this to see if there's really a problem:

- Search a quiet place ingame and save there

- Then, set the chances really high in the MCM and deactivate any restrictions

- After this, try to manually un-/equip some piece of armor or clothing every few seconds (don't spam it, though)

- Eventually, if everything's ok, it should successfully trigger for that normal armor, if not, then send me the log of that try

Link to comment
On 7/30/2021 at 1:32 PM, forsythia_vahl said:

Hi!

I need help since I cant get it work at all!

 

The papyrus.log only shows:

...
[Mimic Clothes] Equip event attempts triggering - 
[Mimic Clothes] Unequip event attempts triggering - 
...
But nothing happened.
 

Same issue, fresh install of 2.4, mod events do nothing and prompt - instead of item name.
Downgraded to 2.3.2, event message appears, but no item is getting equipped. Maybe 5.1 DD is incompatible?

Edited by BreadDain
Link to comment

@BreadDain Did you try to force Events for certain items? Eg, take a leather armor and try to equip and unequip it every few seconds until something triggers.

Basically try forcing a event with an item of that you're sure that it should be possible.

 

And a Papyrus log of that could help, too.

Link to comment

@Mister X no problemo, here you go
2.4
Papyrus.1.log
Nothing relevant in the file, debug line appears in game.

2.3.2
Papyrus.0.log
Event fires, messagebox appears, log line exists with erroneous item reference.
 

Spoiler

ScreenShot10.png.9467ad0735f7892e4ea0b510da222151.png



Note: DD 5.1 (recent), SexLab 163 beta 9 (recent, experimental), SL Aroused Modular (experimental). The latter 2 shouldn't matter I think, issue is most likely within DD conflict or the mod itself.

UPD Yes I tried testing it extensively with low cooldown and 100% proc chances, nothing worked.

Edited by BreadDain
Link to comment

Hmm, it seems you DID have enabled the debug flag (set dmcDebug to 1 in console) as you got the messages on screen, right?

The thing is, that there are absolutely no messages of my mod in your log, normally it would give additional information when debugging is enabled.

 

Like this I only can tell, that a variable that should hold the piece of armor somewhere gets emptied for some reason, but I'm not really sure where or when.

Especially, as I didn't really change anything essential in between those versions concerning those functions ...

Link to comment
1 hour ago, Mister X said:

Hmm, it seems you DID have enabled the debug flag (set dmcDebug to 1 in console) as you got the messages on screen, right?

The thing is, that there are absolutely no messages of my mod in your log, normally it would give additional information when debugging is enabled.

 

Like this I only can tell, that a variable that should hold the piece of armor somewhere gets emptied for some reason, but I'm not really sure where or when.

Especially, as I didn't really change anything essential in between those versions concerning those functions ...

Yes, version 2.4 of your mod is completely silent (except in-game debug log). Screenshot is from 2.3.2, and yes, I toggled debug mode on both tests.

Edited by BreadDain
Link to comment
On 7/19/2021 at 4:47 AM, Mister X said:

 

Heyho, yes, that issue already has been reported and I came across it by myself, too. The thing is, I never was able to find a good solution, as the problem isn't in my code but in the one of the DD framework or in the game engine itself.

For some reason, sometimes my LeveledItem I fill with the allowed and usable DD items, doesn't get transferred or read properly to the framework code.

The log spam is a result of that: the framework has only a sanity check for the first iteration, after that it will try until the end of time. It always get's past that first check, which tells me that my stuff got filled properly, but then the framework gets stuck in a loop forever.

 

On my end though, anything seems to be fine, even two other coders couldn't find an error in the scripting. So I absolutely have no idea, how to get rid of this :/ 

I even asked Kimy some time ago but didn't get an answer for this.

 

Hi,

I may have found a workaround for the papyrus blow up problem. It's definitely not a solution, but....

  • I saved and quit the game.
  • I scrolled through the papyrus log noticed that most if not all the bloat involved the .dmcarmorthreadscript.
  • I copied the script to a safe place and then deleted it from my game's Data/scripts folder.
  • Started Skyrim SE, played a couple of minutes w/o issue.
  • Saved and quit.
  • Copied the script back into the Data/scripts folder.
  • Opened the game and went to the debug section in the MCM, saw that events were blocked and reset the block flags.
  • Tested that mimic worked by setting equip chance to 100% and trying things on. Worked - I got mimiced!

It's not elegant. Maybe I didn't have to do that save without script. I don't know if there will be some weird long-term effect down the road. I do know that I didn't have to load a previous save, losing however much game played time, or go through the hassle of uninstalling the mod, making a clean save, reinstalling the mod. My papyrus log went from over 81k lines in 3 minutes to less than 3000 lines in over 30 minutes.

 

I'm still using v. 2.3.2. I didn't upgrade because I didn't see anything about this issue being fixed or patched or anything. The Protector charms sound interesting, but not enough to make the switch mid-game. Just thought I'd share what I did in case it was useful to someone.

Link to comment
6 hours ago, Seeker999 said:

The Protector charms sound interesting, but not enough to make the switch mid-game

 

Well, it should be safe to update mid-game, but that's your decision.

 

And that's definitely an interesting approach and I'm somewhat even more amazed that it actually worked. The thing is, the problematic function isn't even part of my scripts but in a file of the DD framework. But I'm happy it worked on your end, I'm just not sure about recommending it generally.

Link to comment

Had an idea for a small (and hopefully easy to add feature). Can we get a slider to set the chance that a mimic will actually equip a device? If we have items equipped it would just destroy it sometimes (or most of the time depending on how you set the slider) instead of always equipping a device.

Link to comment

Ok so I had another attempt of fixing the mod since script recompilation didn't just work. Added some console logging to check what scripts are running and how do they run. It seems like the mod a) can't fetch actor being valid for event at all and b) script is designed in such way (a bad one) that a single armor unequip produces several script loops without a reason. I guess some failsaves are required.

This is console log for a single armor unequip event after I tried to fiddle with a lot of equipment at once. Note that conditions before equipping are checked several times for no reason and everywhere actor is being invalid. Will look into it a bit more.

Spoiler

839281344_.png.4c710606fc8db6aa11fb0f88deac1cc1.png


UPD1 Actor wasn't valid because there is a condition if the first main quest was completed (not just active as it could be), which blocked mod from working in test cell. In real gameplay conditions it appears that mod is working, but ultimately slow and with overlapping loops. I pinpointed possible part of the script that has a long work time before it lets other functions fire.

dmcArmorThreadScript, line 156-166
 

Spoiler

            ; check for already worn device, try to find alternative
            int i = 0
            While (akDevice && i < 10 && libs.GetWornDeviceFuzzyMatch(theVictim, ddKw))
                akDevice = ddList.GetRandomDevice(liDevicePool)
                ddKw = libs.GetDeviceKeyword(akDevice)

                i += 1
            EndWhile
            If (akDevice && libs.GetWornDeviceFuzzyMatch(theVictim, ddKw))
                akDevice = none
            EndIf


UPD2 dmcMainTrigger, line 125, doesn't check if cooldown is possible and always sets trigger on cooldown.
UPD3 dmcArmorThreadScript, line 152-153 sometimes also take too long to pass. Should be DD framework to blame.
 

Spoiler

            akDevice = ddList.GetRandomDevice(liDevicePool)
            Keyword ddKw = libs.GetDeviceKeyword(akDevice)

 

Edited by BreadDain
Link to comment
On 8/17/2021 at 10:05 PM, TrickyK said:

Had an idea for a small (and hopefully easy to add feature). Can we get a slider to set the chance that a mimic will actually equip a device? If we have items equipped it would just destroy it sometimes (or most of the time depending on how you set the slider) instead of always equipping a device.

 

A bit ago I've added the feature of "struggling" based on your character stats: sometimes your PC can struggle effectively against a mimic after it triggered. In that case nothing will be ewuipped. There's a toggle, too, to set whether your piece of clothing should get destroyed even when struggling is successful. Is that what you meant?

 

 

3 hours ago, BreadDain said:

Ok so I had another attempt of fixing the mod since script recompilation didn't just work. Added some console logging to check what scripts are running and how do they run. It seems like the mod a) can't fetch actor being valid for event at all and b) script is designed in such way (a bad one) that a single armor unequip produces several script loops without a reason. I guess some failsaves are required.

This is console log for a single armor unequip event after I tried to fiddle with a lot of equipment at once. Note that conditions before equipping are checked several times for no reason and everywhere actor is being invalid. Will look into it a bit more.

  Reveal hidden contents

839281344_.png.4c710606fc8db6aa11fb0f88deac1cc1.png


UPD1 Actor wasn't valid because there is a condition if the first main quest was completed (not just active as it could be), which blocked mod from working in test cell. In real gameplay conditions it appears that mod is working, but ultimately slow and with overlapping loops. I pinpointed possible part of the script that has a long work time before it lets other functions fire.

dmcArmorThreadScript, line 156-166
 

  Reveal hidden contents

            ; check for already worn device, try to find alternative
            int i = 0
            While (akDevice && i < 10 && libs.GetWornDeviceFuzzyMatch(theVictim, ddKw))
                akDevice = ddList.GetRandomDevice(liDevicePool)
                ddKw = libs.GetDeviceKeyword(akDevice)

                i += 1
            EndWhile
            If (akDevice && libs.GetWornDeviceFuzzyMatch(theVictim, ddKw))
                akDevice = none
            EndIf


UPD2 dmcMainTrigger, line 125, doesn't check if cooldown is possible and always sets trigger on cooldown.
UPD3 dmcArmorThreadScript, line 152-153 sometimes also take too long to pass. Should be DD framework to blame.
 

  Reveal hidden contents

            akDevice = ddList.GetRandomDevice(liDevicePool)
            Keyword ddKw = libs.GetDeviceKeyword(akDevice)

 

 

For 1) It checks only once whether an actor is a valid target, afterwards it just uses that result again to check if different outcomes are usable.

The thing with the first main quest is there, so you don't get mimics during character creation, or when playing the vanilla intro. That's how many mods check if they are allowed to run, I just used existing code for that. If you don't like that: for testing, I used Alternate Start with the "I want to escape this cell", works like a charm, too ;)

 

For UPD 1) The overlapping loops are there because of the multi-threaded coding of the mod. It was even slower for v1, where each and every check was done one after another.

So, before v2 the checks where serial with low stress on the engine, now they are parallel but with more stress on the engine. It won't matter though for the most time.

dmcArmorThreadScript is the one that checks if the armor is usable and what device fits to the body region of that armor. I already sourced out as much as I can to formlists and alike to avoid Papyrus Arrays, still you have to iterate a list. The speed of that is just limited by the current speed of your Papyrus engine and the amount of other active scripts.

The loop you pinpointed just really is used, when other devices are worn in the affected body region. It won't run if no devices are worn there. I could try to speed it up a bit by using an alternate DDf function for collision checks, that will have bad negatives more often though. The other possibility is to lower the number of iterations before aborting, but I don't know if this will have much influence as most often you won't have more than 3 iterations.

For UPD 2), I will look into that, thanks for that report.

EDIT That's totally fine, cooldown set just saves the time of the last trigger. The HasCooldown() function respects whether to use cooldown. And even then, a small CD of 2 ingame minutes always is there to avoid a new trigger right after a successful one.

 

For UPD 3) There you have found a culprit for a bug report I received long ago, yet I have still no idea how to fix it. Sometimes that DDf function seems to get a LeveledItem with nothing in it, so it is caught in an endless loop. I've already reported that to Kimy, but I don't know when or if she will fix that. Neither do I know why my mod seems to fail with filling the LeveledItem sometimes, I wasn't really able to reliable reproduce the bug, even though I came across it myself a few times already.

Edited by Mister X
Added explanation
Link to comment
1 hour ago, Mister X said:

...

Don't really trust AS LAL because Arthmoor implemented some console blocking stuff, that's why I am using Dimes instead. Still loading qasmoke is somewhat faster for testing, but alright, at least I figured why mod didn't work at all. Wonder if similar to Sheogorath's quest condition will work better, isrunning and !iscompleted.
About cooldown - that's somewhat contrary to mcm option because cooldown is expected to be removed entirely, but again, alright. Just gave me a feeling that something was wrong when console was silent and didn't produce any logs.

But the problem is still there, something is hogging a lot of script execution time and mod hits 10/30 second failsave boundaries. I am constantly getting (customized message for debugging purposes):

Quote

[Mimic Clothes] Armor thread probably encountered an error and is locked up;

from ArmorFuture script, so it doesn't recieve the 'end result' and stops working. Thread clears itself afterwards and nothing happens.

I don't really understand the mod in-depth, but I actually think that a lot of resources can be saved with certain optimizations. Since DD functions are to blame, why just not move it after mod calculates trigger chances and validates an actor?
It is also probably worth to reduce the use of GetWornDeviceFuzzyMatch by removing records from liDevicePool each loop, so script doesn't have a possibility to hit one and the same record each time, which it had previously checked. I also don't really get it why this loop fires even if an actor doesn't have any devices equipped? Why I=10? Isn't it better to link loop number to the list size of items it can possibly check every time?
But again, I am really low skill at scripting, these are just wild ideas to try. If you think they could help, I would be glad that I've tried.

PS I see it is a static Leveled list, but it's still worth to consider an additional stress on Papyrus from 10 loops when the list contains less devices in pool. God, I am too sleepy for this right now, need a break.

Edited by BreadDain
Link to comment
1 hour ago, BreadDain said:

Wonder if similar to Sheogorath's quest condition will work better, isrunning and !iscompleted.

 

This works for Sheogoraths quest as that the player can choose when to start. The first quest is the intro, the Vanilla Helgen escape, where the player can't choose whether or when to start it normally. But since alternate start mods (not just ASLAL) won't necessarily FINISH the quest, I chose to check if it got to state 1000 (which is the destroyed Helgen), as every alternate start mod I've found sets that stage after you chose your start. I honestly don't know if that finishes the quest, too, but like that it works as I want to, so I'll probably leave it that way ^^

 

1 hour ago, BreadDain said:

Since DD functions are to blame, why just not move it after mod calculates trigger chances and validates an actor?

 

Because all those three things are done at the same time. It's multi-threaded, so it validates the actor in one thread, validation of the armor in another one and calculation of the chances in the third thread.

When it's done calculating the chances it asks for the results of the other  twothreads and waits until it gets those to decide which outcome to use.

 

1 hour ago, BreadDain said:

removing records from liDevicePool each loop

 

That won't be possible as those are nested LeveledItem lists. So, it's a LeveledItem inside a LeveledItem inside a LeveledItem and only the lowest layer really contains the devices. As those LeveledItems are provided by the framework, I can't remove a device from them. So, I only could remove a top layer LeveledItem, which then as consequence would remove a handful to a dozen of devices and not only the one which wouldn't work.

Additionally I don't have a good way of finding out which LeveledItem holds the chosen device: diving INTO the LeveledItem layers is easier than diving out of them and that's done by the framework, too, which only gives back the found device and not the LeveledItem where it found it.

 

That's also a reason why i=10: I don't really know how many LeveledItem lists are there and moreover how many are NESTED INSIDE of those. You can see it like a tree diagram, where each branch is a LeveledItem and only the most bottom layer are the devices. Look at the example picture.

 

I can't calculate how many actual DEVICES I can choose from, so I use a fixed, not too high number to restrict the attempts.

Spoiler

tree.png.91d92a8680526b12c8817c93914dbf43.png

 

Edited by Mister X
Add picture
Link to comment

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue. For more information, see our Privacy Policy & Terms of Use