GSOC Day 3 – DynamicObjects, Positions, and Paths

I began looking at DynamicObjects today, one of the main new features of TP04. The Path overlay was still using obj.pos, which the new DynamicObjects don’t have. Instead, they have a nested set of properties, including one or more positions, velocities, orders, etc. My task was to extract the positions from the objects, so they could be dealt with.

First, I had to figure out how positions were stored. They are nested inside a GroupStructure containing multiple different categories of properties, so I had to dig down into that. Inside, I found ObjectParamPosition3d parameters, which hold the actual position in yet more nested GroupStructures. An example:

[Position: [vector: [x(q): -249954075, y(q): -4000034262L, z(q): 0], relative(I): 0], Velocity: [vector: [x(q): 0, y(q): 0, z(q): 0], relative(I): 0], Size: [size(Q): 2]]
[Owner: [type(i): 7, id(I): 0]]
[Order Queue: [queueid(I): 0, numorders(I): 0, ordertypes([I]): []]]
[Resource List: [resources([IIII]): []]]

Inside the position, there are x, y, and z coordinates. I first thought I needed to use the pack() and unpack() methods to get at these, but Mithro informed me that I can access them by name using getattr().

The next complication came in the form of relative coordinates. The last part of the position parameter can hold an object ID number, and in that case, the coordinates listed are relative to the coordinates of that object. I made a method to extract the coordinates of an object, and to attempt to look up the coordinates of any parent object and add them so that the result is an absolute point.

One last thing, though – if the parent object has multiple coordinates, there is no way to determine which set to use as the point of reference. This is a problem with the tp04 protocol, not something I can fix. So I sent an e-mail to the developers list explaining the issue – we’ll see what comes of it.

The method I ended up with to find positions, I didn’t know where to put it. It should be useful in many places throughout the code, so I eventually decided to make a new file: extras/ This file will contain helper methods for dealing with DynamicObjects. I have the feeling I’ll be writing quite a few of those.

Here’s what the method looks like as it stands now:

# Get a list of the position references of a DynamicObject as tuples.
# Each tuple has the form: (x, y, z, coord name)
def get_position_list(obj):
    positionslist = []
    for propertygroup in
        if type(propertygroup) != Structures.GroupStructure:
        positionattrsstruct = getattr(obj,
        for property in propertygroup.structures:
            if type(property) != parameters.ObjectParamPosition3d:
            coords = getattr(positionattrsstruct,
            relative = getattr(positionattrsstruct,
            if relative == 0:
                positionslist.append((coords.x, coords.y, coords.z,
            refpositions = get_position_list(cache.objects[relative])
            if refpositions == []:
                raise ValueError("Reference object for coordinates does not have a position.")
            positionslist.append((coords.x + refpositions[0][0], coords.y + refpositions[0][1], coords.z + refpositions[0][2],
    return positionslist

There is a seemingly endless stream of other outdated position and order code causing error messages left and right, so it looks like I’m in for a lot more of this introspection and helper method coding. I’ll work on some more of those bugs tomorrow, and, now that I know what I’m doing a bit better, I might be able to get more than one done per day. Here’s hoping.


~ by greywhind on May 25, 2009.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: