Ashal Posted February 24, 2014 Author Posted February 24, 2014 Just tested it, and it works now, giving it just "SexLabMissionary." and keyContains = true it exports the tags as expected. It does however insert some null's before and after the list: { "stringlist" : [ null, { "key" : [ 77, 1158035935, "SexLab.esp" ], "value" : [ { "key" : "SexLabMissionary.Tags", "value" : [ "Default", "sex", "Missionary", "Laying", "Vaginal", "MF" ] } ] }, null ] } Which doesn't happen when not doing keyContains.
Someone92 Posted February 25, 2014 Posted February 25, 2014 I've used the examples given in the OP to store a variable on an actor and then manipulate it. However the variable stays '0'. My code: int i = 0 while i < lengthOfActorList if StorageUtil.IntListCount(actorList[i], "SLMF_WearTearVaginal") == 0 ;if variable doesn't exist yet initialize it StorageUtil.IntListAdd(actorList[i], "SLMF_WearTearVaginal", 0) StorageUtil.IntListAdd(actorList[i], "SLMF_WearTearVaginal", 0) endIf int temp = StorageUtil.IntListGet(actorList[i], "SLMF_WearTearVaginal", 1) + 100 ;increase second value of array by 100 StorageUtil.IntListSet(actorList[i], "SLMF_WearTearVaginal", 1, temp) i += 1 endWhile debug.Notification("WearTearVaginal = " + StorageUtil.IntListGet(game.getPlayer(), "SLMF_WearTearVaginal", 1)) ;print value ;Error: Always returns 0 edit: 'actorList' and 'game.getPlayer()' point towards the same actor.
gooser Posted February 25, 2014 Posted February 25, 2014 I've used the examples given in the OP to store a variable on an actor and then manipulate it. However the variable stays '0'. My code: int i = 0 while i < lengthOfActorList if StorageUtil.IntListCount(actorList[i], "SLMF_WearTearVaginal") == 0 ;if variable doesn't exist yet initialize it StorageUtil.IntListAdd(actorList[i], "SLMF_WearTearVaginal", 0) StorageUtil.IntListAdd(actorList[i], "SLMF_WearTearVaginal", 0) endIf int temp = StorageUtil.IntListGet(actorList[i], "SLMF_WearTearVaginal", 1) + 100 ;increase second value of array by 100 StorageUtil.IntListSet(actorList[i], "SLMF_WearTearVaginal", 1, temp) i += 1 endWhile debug.Notification("WearTearVaginal = " + StorageUtil.IntListGet(game.getPlayer(), "SLMF_WearTearVaginal", 1)) ;print value ;Error: Always returns 0 edit: 'actorList' and 'game.getPlayer()' point towards the same actor. Can you try a couple of test lines like: PapyrusUtil.SetIntValue(myActor, "TestVar", 10) Int result = PapyrusUtil.GetIntValue(myActor, "TestVar") Bool worked = result == 10
Ashal Posted February 25, 2014 Author Posted February 25, 2014 If your 100% positive actorList has the same form as Game.GetPlayer() (which you should almost never use by the way, a PlayerRef property is significantly faster), than the issue is most likely with your initialization, try this: int i = actorList.Length while i i -= 1 while StorageUtil.IntListCount(actorList[i], "SLMF_WearTearVaginal") < 2 StorageUtil.IntListAdd(actorList[i], "SLMF_WearTearVaginal", 0) endwhile StorageUtil.IntListSet(actorList[i], "SLMF_WearTearVaginal", 1, (StorageUtil.IntListGet(actorList[i], "SLMF_WearTearVaginal", 1) + 100)) Debug.Notification("IsPlayer = "+(actorList[i] == Game.GetPlayer())+" - WearTearVaginal = "+StorageUtil.IntListGet(actorList[i], "SLMF_WearTearVaginal", 1)) endWhile That'll more reliably initialize it to your presumably desired length of 2, and adjust the second value of the list by 100, then inform you if actorlist is definitely the same as Game.GetPlayer() or not.
Ashal Posted February 25, 2014 Author Posted February 25, 2014 Just tested it, and it works now, giving it just "SexLabMissionary." and keyContains = true it exports the tags as expected. It does however insert some null's before and after the list: { "stringlist" : [ null, { "key" : [ 77, 1158035935, "SexLab.esp" ], "value" : [ { "key" : "SexLabMissionary.Tags", "value" : [ "Default", "sex", "Missionary", "Laying", "Vaginal", "MF" ] } ] }, null ] } Which doesn't happen when not doing keyContains. To add more to this, I left the code alone for awhile while I worked on some other stuff, so it ran repeatedly a couple times without me checking the results, but I just looked my test json file again and now after it's run a couple more times it looks like this: { "stringlist" : [ null, null, null, null, null, null, null, null, { "key" : [ 77, 1158035935, "SexLab.esp" ], "value" : [ { "key" : "SexLabMissionary.Tags", "value" : [ "Default", "sex", "Missionary", "Laying", "Vaginal", "MF" ] } ] }, null, null, null, null, null, null, null, null ] }
zax Posted February 25, 2014 Posted February 25, 2014 I'm confused, an author confirmed that this is causing skse save bloat, then I see that you can clean everything backwards (the forms modified by yourself) - so how do you do it guys? Will something that gets removed leave empty entry in array?
gooser Posted February 25, 2014 Posted February 25, 2014 If your 100% positive actorList has the same form as Game.GetPlayer() (which you should almost never use by the way, a PlayerRef property is significantly faster), than the issue is most likely with your initialization, try this: int i = actorList.Length while i i -= 1 while StorageUtil.IntListCount(actorList[i], "SLMF_WearTearVaginal") < 2 StorageUtil.IntListAdd(actorList[i], "SLMF_WearTearVaginal", 0) endwhile StorageUtil.IntListSet(actorList[i], "SLMF_WearTearVaginal", 1, (StorageUtil.IntListGet(actorList[i], "SLMF_WearTearVaginal", 1) + 100)) Debug.Notification("IsPlayer = "+(actorList[i] == Game.GetPlayer())+" - WearTearVaginal = "+StorageUtil.IntListGet(actorList[i], "SLMF_WearTearVaginal", 1)) endWhile That'll more reliably initialize it to your presumably desired length of 2, and adjust the second value of the list by 100, then inform you if actorlist is definitely the same as Game.GetPlayer() or not. Ashal, I'm having a hard time seeing the advantage of: while StorageUtil.IntListCount(actorList[i], "SLMF_WearTearVaginal") < 2 StorageUtil.IntListAdd(actorList[i], "SLMF_WearTearVaginal", 0) endwhile Over if StorageUtil.IntListCount(actorList[i], "SLMF_WearTearVaginal") == 0 StorageUtil.IntListAdd(actorList[i], "SLMF_WearTearVaginal", 0) StorageUtil.IntListAdd(actorList[i], "SLMF_WearTearVaginal", 0) endIf Can you kindly please explain? They look equivalent to me, and actually the second is easier to read (I don't have to 'think' about looping, etc)
Ashal Posted February 25, 2014 Author Posted February 25, 2014 If your 100% positive actorList has the same form as Game.GetPlayer() (which you should almost never use by the way, a PlayerRef property is significantly faster), than the issue is most likely with your initialization, try this: int i = actorList.Length while i i -= 1 while StorageUtil.IntListCount(actorList[i], "SLMF_WearTearVaginal") < 2 StorageUtil.IntListAdd(actorList[i], "SLMF_WearTearVaginal", 0) endwhile StorageUtil.IntListSet(actorList[i], "SLMF_WearTearVaginal", 1, (StorageUtil.IntListGet(actorList[i], "SLMF_WearTearVaginal", 1) + 100)) Debug.Notification("IsPlayer = "+(actorList[i] == Game.GetPlayer())+" - WearTearVaginal = "+StorageUtil.IntListGet(actorList[i], "SLMF_WearTearVaginal", 1)) endWhile That'll more reliably initialize it to your presumably desired length of 2, and adjust the second value of the list by 100, then inform you if actorlist is definitely the same as Game.GetPlayer() or not. Ashal, I'm having a hard time seeing the advantage of: while StorageUtil.IntListCount(actorList[i], "SLMF_WearTearVaginal") < 2 StorageUtil.IntListAdd(actorList[i], "SLMF_WearTearVaginal", 0) endwhile Over if StorageUtil.IntListCount(actorList[i], "SLMF_WearTearVaginal") == 0 StorageUtil.IntListAdd(actorList[i], "SLMF_WearTearVaginal", 0) StorageUtil.IntListAdd(actorList[i], "SLMF_WearTearVaginal", 0) endIf Can you kindly please explain? They look equivalent to me, and actually the second is easier to read (I don't have to 'think' about looping, etc) Say they were initialized somewhere before with 1 or more elements on that same IntList, whether through a bug or from the authors previous debugging or experimentations. If Count == 0 doesn't account for that, resulting in them skipping the block with their length of 1 and trying to set the second element afterward in the function fails. If Count != 2 has the problem that if they were to go into it with 1, they would end up with a length of 3. The next time they entered the function, they would leave it with a count of 5. And time after that they'd leave with 7. And so on so on. While Count < 2 solves the first problem, and prevents the second from happeneing. Secondly, I'd disagree the second is easier to read. You can just look at the condition's 2 and know that it is going to make the count come out to 2 and be done, it provides an easy way to adjust the size of the list should the author ever wish to, simply by changing the 2 in the loop condition to a different number, and lastly a common mantra of maintainable and good code is "Don't Repeat Yourself" (DRY) and while repeating two simple lines may be so minor that it shouldn't fall under DRY, I'd consider it a bad habit at the least.
gooser Posted February 25, 2014 Posted February 25, 2014 If your 100% positive actorList has the same form as Game.GetPlayer() (which you should almost never use by the way, a PlayerRef property is significantly faster), than the issue is most likely with your initialization, try this: int i = actorList.Length while i i -= 1 while StorageUtil.IntListCount(actorList[i], "SLMF_WearTearVaginal") < 2 StorageUtil.IntListAdd(actorList[i], "SLMF_WearTearVaginal", 0) endwhile StorageUtil.IntListSet(actorList[i], "SLMF_WearTearVaginal", 1, (StorageUtil.IntListGet(actorList[i], "SLMF_WearTearVaginal", 1) + 100)) Debug.Notification("IsPlayer = "+(actorList[i] == Game.GetPlayer())+" - WearTearVaginal = "+StorageUtil.IntListGet(actorList[i], "SLMF_WearTearVaginal", 1)) endWhile That'll more reliably initialize it to your presumably desired length of 2, and adjust the second value of the list by 100, then inform you if actorlist is definitely the same as Game.GetPlayer() or not. Ashal, I'm having a hard time seeing the advantage of: while StorageUtil.IntListCount(actorList[i], "SLMF_WearTearVaginal") < 2 StorageUtil.IntListAdd(actorList[i], "SLMF_WearTearVaginal", 0) endwhile Over if StorageUtil.IntListCount(actorList[i], "SLMF_WearTearVaginal") == 0 StorageUtil.IntListAdd(actorList[i], "SLMF_WearTearVaginal", 0) StorageUtil.IntListAdd(actorList[i], "SLMF_WearTearVaginal", 0) endIf Can you kindly please explain? They look equivalent to me, and actually the second is easier to read (I don't have to 'think' about looping, etc) Say they were initialized somewhere before with 1 or more elements on that same IntList, whether through a bug or from the authors previous debugging or experimentations. If Count == 0 doesn't account for that, resulting in them skipping the block with their length of 1 and trying to set the second element afterward in the function fails. If Count != 2 has the problem that if they were to go into it with 1, they would end up with a length of 3. The next time they entered the function, they would leave it with a count of 5. And time after that they'd leave with 7. And so on so on. While Count < 2 solves the first problem, and prevents the second from happeneing. Secondly, I'd disagree the second is easier to read. You can just look at the condition's 2 and know that it is going to make the count come out to 2 and be done, it provides an easy way to adjust the size of the list should the author ever wish to, simply by changing the 2 in the loop condition to a different number, and lastly a common mantra of maintainable and good code is "Don't Repeat Yourself" (DRY) and while repeating two simple lines may be so minor that it shouldn't fall under DRY, I'd consider it a bad habit at the least. Thanks for articulating your defensive programming practices. I don't know if I agree with you completely on point 1, but agree that style 2 (Count != 2) would be an laughable code choice. It is possibly that coding with "count<2" might cover up a bug that was introduced before (as you mentioned through author's changes) - that is, the IntList might have an existing member that would silently work with "count<2" whereas "count==0" would possibly rise to the attention earlier (what originally caused the query to be surfaced here). I agree with DRY completely and been following it for decades.
Someone92 Posted February 25, 2014 Posted February 25, 2014 If your 100% positive actorList has the same form as Game.GetPlayer() (which you should almost never use by the way, a PlayerRef property is significantly faster), than the issue is most likely with your initialization, try this: actorList is the actor list you get from SexLab. Aparently for PapyrusUtil GetPlayer() and the player from actorList are not identical. GetPlayer() is faster if you're just debugging, though. PapyrusUtil doesn't seem to work at all for me; this failed as well: StorageUtil.SetIntValue(actorList[0], "TestVar", 10) Int result = StorageUtil.GetIntValue(actorList[0], "TestVar") if result == 10 debug.Notification("It works!") endIf Do I need to include PapyrusUtil to my script or something? Full script: scriptname SexLabMF_WearTear extends Quest {...} SexLabFramework property SexLab auto sslThreadController Controller function OnLoadGame() RegisterForModEvent("AnimationStart", "SexLabAnimStart") RegisterForModEvent("OrgasmStart", "SexLabOrgasmStart") endFunction event SexLabAnimStart(string eventName, string argString, float argNum, form sender) Controller = SexLab.HookController(argString) endEvent event SexLabOrgasmStart(string eventName, string argString, float argNum, form sender) actor[] actorList = Controller.positions ;SexLab.HookActors(argString) int lengthOfActorList = Controller.ActorCount bool isAggressive = Controller.IsAggressive actor victim = Controller.GetVictim() ;hook = Controller.GetHook() int i = 0 while i < lengthOfActorList while StorageUtil.IntListCount(actorList[i], "SLMF_WearTearVaginal") < 2 StorageUtil.IntListAdd(actorList[i], "SLMF_WearTearVaginal", 0) endwhile StorageUtil.IntListSet(actorList[i], "SLMF_WearTearVaginal", 1, (StorageUtil.IntListGet(actorList[i], "SLMF_WearTearVaginal", 1) + 100)) i += 1 endWhile debug.Notification("IsPlayer = "+(actorList[0] == Game.GetPlayer())+" - WearTearVaginal = "+StorageUtil.IntListGet(actorList[0], "SLMF_WearTearVaginal", 1)) StorageUtil.SetIntValue(actorList[0], "TestVar", 10) Int result = StorageUtil.GetIntValue(actorList[0], "TestVar") if result == 10 debug.Notification("It works!") endIf endEvent
nutluck Posted March 8, 2014 Posted March 8, 2014 I have a quick question about this. Is PapyrusUtilv just a rename of StorageUtilv? I only ask to be sure the StorageUtilv13 is just a old version of the current PapyrusUtilv19 and not a second required program, which I think it is just a old version but wanted to be sure.
verteiron Posted March 19, 2014 Posted March 19, 2014 I'm using version 1.9 with SKSE 1.7.0. The ImportFile and ExportFile functions appear to be broken when using "restictForm" after starting a new game. ExportFile writes a file with the correct value and keys, but missing the plugin name from the FormID key. Here is the code used to create the file: ;_kDummyActors[] is an array of ActorBases defined elsewhere SetStringValue(_kDummyActors[idx],sKey + "Name","foo") ExportFile(_kDummyActors[idx].GetName(),restrictForm = _kDummyActors[idx]) Here is the resulting file when the function is run after loading a save game (this is the expected output): { "string" : [ { "key" : [ 43, 855642837, "vMYC_MeetYourCharacters.esp" ], "value" : [ { "key" : "vMYC.Name", "value" : "foo" } ] } ]} Again, this is the correct and expected output. Now, here is the resulting file when the same function is run after starting a new game. It is not in OnInit, but is run several seconds later during an OnUpdate event: { "string" : [ { "key" : [ 43, 855642837, "" ], "value" : [ { "key" : "vMYC.Name", "value" : "foo" } ] } ]} Note the key has the correct FormID, but is missing the plugin name. I am guessing a similar bug in ImportForm is why I can't read form-restricted data after starting a new game, either. If I start a new game, quicksave, quickload, and try it, it works fine. Is there a workaround for this, or is it something you'll have to fix?
Expired6978 Posted March 20, 2014 Posted March 20, 2014 Would it be possible to extend the Condition Function List, so that we can work directly with Variables stored in Papyrus Util? Something like a new Condition Function GetPapyrusUtilVariable. I thought about how to do this but didn't come up with a solution that works for all situations. I wouldn't recommend doing this, this uses the old script API and the functions use fixed function opcodes. There is no interface here for plugins to add their own functions currently. I would steer clear of this until we work something out if this is really in high demand, realistically nobody is going to be using these condition functions until the Creation Kit Extender is up, as the only other way to get your custom functions into a plugin would be low-level record editing the function opcode. Also unrelated to this, but SKSE 1.7.0 beta is currently out and has this in changelog, "enabled previously-temporary Papyrus plugin API" I assume that means they added more official support Papyrus functions to be added with SKSE plugins, and no idea of it makes any difference from the current method you're using to add Papyrus functions, but just a heads up, just in case. Shouldn't make a difference, as it was previously hooking another function call to register. While we recommend switching to the new method it wouldn't be backwards compatible and you would have to force people to update, which is usually not preferable. To register functions you only needed a pointer to the VMClassRegistry, which is only initialized at a certain point, so you could pretty much hook anywhere after the initialization occurs to register your function (Preferably after the vanilla functions have all registered). It was added very early on by me, but it was disabled because we never intended for the API to be that way. We were supposed to decode enough of Papyrus to actually register AND bind the functions (thus eliminating the pex files except for modding). The one who knows the most about Papyrus internally got really busy and hasn't had time to do this so we agreed to just enable the basic API and hope that nobody registers functions for any of the vanilla classes (There's no need to do this anyway, Papyrus member functions are no faster than global functions). Ashal, I'm having a hard time seeing the advantage of: while StorageUtil.IntListCount(actorList[i], "SLMF_WearTearVaginal") < 2 StorageUtil.IntListAdd(actorList[i], "SLMF_WearTearVaginal", 0) endwhile While normally I would agree loops are better, but what we have here is all kinds of bad. There is no exit strategy for a function that could potentially return zero when SKSE isn't running, thus creating an infinite loop as 0 will always be less than 2 until hopefully you re-install the library this function relies on. Never write a Papyrus loop relying on an SKSE function's return value that would evaluate as true if the function were to not exist. If you need to do something like this, wrap it with an exiting counter like 'tries'.
Ashal Posted March 20, 2014 Author Posted March 20, 2014 Ashal, I'm having a hard time seeing the advantage of: while StorageUtil.IntListCount(actorList[i], "SLMF_WearTearVaginal") < 2 StorageUtil.IntListAdd(actorList[i], "SLMF_WearTearVaginal", 0) endwhile While normally I would agree loops are better, but what we have here is all kinds of bad. There is no exit strategy for a function that could potentially return zero when SKSE isn't running, thus creating an infinite loop as 0 will always be less than 2 until hopefully you re-install the library this function relies on. If a mod relies on SKSE, it should have an exit strategy from performing anything at all in the first place, beyond a check for SKSE being enabled at startup. That alleviates the infinite loop concern, at least in my opinion, only real fringe case in that event would be somebody who saved their game mid function/loop call and later reloaded their game without SKSE, which while not impossible, is rather unlikely. Though there is also wisdom in being paranoid about it regardless, and in hindsight it's also kind of ridiculous of me to recommend such a loop for something as simple as a 2 length integer list, though I would defend it in the case of larger initializations when proper SKSE checks are in place beforehand. int n = StorageUtil.IntListCount(actorList[i], "SLMF_WearTearVaginal") while n < 2 StorageUtil.IntListAdd(actorList[i], "SLMF_WearTearVaginal", 0) n += 1 endWhile Would obviously be a safer way to do it in any case.
Earen Posted March 20, 2014 Posted March 20, 2014 To register functions you only needed a pointer to the VMClassRegistry, which is only initialized at a certain point, so you could pretty much hook anywhere after the initialization occurs to register your function (Preferably after the vanilla functions have all registered). Tried that trick without any luck (due to uninitialized registry pointer propably). While looking at other plugins i noticed that they hook into SKSE registation method.. It's the only way to achieven that on pre 1.7.0 SKSE?
Expired6978 Posted March 21, 2014 Posted March 21, 2014 To register functions you only needed a pointer to the VMClassRegistry, which is only initialized at a certain point, so you could pretty much hook anywhere after the initialization occurs to register your function (Preferably after the vanilla functions have all registered). Tried that trick without any luck (due to uninitialized registry pointer propably). While looking at other plugins i noticed that they hook into SKSE registation method.. It's the only way to achieven that on pre 1.7.0 SKSE? Pre 1.7.0 yes.
gooser Posted March 22, 2014 Posted March 22, 2014 Is there a way to account for how much storage StorageUtil is taking up in its various calls against global or forms? As a mod developer I have a pretty good idea how many things I am adding to the game save space, but it would be nice if I could run a diagnostic method that would report information to Papyrus log, etc. Thanks
h38fh2mf Posted March 22, 2014 Posted March 22, 2014 In calls themselves, like on stack? Should be few bytes in addition to papyrus function overhead, debug to see. If you mean data saved in memory then it's saved like this: map<int64, map<string, int32>> ; integers map<int64, map<string, vector<int32>> ; integer lists to save on forms and globally. Each data type has own map. You can calculate the actual bytes but if you try to save memory somehow you may actually make the performance worse. You would need to have hundreds of thousands of entries saved before you think about optimization and the only optimization will be about how many function calls you make and not the memory amount that it occupies. If you mean to save in file (not to confuse with export) then I believe about a thousand integers saved on all different forms (worse case scenario) should be less than 50 KB.
gooser Posted March 22, 2014 Posted March 22, 2014 In calls themselves, like on stack? Should be few bytes in addition to papyrus function overhead, debug to see. If you mean data saved in memory then it's saved like this: map<int64, map<string, int32>> ; integers map<int64, map<string, vector<int32>> ; integer lists to save on forms and globally. Each data type has own map. You can calculate the actual bytes but if you try to save memory somehow you may actually make the performance worse. You would need to have hundreds of thousands of entries saved before you think about optimization and the only optimization will be about how many function calls you make and not the memory amount that it occupies. If you mean to save in file (not to confuse with export) then I believe about a thousand integers saved on all different forms (worse case scenario) should be less than 50 KB. No, not for memory savings. I just want to disprove that my use of PU/StorageUtil is causing save bloat. It may be hard to winnow out what all other mods and SL itself is storing against global or forms though. For property names I always prepend my Mod's name before the property name itself so if I could simply have an MCM function in my mod that runs a method against StorageUtil that simply prints to the log or console based on my mods name as a "namespace" ? Just thinking out loud here.
h38fh2mf Posted March 22, 2014 Posted March 22, 2014 You can iterate all data in storage util from all mods, check out the debug functions. With this data you can do what you want: write to file, log, MCM or console or whereever you wish. Example to iterate all global int values: int count = debug_GetIntKeysCount(none) while(count > 0) count -= 1 string key = debug_GetIntKey(none, count) int val = GetIntValue(none, key) Debug.Trace("Key: " + key + " = " + val) endwhile If you want to iterate forms too not just global then debug_GetIntObjectCount() for count and debug_GetIntObject(index) to get the object, then instead of none use that Form. Just printing out the count of saved values should be enough to see if there is bloat though. I'm almost certain this doesn't cause any noticable save file size change unless there's a mistake in someone's script and added like millions of values but you would also notice that the saving of game would take a long time. Edit: I could compile a debug version for you that writes to console the size of data section this mod uses when saving game.
gooser Posted March 22, 2014 Posted March 22, 2014 You can iterate all data in storage util from all mods, check out the debug functions. With this data you can do what you want: write to file, log, MCM or console or whereever you wish. Example to iterate all global int values: int count = debug_GetIntKeysCount(none) while(count > 0) count -= 1 string key = debug_GetIntKey(none, count) int val = GetIntValue(none, key) Debug.Trace("Key: " + key + " = " + val) endwhile If you want to iterate forms too not just global then debug_GetIntObjectCount() for count and debug_GetIntObject(index) to get the object, then instead of none use that Form. Just printing out the count of saved values should be enough to see if there is bloat though. I'm almost certain this doesn't cause any noticable save file size change unless there's a mistake in someone's script and added like millions of values but you would also notice that the saving of game would take a long time. Edit: I could compile a debug version for you that writes to console the size of data section this mod uses when saving game. Thanks, I guess I wasn't aware of the debug_ functions. I'm not presupposing PU/StorageUtil is at fault - i'm actually just trying to prove that my code isn't using PU/SU inappropriately or naively. Regarding your proposal - that would be helpful to me at least. Console and Papyrus log?
gooser Posted March 22, 2014 Posted March 22, 2014 I think having the specially instrumented .dll would be helpful as part of the development of a mod, as a great debug tool or even sanity check/smoke test. Also using the methods above would help me to insert some diagnostics inside my mod to be executed "in the field" so to speak. thanks!
h38fh2mf Posted March 22, 2014 Posted March 22, 2014 Ok done, made a new version out of it while I was doing things. Didn't test anything, I don't have time. If something is not working right let me know and I'll try to fix. This new version includes: Fix for JSON export (maybe) - Ashal List insert and sort for .. I forget but someone asked Debug mode for reporting StorageUtil section size in save games - gooser and perhaps helpful to many others as well Edit: StorageUtil.debug_SetDebugMode(true) ; enable debug mode until you exit game or set false Currently only thing it does is when you load or save a game it displays the size of StorageUtil section in save game in bytes on console. You may need to open console at least once first, someone said.
Heromaster Posted March 22, 2014 Posted March 22, 2014 Thank you for the update. Sort and Insert are exactly the methods I needed for my project. I will test it out.
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