BlueMoonProductions
NL EN


N-dimensional arrays
GameMaker unfortunately doesn't support arrays with more than two dimensions, contrary to most other programming languages. This tutorial will show you how to make three-dimensional arrays, and eventually, n-dimensional.
Required software: GameMaker 5 or higher
Difficulty: Difficult

The most obvious method is the same method used for RGB encoding. De 'R', 'G' and 'B' values range from 0 to 255, which is saved in one number using the following formula:

C = R + G*R_max + B*G_max*R_max

R, G and B are the color values, and R_max and G_max the maximal values of R and G, in this case 255. To demonstrate this: the built-in function make_color_rgb(red, green blue) will probably look a lot like this:
GML
return ((argument0+1) + (argument1+1)*256 + (argument2+1) * 65536)-1
(2562 = 65536)
Of course, we can also reverse this process:

R = C mod 256;
G = (C div 256) mod 256;
B = C div 65536;

We can also use this technique for arrays.
We take A, B and C, turn them into one number using the formula A+B*Amax+C*Amax*Bmax, and use that as our index for a one-dimensional array. However, there is one problem here: GameMaker has a limit for array indices: it cannot go above 32000. This seems like a pretty big number, but it isn't. The final value of our three-dimensional array cannot exceed 32000, so the maximal value of Amax*Bmax*Cmax is 32000, meaning that the maximal value for A, B and C equals 320001/3, which equals the disappointing value 31.75.
So if you are fine with an array of the size 31*31*31: great. But I think we can do more.

Luckily we do have two-dimensional arrays. The most obvious thing to do would be storing the value of A in the first index, and B and C in the second. The second index would then be calculated like this:

B + C*B_max

The maximal values of B and C are then equal to 320001/2, which results in a higher but still disappointing value of 178.89.
Our array size would then be 32000*178*178, which seems a little bit unfair.

So, we'll have to find a way to spread A, B and C out over the two indices, in such a way that all the indices have the same maximal value.

As I mentioned before, the RGB encoding can also be used backwards: to split one number up into three. And this also works for one-into-two:

index1 = N div Max
index2 = N mod Max


(I rated this tutorial Difficult, so I hope you know what this does)
In this example, Max is the maximal value one of the two final indices can have: this is obviously 32000.
Your maximal maximum for each of your first three indices would be 32000*320001/3, which can be rounded down to 1007.

Calculating your indices would work like this:
GML
var index, index1, index2;
A = 12;
B = 34;
C = 56;
A_max = 20;
B_max = 40;
C_max = 60;

index = A + B*A_max + C*B_max*A_max;
index1 = index mod 32000;
index2 = index div 32000;
array[index1,index2] = 0;
And you can continue like this for four-dimensional arrays(that have a maximum of 178 each):
GML
var index, index1, index2;
A = 12;
B = 34;
C = 56;
D = 12; 
A_max = 20;
B_max = 40;
C_max = 60;
D_max = 20; 

index = A + B*A_max + C*B_max*A_max + D*C_max*B_max*A_max;
index1 = index mod 32000;
index2 = index div 32000;
array[index1,index2] = 0;

The formula for the maximal value of each of your starting indices is this:

(max_final_index_1 * max_final_index_2) ^ (1/starting_indices)
(32000 * 32000) ^ (1/n)
= (320002)1/n
= 320002/n


This doesn't only work for more than two indices, it also works for one-dimensional arrays. Using this technique, you can expand the capacity of your one-dimensional arrays from 32000 to (320002=) 1,024,000,000!

That's it, I hope you found this useful!

This work is licensed.
License


NL EN