Tutorial: Array Variables 1

From GECK

Array variables refer to arrays. Arrays are lists of items - imagine them as 2-column tables that you'd use in Word or some such. See for instance these examples given on the Oblivion wiki.

Arrays are kept by NVSE for you, and whichever ones exist when a savegame is made will be stored in the .nvse file that corresponds to your save. They're the same as string vars that way.

Unlike with string vars, NVSE automatically cleans up redundant array variables when they are no longer referenced by an active script or another array. Array variables, like other types, will exist permanently if stored in a quest, but otherwise (Object, Spell and UDF scripts) are deleted when a script ends.

Types of Arrays, Keys and Values

There are different types of arrays we can use. The first, which we'll call a 'regular' array (array-type array, 'array' array and list array are also used) look and function a lot like vanilla formlists:

Example form list:
NonAlcholicDrinks:
0    MS05NukaColaQstm
1    MS05IceNukaCola
2    NukaCola
3    WaterUnpurified
4    WaterPurified

Like formlists, regular arrays are indexed by positive consecutive integer numbers running from 0 to (Total Size - 1). Those index numbers are called keys.

The main difference, and the main advantage that all array types have, is that what's associated with those keys - the values - can be anything: not just forms and refs, but also numbers, strings and even other arrays. (When we talk about a key-value combination, we use the term "element".)

Example Regular Array:
SomeArray:
0    NukaCola                          ; form
1    3                                 ; number
2    "You can't beat the real thing"   ; string
3    RecipesInvolvingNukaColaArray     ; array

As with formlists, the indexes will always be consecutive; if you remove any element, the others with a higher index will move up - index gaps are not allowed, and neither are floats or negative numbers.

This is a limitation sometimes, so for a different kind of numbered indexing, we have maps, which are arrays that can take any number as key, and allow for gaps (they have to because they allow decimals). So we can convert the "agenda" example from the CS wiki to this map, with the time converted to decimal and the activities held in strings:

Example Map:
8.5    "Sign in, coffee"  
9      "Introduction"
9.5    "Presentation A"
10.5   "Coffee break"
11     "Presentation B"

; Note: arrays don't store the quotation marks, I just put them there to remind you they're strings

Here's another one that stores some exterior cells as values with their X coordinates as keys, some of them are negative:

Another Map:
-21    MojaveOutpost
-9     MojaveDriveIn
7      188TradingPost    
12     BoulderCity
17     BitterSprings

Finally, sometimes numbers of whichever kind just don't cut it, so we have stringmaps, which take strings as keys:

Example StringMap:
"Name"                   "Prudencia"
"Age"                    27
"Body"                   "T6M"
"Profession"             "Test character"
"Time played (hrs)"      106.5
"Cells visited"          CellsVisitedArray

Declaring and Initializing Arrays

You declare an array var of any type, just like any other variable:

array_var SomeArrayVarName
int SomeIntName
ref SomeRefName

And just like string vars, you can't do anything with them until they're initialized and refer to an actual array in NVSE. You may initialize arrays by either:

  • Explicitly constructing them, by letting them to the Ar_Construct function, with the array type as parameter, if you want a new empty array:
        let somearrayvarname := ar_construct array
        let somearrayvarname := ar_construct map
        let somearrayvarname := ar_construct stringmap

The type 'array', 'map' and 'stringmap' are string parameters to the Ar_Construct function, just like 'Health' is to GetAV in GetAV Health. Especially if you toggle the Script Compiler Override on, you will see a warning about such strings, in which GeckPU will basically say 'I'm assuming these are strings but you can still change your mind so I'm not compiling yet'. If you ignore that warning and compile anyway, things will work fine in-game. Or you can enclose them in "" speech marks to prevent the warning.


  • By letting them to another array var, which makes both array vars refer to the same array:
let somearrayvar2 := somearrayvar1
let somearrayvar1[2] := something  
;    --> somearrayvar2 now also has the new element, because it's the same array
     If 2 array vars refer to the same array like that, you can break one free by ar_constructing it, which makes it point to a new, empty array:

let somearrayvar2 := ar_construct array       --> somearrayvar2 now refers to brand new, empty array         

If you want to genuinely duplicate an array, use Ar_Copy or Ar_DeepCopy.


array_var Beatles
array_var MagicNumberToString
array_var StringToMagicNumber

let Beatles := Ar_List JohnREF, PaulREF, GeorgeREF, RingoREF ; * new regular array

let MagicNumberToStrong := Ar_Map 2::"Upper body", 5::"Weapon", 10::"Hat" ; * new map

let StringToMagicNumber := Ar_Map "Upper body"::2, "Weapon"::5, "Hat"::10 ; * new stringmap


You can also uninitialize an array var by letting it to Ar_Null:

let somearrayvar := ar_Null

From that point on it's pretty much like a null ref var. If you want to know if an array is initialized or not before you try and do something with it, you can just check it as a bool, or use LogicalNot (!) to check its being uninitialized:

if somearrayvar
   ; arrayvar is initialized
else
   ; uninitialized
endif

if eval !(somearrayvar)
   ; array var is not initialized
endif

If you already know it's initialized, there's no point.


Part 2: Retrieving and Storing Elements


External Links

Personal tools