How do arrays work?

Discussions about Coding and Scripting
Post Reply
User avatar
ANUBITEK
Adept
Posts: 261
Joined: Sun Dec 28, 2014 1:10 am
Location: Anubitek

How do arrays work?

Post by ANUBITEK »

Could anyone better describe (with examples) how both static and dynamic arrays work? I have some links here:
https://web.archive.org/web/20150620045 ... ble_Syntax
https://web.archive.org/web/20150608213 ... alEngine_1
But I can't quite make sense of how they operate. I need this for a section of the guide, but I could use some help/examples.

EDIT:

Here is what I have written so far, based on what I've seen. From what I can tell, an array is used to store multiple values of the same type (so "var int Numbers[10]" below declares an array of 10 integers. What would I have to do if I wanted to say, edit the third value stored in this array?

Code: Select all

[>>] Arrays ( xArray[20] )
A static array has a length known at compile time and is not resizeable.  Dynamic arrays were
	not implemented in UnrealScript until Unreal Engine 2, so they will not be covered.  To
	create an array just specify its length in brackets behind the variable's name.
		> Note: UnrealScript supports only single-dimensional arrays, though you can simulate
			multidimensional arrays by carrying out the row/column math yourself.
*/
//=============================================================================
var/local type name[length], ...;
// Example:
var int Numbers[10];
<<| http://uncodex.ut-files.com/ |>>

Code reference for UGold, UT99, Unreal2, UT2k3, UT3
Additional Beyond Unreal Wiki Links
wiki.beyondunreal.com/Legacy:Console_Bar
wiki.beyondunreal.com/Exec_commands#Load
wiki.beyondunreal.com/Legacy:Exec_Directive#Loading_Other_Packages
wiki.beyondunreal.com/Legacy:Config_Vars_And_.Ini_Files
wiki.beyondunreal.com/Legacy:INT_File
User avatar
Wormbo
Adept
Posts: 258
Joined: Sat Aug 24, 2013 6:04 pm
Contact:

Re: How do arrays work?

Post by Wormbo »

Don't confuse people with dynamic arrays in UE1, that wiki article looks quite vile in terms of performance.

For static arrays there's not much to say other than that the number between the square brackets determines the number of elements in the declaration and the element to access anyhwere else. There's ArrayCount(expression leading to a static aray variable) as a compiler macro to give the number of elements as a constant. Static array elements are almost always treated as individual elements (e.g. for replication) and static arrays cannot be passed as a whole directly in assignments.
User avatar
ANUBITEK
Adept
Posts: 261
Joined: Sun Dec 28, 2014 1:10 am
Location: Anubitek

Re: How do arrays work?

Post by ANUBITEK »

So what do you mean about dynamic arrays? I've read they can't be done, but then read info on how to do them.
<<| http://uncodex.ut-files.com/ |>>

Code reference for UGold, UT99, Unreal2, UT2k3, UT3
Additional Beyond Unreal Wiki Links
wiki.beyondunreal.com/Legacy:Console_Bar
wiki.beyondunreal.com/Exec_commands#Load
wiki.beyondunreal.com/Legacy:Exec_Directive#Loading_Other_Packages
wiki.beyondunreal.com/Legacy:Config_Vars_And_.Ini_Files
wiki.beyondunreal.com/Legacy:INT_File
User avatar
'Zac
Experienced
Posts: 111
Joined: Tue Jul 29, 2014 9:35 pm
Personal rank: Who knows.
Location: NC

Re: How do arrays work?

Post by 'Zac »

dynamic arrays are more systematic arrays than statics.
dyanmic array:
' var array<Actor> ActorSlots '
and you can insert an actor into ActorSlots[0] or you can remove ActorSlots[4] and you can get ActorSlots.length which returns an INT of how many items in the array. you can just do more with dynamic arrays
Prophunt for UT99!!!
Image
Github
Higor
Godlike
Posts: 1866
Joined: Sun Mar 04, 2012 6:47 pm

Re: How do arrays work?

Post by Higor »

You can operate dynamic arrays in UnrealScript on Unreal 227, and UT's XC_Engine.
What are dynamic arrays then? Let's talk about memory allocation.

You have an object, be it a struct, class or whatever.
This 'object' can be a part of any other object, it can exist on any part of the system, including the CPU cache's... and even where you don't expect to see them.
As a matter of fact, I pick some random 12 bytes in any part of your system's memory and those 12 bytes can be a X,Y,Z FLOAT vector, the same memory I can read it as a 'rotator' type if I wanted to.
Bottom line is, objects are what they are because of how we and our code candles them.

So before we continue, learn this well:
An object can be anywhere, a chunk of memory can be anything

===============================
Let's continue with arrays.
In UnrealScript the most basic type of array is the static array, it is a chunk of memory defined within the struct, class or stack you're operating on.
In the case of INT arrays, INT is a datatype 4 bytes long and therefore each element of an INT array will require 4 bytes.
A INT array of 128 elements long will take 4*128 bytes of contiguous memory.

Contiguous, the elements of an array will never occupy different regions of memory (virtual memory we're talking about) and the access method is very simple.
In UnrealScript and other high level languages, access via array index is absolute offset.
Meaning, we see where the element 0 is, then we move the registers ahead using SIZE*INDEX (4*i) to locate the memory region we want to access.
C++ compilers will usually optimize loops to add (SIZE) to the iterator registers after every loop, etc.

It's very simple to do and just like any other variable, no extra steps or anything.
UnrealScript defines an opcode that takes a 'variable' opcode, and a 'index' opcode as parameters to understand what array and what index you want to access for read or writing.
Opcodes unlike constants can result in anything, even function calls, which explains why you can sometimes call functions inside a [] block, or why you can specify an array from a different object (Object2.OtherArray).

When it comes to UnrealScript, the Dynamic Array accesor opcode (0x0F I believe) is identical to the static array one, they are compiled the same but with a different index so it gets treated internally like a dynamic array.
But of course, both things are not identical.
Dynamic arrays can have any size and thus, can be altered so that their size changes, so we need extra functions to know these details and to do said alterations.
Now you wonder... If static code already has predefined variable offsets and precompiled the way to operate on those... how in earth is it possible to have an object that changes size?

It's simple in the case of Unreal's FArray types: 12 bytes
- Data pointer (offset 0)
- Array number (current max, offset 4)
- Array max (maximum allocated, offset 8)
FArray is initally created with all three values zero'd, which automatically translates to: no allocated memory, zero elements.
The Data pointer indicates where our data is, it's a chunk of memory we dynamically allocate for our purposes, in this case: simple data storage reserved by the program.

When we issue the first size change order via ADD, INSERT or using the [] assignment operator (in write mode, it does ADD internally), the internal code will fetch some free memory using arbitrary rules.
Let's say... we want to insert 8 INT's, the code will probably fetch 44 bytes and the result will be this:
- Data pointer = address of new memory
- Array number = 8
- Array max = 11 (44 / sizeof(INT))
Memory allocation and deallocation can be very expensive and fetching additional memory will allow us to more efficiently add elements one by one, for example.
So let's say... we do Array_Add(1); and add one more element, we get:
- Data pointer = same as before
- Array number = 9
- Array max = 11
Following these arbitrary rules, the code will attempt to get more memory (using a different address) or will attempt to shrink the size of the allocated memory when necessary.
All done internally as you add, remove, set stuff on UnrealScript.


With the internals over, how do we efficently code in UnrealScript, and how do we fulfill our purposes?
Some simple things to know:
- If you intend an array's data to be known to clients connected to a server, you cannot use dynamic arrays, replication doesn't support those.
- If you don't want to loop over a full static array over and over, define an 'ArrayNum' variable yourself and imitate the behaviour of a dynamic array.

Code: Select all

Basically: var int Data[512]; var int DataCount; For (i=0 ; i<DataCount ; i++ ) Log("Found data: "$Data[i]);
- If you know how many things you're going to operate with in an algorithm, always use static arrays.
- If you constantly need to keep an element order, even when you remove elements from the middle of an array, consider using dynamic arrays.
- Don't do dynamic arrays inside functions, sometimes using a 512-sized static array is faster and easier to debug.
User avatar
sektor2111
Godlike
Posts: 6410
Joined: Sun May 09, 2010 6:15 pm
Location: On the roof.

Re: How do arrays work?

Post by sektor2111 »

Tiny bumpy...
Without to look deeper at class I have seen some MapList.uc class inside Engine.U package. As I know so far Engine.u doesn't know how many maps you have or how many maps you'll have at certain moment. However is able to load 50 or 150 maps in the same way - a kind of dynamic array containing... Strings from a shown List previously loaded. The rest of MapLists are just null child classes having changed default properties with a couple of basic data (STOCK), but for sure it might create slots for Levels added later.
User avatar
Wormbo
Adept
Posts: 258
Joined: Sat Aug 24, 2013 6:04 pm
Contact:

Re: How do arrays work?

Post by Wormbo »

sektor2111 wrote:Tiny bumpy...
Without to look deeper at class I have seen some MapList.uc class inside Engine.U package. As I know so far Engine.u doesn't know how many maps you have or how many maps you'll have at certain moment. However is able to load 50 or 150 maps in the same way - a kind of dynamic array containing... Strings from a shown List previously loaded.
Take another look, it's less than 50 lines of code. The Engine.MapList class in UT v436 has a static array for 32 strings and a map counter to specify the current map, that's all. The code consists of a single function responsible for returning the next map in the sequence, starting over when it hits the end of the array or an empty slot, whichever comes first.

Map lists for the UI are in fact linked list. Actually, the entire UI is a big construction of nested linked lists.
User avatar
sektor2111
Godlike
Posts: 6410
Joined: Sun May 09, 2010 6:15 pm
Location: On the roof.

Re: How do arrays work?

Post by sektor2111 »

Yes, and it's functional, just a note. Usually I'm thinking simple, all old people coding for UT were doing a good job in the past and even now-days, only new comers have UCC problems, array problems, bytes saving, string problems, and the rest of things making life harder than it needs to be :mrgreen: .
Post Reply