Associating data with a reference

From the Fallout3 GECK Wiki
Revision as of 14:04, 30 August 2014 by imported>Odessa (created article)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

There are many situations when a modder may wish to associate arbitrary data with a reference. This article details several possibilities, with their benefits and shortcomings to achieve this.

Object Scripts

The approach used in the vanilla game is to attach on object script to a reference, with variables included in. This technique works well for one's mod added NPCS, but is a poor choice for vanilla ones.

  • All variables must be predefined, although if one of them is an array it is easy to add arbitrary data.
  • The script can be attached in the GECK, or using SetScript to add or change the existing script. However, using this approach to modify vanilla references it is risky for compatibility with other mods and the vanilla game.
  • In the vanilla game variables can only be accessed by direct reference, not via a Ref Variable. However, the NVSE functions such as GetVariable and SetVariable allow this. These commands also allow two mods to access the same data without one being the master to the other.
SomeActor.SetVariable "SomeVarName", 1234
let MyData := SomeActor.GetVariable "SomeVarName"

Actor Values

There are many actor values, including the unused Variable01-Variable10, which can be modified using for example, ForceActorValue

  • These can only store numbers, although a single number could be used as the key to map array attached to a quest script, to facilitate storing any arbitrary data. By using BuildRef or perhaps referencing array IDs it is possible for two mods to share this data without one being an official master to the other.
  • Since actor values exist in the vanilla game are are accessible to all modders, but there is no guarantee another mod will not overwrite your data with something irrelevant.
let MyData := MyArray[(SomeActor.GetAV Variable01)]

Using the reference as an array key

Map and string map arrays allow either numeric or string keys to retrieve arbitrary data, but it is not possible to directly use a reference as a key. A number of workarounds exist however.

  • You can use ToString($) to obtain the name of a reference as a string. However, all references with identical names will share the same data.
  • You can use GetFormIDString to return the unique form id as a string for any reference. However, form ids may change on game load with load order. Hence, if the data must be persistent some additional scripting is required.
  • You can also store the reference as an entry rather than key in an array, and use some search technique to find it. Beware that references are removed if their parent mod is unloaded, so no static order to array data can be assumed.
let MyKey := $SomeActor ; or:
let MyKey := GetFormIDString SomeActor

let MyData := MyArray[MyKey]

Using Tokens

NVSE 3 added tokens which individually are capable of storing one number and one form.

  • They can not store strings or arrays, although the number could be an external map array key.
  • Each token can only store two values, and each token in an inventory must be unique. Therefore this solution is awkward for large amounts of data.
  • It is awkward for two mods to reference the same data without needing to be a master.
SomeActor.AddItem MyToken, 1
SomeActor.SetTokenValue MyToken, 1234
let MyData := SomeActor.GetTokenValue MyToken

NX Variables

Added by the NX plugin for NVSE, and are probably the most powerful way to associate data with a reference. Of course, the plugin is then required by all users.

  • Any number of persistent variables of either numeric, form or string may be stored on any reference.
  • NX variables are fully accessible to all mods without needing masters. If a variable does not exist, the value 0 is simply returned.
  • Many functions exist to easily manipulate the variables.
SomeActor.NX_SetEVFl "MyMod:SomeVarName", 1234
let MyData := SomeActor.NX_GetEVFl "SomeOtherMod:SomeVarName"