And yes, you can have MUSH descriptions respond to game data and commands:

The Harbor View Restaurant
[space(7)][ifelse(%vo,Through the many panes of the broad bay picture window\, [ifelse(day(),a picturesque view of the harbor dominates the room.,running lights bob in the darkness across the harbor.)],A floor to ceiling curtain conceals a broad bay picture window.)] Rough tables and worn captain's chairs add to the flavor of the setting, if not the food.

The %vo in the first ifelse() is a toggle value stored in the room by a command that opens and closes the curtains. The day() function in the second is part of the weather system, and returns a boolean value for day or night. For more variation, you could use the switch() function, and have as many choices as you want. For instance, you could switch on season() and change the pictures on a calandar. WoD games have separate or extra descs depending on who's looking at them. Pratically any information in the game is available (except passwords) to objects with Wizard permissions.

The point, really, is that mushcode can be imbedded in text. It will be executed whenever the text goes through the parser. You can put code in room or player descriptions, in exit success messages, and even in says and emotes.

Here's another example from Lydia Leong's "Pax Magica" TinyMUSH, which was based on Ars Magica rules and set in Venice, 1100 AD. I wrote the descs and the mutter code (a brash thing to do, as Lydia wrote the original mutter code years before), so I don't think she'd mind my posting it.

@dig/teleport Domo Dandolo: Salone
&STD here=Morning and afternoon, a gentle Mediteranean light filters through the
coloured panes of the ornately framed windows high on the end walls and bathes
the fading frescos on the side walls with a restorative glow. Sumptuous woolen
oriental rugs are arrayed askance with a lack of precision contrapuntal to the
geometric parquet floor. Low couches, chairs, and tables with an Egyptian look
cluster in several settings.
&SHORT-DESC here=A large, bright room with clusters of Egyptian furniture on
Persian rugs.
&EXITS here=To the south there are two large, intricately carved doors leading
out to the balcony overlooking the front campo. Along both the east and west
walls there are three exits, the southern-most are two broad archways opening to
the Libreria and the Sala da Pranzo. %bNorth of these are four arched doorways,
two on each side, leading to the private chambers of the family.%b At the north
end of the room is a marble balustrade around the stairway to the androne below.
&SAY1 here=^* *"*.":@switch num(%0)=#-1,,@pemit/contents #1963=Through the arch
to the Salone\, a [switch(get(%0/sex),M*,male%b,F*,female%b,)]voice says\,
"[u(mutter,%2)]."
&SAY2 here=^* *"*!":@switch num(%0)=#-1,,@pemit/contents #1963=Through the arch
to the Salone\, a [switch(get(%0/sex),M*,male%b,F*,female%b,)]voice exclaims\,
"%2!"
&SAY3 here=^* *"*\?":@switch num(%0)=#-1,,@pemit/contents #1963=Through the arch
to the Salone\, a [switch(get(%0/sex),M*,male%b,F*,female%b,)]voice asks\,
"[u(mutter,%2)]?"
&MUTTER here=setq(0,words(%0))
[setq(1,switch(1,%q0,1,lte(%q0,5),sub(%q0,1),sub(%q0,rand(4))))]
[setq(2,extract(shuffle(lnum(%q0,1)),1,%q1))][map(dots,elements(%0,sort(%q2)))]
&DOTS here=%0..
&SAY4 here=^* *"*.":@switch num(%0)=#-1,,@pemit/contents #1962=Through the arch
to the Salone\, a [switch(get(%0/sex),M*,male%b,F*,female%b,)]voice says\,
"[u(mutter,%2)]."
&SAY5 here=^* *"*!":@switch num(%0)=#-1,,@pemit/contents #1962=Through the arch
to the Salone\, a [switch(get(%0/sex),M*,male%b,F*,female%b,)]voice exclaims\,
"%2!"
&SAY6 here=^* *"*\?":@switch num(%0)=#-1,,@pemit/contents #1962=Through the arch
to the Salone\, a [switch(get(%0/sex),M*,male%b,F*,female%b,)]voice asks\,
"[u(mutter,%2)]?"
&PLACESMAX here=3
&PLACESCLEANUP1 here=^* has left.: placescleanup(%#)
&PLACESCLEANUP2 here=^* has disconnected.: placescleanup(%#)
&PLACENUMS here=|||
&PLACE1 here=the cluster of chairs by the balustrade|6|3||There's no room to add
a chair there.|There's no place to move there.|You sit down at|sits down at|You
stand and leave|stands and leaves|At your setting
&PLACE2 here=the grouping in the center of the room|6|6||There's no room to add a
chair there.|There's no place to move there.|You sit down at|sits down at|You
stand and leave|stands and leaves|At your setting
&PLACE3 here=the couches and chairs between the arches|8|6||There's no room to
add a chair there.|There's no place to move there.|You sit down at|sits down
at|You stand and leave|stands and leaves|At your setting
@VW here=[switch([atplace(#1964,3)],,,{with
[iter(atplace(#1964,3),[name(##)])]})]
@set here=FLOATING
@set here=JUMP_OK
@set here=MONITOR
&COMPASS here=mini show_dark
&AURA here=Mundane 0
@set here=FLOATING

Again, the desc is right justified in a fixed-width font. This rooms features three virtual "places" where you can sit and chat privately with several other people. The Places code is "global" and works anywhere, all that's here is local setup data. The room also has two broadly arched doorways through which partial snippets of conversations can be heard from other rooms. That is, if there was a fight going on in the Library you might hear, "Enrique...have... ... a donkey!" This code is local, and is entirely on the room.

(the following is a programmer's rant, and a bit of a tangent, so feel free to ignore it)

I do actually have what I feel are some pretty sound reasons for disliking mushcode as it actually gets used - the emote example earlier is pretty innocent and, IMO, just about as far as you can go without turning mushcode into noise. Anyway here's my list of grievances:

- It's used for things that really ought to be done with an actual programming language (we have Python for this). Mushcode does not scale.
- The interpreter is slow and childish. There's no intermediate representation of any kind. This is not an issue for simple stuff, but see point 1.
- Some people try to sell it as a 'Lisp-like' language. I don't know how common this is but I've definitely seen it referred to in this way. As a Lisp hacker I find this personally offensive.
- Related to the last issue is the matter of syntax. One of Lisp's defining features is its uniform syntax (S-expressions). Mushcode functions have the unique distinction of parsing and evaluating their own arguments, so there is no consistent syntax whatsoever. There are weird, silly things going on with it as a result.
- Registers. Here in the 21st century we give names to our variables.
- "List processing." Yeah right. More like string processing pretending to be list processing. Reminds me of tcl, except tcl is fairly sane.

While I can appreciate the hack value of mushcode, to me it's a lot like programming in TeX. As anybody who has read appendix D of the TeXbook can tell you, that definitely qualifies it as evil.

Sandi wrote:

The point, really, is that mushcode can be imbedded in text. It will be executed whenever the text goes through the parser. You can put code in room or player descriptions, in exit success messages, and even in says and emotes.

Yes this is quite a convenient feature. One which I am intent on replicating. I implemented this for rooms earlier today, but I can't make it fully general purpose until I have a quota/security model in place.

(hmm... it's very dark in here... maybe I should rant about MUF instead)

In ColdC you build through a series of commands, just like in a MOO or Mush or OLC. And since the game is soft-coded people can write their own custom building commands or scripts.

For example, in ColdCore there is an interactive @build command:

Quote:

@build
This is the do-it-all system for building places. At any time you can enter "@abort" to abort building. To turn off these hints "@set experienced" in your regular command environment.
----------------------------------------------------------------------------
Name aliases can be specified on the same line as the name. This is done by seperating them from the name with commas. Any number of aliases can be specified in this manner (such as "Name, alias, alias, alias"). Names types can be defined by appending +type, where type is one of proper, unique or normal. Not specifying a type defaults to normal.
----------------------------------------------------------------------------
Destination:
Fork
The specified destination does not exist, therefore a new one will be created with the name you specified.
----------------------------------------------------------------------------
Realms are used to keep locations in relation with each other. To get a list of commonly known realms type @realms.
----------------------------------------------------------------------------
What realm is Fork in? [<Creation>]

Name aliases can be specified on the same line as the name. This is done by seperating them from the name with commas. Any number of aliases can be specified in this manner (such as "Name, alias, alias, alias"). Names types can be defined by appending +type, where type is one of proper, unique or normal. Not specifying a type defaults to normal.
----------------------------------------------------------------------------
Exit from the road not travelled to Fork:
north, fork
Name aliases can be specified on the same line as the name. This is done by seperating them from the name with commas. Any number of aliases can be specified in this manner (such as "Name, alias, alias, alias"). Names types can be defined by appending +type, where type is one of proper, unique or normal. Not specifying a type defaults to normal.
----------------------------------------------------------------------------
Exit from Fork to the road not travelled [south]
south, road
Completed building to Fork.
post-configuration..
Describe place Fork, Enter "." to finish or "@abort" to abort description.
There is a fork in the road here. Watch your step!
.
You submitted the following description:

There is a fork in the road here. Watch your step!

Keep this description? [yes]

Describe exit north, Enter "." to finish or "@abort" to abort description.
The fork ahead.
.
You submitted the following description:

The fork ahead.

Keep this description? [yes]

Completed post-configuration.
l

the road not travelled
The long and winding road goes ever on.

Visible Exits: north
n
You take north.

Fork
There is a fork in the road here. Watch your step!

Visible Exits: south
s
You take south.

the road not travelled
The long and winding road goes ever on.

Visible Exits: north
look north

north
The fork ahead.

Through north you see..

Fork
There is a fork in the road here. Watch your step!

Of course this can be accomplished with a string of individual commands or you can write your own commands. @dig makes places (rooms) and @attach makes pathways (exits). Places are placed in realms which are like Merc areas.

It's an object-oriented system so one creates new objects from exising prototype objects.
Objects can have any arbitrary new properties added the builder needs.

For example $wearable is the prototype for things you can wear.
Creating a new item can be done like this:

Tyche wrote:
It's an object-oriented system so one creates new objects from exising prototype objects.

Could you elaborate a bit about just what else defines an 'object-oriented' mud, please. It's one of the examples of where I've had misunderstandings in the past, because 'object-oriented' apparently means different things to different interpreters, rather like the term RPI does to some.

For instance I used to call our mud 'object-oriented', because that is a large part of the goals of our gameplay - to collect the best possible set of objects that are useful for different purposes (not just weapons and armour). In other muds I've seen objects play a very minor role (apart from the above-mentioned weapons and armour - they often don't even have a description, let alone a valid use).

But apparently, since it means something totally different code-wise, using the term in this other context seemed to offend some people. So perhaps you could explain why it was such a touchy subject? Note, I am not asking this to be cute, I genuinely want to know.

ColdC is object oriented in that everything in the database (which encompasses basically the entire game including some fairly low level details) is an object: a collection of code (methods) and data (variables) which can 'inherit' variables and methods from parent objects. So, for example, there's an object called $place which every place inherits from.

Okay, what does this mean? Well let's take a look at an actual ColdC object. I went and picked a man-eating sofa. This object inherits two others: $thing and $has_seats. $thing is the base of all things located inside the world. By inheriting $has_seats, the object automatically gains a set of methods which allow users to sit on (and get swallowed by) the object.

Each object also defines a set of variables: for example most things in the game are derived from $has_name, which has a variable for the name of an object. $place defines a list of exits, entrances, a realm, etc.

$sofa, though, is basically equivalent to a 'prototype' in a dikumud: in order to create an actual sofa, we clone this object, producing $sofa_1, and put it in an actual place.

You can browse the objects in ColdCore here if you're interested, and a much more coherent description of the object system is available in the ColdCore manual.

I do actually have what I feel are some pretty sound reasons for disliking mushcode as it actually gets used - the emote example earlier is pretty innocent and, IMO, just about as far as you can go without turning mushcode into noise.

Okay, let's put this one to bed. On a slab in the Morgue.

eiz is quite right on all his points. The fundamental failing of mushcode is the better it gets, the harder it is to read. And I'm saying this as one whose native lanuguage is mushcode, one who is fluent in it to the point of poetry. Perhaps this is true of all languages (maybe there's an equation proving diminishing returns, for instance, consider haiku), nevertheless mushcode's usefullness as a maintainable codebase is limited, in today's gaming terms, to relatively small-scale endeavors.

Another serious problem with mushcode, that eiz mentioned indirectly, is security. It isn't. And this is compounded by the readability problem. The only way to keep it safe is to limit the entry points right from the beginning, because you'll never be able to go back through it and clean it up. Again, this points to keeping it small.

So why have I wasted your time with it? MUSHes are beautiful flowers (though perhaps poisonous), and they have attracted some of the best minds in MUDing, who work together in ways unthinkable in the DIKU world. Mushcode has many cool features to recommend it. Many things I feel someone creating a building system or extending a scripting system should be aware of.

Another serious problem with mushcode, that eiz mentioned indirectly, is security. It isn't. And this is compounded by the readability problem. The only way to keep it safe is to limit the entry points right from the beginning, because you'll never be able to go back through it and clean it up. Again, this points to keeping it small.

Well by needing to get a security system in I meant more along the lines of not letting random users execute arbitrary programs on the server, cause infinite recursion, and other nastiness that I have not yet bothered to prevent. I think what I'm going to do is allow ACLs to be attached to methods and properties, and then setup resource use limits. We'll see how it goes.

Sandi wrote:

So why have I wasted your time with it? MUSHes are beautiful flowers (though perhaps poisonous), and they have attracted some of the best minds in MUDing, who work together in ways unthinkable in the DIKU world. Mushcode has many cool features to recommend it. Many things I feel someone creating a building system or extending a scripting system should be aware of.

Well, it's certainly not a waste of time to look at mushcode. IMO, a language like mushcode is most effective at the finest level of detail, that is in the actual descriptions and so on, with some other system available (I believe KaVir was considering lua) for more substantial chunks of code where being maintainable is more important than being terse. I do not believe there will ever be a single language that solves all problems, as the concerns are just mutually exclusive.

For instance I used to call our mud 'object-oriented', because that is a large part of the goals of our gameplay - to collect the best possible set of objects that are useful for different purposes (not just weapons and armour). In other muds I've seen objects play a very minor role (apart from the above-mentioned weapons and armour - they often don't even have a description, let alone a valid use).

To prevent confusion, I'd be inclined to call such a mud equipment-oriented or item-oriented, as a specific subset of goal-oriented games. Object-oriented is really generally used to describe code structure.

Regarding scripting languages, so far I have the impression that the specific language itself doesn't matter that much except for the implementation level.

The interface of the scripting languages used seems to make the big difference.

Mush looks like half of it is composed of randomly assigned letters.
G II looks like someone forgot to finish the scripting language.
Cold looks like geek heaven, as well as someone taking olc a little too far.
Merc looks like the retarded little brother C never wanted.

While I'm not entirely sure how my contribution is useful, I do have a question, does any of these languages have a switch statement?

Could you elaborate a bit about just what else defines an 'object-oriented' mud, please.

Well I meant above and in the same as the name of MOO (or Mud Object Oriented) the programming sense. That is the programming language environment and to the extent that it influences the builder's view is object oriented. They need to know a bit about inheritence and encapsulation when building. OOD and OOP. Not a lot. After all they would mostly be working with objects from the leaves of that OO tree.

Of course builders anywhere do have to know something about the game goals too. I suppose you could say that equipment aquisition is object-oriented play. I don't mean that above; they can build any type of game they want and my comments are neutral to that use of object-oriented.

Sloth has an in-game scripting language but even so, I've found it worthwhile to make hard-coded mob functions (in the underlying language, C). These are mostly functions that could be done using the scripting language.

We seem to have a sizeable population of builders who don't want to mess with a scripting language (even a nice one like mine - sigh) but who do want to make fancier content than just rooms with exits, mobs with hit points, and objects with weights. The trick to getting builders to use a piece of hard-coded mob functionality seems to be first, intelligent default settings, and second, good documentation. In my experience having a function that does something reasonable if you stick it on a mob without setting any of the parameters is absolutely vital. I try to handle this by having it guess default settings for missing parameters from the mob level, species, and whatever else is available.

Of course, if your mud has a scripting language then you can write this sort of functionality in the scripting language instead of the underlying language (I generally don't, because my scripting language is deliberately missing a lot of stuff in order that it be impossible to write an infinite loop). Either way, many builders seem to prefer such pregenerated functions to rolling their own.

Well it's not really a scripting language, just a dynamic description system - it has basic support for 'if' statements, and I may extend the functionality later, but it's main purpose is text replacement for messages like "{name} swings {his/her} {weapon} at {opponent} in a vicious cleave."

We seem to have a sizeable population of builders who don't want to mess with a scripting language (even a nice one like mine - sigh) but who do want to make fancier content than just rooms with exits, mobs with hit points, and objects with weights.

Thatís funny, because the first thing new builders ask for in our mud is usually to get access to the script commands. We donít give it to them, until they have proven themselves to be serious builders by producing at least 50 rooms with mobs, objects and resets. The reason for this reluctance is merely protection for the other builders, because giving an unskilled builder script abilities is more or less like giving a razor to a monkey. Bad scripts cause more lag and crashes than any other form of bad building, and believe me, over the years I have seen plenty of examples.

But we probably should move the future script discussions over to the new thread I just started about script and mob_progs. Itís not that I am nitpicky with going off on tangents, itís just that it is easier to find things later if we stay on topic.