Thursday, 7 March 2013

Class heirarchy and stuff

I was looking through the duskz code as it is right now and there are still plenty of messy bits that I want to do something about. In some places there just seems to be more code than there should be to do fairly simple things, often a simple routine is just coded inline and repeated multiple times. And each object implements it's own parser as well as a different format/convention for storing it's state.

Although there is an object class hierarchy for the in-game objects, there is little to no use of the facilities in Java for object oriented programming such as virtual methods, or even inheriting during object initialisation. Apart from the classes there is also class information stored in type fields as well. e.g. a basic LivingThing can be a player, or a pet, an Item can be any type of item from armour to a backpack. Each container includes fields which are only applicable depending on some other field. They then have testing methods to determine what type they are, but it leads to ugly code with lots of manual checking in places. Actually the code looks more like a C design, where the objects are just data containers.

The existing class structure is something like:

DuskObject
  LivingThing
    Mob
  Item
  Merchant
  PlayerMerchant
  Prop
  Sign

Each class either does its own i/o completely, or has it's i/o done for it in a completely separate class. I started an inconsistent stab at addressing this but I think to do it properly will require a common format/parser too. I'm going to stick with a Properties-like format for simplicity (name=value), but relax the requirement for unique keys (to allow multi-valued items).

First requirement is to clean up the class structure. I started at the base class and came up with a new hierarchy, which grew somewhat large by the end. I've also filled out most of the fields - in some cases it was hard to work out just which type of object a given field is restricted to. I gave them mostly unique names with the aim of avoiding clashes as I develop it, although they'll probably mostly stick.

Thing
  Active
    Player
    Pet
    Mobile
  Holdable
    Useable
      Food
      Drink
      Item
    Wearable
      Weapon
      Armour
    Container
  Shop
    Merchant
    PlayerMerchant
  Sign
  Prop

This will let me do things like move the 'get list of sellable items' to a function on Shop, rather than having it appear in multiple places throughout the code, each having to test which type of merchant too.

The code for game logic is also spread across mostly LivingThing and DuskEngine in random ways (some of it my fault by this time). Even things like the game pulse - there are two separate tick threads, for no particularly obvious reason? It might have been created to run enemy a/i on a separate thread, but extra stuff got added later - in any event it should run on a common clock.

I started just investigating the current structure to see how it's used, but I think i'll just rewrite the whole lot, the objects, the i/o & file formats, and well, most of the behaviour code too. The game logic itself is fairly simple so i'm hoping I can hide some of the dumb-but-necessary code like i/o away to expose the simplicity. There wont be much left of the original code apart from the battle logic, and the overall behaviour.

Could keep me busy for a while though ...

Update: I found there was a single weapon - a "runed shortsword", which was also "useable", so I decided to put the useable fields into Holdable instead so anything can be "used", if the game so desires. Non-usability is set by simply not setting hose fields. This could be extended to other types of item, but doesn't seem useful.

3 comments:

Sykobee said...

You might want to look at using a component based object system.

Here's a recent article: http://www.grimrock.net/2013/02/26/refactoring-the-object-system/

Jeremy Harton said...

Was reading your blog (link from Dusk MMORPG blog which I found from the github code and the internet) and I was wondering...

Thing
Active
Player
Pet
Mobile
Holdable
Useable
Food
Drink
Item
Wearable
Weapon
Armour
Container
Shop
Merchant
PlayerMerchant
Sign
Prop

So, is that purely a basic hierarchy, or are you using interfaces and/or abstract classes?
Just curious because Holdable->Usable, Wearable and Shop look like potential candidates for abstract classes/interface. Especially since I assume that you aren't going to have just a Shop.

NotZed said...

skyobee: i don't see the need for that level of complexity with such a simple game, and I think they're solving a different problem. The only rendering information for example is a single image number, and behaviour is defined elsewhere. But i'll keep it in mind for the future should i work on a more complex design.

jeremy: all the non-leaf classes are abstract, and it's just a straight class hierarchy as shown (indented). It's also basically the same as the previous hierarchy, but with some added detail.

Even the abstract classes add some fields or behaviour, so interfaces would just mean more code duplication and general messiness trying to do the same thing.

I'm not allergic to interfaces, I just don't think they're needed at this level, at least not with the current game design. e.g. you're simply not allowed to attack someone with a finger bun or wear a watermelon as a helmet.

PS Neither of you are the first to be caught out by the 'it's moderated' thing :)