Tuesday, August 24, 2010

Modularization - The joys

Modularization, the process of breaking a monolithic software component into multiple separate components. To be honest, it isn't very much fun. For a year or so, I did a lot of it at work, enough so that my wife recognizes the word and knows it isn't very much fun. This is what I did all weekend.

The first question is why I would spend a significant portion of the weekend doing something I admit isn't fun as part of my "hobby". The truth is that in most hobbies there are parts that one does not enjoy. Runners don't always enjoy getting up early to run, some parts of video games are called "grinds", and practicing a skill or instrument isn't often fun.

Magecrawl during development had a few modular boundaries established early on, between the GameEngine and the UI, that has been honored. However, the "GameEngine" component has grown to include much of the games logic, enough that I felt for testability (more on that in further posts) and understandability, things had to be broken up.

Here is a picture of what I currently have:



A bit of explanation, everything that isn't MageCrawl.exe, GameUI, Interfaces, and Utilities used to be in GameEngine. Here's a rough idea of what everything does:

  • Utilities - Low level stuff, like the Point class, Preferences, and helper classes for saving and finding types at run time.
  • Interfaces - These are interfaces that the GameEngine as a whole provide that allow the GameUI and controls to query information about the current game state. Things like IPlayer, IMap, IGameEngine, etc.
  • GameUI - This is what draws the map, menus, etc.
  • MageCrawl - This is the game engine proper. It has an implicit dependency of GameEngine via MEF. It kicks everything off and runs the main game loop.
  • EngineInterfaces - This is a set of internal interfaces the game engine components use to talk about objects everyone needs to know about. For example IGameEngineCore describes the calls to the GameEngine the various modules can use to implement their behavior. For example, those interfaces might expose how to add a status effect to a creature, but to do that you need to know what a status effect is. But status effects live "above" this module, so we create an interfaces that we can expose at this low level, IStatusEffectCore (IStatusEffect is in Interfaces for the GUI).
  • Items - This guy technically existed last release. It was the newest written code, hence being formed as a separate module. This guy handles creating items and exposing their behavior via Attributes.
  • StatusEffect - This guy handles short and long term status effects, things like poison, haste, and the like. It acts by using the exposed interfaces in IGameEngineCore and attributes.
  • Actors - Technically, this module contains monsters (and their AI), along with the Character base class. Characters can wield equipment (Melee for all monsters right now though) and have StatusEffects upon them.  Player lives in GameEngine since it has a lot of other stuff (Spells, Skills, etc).
  • Maps - This was the guy I wanted to pull out. It exposes the map data structures, and the multiple ways to generate maps. Maps place monsters onto them self, and can contain items on the ground.
  • GameEngine - This is where everything else lives. It handles physics (who can move where, etc), combat (resolve attacks), magic (what does the spell do), and the like. 
This is a rough outline of MageCrawl's internal structure. I'll talk about it more in future posts.

3 comments:

Tanthie said...

The picture seems to be missing.

donblas said...

Thanks for the comment. I seem to see it on my machine at work. Can you see the image at this link directly?

http://1.bp.blogspot.com/_HGdMxBYRQLs/THNRL3nQelI/AAAAAAAAATQ/1JW51fH9D3o/s1600/DependencyGraph.png

Tanthie said...

Yes. Chrome also shows it, so I guess my Opera doesn't like it or I have blocked something I shouldn't have. ;p