String Extraction, School, and Blogging

Over my last several posts, I’ve started to notice that I’ve started to have a bit of a longer stride with my entries. I went back in and put some “read full article” thingies in several of my posts.  Sure, two of them are basically articles, but even some of the other ones are getting a little longish.

I haven’t had a great deal of time to work on HamQuest, and the work that I have been doing doesn’t really add any new features, it is “internal” updates that makes things a little more flexible and refactoring to make future enhancements easier. In the end, it does not produce a substantial enough difference to warrant an upload.  Mostly I’ve been refactoring classes in the interior plumbing of the game, mostly to be able to share these in my article series.

Also crowding in my time is school. I’ve got Composition II for IT Majors, which isn’t terribly difficult, but definitely time consuming. My other class is Fundamentals of C#. Yeah, I know. Its part of the degree program.

I did finally get HamQuest into google code.  You can find it at http://code.google.com/p/pdg-hamquest-silverlight/.

So far, I like living at google code.  I’ve put a large backlog of issues and enhancements into the issue tracker. I’ve handled some of them. I like the issue tracking system it has.

Apparently the Chemhex spike which I noticed last week has subsided down to less of a huge roar.  Most of the referrers were stumbleupon. It was interesting, anyway.


Untangling the Knot

First, HamQuest is now in an assembla space:


Second, there has been a lot of refactoring in the HamQuest code base.

I’m finally tackling the “get the creatures into xml” task, and it is proving to be very challenging, and the reason it is challenging is because of the corner I painted myself into with how the creature that represents the player is represented in code.

Slowly but surely I’m starting to unravel the issue, but not without pain, and I’m surprised the thing still actually works after what I just did.

A creature on a map is represented in code by a Creature object.

A Creature object holds the state of the creature (mostly the wounded state), and an index into a creature table.

The creature table consists of two types of object: CreatureDescriptor and a PlayerDescriptor, which derives from CreatureDescriptor.

A CreatureDescriptor is just that: a description of the general type of creature.

A PlayerDescriptor is more than that: it also contains the current state of the player.

The intent was noble: make players and creatures use the same rules for the most part, and only differ when they actually differ in behavior.

In a CreatureDescriptor, the attack value is static. A goblin always has an attack value of 2 no matter what, and nothing will change it ever.

In the PlayerDescriptor, the attack value depends on the weapon equipped by the player.

Now that I’m moving both types of descriptor into the “property bag” model that I put the Items into, I’m using a generic function to grab out the values, but the property bag knows nothing of the values it holds… it just holds them.

So, I “cleverly” wrapped a value into a new “StatisticHolder” class, so that the same looking call can get both the CreatureDescriptor attack value in its own static way, and will get the dynamic value from PlayerDescriptor.

So now CreatureDescriptor is completely empty, and ready for moving to XML, and PlayerDescriptor is not.

Of course, I’m not entirely sure that there is a need to put the player descriptor into xml as a whole.  It may be good enough to put some sort of “base statistics” for the player, and have the player descriptor copy from them, and simply add the PlayerDescriptor to the end of the Creature List, but load the others from xml as originally planned.

In any case, one step closer to the goal, along with the change of almost all enums into static classes with const strings, which may seem crazy and untypesafe (and it is!) but with the mind I have for extensibility of the project, it’ll make sense in the end.

In any case, you can check out the code at assembla, if you want.  Try not to point and laugh.


A Knead For HamQuest

Coming back to code that is “aged” to any extent (HamQuest is about a year old as a code-base), it is easy to spot the flaws and quick decisions that painted the code into a corner.

Normally I think “This code sucks! I totally need to re-write it!”

But then I asked myself a very simple question: “You have written games a hundred times. You have rewritten those games another hundred.  Since when has that ever actually helped you finish any of them?”

So I’ve been slowly going over the code.  In many way, software development is more like making bread.  We add stuff, we remove stuff, we mix stuff around.

What started out as a single executable has turned into an executable and two dlls.  Originally I had just split out a single dll for the game itself, but once I had done that, I could see that there were a number of classes that were generic (something of a pun as most of the classes are generics) enough that they didn’t have anything to do with the game specifically.  There is now a dll called PDGBoardGames, which includes things like a Board class and a Maze class, both of which generic enough that they can be reused whenever I need a board or maze provided I remain in .Net land.

As I keep pulling stuff out of code and into XML files, more and more of the existing classes become unnecessary.  Item management has had the most work done, and there is not a single mention within the ItemTable class about any specific item.  Everything is either in the XML file, or derivable from the data in the xml file.

So, my usual thoughts about a codebase like HamQuest is “If I had done it right in the first place, it wouldn’t be like this.”  But I don’t think that way this time.  As far as codebases go, HamQuest isn’t all that bad or convoluted, which I attribute to my having worked on code for a long time, so a number of good habits have formed along the way.

However, I have spent the last few weeks working over the code and making it do exactly the same thing it did before, just a little more flexibly.  Thankfully, I haven’t had any performance hits.