Thursday, September 28, 2006

Improving On An Old Chestnut

Breaking my own rule that improvements should be belayed until such time as the original game has been reimplemented, I've added waypoints and path finding to agent movement in FreeSynd. I found this documentation of the A* path finding algorithm to be most enlightening.. although, frankly, the sketch is more than adequate to implement a useful algorithm for agent movement.

It always annoyed me when I told my agents to go to point X and they got stuck inside buildings or took some inordinately long path. Now you can hold down the ctrl key and enter waypoints manually, or you can let the path finder do its job (this is the default). Pressing the ctrl key without clicking the mouse will display the selected agents' current path(s) as a bright yellow line. At the moment the planning algorithm does not take elevated terrain into account, so trying to send agents onto bridges or up stairs simply won't work just yet.

There's still a hell of a lot to do before the game is playable, including shooting, enemy AI, vehicle controls, sound, etc. But if you'd like to play around with the path finding, you can grab this all-in-one package I've put together. It includes windows binaries, all the required data files from the original game and source code (so you can build it on linux if that's your prefered platform). If you feel the urge, please report bugs on the bug tracker. I'd also love you hear any ideas you have for new features.


  1. Discovered your blog through your sig on /. (at least, I assume it was your sig).
    I downloaded your sample bundle, and tried to compile it on Linux, but a few problems. A bunch of easily avoided warnings from the constructor of PathNode, and errors from ped when you're calling tileX and tileY - ped.cpp:432: error: passing 'const PathNode' as 'this' argument of 'int PathNode::tileX()' discards qualifiers

    By changing a chunk of PathNode to
    PathNode(int tile_X, int tile_Y, int tile_Z, int off_X = 128, int off_Y = 128) :
    tile_x_(tile_X), tile_y_(tile_Y), tile_z_(tile_Z), off_x_(off_X), off_y_(off_Y) { }

    int tileX() const { return tile_x_; }
    int tileY() const { return tile_y_; }
    int tileZ() const { return tile_z_; }

    the problems are solved. I'd post this to bugzilla, but since I can't access the CVS repo right now, I don't know if this has already been fixed.

  2. Hi, I have been looking around the site and your description of the graphics format makes total sense to me.

    Its the old planar bitmap format from the Amiga days (makes sense since it was an amiga game).

    The graphics are stored as a single bitfield (consider a black and white image 32pixels across), the most efficient way to store this is a run of bits left to right making 4 bytes of data per scanline (repeat 4 bytes for each line).

    When 4 and more color images arrived it was still efficient to use planar bitfields like this, and this continued all the way until the PC VGA card came out with 8 bit 256 color images.

    I remember the complex code we had to do to rotate chunky bytes (which were more efficient for 3d doomesque game rendering) back into planar fields for display on the amiga.

    fun times, thanks for the blast from the past.

  3. This comment has been removed by a blog administrator.

  4. I like what you're doing; -it's nice to see this much dedication and effort into bringing that great game back from dust!