Game Development Community

Back to Basics: Arrays and ways around them

by Dreamer · in Torque Game Engine · 11/06/2005 (12:15 am) · 2 replies

This is the second in a series I'm calling Back to Basics, the whole point of back to basics, is that after having taken a significant time away from TGE, I've come to realize I forgot quite alot, that I should still remember.
In that spirit, I am creating this series of discussion topics, as an easy and convienent way for people who may be just learning or just coming back to TGE, to have a quick and handy refference.

Todays topic is Array handling. The fact is Array handling in TGE looks on the surface alot like PHP, however it just lacks the power inherent in PHP. Now there are resources that add this functionality, such as the "Array" resource. However I believe there are more elegant solutions than that available.

Before we get into that, lets go over what arrays are, and what thier limitations are.

An array is simply a container for a collection of values or objects.
In code an Array looks like this.
$MyArray[0] = 1;
$MyArray[1] = "Hello";

Arrays in Torque are nonassociative string tables, this means that all of the following are equally valid
echo ($MyArray[0]);
echo($MyArray0);
echo($MyArray{0});

So far so good right? Now lets look at what happens when we try to create an associative array.
$stats[WIS]=1;
$stats[STR]=3;
$stats[STA]=10;

Now common programming logic dictates that in an associative array, STR or 1 are both valid keys
However if you try this in TorqueScript it does not work
echo($stats[1]);
echo($stats[STR]);

As you can see nothing is output at index 1, this is because quite simply there is no index value to arrays in TGE. But thats not that only limitation. Also in TorqueScript, you cannot pass an array to a function.
It simply does not work.

But arrays are very handy, and there are at a minimum 3 ways around these limitations.
ScriptObject, you would use a script object when all you need are key, value pairs and not actual object storage. This is by far the simplest method and looks like this.
$stats = new ScriptObject();

//Assignment is extremely simple
$stats[WIS] = 1;

//We just have to make sure to add a count
$stats.count = 1;

Take note though, while this will allow you to pass the array it does not in fact present any real work around to indexing an associative array. In short $stats[STR] != $stats[1]

However a point to remember is this can actually be a feature in some regards. For instance, if I am writing code for a game where I expect that international users may play, it is actually in my best interest not to use an associative array, instead using 2 tables is much more efficient. Here is what I would do.
//Keep these values client side and change them for each language
$skillsID = new ScriptObject();
$skillsID[0]= "chop";
$skillsID[1]="mine";
$skillsID[2]="forage";
$skillsID[3]="swim";
$skillsID[4]="smith";
$skillsID.count = 5;

Then server side it's a simple matter of remembering which skill is meant to mean for instance
%this.skills = new ScriptObject();
makeSetSkills(%this);
echo ("Skills at "@$skillsID[5]@" = "@%this.skills[5]);
function makeSetSkills(%this){
	for(%x = 0; %x <= $skillsID.count; %x++){
		%this.skills[%x] = %x;
	}
	%this.skills.count = $skillsID.count;
}

So the moral of this tale is actually, that in a lot of instances, when you think you need an associative array, what you probably really need are two seperate arrays, and to rethink what you are doing. This method will also save you some serious overhead, as well as alot of headaches if you ever decide to expand the game to support mutliple languages or decide that for instance skill 5 should be refining instead of smithing, etc.


Now if you need to store actual objects you would want to use SimSet and SimGroup, these are discussed in the previous thread.

Ok thats it for now, please feel free to leave feedback, input, corrections or additions to this.

#1
11/06/2005 (1:15 am)
Thank you Dreamer, this is very informative and helpful to me. Have you put this stuff on TDN yet?
#2
11/06/2005 (1:21 am)
Not yet, I fully intend to once the series is written and i have allowed sufficient time for feedback. It's amazing to me how much I thought I knew about this stuff, and how quickly I can be corrected on stuff. I'ld rather wait a few days for discussion/correction and additions as needed before I put it up on TDN.