This framework makes a few assumptions about its use (because it was built to solve my own problem), mainly that it was designed to manage a collection of very unique things, and not lots of similar things. Specifically, ObjectReferences.
Throughout the code, you will see iX and iY used as input parameters. These refer to the indicies in the first (X) and second (Y) dimensions of the logical array, respectively. iXWidth and iYHeight refer to the size of a range starting at some coordinate iX, iY in the array. iX and iY are always the lowest indicies of the range when used in this way. iXWidth and iYHeight refer to the total size of the range. For instance, a range spanning index 0 to 4 would have an iXWidth or iYHeight of 5, not 4.
There are a lot of different applications for something like this. Perhaps someone will write an in-game board game with it or something.
Preparation
In order to use this in your own scripts, you will need to do a bit of manual work. This is why it's "fake".
In your script, in the "empty" (global) scope, define the following:
int iXSize = 16 ;2D Array size in the 1st dimension (max size: n)int iYSize = 16 ;2D Array size in the 2nd dimension (max size: 128)This defines your logical 2D array's dimensions. The 1st dimension (x) has no defined upper limit. The 2nd dimension has the traditional restriction of 128 elements.
After that, in the global scope, define the arrays to be used by the framework. Here (as noted by the iXSize and iYSize above), I am creating a 16x16 2D array. This requires that I create 16 arrays. In these examples (because it happens to be what I needed for the project I'm working on), the arrays are of type ObjectReference. They can be made any type you like, but would require some surgery in other parts of the framework to support it.
;2D Array Declarations;Quantity specified MUST match iXSizeObjectReference[] YNodes0ObjectReference[] YNodes1ObjectReference[] YNodes2ObjectReference[] YNodes3ObjectReference[] YNodes4ObjectReference[] YNodes5ObjectReference[] YNodes6ObjectReference[] YNodes7ObjectReference[] YNodes8ObjectReference[] YNodes9ObjectReference[] YNodes10ObjectReference[] YNodes11ObjectReference[] YNodes12ObjectReference[] YNodes13ObjectReference[] YNodes14ObjectReference[] YNodes15Next we need to write a function that will encapsulate instantiating our arrays. I wish there were a more automatic way of doing this, but Papyrus demands that the array size be known at compile-time in the form of an integer literal instead of a variable.
function Create_2D()
Creates the 2D array.
Spoiler
function Create_2D() ;-----------\ ;Description \ ;---------------------------------------------------------------- ;Creates the 2D array. ;-------------\ ;Return Values \ ;---------------------------------------------------------------- ; None. YNodes0 = new ObjectReference[16] ;Specify integer literal here, must match iYSize YNodes1 = new ObjectReference[16] YNodes2 = new ObjectReference[16] YNodes3 = new ObjectReference[16] YNodes4 = new ObjectReference[16] YNodes5 = new ObjectReference[16] YNodes6 = new ObjectReference[16] YNodes7 = new ObjectReference[16] YNodes8 = new ObjectReference[16] YNodes9 = new ObjectReference[16] YNodes10 = new ObjectReference[16] YNodes11 = new ObjectReference[16] YNodes12 = new ObjectReference[16] YNodes13 = new ObjectReference[16] YNodes14 = new ObjectReference[16] YNodes15 = new ObjectReference[16]endFunction
Now that that's out of the way, we have one last bit of boilerplate to do, which is to map our arrays to numerical IDs in the GetArrayFromID() function.
ObjectReference[] function GetArrayFromID(int iID)
Maps an ID to an array. These arrays MUST be listed manually by the user in the code below in order for the rest of the framework to function!
Spoiler
ObjectReference[] function GetArrayFromID(int iID) ;-----------\ ;Description \ ;---------------------------------------------------------------- ;Maps an ID to an array. ;These arrays MUST be listed manually by the user in the code ;below in order for the rest of the framework to function! ;-------------\ ;Return Values \ ;---------------------------------------------------------------- ; None. if iID == 0 return YNodes0 elseif iID == 1 return YNodes1 elseif iID == 2 return YNodes2 elseif iID == 3 return YNodes3 elseif iID == 4 return YNodes4 elseif iID == 5 return YNodes5 elseif iID == 6 return YNodes6 elseif iID == 7 return YNodes7 elseif iID == 8 return YNodes8 elseif iID == 9 return YNodes9 elseif iID == 10 return YNodes10 elseif iID == 11 return YNodes11 elseif iID == 12 return YNodes12 elseif iID == 13 return YNodes13 elseif iID == 14 return YNodes14 elseif iID == 15 return YNodes15 endifendFunction
As you can see, we just have to take the arrays we defined earlier and map them sequentially to a numerical ID starting at 0.
Somewhere in your code before you attempt to make use of your 2D array functions, you will need to call your instantiation function in order to actually instantiate the arrays you defined:
Create_2D()That's it! Now that that's out of the way, you're able to use all of the rest of the functions in this framework. Have fun, and I hope someone finds them useful.

These haven't been exhaustively tested yet, but I'm (fairly sure) that everything works as intended. If you spot something I messed up, please point it out so I can update this post. I will probably also be making slight tweaks to this over time as this display case project matures.
int[] function Find_2D(ObjectReference akObject)
Finds the first occurrence of akObject in the 2D array. Returns an int[2] with the indicies of the object found.
Spoiler
int[] function Find_2D(ObjectReference akObject) ;-----------\ ;Description \ ;---------------------------------------------------------------- ;Finds the first occurrence of akObject in the 2D array. ;Returns an int[2] with the indicies of the object found. ;-------------\ ;Return Values \ ;---------------------------------------------------------------- ; int[0] = Index of akObject in 1st dimension. ; -1 if not found. ; int[1] = Index of akObject in 2nd dimension. ; -1 if not found. int[] iReturn = new int[2] int iX = 0 while iX < iXSize int iY = GetArrayFromID(iX).Find(akObject) if iY >= 0 iReturn[0] = iX iReturn[1] = iY return iReturn endif iX += 1 endWhile iReturn[0] = -1 iReturn[1] = -1 return iReturnendFunction
ObjectReference function Read_2D(int iX, int iY)
Returns the value at the given indicies.
Spoiler
ObjectReference function Read_2D(int iX, int iY) ;-----------\ ;Description \ ;---------------------------------------------------------------- ;Returns the value at the given indicies. ;-------------\ ;Return Values \ ;---------------------------------------------------------------- ; ObjectReference = The ObjectReference found. ; Returns None if not found. return GetArrayFromID(iX)[iY]endFunction
function Write_2D(int iX, int iY, ObjectReference akObject)
Writes akObject to the specified indicies.
Spoiler
function Write_2D(int iX, int iY, ObjectReference akObject) ;-----------\ ;Description \ ;---------------------------------------------------------------- ;Writes akObject to the specified indicies. ;-------------\ ;Return Values \ ;---------------------------------------------------------------- ; None. GetArrayFromID(iX)[iY] = akObjectendFunction
bool function IsEmpty_2D(int iX, int iY)
Checks whether or not the field at the given indicies is None.
Spoiler
bool function IsEmpty_2D(int iX, int iY) ;-----------\ ;Description \ ;---------------------------------------------------------------- ;Checks whether or not the field at the given indicies is None. ;-------------\ ;Return Values \ ;---------------------------------------------------------------- ; true = The field at the indicies is None. ; false = The field at the indicies is not None. if GetArrayFromID(iX)[iY] == none return true else return false endifendFunction
function Clear_2D(int iX, int iY)
Clears (sets to None) the indicies specified in the 2D array.
Spoiler
function Clear_2D(int iX, int iY) ;-----------\ ;Description \ ;---------------------------------------------------------------- ;Clears (sets to None) the indicies specified in the 2D array. ;-------------\ ;Return Values \ ;---------------------------------------------------------------- ; None. GetArrayFromID(iX)[iY] = NoneendFunction
int[] function FindRange_2D(ObjectReference akObject)
Exhaustively searches the 2D array for akObject, and attempts to return the parameters where this ObjectReference is found contiguously in the 2D array.
If the 2D array is populated with non-contiguous instances of akObject, this function will not return valid results, and will instead return the parameters of the lowest and highest indicies found that contain akObject.
Spoiler
int[] function FindRange_2D(ObjectReference akObject) ;-----------\ ;Description \ ;---------------------------------------------------------------- ;Exhaustively searches the 2D array for akObject, and attempts ;to return the parameters where this ObjectReference is found ;contiguously in the 2D array. ; ;If the 2D array is populated with non-contiguous instances of ;akObject, this function will not return valid results, and ;will instead return the parameters of the lowest and highest ;indicies found that contain akObject. ;-------------\ ;Return Values \ ;---------------------------------------------------------------- ; int[0] = Starting (lowest) index found in 1st dimension. ; -1 if not found. ; int[1] = Starting (lowest) index found in 2nd dimension. ; -1 if not found. ; int[2] = Width of range found in the 1st dimension. ; -1 if either of the first two return values are -1. ; int[3] = Height of range found in the 2nd dimension. ; -1 if either of the first two return values are -1. int[] iReturn = new int[4] int iXStart = -1 int iYStart = -1 int iXWidth = -1 int iYHeight = -1 int iXLargestIndex = -1 int iYLargestIndex = -1 int xD = 0 while xD < iXSize int yD = 0 while yD < iYSize if GetArrayFromID(xD)[yD] != None ObjectReference r = GetArrayFromID(xD)[yD] if r == akObject if iXStart == -1 iXStart = xD iXLargestIndex = xD else iXLargestIndex = xD endif if iYStart == -1 iYStart = yD iYLargestIndex = yD else iYLargestIndex = yD endif endif endif yD += 1 endWhile xD += 1 endWhile if iXStart != -1 && iYStart != -1 iXWidth = (iXLargestIndex - iXStart) + 1 iYHeight = (iYLargestIndex - iYStart) + 1 endif iReturn[0] = iXStart iReturn[1] = iYStart iReturn[2] = iXWidth iReturn[3] = iYHeight return iReturnendFunction
function WriteRange_2D(int iX, int iY, int iXWidth, int iYHeight,ObjectReference akObject)
Writes akObject to the indicies specified by the starting (lowest) indicies iX and iY, over the range iXWidth (1st dimension) and iYHeight (2nd dimension).
Spoiler
function WriteRange_2D(int iX, int iY, int iXWidth, int iYHeight, ObjectReference akObject) ;-----------\ ;Description \ ;---------------------------------------------------------------- ;Writes akObject to the indicies specified by the starting (lowest) ;indicies iX and iY, over the range iXWidth (1st dimension) and ;iYHeight (2nd dimension). ;-------------\ ;Return Values \ ;---------------------------------------------------------------- ; None. int xD = iX while xD < (iXWidth - 1) int yD = iY while yD < (iYHeight - 1) GetArrayFromID(xD)[yD] = akObject yD += 1 endWhile xD += 1 endWhileendFunction
bool function IsEmptyRange_2D(int iX, int iY, int iXWidth, int iYHeight)
Checks whether or not the indicies specified by the starting (lowest) indicies iX and iY, over the range iXWidth (1st dimension) and iYHeight (2nd dimension) contain all None values.
Spoiler
bool function IsEmptyRange_2D(int iX, int iY, int iXWidth, int iYHeight) ;-----------\ ;Description \ ;---------------------------------------------------------------- ;Checks whether or not the indicies specified by the starting (lowest) ;indicies iX and iY, over the range iXWidth (1st dimension) and ;iYHeight (2nd dimension) contain all None values. ;-------------\ ;Return Values \ ;---------------------------------------------------------------- ; true = The entire range of indicies is None. ; false = One or more indicies in the range is not None. int xD = iX while xD < (iXWidth - 1) int yD = iY while yD < (iYHeight - 1) if GetArrayFromID(xD)[yD] != None return false endif yD += 1 endWhile xD += 1 endWhile return trueendFunction
function ClearRange_2D(int iX, int iY, int iXWidth, int iYHeight)
Clears (sets to None) the indicies specified by the starting (lowest) indicies iX and iY, over the range iXWidth (1st dimension) and iYHeight (2nd dimension).
Spoiler
function ClearRange_2D(int iX, int iY, int iXWidth, int iYHeight) ;-----------\ ;Description \ ;---------------------------------------------------------------- ;Clears (sets to None) the indicies specified by the starting (lowest) ;indicies iX and iY, over the range iXWidth (1st dimension) and ;iYHeight (2nd dimension). ;-------------\ ;Return Values \ ;---------------------------------------------------------------- ; None. int xD = iX while xD < (iXWidth - 1) int yD = iY while yD < (iYHeight - 1) GetArrayFromID(xD)[yD] = None yD += 1 endWhile xD += 1 endWhileendFunction
function ClearAll_2D()
Clears (sets to None) the entire 2D array.
Spoiler
function ClearAll_2D() ;-----------\ ;Description \ ;---------------------------------------------------------------- ;Clears (sets to None) the entire 2D array. ;-------------\ ;Return Values \ ;---------------------------------------------------------------- ; None. int xD = 0 while xD < iXSize int yD = 0 while yD < iYSize GetArrayFromID(xD)[yD] = None yD += 1 endWhile xD += 1 endWhileendFunction
function ClearAllReferenceOfType_2D(ObjectReference akObject)
Clears (sets to None) the indicies found in the 2D array that contain akObject.
Spoiler
function ClearAllReferenceOfType_2D(ObjectReference akObject) ;-----------\ ;Description \ ;---------------------------------------------------------------- ;Clears (sets to None) the indicies found in the 2D array ;that contain akObject. ;-------------\ ;Return Values \ ;---------------------------------------------------------------- ; None. int xD = 0 while xD < iXSize int yD = 0 while yD < iYSize if GetArrayFromID(xD)[yD] == akObject GetArrayFromID(xD)[yD] = None endif yD += 1 endWhile xD += 1 endWhileendFunction