Games::RolePlay::MapGen - The base object for generating dungeons and maps


    use Games::RolePlay::MapGen;

    $map->set_generator("Basic");             # This is actually the default generator,
    $map->add_generator_plugin("BasicDoors"); # however, you must add the doors.
    $map->generate("map.txt");                # It'll generate a text map by default.

    $map->set_exporter( "PNG" );              # But a graphical map is probably more useful.

Here are some screenshots of the PNG and XML exporters:


The documentation is pretty light on this, sorry. I had originally intended for this interface to be highly expandable and expected to solicit contributions in various ways.

The interface turned out to be pretty confusing to operate even for me: the author. If you wish to write some things, I will definitely assist you with it and optionally include them with the distribution. However, it's set up so you don't need my help to publish new plugins, so that probably isn't necessary.

new maps

There are basically two ways to get a map. The first is to create a new object and the second is to import xml. Importing xml is really obvious, so let's start there:

    my $map = Games::RolePlay::MapGen->import_xml("map.xml"); 

The more complicated way to do it is only complicated because of all the options you'll need to set. It is in fact enough to simply call new and be done with it, as there are sane defaults, but you'll no doubt want something like this:

  my $map = Games::RolePlay::MapGen->new({
      tile_size    => 10,
      cell_size    => "23x23", 
      num_rooms    => "2d4", 
      bounding_box => "20x20",

Tile Size is in feet (or meters if you prefer, although 10 meter tiles would make the rooms rather large) and indicates a metric used to split up tiles in one of the modules covered below. Tile Size indicates the size of the tile when the map is exported as an image.

The default generator (named Basic even though it's quite complicated), is bounded by a box Bounding Box wide and High. It drops rooms throughout the map and there should be approximately Num Rooms of them.

You can optionally load a few generator plugins. I usually do. There are only two in the distrubution so far:

  $map->add_generator_plugin( "FiveSplit" );

The Five Split breaks up tiles that are 10x10 into tiles that are 5x5 and tiles that are 15x15 into tiles that are 5x5. (This makes less sense if you're working in meters, but you'll survive I hope.)

Since the generators snake around in one tile wide networks, the Five Split is intended to make hallways that are 10ft wide (two tiles wide) or 15ft wide (three tiles wide). It very occasionally throws in some areas that are thinner than the starting snake-width, but don't count on there being too many of them.

  $map->add_generator_plugin( "BasicDoors" );

You'll probably want doors. This basic door generator considers which way the door open and whether they're locked or stuck -- but doesn't attempt to generate any Difficulty Class metrics or other game specific things of that nature.

  $map->generate; # build the map!

This builds the map. Instructions on accessing the internal storage are listed below. First, we'll briefly cover the exporters.

  $map->export( "map.txt" );

By default, we export text maps. They're not terribly informative, but they're technically correct... They are astonishingly hard to read though. Unlike the rogue-like games they're meant to replicate, the mapgen tiles have four "closures" bounding the tile that are independent of the neighboring tiles.

This means you can have a wall between two open tiles, making the text output difficult to draw and to interpret. Fortunately, we can set the exporter to dump in png format.

  $map->set_exporter( "PNG" );
  $map->export( "map.png" );

The png exports should be a lot easier to read. But there's one more way to dump, which is the xml exporter. These files are readable by the import_xml(), which lead the section.

  $map->set_exporter( "XML" );
  $map->export( "map.xml" );

I have included an XSL transformation that converts the xml to an html table with table border colors indicating the different types of closures. I meant to add an XSLT that converts the xml to SVG format, but I never got around to it. It's certainly possible to do so, perhaps even using the table transformation as a demonstration.

Most of the plugins, exporters, and generators have their own documentation. If you are browsing this on CPAN, it should be immediately obvious where to find those documents. If not, go to CPAN or perldoc the module name.

_the_map format

There should almost certainly be a method in the $map object to fetch this data, but there isn't. I have no intention of changing the name, so it's safe to grab it by hand like so:

    my $m = $map->{_the_map};

It is stored as an array of arrays with various helpful hashes indicating the various states of things around the tiles. The usual way to step through it is as follows.

    for my $i ( 0 .. $#m ) {
        for my $j ( 0 .. $#{$m[$i]} ) {
            print "I'm at map location (x=$j,y=$i)\n";

Please note that the first index is the y location and the second index is the x location!

    my $tile = $m->[ $yloc ][ $xloc ];
    my $od_s = $tile->{od}{s};

If you wish to know about the open-ness of the south facing direction, then you'd access the {od}{s}. It is either a 0 (meaning a wall), a 1 (meaning an opening) or a reference to a door.

    if( $od_s ) {
        if( ref $od_s ) {
            if( $od_s->{'open'} ) {
                print "There's a door to the south and it's closed. :(\n";

            } else {
                print "There's a door to the south but it's open. :)\n";

        } else {
            print "There's no closure to the south and we'll ",
             "definitely find another open tile there.\n";
    } else {
        print "There's a wall to the south!\n";

The {od} elements have keys for {'open'}, {locked}, {secret}, and {stuck}. You can set their chance of occuring as arguments to the new() method. They are documented somewhat in Games::RolePlay::MapGen::GeneratorPlugin::BaiscDoors.

The tile to the south is simple to locate. You do not have to locate it by hand. If there is one to find it'll be stored as the {nb}{s}.

    my $nb_s = $tile->{nb}{s};

And if you lose track, the tiles know where they are.

    print "my souther neighbor: ($nb_s->{x},$nb_s->{y})\n";


Paul Miller

I am using this software in my own projects... If you find bugs, please please please let me know.

I normally hang out on #perl on freenode, so you can try to get immediate gratification there if you like. irc://

Special Thanks to Jamis Buck

I emailed Jamis and asked for permission to duplicate the text of portions of his "Random Dungeon Design: The Secret Workings of Jamis Buck's Dungeon Generator" document ( and he was cool with that.

Really, without his work, I never would have written this module!


Copyright (c) 2008 Paul Miller -- LGPL [Software::License::LGPL_2_1]

    perl -MSoftware::License::LGPL_2_1 \
         -e '$l = Software::License::LGPL_2_1->new({
             holder=>"Paul Miller"});
             print $l->fulltext' | less