Introduction to MusicMUD building

Copyright © 2003 Abigail Brady.

ChangeLog:

10th May 2003 - added Rants, Wanders, More Complex Traps, Advanced Rooms, Trade, Zone properties, Advanced Objects.
9th May 2003 - added Containers and States, Doors, and Mobiles.

Introduction

So, you've compiled and got a master user character on your musicmud. And you want to build a small area to play with perhaps, but don't know where to start? This document is for you. It is a work in progress, and more areas of building will be covered with time.

If anything is particularly unclear, or you want to see something in particular covered next or you have any other comments, please feel free to mail me.

Making a zone

All permanent objects/rooms/mobiles are associated with a zone. You need to create the zone first. Type make zone. You'll be asked to enter the name of the zone. This should be a short string of alphanumeric characters. For the purposes of this guide, we'll use the zone name example. So, type that in here, and your new zone will be created.

Going to your zone

Type goin example_zone, and you'll be moved to the zone object. This is used to store rooms created as part of the zone, and any other objects you happen to put there.

Your first room

Enter make room. First of all you get prompted for the zone. If you just press enter here it'll default to the zone you are in at the moment. Then it will ask for the name of the room. This is what's displayed in look, after You are standing on blah in. Let's call it a Garden.

Next, you get asked to confirm the room. Enter yes. Your room is created, and it tells you the ID of the room. It then sets you editing the room description.

If you want to edit a room description do so. You can enter free-form text, with a . on a line by itself to end. Use blank lines to mark new paragraphs.

If you don't want to edit one just now, just enter .

You can now go into the room by goin example_1.

You displace yourself to the Garden (example_1).
Flags [Fixed] [Room] 
  This is a very nice garden.
You see...
  {the floor template_floor_1} 
Obvious exits are...
  None...

One noticeable thing is that it hasn't realised this garden is supposed to be outdoors. Fix this by flags here outdoors 1, which sets the outdoors flag on the room to 1 or true.

This will make two obvious changes. Firstly, the floor will be replaced with 'ground', and secondly, it will print out information about the estimated time of day - which will always be midday until this location gets hooked into a day/night cycle.

Linking rooms together

Type make room again, only this time you want to make a Kitchen, not a garden. The process is the same as before. It'll create example_2 - which is another room, but not connected to the Garden in any way.

To start creating a link, type make exit (from example_1). It will want the direction (say, north), the start position (the default should be ok so just hit enter), the zone (again, just press enter), and the destination. This would be example_2. It defaults to choosing as the destination the most recently made room you made, so you should be able to hit enter here again. You get asked whether you want an exit the other way from example_2 to example_1 - say yes, and finally whether you want to confirm it. Say yes once more.

It has now created the exits, and you can wander from example_1 north to example_2 and back again.

Editing rooms and exits

Room Descs

You can change a room's description with the 'desc' command. Type 'desc here' to change the description of the room you are in, or 'desc <idgt' to change the description of anything you like. It then asks you for the description.

Room Names

To change a room name, you want the 'set' command. For example set example_1 name Front Garden will change example_1's name to, well, Front Garden.

Deleting Rooms and Exits

Accidentally made an example_3 and want to get rid of it? Simply boot example_3. While this will delete all exits from example_3, it won't delete all exits to there. So, suppose you had made a west exit from example_2 to example_3 - you'd boot example_2_west.

Exit retargetting

If you don't want to boot an exit and recreate it, you can simply change where it points. For example, if example_4_west is pointing at example_5, when it should be pointing at example_3, you can retarget it with set example_4_west link example_3.

Simplifying room creation

It's a bit of a pain to keep using the make system to make rooms and exits, so there's a simpler way. Go to the room you want to make an exit to a new room from, and 'dig' in the direction you want.

For example, if you dig west from example_1, it will create a new room, example_3, an example_1_west exit from example_1 to example_3, and an example_3_east from example_3 to example_1.

The rooms and exits created by dig can be amended as above.

Dig will copy some flags - for example Lit and Outdoors from the source room.

Making an object

So, let's make an object in the garden. A tree, perhaps. Go to the garden, then make object. The first thing it asks for is the short name of the object. In this case it wants to be tree. Then, it wants the normal name. It generates "a ^otree^n" by default, and since this is correct, we just hit enter. (If it were wrong, you'd enter what you really wanted).

It then asks for the start location of the object - which is where you are, so just hit enter, and the zone, which again defaults to the right thing. Finally it asks you if the object should be a container no, and whether it should be fixed yes.

A container is an object which you can put other objects in, and a Fixed object is one which is scenery and cannot be taken. You can't put things in trees, and you can't take them.

You then get told the id of the tree (example_tree_1), and put in the description setting mode, which acts the same as for rooms.

Making it interactive

So, we've got our tree now. What happens when you try and climb it? You get the default response Nothing happens when you do that. This response sucks and we should change it.

We do this with a lua trap. In this case we want the one called climb, which is in the property 'lua.climb'.

Enter desc example_tree_1 lua.climb, followed by act(pl, "%1 %[tries/try] to climb the ^otree^n, but %[finds/find] it too smooth.") and return 1 and finally terminate it with a full stop on a line by itself.

This will mean that code is executed every time someone tries to climb the tree. What does the code actually do?

act is a messaging function. You have to give it an actor, and a string. It then processes the string for printing to the actor, and everyone else in the same room as the actor. pl is a constant that's been defined for you. It's the current player - the one who did the climb.

act() uses the same syntax as action strings. In this case, %1 means the actor's name, or 'you', if being printed to the actor. The "%[blahs/blah]" is processed according to plurality and target. If it is being printed to the actor, or the actor is plural, it chooses the second one - blah, and to others, it shows blahs. This means it will show You try to climb the ^otree^n, but find it too smooth. to the actor, and [Name] tries to climb the ^otree^n, but finds it too smooth. to everyone else.

The final bit, return 1, gives a return value to the environment. If you just fall off the end, or return without a value, or return 0, then it will still cause the normal course of events to happen. To abort the printing of the default error message, you do 'return 1'.

Manipulating objects

Changing start

Suppose we accidentally made this object in the wrong location - example_2. To fix this, you don't want to just move it, you need to set it so when it resets it ends up in example_1.

There are several ways of fixing this - the first is to displace example_tree_1 example_1 then unreset example_tree_1. This moves the object to where it should be, then 'unreset's it. Unreset means updating the objects reset state with how it is now, so it will reset to that position in future.

The other is to directly set the start property on the object, with set example_tree_1 start example_1. Nothing happens immediately, but the next time the zone is reset (which you can force by reset example, the tree will be moved to where you said.

Cloning

Imagine we made an object called example_foot_1, which is a severed foot.

If you wanted another one of these to play with, you could simply clone it by typing clone example_foot_1. This clone would save with you, and may disappear when the zone it happens to be lying around in resets.

Plural names and other properties

So, you've cloned several copies of example_foot_1. And, horror of horrors, it now says you have "three foots"! This crime on the English language should not be permitted. You can fix it by doing set example_1 name.plural feet.

The normal name of the object is kept in 'name', and the short name is kept in 'short'.

Deleting

You can simply boot objects just as you do with rooms and exits.

Object mass

Every object that isn't Fixed should have a mass set on it, in grams. set example_foot_1 mass 100 will set the mass of example_foot_1 to 100g. This shows up in 'size', and stops you from carrying too much stuff, or putting too much stuff in containers.

Making containers

Containers are objects with the Container flag, which you can either make directly, or you can turn an object into a Container with the flags command. All containers should have a maxload set on them, in grams, which is the maximum mass you are allowed to put in them, in grams.

Making clothes, armour, and weapons

Clothes

You have made an object called example_shirt_1, called 'a shirt'. You can take it and stuff, but its inert - you can't wear it.

Two properties are used for clothing, wornon and wornlevel. Wornon should be set to something like body or legs or arm or hand or eyes or hands or leftleg as appropriate. [XXX : make a link to a list].

Wornlevel determines what sort of clothing it is - and what it can be worn over. 0 indicates it can be worn over nothing, 1 can be worn over nothing or wornlevel 0 stuff, etc. 0 is used for underwear, 1 for stuff like tshirts or vests, 2 for regular outerwear like shirts, 3 is used for jackets, 4 would be used for overcoats or other protective equipment.

So for our shirt, you would want to set example_shirt_1 wornon body and set example_shirt_1 wornlevel 2. And then you can wear it.

Armour

Armour is just a piece of clothing with the 'armour' property set on it. This can be between 0 and about 20.

Weapons

A weapon is an object that has 'damage' set on it. This should probably range between 5 and 25. Weapons should also have a 'wtype' set on them. This is 1 - impact, 2 - cutting, 5 - stabbing. This determines what combat messages are used, and some other things. You can just use set to set these, e.g. set example_sword_1 wtype impact.

Food and drink

Introduction

Food is again, just a regular object, but with the 'food' property set on it. This is the number of health points it will heal you when you eat it. It can be set to a negative value (causing harm), or 0. If its set to 0 then you can still eat it, but it just won't do any good.

Drink is just like food, except it has the Drink flag.

Empties

If i have a slice of bread and I eat it there is usually nothing left (bar the odd crumb). But if I eat a bar of chocolate, I have a chocolate wrapper left over. You can make an object be automatically cloned when you consume an item, by setting the 'empty' property on the food object to the wrapper object. You can also set the 'empty' on drinks to the container the drink should be in.

Refillables

If I have my pint of beer, I should be able to empty it, and re-use the pint glass. For this to work, the volume property on the glass must be set (in millilitres), along with the WaterTight flag. So, set example_glass_1 volume 568.

Alcohol

If you have a drink, and it has an empty set on it, you can set the 'abv' property on the drink to the alcohol-by-volume. This should be per-10000, so 3% abv would mean you did set example_beer_1 abv 300.

Containers And States

Imagine we made a box which was a Container, and you could put stuff in it. You might also want it to be possible to close or lock the the box.

There are two flags here - CanOpen and CanLock. CanOpen means the user can use the 'open' and 'close' commands to change the object between state 0 and 1. (State is stored in the !state property, and gets set on a reset to either 0, or whatever is in the initstate property. An unreset will set the initstate to the current state.)

State 2 represents Locked. You can only transfer an object into or out of the Locked state if you have a key. For example, if example_box_1's key property is example_key_1 or if example_key_1's lock property is example_box_1. If something is a key for an object, then so are any clones of it.

Different Names for Different States

If you have a dozen clones of example_box_1 and say, half of them are open and a three are locked, and the other three are closed, and they are on the floor and you look, you will see -
You see...
  six boxes (locked)
  three boxes (open)
  three boxes (closed)
This is perhaps rather ugly. We can set the name of the objects in a per-state way. For example, if you set example_box_1 name.0 an open box, and set example_box_1 name.1 a closed box, and set example_box_1 name.2 a locked box, then you will see
You see
  three open boxes
  three locked
  six closed boxes
These can be more interesting than that, for example, people have made envelopes that when they are in state 1 represent a sealed envelope and when in 0 represent a torn open envelope.

Additionally, the stated names will be used in more places than just look. If you examine an object it will say "You examing the open box" rather than "You examine the box", and it will make them appear in inventory, etc.

If you need custom plurals for any of the state-specific names, you can put it in name.0.plural, etc.

Transparence

By default you can only look in, take stuff out of or empty or put stuff in a container, if it is Open (in state 0). But this isn't appropriate for things like a trophy cabinet, where it can be closed but you can still see inside. Set the Transparent flag on any objects you want to be able to see in even though they are closed.

Doors

Doors build on Openable/Closable items. The CanOpen/CanLock/key/lock and states system apply to them also, but with some extensions. Obviously, doors shouldn't be containers. Then, you need two objects for each door - one in each room.

For example, I might put an example_door_1 in example_1 and call it "a back door" and an identical object as example_door_2 in example_2. When I open one, it should open the other - this is accomplished by setting the 'other' property on each door to point to the other door.

However, this just will set up two linked items - it won't actually stop you from moving through the exit whilst the door is closed. To do this, set the 'door' property on the exit to the door.

set example_door_1 other example_door_2
set example_door_2 other example_door_1
set example_1_north door example_door_1
set example_1_south door example_door_2

Hidden Exits

Suppose we wanted a hidden tunnel from the back garden to somewhere else, that you can discover with dig. We'd set up the exit from example_1 down to, say, example_9.

How would we make the exit inaccessible? We'd set the 'door' property on the exit to an object, and make sure that is in state 1 - until you dig, when it should get changed to state 0. Let us use the room itself for that purpose. so

set example_1_down door example_1
set example_1 initstate 1
reset example

If you type 'down' you'll get a really nasty error message about the Back Garden not being open. So, set the 'Secret' flag on the down exit. Then, you will be given the usual 'that exit does not exist' error.

The code to discover the hidden exit is quite simple

desc example_1 lua.dig

-- if example_2 is in state 0 already, we just return (and get the needlessly attempts to dig message)
if state(o1)==0 then
  return
end

-- we now know it is in state 1

act(pl, "%1 %[digs/dig] and %[discovers/discovers] a tunnel leading downwards.")
-- do the messaging

setstate(o1, 0)
-- set the room to be in state 0, hence actually unblocking the exit.

return 1
-- return 1 to the environment, which will cause the usual handling to be aborted.
.
So, after you've dug (for the first time), it will print a message to you and everyone in the room, and the exit will then be free to traverse.

Mobiles

Making Mobiles

For our first mobile, we shall make a guard that stops people going north from the garden into the kitchen. Start off with make mobile, then enter at the zone, and enter guard for the short, and "a guard" for the long name (no colour codes). Hardness should be set to whatever you like - say, medium. Wander is whether the mobile should wander around - say no. Gender should be m or f or n or a.

It then asks for for the tells. Just enter . for all of these at the moment.

Finally, it asks you to confirm the mobile. Do so. You now have example_guard_1

Barring

To make him stop you from going north, set the BarNorth flag on him. As you are an immortal, you will find he isn't actually barring you. You can test this in various ways - remorting, turning that priv off (pflags me NoHassle abey - use reclaim instead of abey to get it back).

Reasons

If you want him to give a reason or other reaction for barring people, you can just set 'barwhy' on him to a command. For example set example_guard barwhy say You aren't allowed in there without a pass!

Allowing Past

Suppose we want this guard to selectively let people past - anyone with example_pass_1. We can set a lua trap on him - lua.before_bar. This can then check to see if example_pass_1 is being carried by the player, and if so, allow the user past.

The code would be something like

if owner("example_pass_1")==pl then
  act(o1, "%1 %[lets/let] %a pass.", pl)
  return 1
end

If the owner of example_pass_1 is the player, then it prints a message that o1 (the potential blocker) lets pl (the player) pass. It then returns 1, which means to not block.

Otherwise, it will just fall off the end and block as per usual.

There are 6 flags, BarNorth/South/East/West/Up/Down, and also one that bars all movement RefuseMove. If you use RefuseMove you will probably want to check in the trap the destination (which is o2), and just return 1 if you don't want to block in that direction.

Body Type and Other Abilities

Not all mobiles are human - they are also used to model dogs, aliens, robots, etc. We don't have full support for different body types, but there are a number of attributes you can set.

Firstly the body property (defaults to human, can also be set to fish, avian, tetrapod, droid, insect, etc). The only real ability this affects is that avians can fly with the 'fly' command.

The other capabilities are flags. Interesting ones include Gills (can breathe and swim underwater), NightVision (can see in dark), NoLegs (has no legs and can't walk), CantTalk (isn't capable of speech). CantTalk should definitely be set on all non-sentient mobiles.

At some point body types will be made more magical, so a certain body type will imply more flags, and different body parts.

Mobile tells

Mobiles can respond to tells on a simple keyword based system. For every word in a tell, it sees if there is a handler for that word, and if so triggers it. It will stop at the first handler.

Handlers can either be normal commands (in which case the property is tell.something), or lua code (lua.tell.something).

For example, set example_guard_1 tell.name tell $1 None of your business.

Will make the guard do "tell $1 None of your business." when he is asked his name. $1 means the name of the player who triggered the tell - you can use this as a target of a give, or an action, or a tell. Of course, any random other command can be used also.

Lua tell handlers can be more complicated. Suppose we wanted the guard to be less rude to the person with the pass. We would remove tell.name from him and replace it with a lua.tell.name as follows

if pl==owner("example_pass_1") then
  tell(o1, pl, "Mr Black, sir.")
else
  tell(o1, pl, "None of your business.")
end

Note: a return 1 is not necessary for a tell trap.

XXX: Telldefault

Mobiles and equipment

Wornfrom

You may have noticed that if you examine the guard, he's not naked. He seems to be wearing the clothes that template_person_1 is wearing. This is the 'wornfrom' feature. Rather than equip lots of mobiles with clothing that is just their for cosmetic purposes, you can instead make them wear the same clothing as a template mobile.

It will consider all mobiles in the same room as template_person_1 and choose the best match. It matches on nation, 'role' property, body type (which must match) and gender (chooses matching gender if available).

You can override the default matching and directly set the wornfrom property. This can be set to a mobile id, or '-' to indicate nothing.

Making a mobile wear a piece of eq

Imagine we have made an example_cap_1, wornon head, wornlevel 2, that we want the guard to wear. We would move it to the guard, force the guard to wear it, then unreset example_cap_1. Then whenever the zone is reset, the guard will start wearing the cap again.

Autoclothes

You can also set up an object to be cloned automatically and worn (or wielded or held) upon a reset. This saves all the tedious copying and so forth. Simply goin the mobile, and do 'addworn' on the object id. Then reset the zone. The mobile will be equipped with a clone of this.

This is how the template mobiles should be equipped with template clothes, for example.

Rants and wandering

Mobiles can be set to do things every so often. There are two mechanisms for this - wandering and rants. Wandering just refers to the mobile walking (or however) around, rants refer to execution of a random command from a list every so often.

Wandering

A wanderer is a mobile with the Wander flag set. It will then wander around. You can limit it to a certain area with the WanderZone flag, then it will only wander around the zone it's a part of. You can make wandering happen faster or slower by setting the wander.time property on the mobile - it defaults to eight.

Rants

A ranter is an object (it need not be a mobile) with the Ranter flag, and a rant array.

Rant array means that it has rant.count set to n, and then rant.0 through rant.n-1 existing. For example
set example_ranter_1 rant.count 3
set example_ranter_1 rant.0 say This is the first rant.
set example_ranter_1 rant.1 say This is the second rant.
set example_ranter_1 rant.2 say This is the third rant.
Then, from time to time, the ranter will execute one of the commands.

XXX: Rantspeed.

More Complex Traps

Suppose we have a mobile (example_guard_1) which carries something you want (example_book_1) They'll give it in exchange for something they want (example_coffee_1). We would make a lua.after_give trap on the mobile. It would check that the object given is the one we are interested in, and if so give the other object to the player, and then refrain from giving it back.

This is what
if o2==get("example_coffee_1") then
  give(o1, "example_book_1", pl)
  return 1
end
does.

Of course, this only accepts the original coffee object. If there are clones around that ought to be just as good, we need to handle that too, which can be done by if isa(o2, "example_coffee_1") then.

So, that's all well and good - except when you give him the second cup of coffee - he'll just try to give you the book again. Who knows whether it will actually teleport the book to him and cause him to give you it? Or whether it will just fail silently or what - try finding out if you like.

So, to handle that, it must be replaced by

if o2==get("example_coffee_1") then
  if owner("example_book_1")==o1 then
    give(o1, "example_book_1", pl)
  else
    tell(o1, pl, "That's funny, I could have sworn I had a book on me a moment ago.")
  end
   return 1
end

Advanced Rooms

Floors

Every room has a 'floor' object in it by default - template_floor_1 for indoors locations, template_ground_1 for outdoors locations.

If you want a custom floor, there are several options. Firstly, you can make an object and put it in the room and give it the Floor flag. If you want it re-use another object you have used elsewhere, set the 'floor' attribute on the room to the id of the floor. You can do this to a whole zone with the 'floor' attribute on the zone. (floor on zone will be overriden by floor on room will be overriden by Floor flag on an object).

If you don't want a floor, just set the 'floor' attribute to '-'.

Prepositions

Suppose you've made a room named "My Office". It will come up as "You are standing on the floor in the My Office." It needs hinting about the right preposition to use. Do this by going to the room and typing 'namestyle in'.

Building Names

There's a room that's called Reception. But from the street, you don't want it to be called Reception - you want it to be called Town Hall, or something else. Simply set the 'building' property on the room to 'Town Hall', then from all Outdoors locations the exit will appear to be called Town Hall.

ByWater, OnWater, UnderWater

The mud supports 3 different types of locations with water in them. ByWater is used to model a beach. There is an interface between the ground, the water, and an air. Players who can swim and walk can transfer between the water and the ground freely.

OnWater is used to model the surface of a body of water nowhere near land. You must have CanSwim to get to these.

UnderWater locations are those that are entirely underwater. You must have breathing equipment (Gills flag or wearing an object with Gills flag) to get here - and if you somehow wind up here without it, then you drown eventually.

You can set a 'seabed' property on a room which will mean when you type dive there, you arrive at the dest. There is also the corresponding 'surface'.

Objects dropped in a water location will (a) if they float, they will try to go to a surface if one is set, otherwise will remain where they are. (b) if they sink, they will go to a seabed location, otherwise they will vanish. The CanFloat flag is used to determine floatingness.

Lighting and Day/Night

Locations default to being lit. You can make a location Dark by setting the Dark flag on it - you can set this on a zone to make everything in it Dark. This can get overriden by the Lit or OnFire flag on objects. If I have a Lit torch in a Dark room, either in my inventory or on the floor, I can see it.

In a dark room, most commands will not work. For example, you won't be able to look, and you won't be able to examine objects. You can make some objects visible (or at least referrable to) without making the whole room light - set the Glowing flag on the object. You won't see it in look, but if you know the lightswitch is there you can 'press switch' to try and switch a Glowing lightswitch.

Outdoors rooms will be light and dark as per the day/night cycle - unless they have the Lit flag, in which case they get automatic lighting at dark. How does it decide on the day/night cycle? You set 'daylen' on the zone to a number, say, 100 or 200.

Trade

Stores

Mobiles can be set to act as traders. Set the 'Store' flag on the mobile, and populate the 'shop' array on it with stuff. For example, you'd set shop.count to 2, shop.0 to example_bucket_1 and shop.1 to example_fish_1. Then the mobile will sell fishes and buckets. You can make it have only a limited stock of fishes, by setting shop.1.istock to 2. Whenever the zone is reset he'll get restocked.

The price is determined by the 'cost' property on the objects, and the ripoff factor of the shop - shop.ripoff which should be a percentage (defaults to 100%).

By default, mobiles will buy back anything. You can change this behaviour by setting the 'stype' - it can be 'none', 'junk', 'anything', 'jewelry', 'vehicle', 'empty', 'weapon', or 'medical'.

[XXX : it's possible to write traps for more fine-grained control on selling back] The price paid for items will be by default 90% of the cost - you can configure this with shop.offer on the mobile.

Traders like this will be capable of wandering around and can sell you stuff from wherever they happen to be. If this isn't desirable, you may want to set the Store flag and all the shop properties on the room instead - and then simply have a shopmob property on the shop pointing at the shopkeeper.

Traders will not buy Contraband stuff unless they themselves have the Contraband flag.

Banks

Make a location have the Bank flag, and a mobile to act as cashier. Set bankmob on the bank to point at the cashier. You have a bank.

Zone properties

Death Points

When you die, it tries sending you to a hospital. It looks in your room's hospital property, the zone's hospital property, chains through 'fwd' properties looking for a hospital property, and then eventually gives up and grabs the contents of $defhospital on @musicmud. It then moves you there, sends you to sleep, and if there's a $blanket on @musicmud set, will clone one and make you wear it.

So, $defhospital should be set up to the default hospital recovery room. And 'hospital' property on zones.

Chains

The zone lookup for this is different than the zone lookup for Light/Dark. With Light/Dark it actually goes to the parent object of the room, so if test_1 is in example_zone, then it will check Dark on example_zone.

But for these zoneprops, it actually grabs the contents of the "zone" property and finds out what _zone object exists for it, and then uses that one. 'fwd' chains should be set up.

Planets

In the default 'who' is a column showing where you are. This comes from a zoneprop called 'planet'.

zonefwdplanethospital
city_zoneFoo Citycity_10 (City Hospital)
suburb_zonecity_zonesuburb_3 (Outskirts Hospital)
enclave_zonecity_zoneBar Enclave

If you are in city_zone, then it will show up as Foo City, and when you die you wake up in the city hospital. If you are in the suburb_zone, it will show up as Foo City still, but when you die you will wake up in the Outskirts hospital. And if you are in the enclave, you'll show up as in Bar Enclave - and when you die you'll end up in the City hospital.

Save Points

The algorithm for deciding where to save you at is as follows:

I tend to like making all rooms sticky apart from those which are part of quests, and that if you logged back into them would be bad.

Advanced Objects

Scenery

It's nice to have examinable scenery in a zone. But it's not so nice to have to build or even manually copy scenery over and over again - corridor walls in all your corridors.

There are two ways of doing this automatically. Auto clones or tele objects.

Auto Objects

Auto objects are cloned on a reset. They come out of the 'auto' array on an object, (This is the same mechanism as autoclothes). Go to the room, addauto the id, and reset the zone. And it's there. You can manipulate the array directly also.

Auto objects act just like regular zone-based objects, they can be removed, they reset with the zone and cause the zone not to reset if observed, and they don't save.

Tele Objects

This is unnecessary overhead for most pieces of scenery, that doesn't need to be modifiable. It should just be there to be examined, and that's it. Rather like floors.

Simply add them to the tele array on the room - e.g. tele.count 1, tele.0 example_wall_1, then it will appear that that room has a wall in it. You can examine it.

Note: tele objects must be non-interactive. They should not be Mobiles, Ranters, Wanders, Containers, Lightable, Pushtoggle, or non-Fixed, and their state may not change otherwise weirdness may result. Static scenery, including fixed tables, chairs and beds are ok.

Discovers

When you examine an object you might discover another - for example, examining a heap of junk and finding a cheque. To do this you'd make the objects and set example_junk_1 discover example_cheque_1. Then when the junk is examined for the first time since the zone was reset, the user will discover the cheque. (In the meantime the cheque should be placed somewhere hidden, like example_zone, or an inaccessible storage room)

If you want to be able to discover multiple items, you can use the 'discover' array, (e.g. example_junk_1 discover.count 2, discover.0 example_cheque_1 and discover.1 example_single_1).

If you want to clone objects for discovery, rather than make specific ones, use the 'disc' array.

All the various forms of discovery can be done at once.

Stated descriptions

As with name, descriptions can be stated - you can have a desc.0 which is used if the object is in state 0 and you examine it, a desc.1, etc. These also apply to 'look' in rooms.

If you have more complex needs than this, you can actually override the handling with a trap. Setting lua.before_show_desc on an object lets you send stuff to pl, and then return 1 will abort the usual lookup for 'desc'.

PushToggle/reveal/light

Some simple switches and other traps can be made directly with flags.

If I had a lightbulb and a lightswitch, I could set PushToggle on the switch and set the light property on the switch to the lightbulb. Whenever i pushed the switch, it would toggle between state 0 and 1, and the lightbulb would get turned on (if the switch is in state 0 now), or turned off (if the switch is in state 1 now), with message to the room the lightbulb is in.

PushToggle objects can be set as doors for exits, and this is especially useful if they have a 'reveal' property, that describes what's going on.

For example, if I have a box that is the door for an exit (a hole in a wall perhaps), I can set the box to state 1, and make it PushToggle. I can then push the box to turn the exit on and off. By defualt it won't actually mention that, just will say "You push the box." But if I set 'reveal' to 'a hole in the north wall', then it will say "You push the box, revealing a hole in the north wall." or "You push a box, blocking a hole in the north wall."

A PushToggle object can also have an other, just like a door.

Seats, Tables, Beds

A chair is an object with a CanSitOn flag. People can then sit on the chair. By default it has no limit on the number of people - you can set one with the OnePerson or TwoPerson flag.

A bed is an object with the CanSleepOn flag. People can sleep on beds, and implicitly sit on them too. But you can't sleep on a chair.

A table is object with the Table flag. You can put stuff onto Tables, take stuff off them. Tables can have heights, so you can't see what's on a table (say, a really high shelf), this is modelled with the 'height' property (measured in mms). If set to above eyelevel (1500mm default), then you can't interact with the shelf.

But, if you stand on a chair or a lower table that's high enough, you can interact with the stuff on the high shelf!

You can stand on tables, beds, chairs, and the floor. Tables beds and chairs should be fixed objects, they will react wackily if moved around.

Mounts

A mount can be either a mobile (e.g. a horse), or an object (e.g. a bike). Just set the Mount flag, and it will start to work.

XXX : bunches of other properties mainly message customisation - including multiple mounters.

Fragiles

Objects with the Fragile flag will break when you smash them, when you drop them, sit on them, sleep on them, or stand on them, or when you throw them at things. You can avoid smashing them by 'putting' them on the floor, rather than dropping them.

Invisibles

Do you not want an object to appear in 'look', but just hide a reference to it in the room description? Set the Invisible flag on it.


Lua Libraries
Traps Available