Game Development Community

Ordering issues when reading DynamicFields from TAML Scriptobject

by Simon Love · in Torque 2D Beginner · 02/11/2013 (7:35 am) · 5 replies

I've noticed weird behavior while playing around with TAML functionalities.

I am not sure if this is the expected behavior and I have a hard time reproducing it consistently so I can't really file it as a bug either. In any case, if anyone stumbles upon this, I've included a workaround at the bottom.

First, the TAML file :
<ScriptObject
MapSize = "1 6"
Layer1 = "0 1 1 0 1 1"
Layer2 = "6 6 7 7 6 6" />

In my code, I call
%map = TamlRead("./maps/map1.taml");

The file loads correctly and is interpreted as a ScriptObject, just like is should.

I then iterate through the Fields (MapSize, Layer1 and Layer2) using %map.getDynamicFieldCount(), which reports the Field count accurately (3).

The problem

When loading the data from the Fields, 9 times out of 10, The Fields are assigned the expected indexes

0=Mapsize, 1=Layer1, 2=Layer2.

Once in a while, the order is apparently randomized, either assigning index 0 to Layer1 or Layer 2.

I change nothing to the script, restart the executable and boom, the order will have changed for no reason.

The workaround

Obviously, the easy way around is to look for the Fields by name instead of indexes

%map.getDynamicField(%i) will yield the Field's name as a string
%map.getFieldValue("Layer"@%i) will yield the value of Layer1 or Layer2, depending on the value of %i.

Still, I'd expect the engine to read Fields in the order in which they appear in the file, no?

About the author

I am here to help. I've worked at every imaginable position in game development, having entered the field originally as an audio guy.


#1
02/11/2013 (7:55 am)
Actually, those functions were put there as the mechanism, not the workaround....

However, that behavior is unexpected. Is there a reason you need the fields to be in a specific order? Are you not putting specifically named fields on object so that you can access them by using %object.field style notation? It sounds like you ran across this doing something a little unorthodox.
#2
02/11/2013 (8:16 am)
I was just fiddling around with TAML reading to gather values in order to load up isometric tile layers.

My 'logic' was as follows :

1 - Get a layer count by calling %map.getDynamicFieldCount()-1
(To remove the 'Mapsize' field from the count)

2 - Simply go through a 'for' loop to load in the remaining Fields one after the other, which were all Layers.

It never occured to me that the Fields would not be loaded sequentially.

To answer your question, no, there is no reason why I would need the fields to be in a specific order. Thanks for the quick response!
#3
02/11/2013 (8:35 am)
The fields are assigned sequentially as they appear in the file, it's a forward parse.

Taml does not interpret the contents of those fields in any way.

Also, don't merge the concept of Taml reading a field to what those SimObject calls do. They have nothing to do with each other. When you call those methods, they are not reading the file so you shouldn't expect the file-order.

SimFields are stored internally as a hash-table which is not guaranteed a specific order. The order is most likely the address of the string which is the field name which can be random.

Again, don't confuse one action with another. :)
#4
02/11/2013 (9:04 am)
Ah, there you have it!

Ok, so to do what you were doing you can access your layers like this;
%count = %object.getDynamicFieldCount() - 1;
for (%i = 1; %i < %count; %i++)
{
  loadLayer(%object.Layer[%i]); // or however you handle it
}
Personally I'd start with Layer0 (which is Layer[0]) and keep a separate LayerCount field specifically for this if there are a variable number of layers.
#5
02/11/2013 (9:11 am)
Thanks Melv for a very thorough answer and thank you Richard for following up.

Now I pray that another un-enlightened soul faces the same non-issue and can fall on this thread so as to make me feel a bit less lonely in the unorthodox thinking camp. :)