Jump to content

Using actors as keys for StorageUtil


xkkmEl

Recommended Posts

I am encountering an issue with using actors as keys in StorageUtil.

Every once in a while, some actors disappear while they are in detached cells. Hroki does that all the time for example.

I have a list of actors on a global key, and an echo of that same list in a faction. I also have additional info stored using the actor as a key.

FormListCount( None, "mymod/npcs")
FormListGet( myactor, "mymod/outfit")

Sometimes, after loading a saved game, the entry in the StorageUtil global list comes back as None. If I go back to the actor in question, its objectref is still valid, using the same formid, and is still a member of the faction, but StorageUtil has forgotten all the data associated with that form id and nulled the corresponding list element in the global list.

I could work around it by converting my actors to a "modname/formid" form myself and not using them as keys, but it'd be a PITA! Am I doing something wrong? Is it a bug in StorageUtil? Is it a game limitation? If I switch to JContainer, will I have the same issue?

Link to comment
Share on other sites

  • 1 month later...

I find it surprising noone has anything to relate. It looks like a pretty standard use case for StorageUtil.

 

In any case, I'm slowly building up a JContainer-based alternative. So far, I find that:

  • both StorateUtil and JContainer return None when you try to access an unloaded actor;
  • StorageUtil writes None into the save file if the Actor is unloaded at the time the save file is created, but JContainer does not mandle these values.

So far I have only tested JArray's behavior against StorageUtil.FormListGet/Add. I will report back after testing JFormMap, which is the real test.

 

I am using the term "unloaded" in a loose sense. I have no actual evidence the behavior I'm seeing lines up with OnLoad/OnUnload events.

 

Link to comment
Share on other sites

Papyrus can only work with loaded objects. If the object is not persistent or not loaded in the current cell(s), it will always return a nil value. This is why you can find in the papyrus log plenty of cases where it assigns a "none object" to a variable and then proceeds to report that it cannot perform the intended actions.

 

I would surmise that any mod that extends the capabilities of papyrus would inherit the same restrictions.

Link to comment
Share on other sites

Thank you Ishara.

 

So my issue is related to persistence, and skse plugins that store objectrefs don't make them persistent. In that light, I would have to see StorageUtil's behavior as a bug.

 

Using JContrainer/StorageUtil then differs from script variables, which do make their values persistent while the assignment holds. Do papyrus arrays work like variables? Or can values stored in the array temporarily become None (from the script's point of view)?

 

If arrays make their value elements persistent, then there is an interesting trade off between stability of references (using arrays) and memory efficiency (using skse plugins like JContainer).

 

PS: I have not found how to turn on logging :-/ I followed instructions provided in https://www.nexusmods.com/skyrim/articles/368/ and inserted the 4-line block in "TSEV Skyrim LE\Skyrim\SkyrimPrefs.ini", "TSEV Skyrim LE\Skyrim\SkyrimCustom.ini", "TSEV Skyrim LE\Skyrim_default.ini" and "TSEV Skyrim LE\SkyrimCustom.ini". I still find no log files being created.

 

Link to comment
Share on other sites

Never modify the Skyrim_default.ini file. This file is used as the base INI when the game has to re-create your INI files. Verify your game with Steam and start once without mods to get your INI files back to normal.

 

Also, the INI files that can be edited should be located in "My Documents > My Games > Skyrim".

Link to comment
Share on other sites

  • 3 weeks later...

Thanx for the tip on ini files.

 

As I am continuing my experiments, I find that arrays don't work either, at least in keeping their elements persistent. Modding is definitely a frustrating experience. Koodos to all those brave coders who have managed such brilliant work.

 

Or am I mistaken and there is some other mechanism that fills my arrays with zero-refids as I am permuting elements? I am using an array as a stack, poping out elements into script variables, and pushing them back in a different order.

; declare stack (qvThread extends ObjectReference)
qvThread[] Property Threads Auto
int idleThreads = Threads.length

bool function ProcessStuff()
  ; pop a thread
  if !idleThreads
    return False
  endif
  idleThreads -= 1
  qvThread thread = Threads[idleThreads]

  thread.DoStuff()

  ; push the thread back
  Threads[idleThreads] = thread
  idleThreads += 1
  return True
endfunction

 

Link to comment
Share on other sites

  • Recently Browsing   0 members

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