<!-- MHonArc v2.4.4 --> <!--X-Subject: SUMMARY: Mud Grammar --> <!--X-From-R13: "Xba O. Znzoreg" <wyflfvapNvk.argpbz.pbz> --> <!--X-Date: Sat, 15 Nov 1997 17:54:09 +0000 --> <!--X-Message-Id: 199711151754.LAA03805@dfw-ix10.ix.netcom.com --> <!--X-Content-Type: text/plain --> <!--X-Head-End--> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN"> <html> <head> <title>MUD-Dev message, SUMMARY: Mud Grammar</title> <!-- meta name="robots" content="noindex,nofollow" --> <link rev="made" href="mailto:jlsysinc#ix,netcom.com"> </head> <body background="/backgrounds/paperback.gif" bgcolor="#ffffff" text="#000000" link="#0000FF" alink="#FF0000" vlink="#006000"> <font size="+4" color="#804040"> <strong><em>MUD-Dev<br>mailing list archive</em></strong> </font> <br> [ <a href="../">Other Periods</a> | <a href="../../">Other mailing lists</a> | <a href="/search.php3">Search</a> ] <br clear=all><hr> <!--X-Body-Begin--> <!--X-User-Header--> <!--X-User-Header-End--> <!--X-TopPNI--> Date: [ <a href="msg00299.html">Previous</a> | <a href="msg00301.html">Next</a> ] Thread: [ <a href="msg00305.html">Previous</a> | <a href="msg00281.html">Next</a> ] Index: [ <A HREF="author.html#00300">Author</A> | <A HREF="#00300">Date</A> | <A HREF="thread.html#00300">Thread</A> ] <!--X-TopPNI-End--> <!--X-MsgBody--> <!--X-Subject-Header-Begin--> <H1>SUMMARY: Mud Grammar</H1> <HR> <!--X-Subject-Header-End--> <!--X-Head-of-Message--> <UL> <LI><em>To</em>: <A HREF="mailto:mud-dev#null,net">mud-dev#null,net</A></LI> <LI><em>Subject</em>: SUMMARY: Mud Grammar</LI> <LI><em>From</em>: "Jon A. Lambert" <<A HREF="mailto:jlsysinc#ix,netcom.com">jlsysinc#ix,netcom.com</A>></LI> <LI><em>Date</em>: Sat, 15 Nov 1997 12:56:07 -4</LI> <LI><em>Comments</em>: Authenticated sender is <jlsysinc#popd,ix.netcom.com></LI> <LI><em>Reply-to</em>: <A HREF="mailto:jlsysinc#ix,netcom.com">jlsysinc#ix,netcom.com</A></LI> </UL> <!--X-Head-of-Message-End--> <!--X-Head-Body-Sep-Begin--> <HR> <!--X-Head-Body-Sep-End--> <!--X-Body-of-Message--> <PRE> The following is a somewhat condensed and highly edited version of a March '97 thread regarding the processing of mud commands entitled "Mud Grammar". I have attempted to arrange the dialogue in a cohesive manner with my comments in << >>. Any mistakes or loss of context are likely due to my cutting and pasting. Comments as to the suitability of this format are welcome. Enjoy. :) <<start thread>> [Carter T. Shock] I posit that, in general, command interpreters for muds are Bad Things. The proposal runs sort of like this: The command interface to a mud can be viewed as a context free grammar. As such, one should be able to whip up a command interpreter with lex/yacc. I've started on it at least a dozen times but never managed to quite finish. Is this worthwhile? Thoughts? [JC Lawrence] A good MUD grammar is incredibly context sensitive. A simple example is the case where the presence or proximity of an object adds verbs to the players. There is no need for this crap to wander through the global namespace, or even warp the general grammar. That approach tends to preclude having a dynamic language where users or objects can add, redefine, mutate or delete verbs and nouns freely at runtime. A Very Bad Idea. [Nathan Yospe] <<Referencing JCL's comments>> Agreed. An object in someone's possession (in one of their bags or pouches, for example) might generate a certain set of new verbs for the owner, and in hand, a new set of new verbs, i.e. a grenade might enable "prime" as a verb, when held. I accomplish this by means of references in my internal language attachment scheme. Another example is: there is a horse in the room. The new verb "mount" has been enabled. "mount", in my system, might refer to a real function not normally accessed by the player, or to a bytecode function written in my internal programming language. [Chris Gray] <<In response to Carter>> I think you'll get a more rigid parser than you want for a MUD. You'll also get one that you can't add verbs to while the MUD is running. If you do it the classical lex/yacc way, you won't even be able to add words to the language! [Adam Wiggins] <<In response to JCL>> I don't actually agree with this. This is where you end up with things like "push" as a social, except for one room on the entire mud where it pushes a button. In another room with a similar button but written by a different person, you have to use "press." I dislike the effect you get from the old adventurer games of "guess the verb" - I want to know what commands I have available to interact with my character right from the start. Thus I know if I see a button in the room, I can always use a certain command straight off to try to push it. [Chris Gray] Actually I tend to agree with this quite strongly. Even though I've got lots of exceptions in my system. I've played "guess the verb" way too many times! However, that said, I think you do want to allow some exceptions, else you end up with the different kind of "guess the verb", where the player knows that verb "balance" is used to find out their balance at a bank, but now they have to figure out what the verb is to try to get the see-saw to stay entirely off the ground. If you put everything into one complex verb, you end up with *no* modularity in your system, and changing anything has ramifications everywhere. Its also a lot more painful to change a complex verb on the fly than it is to add another simple verb. So, I vote for a balanced situation - have a good set of verbs in the main grammar, but allow special case verbs and grammars as needed. [Adam Wiggins] It's a matter of consistency. So you can avoid this with good building - i.e. make people always use "push" to push buttons, pull to pull cords, break to break tripwires or doors or whatever. I'm a proponent of writing the system so that this is, at the least, very easy, and at the best, impossible to use non-standard verbs. Sure, there is overlap...and you can decide things based on context. I.e., we have a verb, "draw", which is mostly used for drawing weapons from their sheathes, but also can be used to draw a card from a stack of playing cards. Since we keep track of what the user is "doing" and what objects they have recently interacted with, it's pretty easy to determine that when they type "draw" and their last targeted object was type "cards", they're probably more interested in drawing a card from the stack on the table in front of them instead of whipping out their sword. (Naturally they can override this with "draw sword".) Of course, the trick is to do all your commands consistently this way; one thing you can end up with (particularly if multiple people are coding different commands) are "smart" commands and "not-so-smart" commands; when does it determine what, etc. But the important thing here, to me, is that you never type "draw" and see, "Huh?" or "Invalid command." Users can get help on the draw command and it will specify exactly how it works. I suppose this is a bit odd with really ultra-specific verbs like "prime" for priming grenades... but it seems to me that if you have grenades in your game, probably you have other types of explosives as well and "prime" becomes a pretty important verb. The main thing I dislike is the quest-y verbs. Dikus are pretty horrible about this; in one room you type "hack bush" to chop through the foliage, and in another you type "cut path". In some you type "disarm tripwire" and others you type "break tripwire", because the first was a trap of type tripwire which uses the disarm skill, the second is a room-routine specifically for that, which doesn't show up anywhere else in the mud and doesn't use any particular skill. This is bad because it's "outside" the system. [Carter T. Shock] << In response to JCL>> I think we have a misunderstanding here. There's grammar (the structure of a language) and then there's vocabulary (all of the individual words that make up the language). I agree that the vocabulary is dynamic. I don't think the grammar is. I'll go one step more and suggest that how you implement the various entities (people, critters, and objects) in your mud can influence the success of such an approach. Lessee... in most mud worlds, the "nouns" are dynamic, but the verbs are not. I put nouns in quotes because often a noun/adjective pairing is required to uniquely identify an object (the long sword, the black sword, etc.). The verbs in the system are your commands. cast, throw, hit, etc. If we want to allow dynamic or generic verbs, now you're getting into natural language processing and I definitely don't want to go there. So there are some distinct sentence structures that emerge: <verb> <object> "hit foo" <verb> <object> <object> "give gold foo" "cast fireball foo" So the first trick is to define your grammar... establish a mapping of verbs to appropriate objects. We'll start with "hit". In most codes if you "hit foo" the code first sees what the allowable targets are for foo, then tries to locate a foo somewhere in the world that satisfies the target rules (get_person_room_vis(), get_obj_room_vis() whatever). The basic flow doesn't change a whole lot. We still have classes of objects... people, things, places, etc. [Nathan Yospe] Hmmm. I, personally, am for dynamic verbs. Thus, my natural (command form only, so far) language parser. My objects respond with a Boolean for recognized on a command, resulting in a list of possible objects. The context engine then locates the proper choice. shoot, for example: <verb> <object> <meanskey> <means> <shoot> <the purple dinosaur> <with> <the rocket launcher> <verb> <object> <lockey> <location> <shoot> <the purple dinosaur> <in> <the kitchen> <verb> <object> <speckey> <specifier> <shoot> <the purple dinosaur> <in> <its left eye> <shoot> <the purple dinosaur> <'s> <left eye> And these are the simple examples. Of course, unless there is a reason to specify, and the time to specify (IE: set up a good shot) you usually type "sho dino" and be done with it. [Carter T. Shock] <<continuing from above.>> One solution is to write our lexical analyzer so it enforces target rules. Another is to write objects so they can respond to any command (I've done sort of a mix here. Done in C++, the base generic object has a handler for all available commands, all of which respond "You can't do that" or somesuch. Real objects are derived from the base. For commands that make sense on the derived object, overload the virtual default handler, multiple levels of inheritance work nicely here). An example of where this works very nicely is with magic. Identify the verb "cast" as special in your lexical analyzer. Rather than <verb> <object> <object> it becomes <verb> <spell> <object> [Nathan Yospe] Of course, this assumes preset commands, something I'd hate to have. Instead, I have my String class parse things as above, and feed the results to the verb and the various potential objects. An object will respond if it recognizes a verb that _needs_ to be recognized (IE: prime), but some verbs are universal, and never bother asking the object for permission (IE: shoot). [Carter T. Shock] <<continues.>> Now the question, why bother? Well, first off, it can make the mud more user-friendly. Rather than simply reporting "huh?" on bad commands, a true parser should be able to: 1) report the exact location of the error in the command 2) offer up suggestions (tab completion of commands) Now, we could do all of this without learning lex/yacc, but doing it in lex/yacc gives you a standard interface.. not to mention someone else has written most of the ugly code for you already. Btw, the newer flavors of the GNU lexer/parser software (glex and bison I think) offer up a C++ version that encapsulates the parser as an object. Nifty side effect is that you can have more than one. So, if you really want to screw with the user's minds you could conceivably have different command sets in different parts of your world. [Chris Gray] << in response to Carter's "I agree that the vocabulary is dynamic. I don't think the grammar is".>> Well, mine is. It was one of the first things that I needed. In the mail room, there are added commands which are used to send email to people outside the MUD and read your email. In the newsroom there are added commands which allow you to read and post news on the local machine, which, if the machine has a regular newsfeed like mine, will actually go out over the Internet. I *didn't* want such commands available everywhere on the MUD! Another example is the way my online building commands work. The system has a verb-type called "VerbTail", where everything in the command after the verb is just passed to the verb as a string. I use that with verb @/build/construct/b, so that that command can then parse the remaining input according to another, completely different, grammar. In fact, if the first word of *that* tail is object/o or room/r, then yet more grammars are invoked on further tails. So: build room new north indoors in the Solarium invokes the 'build' verb. It sees the rest of the input and passes it to the build grammar. The verb is then 'room'. It takes the rest of the input and passes it to the room-building grammar. The room building grammar has a verb 'new' which requires a direction, a room-type and a room-name, all of which are handled as "rest-of-input" processing. It's kinda tough to do this with yacc! (Well, maybe not, but doing it this way keeps all mention of the verbs/etc. for building out of the main grammar - modularity in all things!) How about simple things like "whisper" or "say"? Sure, we all have " or something as a special-cased shortcut for "say", but what about whisper, where you are whispering *to* someone in particular: whisper to Fred Let's attack Sam! Doesn't fit in a yacc grammar very well. I also have a 'with' verb, although I don't currently have any real uses for it in the current scenario. It takes an object, identifies it in your inventory/location, and then looks for a grammar attached to that object to parse the rest of the input with. I intend it for powerful magical objects, e.g.: "with staff zap the frog". Right now, I have a 'cast' verb for wizards. It takes the next word in the input, and looks it up as a procedure in the player's "spell table", which is just another table of whatever's that can be attached to the player or other things. If it finds a procedure by that name, it invokes it, and that procedure has access to the rest of the input command. So, I can do "cast heal Fred", or "cast teleport Fred here", etc. Sure, you can put this in some main, overall grammar, but with this technique, wizards, who can write new code in the running system, can easily add new spell commands to their own spell tables. In my 'build' example above, if you enter "build twiddle", the build command can't find the verb 'twiddle' in the build grammar, so it reports "Unknown build command 'twiddle'." Similar for "build room twiddle". My grammars are already database objects that I can retrieve from wherever I want. I currently don't do what you are saying (other than the bit mentioned above), however. Another issue: do you even want to lexically scan all input the same? By making it context sensitive, you have some greater flexibility. [Carter T. Shock] <<in response to Nathan's "purple dinosaur" example and Chris's "whisper to Fred" example>> As far as the purple dinosaur goes, in all of the examples, whether you are shooting in the next room, the left eye or whatever, the meaning of "shoot" doesn't change. lex/yacc grammars can easily capture the meaning of modifiers such as "with" or "in". The "whisper"/"say" example parses nicely as well. I agree that some commands should not be useful in all parts of the mud. It seems unfair to the player to have the mud simply refuse to recognize your news command when not in the post office. For a consistent interface with the player shouldn't the mud recognize the syntax of the command as valid, but simply deny the command's execution (tell them that the command doesn't work here as opposed to pretending the command doesn't exist). [Nathan Yospe] OK. How about "Use the gun to kill the purple beast." Say your guns are out of ammo. Under my system, the Character would set to beating Barney over the head with the rifle. (unless you were _really_ good at pistol whipping) [Adam Wiggins] Yup. Of course, the reason this works like this is for two reasons I can think of right offhand. First is that frequently these specialty verbs come from scripts attached to objects which you may have on your person or whatever. The mud (of course) doesn't want to search every object in the game for that script in order to figure out if it's valid, it only checks the 'normal' verbs. But I've already expressed why I don't think objects should have this kind of freedom. [Nathan Yospe] This is fine for normal commands, but what of new commands specific to a situation? What of commands open to interpretation, based on context? [Carter T. Shock] I agree wholeheartedly with the lament about whether to use "push" or "press" for the damned button (that may or may not respond to the keyword "button", but that's another issue entirely). It is the grammar that is context free; individual sentences are of course context sensitive. [Nathan Yospe] Not absolutely. If you have no gun, "Kill the soldier with the gun." should at least make sure you _really_ want to make the foolhardy attempt to take down an armed soldier (carrying a gun, of course) with your bare hands. [Carter T. Shock] The point about using a natural language processor is also well taken, but I don't think that's what you've implemented there. If you allowed natural language, I should be able to use any synonym of shoot and purple dinosaur... Let's consider when the user tries: "use gun on purple dinosaur" This is an example of context sensitive grammar. What does "use" mean? Shoot the dinosaur? Whack him over the head with it? Scratch his tummy with the butt of the rifle? It's ambiguous. Natural language processors try to do the "right thing" in these situations (is the dinosaur friend or foe? Is the rifle loaded? Are you a decent shot? Does his tummy itch?). If, however, you allow exactly one meaning for "use" (let's say it means "shoot") then the sentence is unambiguous and the grammar context free. [Chris Gray] Well, yes, but of course this is a computer program, so you can only use synonyms that have been defined for the various terms. I don't find that too different from a natural language - a listener only understands synonyms that they are familiar with. Well, I think of 'use' as a very generic verb. It should do little other than look up on the gun and the dinosaur, properties that tell it what it should do. This could be any of the examples that you discuss. So, as you say, the syntactic structure of the command is context free, but the semantic content of it isn't. [Nathan Yospe] You don't use a rifle for much outside of mayhem, and certainly not with the statement "use". If it isn't loaded, standardUsage becomes "bash ". Of course, the catchall for this is "kill ". Nah, "use " is a wonderful verb. Leave it. [Adam Wiggins] I don't mind the system assuming some things, for instance if I just fired three shots at the dinosaur and I type "shoot" it will fire at the dinosaur again. But I like systems which are obvious in their workings; the user is never left guessing as to what is going to happen when she types a given command, knowing the context. For which I think the "<verb> <object0> ... <objectn>" works pretty well. Only rarely do I even find use for connecting verbs, one of those cases being "look helm on joe"; otherwise you can usually infer from the type of object what the connecting verb should be. "get sword bag" is the same as "get the sword from the bag", and "put sword table" is the same as "put the sword on the table". [Carter T. Shock] Finally, don't think that I'm some devotee of lex/yacc. No reason you can't cook up your own parser. I'm just suggesting that it offers a relatively easy and structured implementation of a grammar. Also, once created, it's easy to modify the grammar (change meanings, add new verbs, etc.). It is similar to the question of how you handle your mud's contents. Depending on how you've implemented the mud's catalog of items, "where sword" may do an iterative search of the entire mud contents, or it may do an SQL query into a set of tables. Both work, the difference is a question of style and portability -- portability not in the sense of cross-platform compilation, but in the sense of when someone else looks at your code if they know lex/yacc they will be able to understand the mud command structure quickly rather than having to pore over your home-grown parser. [Chris Gray] I will comment that I, for one, would not find a lex/yacc system easier to read than my home-grown one (obviously!). However, I would also claim that the same would be true of anyone who has never used lex/yacc, and of many who have. Given documentation that says that a "Verb1" form takes commands like "verb [separator] [art] {adj} <noun> [punctuation]" and "verb [art] {adj} <noun> [separator] [punctuation]", with examples like "pick the big red book up." and "Pick up the big red book", it seems pretty straightforward to add a new "put down" verb. Much easier for most folks that reading documentation that talks about avoiding shift/reduce conflicts! <<end thread>> </PRE> <!--X-Body-of-Message-End--> <!--X-MsgBody-End--> <!--X-Follow-Ups--> <HR> <!--X-Follow-Ups-End--> <!--X-References--> <!--X-References-End--> <!--X-BotPNI--> <UL> <LI>Prev by Date: <STRONG><A HREF="msg00299.html">Re: [MUD-Dev] A flamewar startingpoint.</A></STRONG> </LI> <LI>Next by Date: <STRONG><A HREF="msg00301.html">Re: [MUD-Dev] Re: Less numbers, more roleplaying.</A></STRONG> </LI> <LI>Prev by thread: <STRONG><A HREF="msg00305.html">Dynamic room descriptions</A></STRONG> </LI> <LI>Next by thread: <STRONG><A HREF="msg00281.html">Re: [MUD-Dev] A flamewar startingpoint.</A></STRONG> </LI> <LI>Index(es): <UL> <LI><A HREF="index.html#00300"><STRONG>Date</STRONG></A></LI> <LI><A HREF="thread.html#00300"><STRONG>Thread</STRONG></A></LI> </UL> </LI> </UL> <!--X-BotPNI-End--> <!--X-User-Footer--> <!--X-User-Footer-End--> <ul><li>Thread context: <BLOCKQUOTE><UL> <LI><STRONG>Re: [MUD-Dev] Re: Introductions and descriptions</STRONG>, <EM>(continued)</EM> <ul compact> <ul compact> <ul compact> <ul compact> <ul compact> <LI><strong><A NAME="00671" HREF="msg00671.html">Re: [MUD-Dev] Re: Introductions and descriptions</A></strong>, coder <a href="mailto:coder#ibm,net">coder#ibm,net</a>, Thu 11 Dec 1997, 05:00 GMT </LI> </ul> <LI><strong><A NAME="00673" HREF="msg00673.html">Re: [MUD-Dev] Re: Introductions and descriptions</A></strong>, coder <a href="mailto:coder#ibm,net">coder#ibm,net</a>, Thu 11 Dec 1997, 05:01 GMT <UL> <LI><strong><A NAME="00735" HREF="msg00735.html">Re: [MUD-Dev] Re: Introductions and descriptions</A></strong>, Adam Wiggins <a href="mailto:nightfall#user1,inficad.com">nightfall#user1,inficad.com</a>, Fri 12 Dec 1997, 08:29 GMT </LI> </UL> </LI> </ul> </ul> </ul> </ul> </LI> <LI><strong><A NAME="00305" HREF="msg00305.html">Dynamic room descriptions</A></strong>, Richard Woolcock <a href="mailto:KaVir#dial,pipex.comNOSPAM">KaVir#dial,pipex.comNOSPAM</a>, Sun 16 Nov 1997, 21:16 GMT <LI><strong><A NAME="00300" HREF="msg00300.html">SUMMARY: Mud Grammar</A></strong>, Jon A. Lambert <a href="mailto:jlsysinc#ix,netcom.com">jlsysinc#ix,netcom.com</a>, Sat 15 Nov 1997, 17:54 GMT <LI><strong><A NAME="00281" HREF="msg00281.html">Re: [MUD-Dev] A flamewar startingpoint.</A></strong>, Brandon J. Rickman <a href="mailto:ashes#pc4,zennet.com">ashes#pc4,zennet.com</a>, Thu 13 Nov 1997, 00:07 GMT <UL> <LI><strong><A NAME="00286" HREF="msg00286.html">[MUD-Dev] Eating and sleeping (was: A flamewar startingpoint.)</A></strong>, Derrick Jones <a href="mailto:gunther#online1,magnus1.com">gunther#online1,magnus1.com</a>, Thu 13 Nov 1997, 08:52 GMT </LI> </UL> </LI> <LI><strong><A NAME="00273" HREF="msg00273.html">Re: [MUD-Dev] A flamewar startingpoint.</A></strong>, Chris Gray <a href="mailto:cg#ami-cg,GraySage.Edmonton.AB.CA">cg#ami-cg,GraySage.Edmonton.AB.CA</a>, Mon 10 Nov 1997, 20:17 GMT <UL> <LI><strong><A NAME="00274" HREF="msg00274.html">Re: [MUD-Dev] A flamewar startingpoint.</A></strong>, Brandon Cline <a href="mailto:brandon#merlin,sedona.net">brandon#merlin,sedona.net</a>, Tue 11 Nov 1997, 09:02 GMT </LI> </UL> </LI> </UL></BLOCKQUOTE> </ul> <hr> <center> [ <a href="../">Other Periods</a> | <a href="../../">Other mailing lists</a> | <a href="/search.php3">Search</a> ] </center> <hr> </body> </html>