-
Notifications
You must be signed in to change notification settings - Fork 8
Understanding Forms, Object References, Reference Aliases, and Persistence
A Form
is a base type. Every single object that you see in the Object Window is a Form
, including actors, spells, keywords, etc. In the game, these Form
s are instantiated into ObjectReference
s, which are subclasses of Form
. An ObjectReference
is simply a Form
that has been loaded into memory. Because an ObjectReference
exists only in memory, it is temporary. A specific ObjectReference
and all of its details (AI packages, script properties, etc.) are not stored in a save file. Instead, nothing but the base Form
of each temporary ObjectReference
is stored in the save file, and then when the game is loaded, a new ObjectReference
is created for each mention of each Form
in the save file. That new ObjectReference
will start off with a clean slate, without any of the modifications that may have taken place before the game was saved/loaded. This is great for memory management. Nothing sticks in memory too long. However, it's bad if you need to uniquely identify objects so that you can store information specific to each object and maintain that information between saves. For this, you'll need to make the ObjectReference
persistent.
An object can be manipulated only while it's in memory. Objects are loaded into memory selectively for performance. It would be ridiculous if the entire game (All locations, dungeons, players, items, spells, visual effects, etc.) were in memory at the same time. No video game can operate like that. Most objects in the game are non-persistent. That is, objects are loaded into memory when you enter the cell that contains them. They are thrown out of memory when they are consumed, deleted, or the player moves out of that cell. A persistent object, on the other hand, will be thrown out of memory only when it is deleted or consumed. It will remain in memory even when the player moves to a different cell that doesn't contain that object.
There are two main ways to make an ObjectReference
persistent:
- Create the
ObjectReference
using thePlaceAtMe
function and pass in true for its last parameter. This will return anObjectReference
just like any other, but it will be forced to be persistent. - Fill a
ReferenceAlias
with theObjectReference
you want to become persistent. Think of aReferenceAlias
like a blanket. AReferenceAlias
is attached on top of an existingObjectReference
and it allows you to add scripts, AI packages, keywords, and other objects onto thatObjectReference
. It's like editing the values of an object at runtime.ReferenceAlias
es can be cleared, thus disassociating them with theirObjectReference
. This removes everything that was added by theReferenceAlias
and leaves the originalObjectReference
untouched. While anObjectReference
is filled in aReferenceAlias
, thatObjectReference
is persistent.ReferenceAliases
are created by filling Quest Aliases. Learn how to fill Quest Alises by learning more about the Story Manager. See also Quests. A filledReferenceAlias
will remain persistent for as long as itsQuest
is running.
A persistent ObjectReference
will have a unique ID that you can access with myObjectReference.GetFormID()
. GetFormID
is a function of the Form
script, but when called on an ObjectReference
, it returns the ID of that ObjectReference
rather than its base form's ID.
Once you've made an ObjectReference
persistent in one of the above two ways, you can rely on it being in memory, having the same unique ID, and maintaining all of its state information until you explicitly destroy it:
ObjectReference myObjectReference ; Some ObjectRefrence from anywhere
myObjectReference.Delete()
myObjectReference = None
- When an item is destroyed, such as when a soul gem is removed from the player's inventory as its used up at the enchanting workbench, there will be an
OnItemRemoved
event sent to thePlayer
. AlthoughObjectReference akItemReference
is one of the parameters ofOnItemRemoved
, it was alwaysNone
in my tests with destroying soul gems at the enchanting table. Although it will always pass in the base form that was removed, there were times when it told me the base form that was removed, but it didn't tell me exactly whichObjectReference
was removed. This makes it less useful for testing when a persistent object you're tracking is destroyed.