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.
#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.
- 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.