Dwood has asked for the wisdom of the Perl Monks concerning the following question:

Hey I was writing a simple MUD the other day and it hit me that it would be better if I made the whole thing it's own object and module, so I decided on creating a Roleplay module!

The only question I have, is how should I organize this?

(this is not meant to go online/run in a cgi)

Currently it's formatted with just a single Module, called Roleplay but that module is doing nothing...

Is it okay for me to have an empty namespace (Roleplay) and go straight for Roleplay::Player or Roleplay::Goblin?

Or does anyone have any ideas of how I could use a Roleplay Object?

Replies are listed 'Best First'.
Re: Module Organization
by kcott (Archbishop) on Oct 12, 2010 at 23:21 UTC

    If this is intended to be uploaded to CPAN, this PAUSE page has details under the heading Register your namespace!

    Regardless of whether this is for CPAN or just personal use, I would strongly recommend you do a design first. I foresee you drowning in a sea of Roleplay::* modules for every type of creature, weapon, armour, potion, spell, etc.

    Also give some thought to the long term. Even if your Players are only slaughtering Goblins this week, they'll probably want to move on to Trolls, Dragons and so on.

    The project sounds like fun - enjoy!

    -- Ken

      Heh, I was actually thinking about it, which is why I was wondering about the design of the MUD.... I don't want to have Roleplay::Goblin, Dragon, Witch, Knight etc etc, and since I'm really new to Perl I don't want to do too much that I can't use later

      I don't seem to be capable of finding information on OOP in perl that either I can understand or doesn't repeat the same stuff over and over again as other tutorials, it's all usually just barebones tutorials or outdated from 1990's... *looks in tutorial section again*

      I've been working with matrices lately in perl as well so I may wish to use a graphics system for tiling at some point. Would you be willing to help me get started by taking looks at my code and offering suggestions? Also, thanks, I hope to make this fairly fun! :P

        I noticed your "I'm still really new to Perl ..." so I'm guessing a CPAN contribution wasn't really what you were looking at. This makes the answer to "Is it okay for me to have an empty namespace (Roleplay) and go straight for Roleplay::Player or Roleplay::Goblin?" a more straightforward YES!

        You can have these:

        /path/to/perl/mods/Roleplay/Player.pm /path/to/perl/mods/Roleplay/Goblin.pm

        without needing to have this:

        /path/to/perl/mods/Roleplay.pm

        You may still want a top-level Roleplay class but it's not a requirement of Perl.

        In terms of tutorials, I'd suggest going to Perldoc and looking under GETTING HELP - Tutorials. perlboot, perltoot, perltooc and perlbot are all directly related to Perl OO programming. perlfaq2 - Obtaining and Learning about Perl lists many resources you'll probably find useful. Scrolling down a bit further, you'll see Reference Manual which links to a large amount of documentation including OO topics such as perlmod and perlobj. I recommend you bookmark Perldoc and refer to it often.

        Regarding graphics, take a look at CPAN. The Graphics and User Interfaces sections should probably be your first ports of call.

        You can post your code to, ask questions of and seek advice from PerlMonks at any time. Perlmonks FAQ describes how to do these things. In general, a clearly written question with examples of what you've already tried (including appropriate output, particularly error messages) will be far better received than a "it didn't work" or "please write this for me" type posting.

        -- Ken

        This layout -- Roleplay::Goblin -- will break down very quickly. Consider the Monster Manual, for example. Then the Fiend Folio. Then the Monster Manual 2. Then custom monsters from modules... And you've already got a couple thousand .pm files in a single directory. Not fun to edit or maintain.

        You want to abstract it more. MyRPG::NPC or something. Then it can have basic attributes like hit points, damage taken, and alignment; and roles (see Moose for ideas there) for things like "magic (spell list)," "flight," "healing," et cetera. NPCs could then be built from configuration which would be much easier to maintain, write, and generate on the fly.

Re: Module Organization
by blue_cowdawg (Monsignor) on Oct 14, 2010 at 14:21 UTC
        The only question I have, is how should I organize this?

    In my humble opinion your first question should be "what am I trying to accomplish?" Problem definition goes a long way to proper planning and proper prior planning prevents p*** poor performance.

    Module organization should be driven by what makes sense against the backdrop of that answer. More over if you are going to be working with a team of people then the organization of your modules should fit some agreed upon standards

    The first thing you have to decide after answering the "what am I trying to accomplish?" question is what you are trying to use the modules for. There are task oriented modules and there are data oriented modules, just to come up with broad categories, and the lines between those two can be very blurred.

    Thinking of your MUD application for a second (why does everybody seem to want to write a MUD anyway?) let's come up with a theoretical set of modules:

    • Characters
      • NPC
      • PC
    • Character Classes
      • Mage
      • Fighter
      • Cleric
      • Thief

    In my very limited example above you need to assign attributes to each of these "classes" that are in common but distinctive. (Loyalty, movement, hit points, energy points, etc. etc. etc.) and some way to act on those. In a much simpler example:

    package Animal; sub new { return bless {},"Animal"; } sub speak { }; 1; package Animal::Dog; use Animal; our @ISA = qw/ Animal /; sub new { return bless {},"Animal::Dog"; } sub speak { print "Woof!\n"; } 1; package Animal::Cat; use Animal; our @ISA= qw/ Animal /; sub new { reutrn bless {},"Animal::Cat"; } sub speak { print "Meow!\n"; } 1; -- ad nauseum --

    We have a parent module Animal with two children modules Dog and Cat. They are both animals, they both "speak" but they are different.

    I could have expanded the definition further to include attributes like fur, purring, growling, hissing, tail or no tail, etc. etc. but for simplification I didn't. So when you are designing and organizing your modules think in terms of functionality, commonality as well as disparity.

    Another module organization example, this one from Real Life &tm;.

    package Report; sub new { shift; my $type= shift; my $self = { format => "html", destination => undef }; my $token = ( $type == 1 ? "::HighLevel" : "::Status" ); bless $self,"Report" . $token; } sub emit { my $self = shift; if { $self->{destination} ) { if ( $self->{format} eq 'html' ) { print $self->{destination} $self->as_html(); } else { print $self->{destination} $self->as_text(); } } else { if ( $self -> {format} eq 'html' ) { print $self->as_html(); } else { print $self->as_text(); } } } sub set_format { my ($self,$format} = @_; $self->{format} = $format; } sub set_destination { my ($self,$destination) =@_; $self->{destination} = $destination; } sub generate { } ; package Report::HighLevel; use Report; our @ISA=qw/ Report /; sub generate { my $self = shift; # report generation logic here... } sub as_html{ # HTML generation code here. } sub as_text { # text generation code here. } 1;

    What's happening here is I have two types of reports that an application is generating (actually, this is a very condensed version of the real deal) a High Level Report (for management types) and a Status Report (for the troops in the trenches) and depending on how the constructure new is being called for the module Report you get a reference back to a blessed object of either Report::HighLevel or Report::Status. In both cases they have the method generate defined so if I invoke

    my $report1 = new Report(1); # gets Report::HighLevel my $report2 = new Report(0); # gets Report::Status $report1->generate(); $report2->generate();
    it works the same. That's the beauty of OOP.

    Hope my long winded answer is of some help.


    Peter L. Berghold -- Unix Professional
    Peter -at- Berghold -dot- Net; AOL IM redcowdawg Yahoo IM: blue_cowdawg
Re: Module Organization
by afresh1 (Hermit) on Oct 12, 2010 at 23:06 UTC

    You should organize it in a way that makes sense to you. I think an OOP primer might be a good place to start.

    I would use the Roleplay module to define how the objects in your MUD interact, but that is entirely up to you.

    l8rZ,
    --
    andrew
      What do you mean using it to define how they interact? I'm still really new to Perl (as you can tell, haha) - do you have any really good examples I can take a look at?

        What I mean by interact are the game mechanics, Things like keeping track of where the players and items are, what quests are currently active. I am not really much of a role player, but I am imagining it acting as the Dungeon Master.

        I am thinking of this project as a way to learn OOPerl so I don't see the large numbers of files as big a problem as they would be if it were something that was going to end up with a public release. I think it is probably easier to start with something concrete like Roleplay::Orc instead of Roleplay::NPC. Once you get more familiar with perl you will likely want to rewrite it anyway.

        Perhaps look at some of the nodes here: Object Oriented Programming

        l8rZ,
        --
        andrew
Re: Module Organization
by locked_user sundialsvc4 (Abbot) on Oct 13, 2010 at 11:46 UTC

    That’s purely up to you, isn”t it?   It’s your program ...

    A modular topology can be pursued, for instance, “so that common code, behavior, or characteristics are commonized,” or they can simply represent a taxonomy -- the way that you naturally prefer to organize things and to think about them.   There are “suggestions” that one might make on this subject ... and of course, textbooks to be sold at high prices to unwilling students   ;-)   ... but, really, no hard-and-fast rules or ten commandments.   Whatever you decide, it will be something that you will be living with for quite some time, so ponder carefully.

      textbooks to be sold at high prices to unwilling students

      Hah! That actually reminded me that the head of our school's CS department had an O'Reilly Perl book he offered to give to me since it was just sitting on his shelf doing nothing...

      That’s purely up to you, isn”t it? It’s your program ...

      The thing that I probably left out was that I'm new to perl modules and CPAN... As well as how very oddly perl handles the concepts of objects and scalar variables, stuff like the perlboot tutorial: (just takes getting used to I guess)
      1. $a = "Class"; 2. $a->method(@args);

      Really put me up side down!

      I think I'm going to get tired of defining a new class every single time I wanted to add a new character... but I guess it wouldn't be a bad idea to start out with that.