Rule Role's or Role's Rule?

In my last post I used a role called 'MaxLevel' to define a small set of game rules that define both the 'Player Classes' and 'Maximum Player Level' a race can obtain. That got me thinking that perhaps I could improve my 'Race' class a little by getting rid of the 'ability_mins' attribute and moving it into a role.

player-character-deaths-d-amp-d-dungeons-dragons-character-d-demotivational-poster-1242486691.jpg

After a little more head scratching what I decided on was to reorganize my namespace a little so all the 'Game Rules' or 'Business Rules' if you like will be in logical places. So all rules for a 'Race' are in its folder and all 'Races' have the same set of rules but with slightly different code.

So step one I converted my 'ability_mins' into a role like this.


package RPG::ADD::Race::Dwarf::AbilityMins;

use Moose::Role;
sub ability_mins {
my $self = shift;
return {strength=>8,constitution=>12};
}

I took the opportunity to change the namespace yet again and I think without that 'Character' it makes it a little easier to read. So my new 'Dwarf' class is like this;


package RPG::ADD::Creator::Race::Dwarf;
 use Moose;
 extends 'RPG::ADD::Creator::Race';
 with (qw( 	RPG::ADD::Race::Dwarf::MaxLevel 
		RPG::ADD::Race::Dwarf::AbilityMins
	   ));
 
sub Dwarf { return 1;}

and in my 'Race' class I simply removed the 'ability_mins' attribute. So I carried on and cleaned up the namespaces of the other 'Race' classes and add in the new roles for them as well. Now it should just still run.


use Data::Dumper;
use RPG::ADD::Creator;
my $str = RPG::ADD::Creator->new({race=>'Dwarf',strength=>9,
	dexterity=>17,
	constitution=>12,
	charisma=>9,
	intelligence=>8,
	wisdom=>9,
	});

print "allowed Classes= ".Dumper($str->allowed_classes);

and it does;


allowed Classes= $VAR1 = {
          'Assassin' => 9,
          'Thief' => 'U',
          'Fighter' => 9
        };

Well the question is this now better??

Looking at it on a maintainability and expandability aspect it does give me some things. I have now at least a template that I can copy if I want to add in new 'Character Races' and or 'Character Classes'. Do I run the risk of creating an anit-pattern here? I will be duplicating code (all be it very simple code) with each new 'Race' or 'Class' I add.

Did I start out wrong with this 'Creator' class. Should these types of 'Game Rules' be outside the 'Class','Race' and 'Character' design entirely? I could shove all of these little rules into one big rule set but then all I am doing is going back to procedural coding and or creating a 'god' object by placing all the rules in one place.

As most of the 'rules' are simple data sets like this


my $classes  = {Fighter=>7,'Magic-User'=>11,Thief=>'U',Assassin=>10 };

I could just create a factory class that reads from a YLM file that has simple rules in it then set these up as attributes which I can load in at instantiation? Am I now just adding Gold Plating to an other wise sound design?? After all I only foresee adding a few 'Races' or 'Classes' not hundreds.

I guess that is one of the problems with OO Design there are so man ways to do things that you tend to be led astray.

Leave a comment

About byterock

user-pic Long time Perl guy, a few CPAN mods allot of work on DBD::Oracle and a few YAPC presentations