Saturday, January 30, 2010

Moving!

Not a whole lot of progress is likely in the next couple of weeks since my wife and I are moving across country to Seattle.  North Carolina has been a great place to live, but we're looking for a change of location (especially to somewhere with mountains nearby), and it's a good excuse to mix things up career-wise as well.  Hopefully I'll get my main dev machine back from the movers in a week or so, and in the meantime I've got my laptop which will have to do for now.

In the meantime go check out the second Magecrawl Tech demo.

Tuesday, January 26, 2010

SDLconsole support

I decided to dust off the SDL wrapper for my console class to see how it's held up.  Somehow my switch to unicode support introduced a nice obscure link error that took at while to track down - project settings were correct, just needed to include sdlmain.lib now explicitly.  The wrapper was sort of half implemented and there was no useful keyboard support other than up/down/enter, so I went ahead and plugged in some basics so none of the menus are blocked.



It will need quite a bit of work to make it pretty that's for sure, but the basics are there.  Extended ascii characters in the font for one so that my grass and walls show up would be nice, and then some sort of method to expose true 32bit color support for SDL but still be able to bucket it for the console builds.  I have a couple ideas on how to have the property system automatically support this extra data without too much trouble, and then it would be a matter of just making sure there's plenty of fallbacks when the extra data in unnecessary/unwanted.

Monday, January 25, 2010

Progress

I've knocked out some major steps that makes it likely that this project might actually playable at some point.  I've updated the picasa gallery with 5 new screenshots, check the entire album out here.  I'm nearly up to 150 submissions in my source repository so far, spanning over 2 years (with huge gaps, looks like I didn't touch the project for a year and a half altogether), and it's finally starting to get some legs.  Lots of work ahead of me no doubt, but I'm excited to have made it this far.
  • Inventory is now implemented in a mostly usable form.  Creatures have a configurable list of body slots that Items can be equipped too, along with all the appropriate hooks for status modification down the road (cursed items, status changes, etc).  I spent quite a bit of time on the inventory screen as well, which worked well in testing out both the inventory and UI frameworks.


  • Combat has been scrubbed a bit as I try to figure out how exactly the mechanics of attacking, dodging, and damage absorption should work.  I've gone and forth on a couple systems, but for now I think I've settled on the idea that items themselves hold the most influence on combat values, while creature stats and skills either scale those values or enforce a minimum.  Weapons for example dictate a base chance to hit, attack speed, and damage range, and a player's agility would modify the minimum chance to hit and attack speeds, while the matching weapon skill would scale the weapon's base values.  I have no idea if this approach will work or not in the long term, but for now I've got something in that I can start playing with.


  • It's now possible to level up!  Coming up with an XP table generator is voodoo magic, and I ended up spending an hour or so playing with some weird combination of formulas that eventually generated something that looked "right".  The more important part is that it's now possible to go past level 1, so there's actually a point to killing all those goblins and rats.


  • Level Generator and Populator classes are now roughly implemented, and I moved my basic cave generator into it's new (data driven) home.  Now it's trivial to tweak all the various parameters of the generation or creature population, and no longer requires recompiling the executable.  I think the growing pains with my property reflection/serialization system are starting to yield some awesome rewards.  It's very rewarding to watch all the individual components I've been working start to come together.  This shot shows the debug console with some of my in-game debug commands to inspect the  type registry, and then dive into the properties of a specific type/instace.



I'm looking forward to start adding more and more of the actual game bits now that the underlying frameworks are mostly working.  I can tell there's going to be more fun ahead already... I'm pretty sure my current implementation of time in the engine is going to be asking for a rewrite very shortly.

Macros really are evil... :(

I knew my property system macros were fragile, and I ran into a fun one the other day when adding properties for the new level generators.  When loading up some test data my structure was getting turned into garbage, which I eventually tracked down to the second property in the struct having an invalid offset.  Thankfully Visual Studio's debugger is badass, and was able to find that I had accidentally setup a string property (12 bytes) into a string pointer (4 bytes), doh!

struct LevelPopulatorCreatureInfo
{
    TString* CreatureName;   // this shouldn't be a pointer, and throws off all other offsets by 8
    ...
}

ADD_PROPERTY(CREATE_PROPERTY_CUSTOM(LevelPopulatorCreatureInfo,String,CreatureName));

The question now is to add some verification asserts to the already convoluted macros, or should I bite the bullet and refactor the system to make the compiler do the type checking?  This might be a fun post to look back on in a couple months....

Monday, January 11, 2010

Macros are evil...

For some reason I thought it would be clever (and elegant) to wrap my property system declarations in some simple macros, which of course worked decently for simple cases...

DEFINE_PROPERTY_STRUCT(ACreatureClass,Range_Int,BaseXpValue));
DEFINE_PROPERTY(ACreatureClass,float,BaseEvasion));

The macro handles creating a new Property class instance and adding it to the DataType's list of properties, etc etc. Now recently I find myself add a new Property_Array class (now that I'm actually creating a game I have need of data driven lists), which worked out fairly well initially

#define DEFINE_PROPERTY_ARRAY(ClassType,PropType,PropName) Type->Properties.Add( new Property_Array(#PropName,GET_OFFSET(ClassType,PropName)) );

Which worked great for my test case for array of integers, but quickly fell apart once I wanted to make an array of enums (or for more pain, an array of structs of arrays...). I've since refactored the macros to support embedding of property creation within the array property creation macro, but it's turned into a real mess that I'm not proud of...

ADD_PROPERTY(CREATE_PROPERTY_ARRAY_EXT(ACreatureClass,ItemBodySlot,BodySlots,CREATE_PROPERTY_ENUM(ACreatureClass,ItemBodySlot,BodySlots,NumItemBodySlots,ItemBodySlots,ItemBodySlotNames)));

And with the (ab)use of the temporary LastProperty it's a pretty frail system, where any bit of manual monkeying when defining properties could very easy cause bad things. Alas I've resisted the temptation to refactor the entire system altogether for now (got to make a game you see!), but at least there's a nice juicy comment admitting the problems with the approach. As if that somehow makes it okay to write bad code....