Jump to content

[LE] Clearing out unused forms?


monsto

Recommended Posts

I have a mod that adds forms/references (mannequins) that have a few scripts attached to them. When deleting these via script, they are removed from play, but remain in memory and over time will seriously bloat the save file.

 

The main question is: How do I unload these forms/refs from memory?

 

Here's how I'm removing currently:

	elseif configChoice == 5
		; Pick Up
		self.removeAllItems(game.getPlayer() as objectReference, true, true)
		BUMPed.delete()  // pedestal form
		notify("Mannequin inventory moved to you.")		
		self.delete()  // self = mannequin form.
		return
	endif

Yet looking at the savefile (using the program Savetool) it looks like the form references and I think the scripts are not removed at all because they stay in the save. The save file has 15000 forms on the cell that I'm using, while skyrim.esm shows 8000.

 

 

https://i.imgur.com/ZgApc8o.png

 

https://i.imgur.com/Yb2GpR9.png

 

 

According to https://www.creationkit.com/index.php?title=Delete_-_ObjectReference

 

Remember that Delete() only flags an object for deletion; the actual deletion takes place later. Per this USKP discussion (a dead link), if a variable still points to the object, the object will remain temporarily persistent; the deletion won't occur until that variable is cleared (i.e. by setting it to None).

 

So the questions:

  • how do I go about using a more efficient way to delete things than simply using the `delete` method?
  • If I need to set some variable to `None`, which should I set?
  • According to the above snippet, would it be valid to set `self = None`?
  • `BUMPed` variable refers to a property. would it be valid to set THAT to `None`?
  • Is there a better save editor that can show which items have been `marked for delete` but are still present?

 

I'm asking these questions here instead of just doing it because it takes effin forever to start CK and try these things.

Edited by monsto
Link to comment
Share on other sites

The actual 'Delete' happens when you leave the cell in which the function was called, to be more precise:

- When you detach from the cell and when that detached cell gets unloaded, which it may not happen immidiately on Cell Detach, but when enough cells / references has occupied that particular part of the memory the cell in which the deletion took place.


Setting a reference to "None" must be called either by the script that is manipulating that specific reference, or if it is used by two scripts then it should be set to "None" by both, so that the script that will do the deletion can actually delete it.

For example:

Script A = Activator A

EVENT SomeEvent......

MyObject.Enable()

MyObject = NONE

ENDEVENT


Script B = Activator B

EVENT SomeEvent......

MyObject.Disable()

MyObject.Delete()

MyObject = NONE

ENDEVENT


For a more efficient way to delete things, i don't know if there are any, cause from what i know there is only 1 delete function.

Link to comment
Share on other sites

 

The actual 'Delete' happens when you leave the cell in which the function was called, to be more precise:
- When you detach from the cell and when that detached cell gets unloaded, which it may not happen immidiately on Cell Detach, but when enough cells / references has occupied that particular part of the memory the cell in which the deletion took place.
Setting a reference to "None" must be called either by the script that is manipulating that specific reference, or if it is used by two scripts then it should be set to "None" by both, so that the script that will do the deletion can actually delete it.
For example:
Script A = Activator A
EVENT SomeEvent......
MyObject.Enable()
MyObject = NONE
ENDEVENT
Script B = Activator B
EVENT SomeEvent......
MyObject.Disable()
MyObject.Delete()
MyObject = NONE
ENDEVENT
For a more efficient way to delete things, i don't know if there are any, cause from what i know there is only 1 delete function.

 

 

 

Thanks for the quick reply!

 

To directly address the things you've said...

 

I've "left" the cell many times, unless it's only triggered on an in-game cell change, such as using a door. Occassionally I will `COC` to another cell, use console `PCB` (purge cell buffers) which resets a number of things in cells you're not in, and then `COC` back to the origin cell. Does that not count for what you're tlaking about?

 

The pseudo-code blocks you wrote is basically what I was asking if it would work, so I'm guessing it will. Will that only work on "leaving the cell" also, or would it work to immediately unload/delete the refs/forms?

 

Thanks for your advice.

Link to comment
Share on other sites

The problem with "self" is, you cannot do that

self = None          ; this is not a regular papyrus code !!!

The mannequin object and the attached script is not removed from memory because it holds a persistent object (the pedestal) like your code. Delete() marks the object for deletion only. If a variable or property still points to an objectReference or actor, it will remain temporarily persistent. The deletion won't occur until it's cleared (i.e. by setting it to None).

 

You asked: "`BUMPed` variable refers to a property. would it be valid to set THAT to `None`?"

    elseif configChoice == 5
        ; Pick Up
        self.removeAllItems(game.getPlayer() as objectReference, true, true)
        BUMPed.Disable()                                   ; 1a optional, but should be used almost before delete() function
;;;     BUMPed.DisableNoWait()                             ; 1b optional alternative
        BUMPed.delete() // pedestal form                   ; 2
        BUMPed = None                                      ; 3 this was missing in your code !
        notify("Mannequin inventory moved to you.")        
        self.delete() // self = mannequin form.
        return
    endif

I hope you understand persistence of objects much better. Keep in mind every actor (stored to a property or variable) is also affected by this persistence.

Edited by ReDragon2013
Link to comment
Share on other sites

I don't know how 'Delete' behaves with 'COC', what i posted was referring to 'cell attach' and 'cell detach' IN-GAME.

Deletion takes place when the cell that the function was called has been UNLOAD FROM MEMORY, after this happens your deletion will be done in your next 'save'.


'COC' it's ok to check the building progress of your cell, but it should be avoided for testing things like scripts, packages, quests.... etc.

For example:

Packages will always malfunction when you 'COC', and especially if you are not just testing 1 npc but you have a bunch of them.


There are a bunch of things that will go wrong with 'COC' when testing, haven't you wonder why when you 'COC' to a cell it take way less time than from using a 'Load Door' ?.


Have a nice weekend.

Link to comment
Share on other sites

  • Recently Browsing   0 members

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