The Mapsystem - An easy way to make a lot of uninterresting rooms

The Mapsystem
An easy way to make a lot of uninterresting rooms


Introduction

First, I must stress something that my LPC-Tutor once told me..
Making good armours and weapons is probably the best way to ensure that players will visit your area, but beware, too good stuff will invariably cause some sort of inflation in weapons and armours. You'll become inpopular among the older and higher wizards. Your chances of advancing beyond wizardhood may reduce. If you still want to make a bunch of really good weapons then make sure that they are very hard to get and that your area is inpeckable, variated and full of surprises. That way noone can complain and you can motivate your good weapons.
So, even though it is easy to make large, empty areas with my mapsystem, DON'T!!! In this aspect of the mud, as in all other, use your common sence, and only make areas which you yourself would find interresting to explore.

What is a mapsystem?

A mapsystem is a tool to be used by wizards who want to make fancy areas, with a lot of nice items and logical connections between all "rooms", but without the programming skill, or patience, to create such an area. It will also save some CPU and memory, and infact write part of the long descriptions of the rooms for you, all by itself.
You are following a forest track which leads through a
forest. The forest is dark and gloomy, and you do not really
want to enter it, you feel much safer on the track. To the
east and west the path continues, to the north there is a
forest and to the south there is a small beach, bordering to
a lake.
The text in italics is automatically generated by the mapsystem, from your definitions in the mapsystem databasefile.

It is also a database, managing a lot of rooms and items, and keeping them connected to eachother, even if some of the objects are destroyed, or cleaned out by the mapsystem to save some more memory.


What isn't a mapsystem?

A roommaker. The mapsystem will NOT create a file for each room, instead it clones a standard room, and patches functions in that room to set it up, then moves the player on to that room.

It is not a tool to make advanced monsters, which reply to everything the player says, and find their way around the mud on their own, but on the other hand, nothing will prevent you from putting a monster like that of your own creation in a map you have made.


Getting started

The very first thing to do is to choose what roomtypes you want, and their visual representation. There are many different ways to do thins, but the one that seems to be prefered by most wizards is to try to get a graphical representation of the roomtype, like '/\' for mountains, and '~~' for water, etc. Note that '__' is a special token, an empty room, and that ' ' is not allowed.

Drawing the map

Then it is time to draw the map.
#begin 0,0,0
__ __ __ /\ __ __ __
__ __ /\ ++ /\ __ __
__ /\ ++ ++ ++ /\ __
__ /\ ++ ++ ++ /\ __
__ __ /\ ++ /\ __ __
__ __ __ /\ __ __ __
#end
The first line is the begin command, which tells my 'mapmake' program that the map starts there, on the coordinates 0,0,0 (x,y,z) Then the actual map follows. This is supposed to be a small valley surrounded by mountains. Each two characters, separated by spaces, are called tokens. A map is built from tokens, put in a file and which is run through the 'mapmake' tool in the mud. The end command tells the program to stop parsing, and search for a new begin. All text in between begin/end pairs is therefore ignored, as well as the text before the first begin, and after the last end. This is a good place to put comments to help your own memory, like, what the tokens means. This will make it easier to change the map later on. I learnt this the hard way, when I forgot what the 50+ tokens in my area really was supposed to be.
A small example:

map.dat An example map
__ -- Empty room (Default, cannot be changed) /\ -- An unclimbable mountain ++ -- A faery forest #begin 0,0,0 __ __ __ /\ __ __ __ __ __ /\ ++ /\ __ __ __ /\ ++ ++ ++ /\ __ /\ ++ ++ ++ ++ ++ /\ __ /\ ++ ++ ++ /\ __ __ __ /\ ++ /\ __ __ __ __ __ /\ __ __ __ #end Now we will overwrite some of the data... Te -- A temple Pa -- A small path, leading from the temple #begin 3,3,0 Te Pa #end
This will result in
__ __ __ /\ __ __ __
__ __ /\ ++ /\ __ __
__ /\ ++ ++ ++ /\ __
/\ ++ ++ ++ ++ ++ /\
__ /\ ++ Te Pa /\ __
__ __ /\ ++ /\ __ __
__ __ __ /\ __ __ __
So, now we have a simple map, but what does all thoose fancy tokens mean? How does the mapsystem know that /\ is supposed to be mountains, and ++ fields? Or perhaps a forest?

Well, to answer that, we must move on to the next file, the mapdatabase file.

The mapdatabase file, and how you add roomtypes and life to your mapsystem

The mapdatabase file is in some ways the core of the mapsystem. In this object all roomtypes is stored, and the 'compiled' map as well. This is what it looks like:

data.c An example mapdatabase file
#include "/players/milamber/local.h" /* Some defines */ inherit DATABASE; /* defined in local.h */ reset(arg) { if (!arg) { map_title="The title"; /* Seen on top af all maps */ short_info="A testarea"; /* Seen by wizards doing "minfo" */ #include "map.h" /* The map (made with mmake) */ /* Now, lets define a roomtype, called "++", which is infact a /* field covered with grass. */ set_romtype("++"); set_long("You are standing on a large field."); set_short("on a field"); add_item("grass","it is green"); /* * This large item can be examined from outside this roomtype, * so, when the player sees a text like 'to the west there is a field' * [s]he can examine it, quite automatically. So, there is no need * to add the items to all rooms. */ add_large_item("field","it is covered with green grass"); set_seen_from_other("there is a field"); set_seen_from_same("the field continues"); set_enterable(1); /* Then the /\ mountain roomtype. Note the quoting of \. */ set_roomtype("/\\"); add_large_item("mountains","They are blocking your progress"); add_large_item("mountain","It is blocking your progress"); set_seen_from_other("there is a mountain"); /* This one should be set to something more interresting than */ /* this, but the example would get to long... */ set_roomtype("Te"); copy_roomtype("++"); /* This one should be set to something more interresting than */ /* this, but the example would get to long... */ set_roomtype("Pa"); copy_roomtype("++"); } ::reset(arg); /* VERY important, will initialize the * mapsystem and get it all started. */ }
If you have programed LPC before, you will get atleast the basic concepts from this. Now, the exhaustive explanation of how it works.

First, a file with some standard declaration is included, to make it easier for me to maintain the mapsystem. (If I move the mapdatabase, I only have to change the definition of DATABASE).
Then, the mapdatabase standard object is inherited. In this object all functions like add_item, set_long etc is placed.
Now it's time to set some variables. We'll start with 'map_title'. This string, if any, will be placed on top of all maps of the area generated with either the mmap command in my shellmodule, or maps placed in it by you. Then there is the 'short_info' string, used only in the 'minfo' command in the maptool.

Now some more exiting stuff.
#include "your_map.h"
This will include your map, generated with 'mmake' command from your map, as discussed above (will be discussed more later on).

And now.. What this part of the documentation is really all about: How DO you define roomtypes, and how do they work and interact with each other?

Each roomtype can be considered to be a information post in a database, containing a lot of different fields, like long, short, items etc. There is also a special roomtype, inherited by all other roomtypes: 'DEFAULT'. If you add items to this romtype, they will in effect be added to all other roomtypes as well. The same is true for properties and realm, etc.

So, what can you set in a roomtype?
The easy answer to that question is: Much more than you will EVER need!

But, here comes the most basic things:

Long -- The long description
This is the long description of the roomtype, much like the long in any room, or object, but, there should not be any '\n' in it, as they will be added by the mapsystem automatically. Set with set_long(string);

Short -- The short description
Similar to the long, but used when in brief mode. Set with set_short(string);

Items -- The items to look at in the mapsystem.
Use add_item("item_name","description"); to add a item. If you want to add more than one items which looks the same, you can do add_item(({"item1", "item2", .. }), "description");

Large items -- Items seen from the room(s) around the roomtype as well
Usable when you want roomtypes that cannot be entered, but examined, like a wall or a very steep mountain. This can also be used for very large items in normal rooms (Like a house, seen through the branches of the forest...)
Use add_large_item("item","description") in a similar way to add_item. Note: the array feature to add multiple items is not included in add_large_item.

Enterable -- Can the roomtype be entered
This is 0 by default, the most common mistake when making mapsystems must be to forget to make the roomtypes enterable. Only roomtypes that should block progress should be have enterable set to 0.
Use set_enterable(1); to make the roomtype enterable

Seen from other -- What the room looks like seen from other roomtypes
This one is used to produce part of the long description of any given room. Usually set to something like "there is a ...", or "a ... begins".
Set with set_seen_from_other("seens");

Seen from same -- What the room looks like seen from the same roomtype
This one is used to produce part of the long description of any given room. Usually set to something like "the ... continues", or "... goes on".
Set with set_seen_from_same("seens");

Seen from many -- The room looks different from different roomtypes.
This one can infact be quite usable, lets say that you have a road at the edge of a forest. When looking from the forest, you should barely be able to see the road, between the branches, but, when you look at it from the fields it should be clearly visible.

It is supposed to be a mapping in this format:

([
  "roomtype1":"seen from roomtype1",
  "roomtype2":"seen from roomtype2",
     ...  
  "roomtypen":"seen from roomtypen",
]);
If no roomtype match, Seen from other or Seen from same is used. Use set("seen",mapping); to set this.
Properties -- Is it no_magic?
See the help for properties in the nannymud help-pages.
Set with add_property("property"[, "data"]);

Realm -- The realm
Set with set_realm("string");

Random string -- Events in the roomtype
The string will be randomly be echoed to players entering the room. Add a string with add_string("the string.\n");

Replace -- What to show to mortals when using a map
Useful if you, as an example, want to make a special room, where you will find a nice item. Obviously, you do not this rom to show up as anything special on the map, so, simply set_replace("token"); to something more convenient.

Actions -- Extra commands in the room
This one is used to add some actions to a room. Lets, as an example, suppose that we want to be able to do the command 'smell' in all rooms. This is easily acomplished by doing add_actions(file_name(this_object()),({"smell"})); to the DEFAULT roomtype. The first argument is the file in which to call the function called 'var_func' (Example further down), and the array is the verbs to search for. Now, here is how var_func works:
var_func(verb,what,roomtype,where)
{
  switch(verb)
  {
   case "smell":
    if(roomtype=="Sm")
      write("It smells awfull in here.\n");
    else
      write("You can't smell anything special.\n");
    return 1:

   default:
    return 0; /* No action here */
  }
}
This piece of code should be placed in the database file. (Or,whatever file you want it to recide in, simply use the filename as the first argument to add_actions();.)

In or out -- Is it inside or outside?
Works like inorout in the standard room. When set to 1, it is inside, and when it is 2, the room is outdoors. (The default is 0, which means undefined.)
Use set("inout",inorout); inorout is 1 or 2.

Add object -- Add an object
Will add a clone of a file to the map.
Use add_object(filename); to add it. Example: add_object("obj/torch"); will add a torch.

Dark -- Is the room dark?
Set this to get a dark room. The higher the value, the darker the room.
Use set("dark",value); to set the darkness level of the roomtype.

Class -- The roomtype class.
Use this to group many romtypes together as the same class, all roomtypes with class set to the same thing will use Seen from same, instead of Seen from other.
Set with set("class",the_class);


The maptool commands

The file is called /players/milamber/mapsystem/maptool.c, and can be linked to the shell. OBS - This is a shell module and not a clonable object, do 'shellhelp modules' for more info.

Commands


NAME
minfo - show info for mapsystem(s)

SYNOPSIS
minfo [-1]

DESCRIPTION
See some info for all mapsystems.
If -1 is specifed, you will see if the mapsystem is loaded,
and if so, if it is open for mortals. Unloaded mapsystems are always considered to be closed


NAME
mgoto - goto a location on a map

SYNOPSIS
mgoto map,x,y,z

DESCRIPTION
This one is simple.. It will move you to location x,y,z on the map map.
The number for map is the same one as in minfo. It is quite possible to enter an undefined room, but nothing will happend.
NAME
mmap - Draw a map of the mapsystem you are standing on.

SYNOPSIS
mmap [-1]
if -1 is specified, the REAL roomtypes will be showed, instead thoose that are specified with 'set_replace'.

NAME
mmake - make a .h file from a .map file.

SYNOPSYS
mmake from-file to-file

DESCRIPTION
This will make the file from-file into to-file, using a filter
that will:

1> scan for a '#begin x,y,z\n'
2> read data until it sees a '#end\n'
3> If any file is still there, go to 1.