Jump to content

NVSE Arrays problem


miguick

Recommended Posts

SOLVED. Always be wary of confusing base objects and references in your scripts, people. It can have fatal consequences.

 

 

I'm hoping someone familiar with how NVSE handles arrays in scripts can answer this.

 

I've recently noticed a disturbing trend in my savegames regarding arrays, in that they don't seem to be getting reused as I'd expect. I'll try to explain as best as I can...

 

My understanding was that when a script creates an array, as per the usual way of assigning an array_var to some command that returns an array:

array_var aSomeArray
...
let aSomeArray := ar_Construct "Array"
...
let aSomeArray := ar_Null
...
ForEach aSomeArray <- GetActorsByProcessingLevel 0
...
loop
...
(etc)

Internally, this "aSomeArray" variable holds the array identified by an integer, which denotes the order of creation of that array relative to all the others still in the savegame. So, for example, using sqv <quest from ID> in the console, which dumps the variables its script contains and their values, would show something like "aSomeArray = 13" or whatever. You can then use "ar_DumpID 13" to see what's stored inside the "aSomeArray" variable

AFAIK, this "aSomeArray" would then remain as such until the script either destroys it, by assigning it to ar_Null, or assigns it to some other array operation. When that happens, if the array nº 13 or whichever that the variable pointed to has no other variable referencing it left, it would be destroyed, and that integer "13" would be freed up for the taking by another array assignation in other scripts. In the case of a ForEach loop as shown before, I was also under the impression that it worked as a temporary array and when the loop ended it was automatically destroyed.

 

However, I'm seeing my scripts report arrays numbering as high as 21000. Yes, twenty one thousand, and my nvse cosaves are now 2.5 MB large, which leads me to believe that arrays are not getting destroyed and recycled at all on my end, just piling up endlessly. The various ForEach loops in my various mods' scripts would be the main cuplrits if they are creating a new array at each step of their iteration and failing to remove them afterwards. But if it's as it sounds, then I'm seeing a critical error in NVSE itself which allows arrays to remain in the cosave with no variables left pointing at them, instead of destroying them as expected, which means even using ar_Null is not doing anything.

 

I'm pretty certain this does not happen in Oblivion when using arrays through OBSE. Hell, I'll even comment on something they do differently which called my attention. See this part?:

ForEach aSomeArray <- GetActorsByProcessingLevel 0
...
loop

In Oblivion, this (the equivalent of) works just fine. If there are no actors in high processing that GetActorsByProcessingLevel 0 can gather, the loop simply doesn't execute. But I've noticed this is not the case in FNV. If that happens, the script halts throwing an error inside the loop due to null assignations. So you have to proof them beforehand, for example:

let aSomeArray := GetActorsByProcessingLevel 0
if eval (ar_Size aSomeArray) < 1
;don't enter the loop
else
   ForEach aSomeArray <- GetActorsByProcessingLevel 0
   ...
   loop
endif

Does this have to with the problem at hand, somehow?

 

 

Maybe it's not so critical, I have a lot of hours lodged in a savegame 16 MB large and so far it loads and saves smoothly. But I can't help feeling something is amiss in the NVSE code itself which shouldn't be, and I feel trying to jump through hoops in the scripts can't fix it. Not to mention it's just a lot of scripts from a lot of different mods which are showing this problem most likely by now.

 

Well, this is all probably too technical and perhaps people who actually know what could be up are unlikely to frequent this forum anyways. At least it'd serve me to write it down for reference.

Link to comment
Share on other sites

This is interesting. For what it's worth, I haven't run into any problems with arrays halting the script as you describe, or the numbers getting that high. I'll pay a bit more attention to it and dump some more and let you know if I find anything interesting. It's absolutely possible that I've missed it, but none of my scripts have caused problems when they tried to loop and nothing was available. If you meant just that particular function, I do have experience with it but not a lot and I don't remember anything noteworthy.

 

My largest game save is 13MB, which is close to 16. Never caused any problems.

 

I'm interested to know what you learn about this if you do find any information. I'm inclined to think it isn't a huge problem, but I'm still interested to know what you find.

Link to comment
Share on other sites

Oh my god... after some array dumping in the console, I'm seeing that pretty much all of them from a certain number onward belong to a mod of mine I'm developing, always returning the same key-value pair. Well, I'll update when I find what I screwed up in it, but it looks like the issue I described doesn't really happen unless the modder (me) screws up big time. I've even tested a bit and the recycling behavior I described works as expected.

Worst comes to worst and I don't find the issue, I can simply do a clean save from that mod to deflate the nvse cosave big time, I hope.

Link to comment
Share on other sites

SOLVED

 

I was using a loop like:

 

array_var aIter

ref rActor

...

ForEach aIter <- GetListForms flstEDEs

let rActor := *aIter

if rActor.GetPlayerTeammate

...

endif

loop

 

The flstEDEs is holding BASE objects, NOT placed references. When trying to run GetPlayerTeammate on the retrieved ref variable as if it were a placed reference, the script just gave up, leaving the aIter assignation floating behind.

 

Unfortunately, those leftover arrays are not in the mod, but baked in the savegame now, ar_DumpID reports the owning mod is "FF", which is the savegame's index. Not even a clean save helps, so I have to live with arrays up to nº 20940 as leftovers bloating the nvse cosave. Oh well. At least it can't get any worse now.

 

Mixing up references and base objects, one of the most common and lethal mistakes in gamebryo scripting.

Link to comment
Share on other sites

  • 8 months later...

Hi.

 

I was also having trouble with an array issue in my Oblivion save file; the crafting feature of Maskar's Oblivion Overhaul relies on arrays to store ''recipies'' for the player to craft.

After some hours of playtime, I've added a few script-heavy mods (like AoG & Detect Item), and I noticed later that crafting had stopped working properly. The debug messages blamed the arrays, which were being fed with wrong variable types, among other things.

 

After reading your posts, I've thought of erasing my obse cosave.

After all my other failed attempts, this one has remarkably worked!

 

I'd feared the game would crash on load, but it seems normal so far. I'll keep an eye out for any problems.

 

If any of you have a history of trying this method, any feedback would be greatly appreciated.

 

Thanks for the insight, and have a good day!

Link to comment
Share on other sites

Appreciate you passing along that information. One would suspect the deletion of that file might result in the loss of some items or information used by other "script extender" mods. But the trade-off might be worth it, and only experimentation will tell in each case. Having an option is always useful.

 

Added as a warning to the 'TIP: Best Practice - Type prefixes for Variables' entry for "a - arrays" under the "Scripting" section of the wiki "Getting started creating mods using GECK" article.

 

-Dubious-

Link to comment
Share on other sites

And now I come with sad news:

 

The game froze when I entered a cell where MOO attempts to update lists, which I assume no longer exist.

Still haven't checked the log, but I believe that mod is the main culprit. I still want to see if the game is playable with other mod lists.

 

Sorry about the false alarm.

 

Edit: The log is currently at 87 Megabytes, but with the same script error coming from a different mod (Kuertee's Cleanup). I'll try removing that one and see what happens.

 

EDIT 2: Good news once more; it worked!

Edited by LiLuYoBoNi
Link to comment
Share on other sites

  • Recently Browsing   0 members

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