Setup for Programmer's tutorial (#3301).

Object setup.

Object name:Programmer's tutorial
Location:MOO tutorial dispenser (#3297)
Parent:Generic Letter (#155)
Owner:Odo (#987)
Description:
Programmer's tutorial version 1.6 by Odo. 'Burn tutorial' to get rid of it.

Physical setup.

Anchor: unanchored
Key/lock: unreadable

Note setup.

Text:
LambdaMOO Programmer's Tutorial version 1.6 For SchoolNet MOO September 1997 by Neil Fraser (aka Odo) nfraser@ingenia.com This is a tutorial for players who have achieved 'Programmer' status on a MOO, but don't know how to program. It will be necessary to print out a copy of this document (5 pages) so that you can refer to it while on the MOO. Before starting this tutorial (and programming) you must have mastered the builder commands. Make certain you have successfully used ALL of the following commands: ? (The most useful command; use it before pestering someone.) @create, @recycle, @rename, @describe @lock, @addalias, @messages @mail, @send, @rmm, @notedit @audit, @dump, @d @kids, @parents, @locations, @contentsIf you are not familiar with all of those commands you will waste a lot of time programming features that are already available through the command line. The first task in this tutorial is to use the familiar builder commands to make a new object called "Odo's mouse" (substitute your own player's name), with aliases "mouse", and "pet". Give it a suitable description, and configure the mouse so that whenever somebody other than you tries to pick it up they fail, and are told "Odo's mouse bites you, and you drop the rodent." while everyone else in the room is told "Max tries to catch Odo's mouse, but gets bitten.". If you can't do all of that unaided, you are not ready to program. Now create a new verb on your mouse that will make it squeak when the mouse is pinched. Type '@verb mouse:pinch this none none'. You now have the verb, but there is no code to execute. Type '@edit mouse:pinch'. You are now in the verb editor, we will worry about how it works later, right now let's get some code writen. Type the following commands (including the initial quote): "this.location:announce_all("Odo's mouse squeaks!"); "this.location:announce_all("Odo's mouse gnashes its teeth.");The verb now has two lines of code. Use the 'compile' command to save the code. If there was an error while it was compiling, type 'del 1' or 'del 2', retype the offending line, and then 'compile'. If you somehow get into serious trouble, type 'abort' and start over again. When it has successfuly compiled, 'quit' back to the command line, and test the verb by typing 'pinch mouse'. Now for some theory. Type '@list mouse:pinch' to see the code for your verb. The word 'this' in a verb is a built-in variable that returns the object that the verb is running on. In your verb, 'this' always returns the object number of your mouse. All objects have a 'location' property that stores the object number of the room, player, or container that they are sitting inside of. Putting these two together 'this.location' returns the mouse's containing object. All rooms have a verb 'announce_all' that tells all objects in the room the text that you give it ('@list here:announce_all' to see this verb's code). If the mouse is sitting in a room, then the room's 'announce_all' verb is called. If the mouse is being carried by a player, then the player's 'announce_all' verb is called (which passes it to the room). The verb editor is not very user-friendly, so it deserves some explanations. Type '@edit mouse:pinch' to get back in and 'list' to show your two lines of code. You can use 'p' and 'n' (previous, next) to move the insertion point (cursor) up and down. Position this point between your two existing lines of code and use " (say) to add 'suspend (15);' as a line of code. Remember, use '?' if you run into dificulties, and 'look' while in the editor gives you an overview of the editing commands. Once you have got the line inserted, 'list' the code and make sure that it is between the other two. If it isn't, use 'move' to correct the problem. Now change the '15' to be '2' with substitute. Type 's /15/2' and list the code to verify the change. The substitute command will be the most used command because it allows you to fix bugs without deleting the line and restarting. Compile the code (and fix any errors), then quit from the editor. Pinch your mouse again and note the two second delay between the two messages. Take a guess as to what 'suspend (60);' would have done. There is still a problem with the verb; when someone pinches your mouse, other people hear the mouse's reaction, but they have no idea what caused it. Edit the verb again and insert the following two lines before all the others, then compile (fix errors) and quit. player:tell("You pinch Odo's mouse."); this.location:announce(player.name + " pinches Odo's mouse.");There are four new items in these lines. You already know that 'this' in a verb returns the object that the verb is running on. The built-in variable 'player' is simmilar, it always returns the object number of the player who activated the verb. On every player is a verb 'tell' that will tell the text to only that player. The exact opposite is a room's 'announce' verb that tells the text to everyone in that room, except the 'player' who activated the verb. You know what the 'location' property returns, so given the context you should have figured out that the 'name' property returns. Find somebody else who is logged on to the MOO and test your mouse with them. Now make a rat with exactly the same attributes as your mouse. There are three methods.1) Create another $thing and program it from scratch.2) Create another $thing and '@copy mouse:squeak to rat'.3) Create a child of your mouse.The first suggestion is stupid if you know about @copy. The second isn't bad, but it wastes disk space and is no good when copying objects with dozens of verbs. The third is really simple: @create #1234 called "Odo's rat", "rat", "pet"where #1234 is the object number of your mouse, and 'Odo' is replaced with your character's name. Note that when you @dump your mouse you see the pinch verb, but not when you dump the rat. '@list rat:pinch' will show you the verb, but after telling you that it was found on the mouse. This is called inheritence. There is a final problem with the pinch verb, when you pinch the rat, one is informed that the mouse was pinched. This is because the name is hard-coded into the text. Edit the mouse's pinch verb, and on all four applicable lines use substitute to change 'Odo's mouse' to 'this.name' with the apropriate quotes and pluses. While you are editing the verb, replace the expression 'player.name' with 'player:title()'. It is customary to use :title() instead of .name when requesting the name of a player. This is so that if the player wants to add Mr/Mrs/Cptn/Dr in front of the name (or otherwise change how their name is seen) they may do so without modifying the name property (which, for players, isn't allowed to have spaces in it). After all the editing, your verb should look like this: player:tell("You pinch " + this.name + "."); this.location:announce(player:title() + " pinches " + this.name + "."); this.location:announce_all(this.name + " squeaks!"); suspend(2); this.location:announce_all(this.name + " gnashes its teeth."); One of the most interesting types of verb is the one that listens to conversation in a room, and reacts accordingly. This is easilly done. Whenever anything is said, the room calls the 'notify' verb on every object in the room, if that verb exists. Type '@verb mouse:notify this none this' then edit the new verb so that is contains the following (try using 'enter' instead of " ): if (index(args[1], " says, ")) if (index(args[1], "cheese")) this.location:announce_all(this.name + " looks up at the mention of its favourite food."); endif endifThe text of what was said is returned by the 'args[1]' variable. The function call `index(args[1], "cheese")' returns true if the word 'cheese' was found in the text of args[1]. The first 'if' is checking to see whether the notify verb was called by somebody saying something (Odo says, "I like cheese.") as opposed to an emote (Odo likes cheese.) or background noise (Odo drops the cheese.). In the event that both ifs are passed, someone has said the word cheese (or is trying to trick the verb). Test the verb; remember that objects in your pocket can't hear what is said outside -- you must drop your rodents first. Find somebody else who is logged on and have them test it. You should notice a bug. Occasionally when somebody else says cheese you get the rodent's response BEFORE you hear the triggering text. This 'time travel' effect occurs because the room calls the notifys on all the objects one by one. If it gets to the rodent before it gets to you, then the rodent responds before you hear the trigger. Were you to insert 'suspend(1);' in the mouse's notify verb, the whole proccess would be suspended for one second, but the order of messages would be unchanged. What you need to do is insert the line 'fork (1)' before, and 'endfork' after, the announce_all line. This will cause the normal execution to jump over the announce_all line and continue uninterrupted, and then one second later the announce_all line will be executed. Crude, but it works.Insert the following lines between the endfork and the first endif: elseif (index(args[1], "cat") || index(args[1], "hawk")) fork (1) this.location:announce_all(this.name + " looks around nervously."); endforkThe '||' symbol means 'or'. Other symbols you should know about are: && - and == - equals (as opposed to '=' which means 'assign') != - is not equalMake your own improvements to the verb so that it will catch other words. Try making the rodent say 'Hello' when somebody says 'hello' or 'hi' (the index function is case-insensitive). Or make your rodent cough or sneeze when somebody says something with the letter 'q' in it, or 'tion'. When you are ready to continue, add these lines before the very last endif. elseif (index(args[1], " squeaks!")) fork (1) player:tell(this.name + " glares at you."); this.location:announce(this.name + " glares at " + player:title() + "."); endforkBecause of the location of these lines they can never be trigered by spoken text. Try pinching the mouse. The mouse will squeak and will thus trigger the glare reaction. It will also trigger the glare reaction from all other sympathetic rodents in the room. The second last verb I am giving you is created with '@verb me:whistle none none none' and has the following code: player:tell("You whistle a note so high that it is inaudibe."); player.location:announce("You hear " + player:title() + " whistle an inaudibly high note."); rodent_list = {#1234, #2345}; -- substitute the #s of your rodents. for rodent in (rodent_list) move(rodent, player.location); rodent.location:announce_all(rodent.name + " scampers in."); endforSince this code is located on you, and you would normally be the one executing the code, 'player' and 'this' are interchangable. There are three new items in this verb. The simplest is the function 'move(what, where)'. You may use this function to move objects that you own (including yourself), to locations that aren't locked. The next new item is the list. Lists are equivalent to the 'arrays' found in other programming languages. Lists can store groups of strings (text), numbers, object numbers, other lists, variables, or a combination of the above. One use for lists is as a control for 'for' loops, the third new item. The for loop will step through the controlling list and assign the 'rodent' variable to be equal to each item in the list in turn, and execute the enclosed statements once every time. The total number of repetitions equals the length of the controlling list. If you create more rodents, then just add their object numbers to the list. When you test the verb (just 'whistle') you will discover a bug. If a rodent is already in the room when you whistle it emits the 'scampers in' message, and stays where it is. Fix this problem by enclosing the contents of the 'for' loop with 'if (rodent.location != player.location)' and 'endif'. You are already familiar with the 'location' and the 'name' properties found on every object. You can create your own properties on objects you own. Use '@prop me.rodent_list' to create one on your character. Then set the contents of the new property with '@set me.rodent_list to {#1234, #2345}' where the numbers are the object numbers of your mouse and rat (and any others you create). The property now contains a list which may be used in any verb. Edit the whistle verb and replace the current list with 'this.rodent_list', or delete that line completely and replace 'rodent_list' in the 'for' loop line with 'this.rodent_list'. The advantage of this change is that other verbs and other objects now have access to that list as '#<your player's #>.rodent_list'. One such item would be a status report of your rodents. Create an object (based on a $thing) called "a rodent report" with aliases "rodent report" and "report". Set the description to be: "The current locations of Odo's rodents are:". Use '@verb report:description this none this' to create a new verb, and add the following lines to it: desc = {pass(@args)}; for rodent in (#<your player's #>.rodent_list) line = rodent.name + " is in " + rodent.location.name + "."; desc = {@desc, line}; endfor line = "Odo has " + tostr(length(#<your player's #>.rodent_list)) + " rodents."; desc = {@desc, line}; return desc;When you look at an object, its description verb is called. The default description verb simply returns the object's description which is then printed. The description verb you just wrote calls the default description verb (using 'pass(@args)'), adds some extra text to the description, and returns (to the look verb) the modified description. Thus you never have to call this verb, you just look at the object. The phrase 'desc = {@desc, line}' appends the 'line' to the end of the existing description list. Each entry in this list is a line of text. The 'length()' function simply returns the number of items on the given list. Since that value is a number, the 'tostr()' function must be used to convert it to text. Also note that on line #3 'rodent.location' would have returned an object number, not a name. You now have at least four verbs. When you try to make your own verbs you will find that they will not work unless you have defined their arguments correctly with the @verb command. In the examples I have used 'this none none', 'this none this', and 'none none none'. The best way to explain what arguments a verb needs is by example, here are some of the ones you will most likely use.Verb: Arguments: Usage:Odo:whistle none none none whistlemouse:pinch this none none pinch mouseOdo:kick any none none kick Maxpie:throw this at any throw pie at MaxOdo:apologize none to any apologize to MaxOdo:title this none this May only be called from other verbs.Use the above list for reference when creating new verbs. If you have actually done this tutorial (as opposed to just reading it), you've got a basic foundation of knowledge regarding the MOO programming language. To explore further, obtain a copy of the excellent 'LambdaMOO Programmer's Manual', and experiment.
Encryption: unreadable

Update and repair this object.

Check this object's web page with the W3 HTML 4.0 validator.

Destroy this object utterly and irretrievably.


You are not logged in.

[home | help | who | search | setup | code]