ADVEXT.T DOCUMENTATION BY KEVIN VENZKE stepjak@yahoo.fr, http://nodesiege.tripod.com/if/ VERSION 0.1, DEC 11 2005 CONTENTS 1. introduction 2. license 3. getting this to work with Ditch Day Drifter and Deep Space Drifter 4. description of features 5. list of new/changed objects, functions, and properties 6. version history 1. INTRODUCTION Advext.t is an add-on library for TADS 2. The idea is that you can include it after adv.t and program in TADS just as you normally would. You're then free to use whatever advext.t features are useful to you. 2. LICENSE Please do not publicly distribute a modified version of this file without changing the name to something other than "advext.t." Otherwise, you can make whatever use you like of the contents of advext.t. 3. GETTING THIS TO WORK WITH DITCH DAY DRIFTER AND DEEP SPACE DRIFTER Ditch Day Drifter includes adv.t and gameinfo.t. If you include advext.t just after these two, you have only two problems compiling: 1. Ditch Day Drifter defines preparse. Advext.t tries to also. Since Ditch Day doesn't do anything with its preparse, you could just remove it. Or else, just change "preparse" to "replace gamePreparse," and advext.t will call it from its own preparse. 2. Ditch Day Drifter defines its own forPrep. It is identical to the forPrep that advext.t already defines. Therefore, you can either remove Ditch Day's forPrep, or start it out as "replace forPrep." Deep Space Drifter includes adv.t and gameinfo.t also. Include advext.t after these two, and you're set: No compile errors result from this. 4. DESCRIPTION OF FEATURES a. support for ASK FOR, gamePreparse b. origitems and origdescs c. genitems and components d. chatter and auto e. scopeActions f. isAn and isProper g. autotake, taketolook, havelooked h. taken, takenfrom, dropped i. rdescs and referring to rooms j. adjacent rooms k. haschanged and changenotices l. exits display m. cansee and fardesc n. duringTravel stage and pushables o. getting out of nestedrooms p. things you don't need to refer to q. disambiguation scoring r. preventing objects from being defaults s. shufflers a. SUPPORT FOR ASK FOR, GAMEPREPARSE Advext.t implements "ask for" in exactly the same way that adv.t already implements "ask about." The verification and action methods are verIoAskFor, verDoAskFor, and ioAskFor. The properties disavowAskFor and askForword work in the same way as disavow and askWord. Just as with "ask about," the player may "ask for" things that aren't even present. You might use these like this: maria: Actor disavowAskFor = "\"I certainly can't give you that,\" says Maria. " askForWord(word,list) = { if((word='wrench' or word='tools') and wrench.location= self) { "\"Okay, you can have the wrench,\"" says Maria, handing you the wrench. "; wrench.moveInto(Me); return true; } return nil; //no match! } ; Also, advext.t recasts PERSON, GIVE (ME) X (TO ME) as ASK PERSON FOR X. This avoids the problem that adv.t will normally require that the object you ask for be visible. Advext.t uses preparse to make this transformation. If your game also defines preparse, you'll get a compile error. You can fix this by changing your preparse into a replacement of gamePreparse, which is called by advext.t's preparse. For example, suppose you were using preparse to transform, "PERSON, YES" into a simple "YES". You could change this to: replace gamePreparse: function(cmd) { if( reSearch('^.+, *yes%>',cmd)<>nil ) cmd:='yes'; return cmd; } Alternatively, if you do not want PERSON, GIVE ME X to work the same as ASK PERSON FOR X, you could use "replace preparse" to only use your own preparse method. b. ORIGITEMS AND ORIGDESCS Adv.t does not give you an easy way to give an object a special description for the first time you see it. Advext.t offers a class called "origitem" and a property called "origdesc". An origitem is an item that specifies an origdesc to be displayed while the object is not listed (isListed=nil). It's not listed by default. Once the object has been moved (probably taken), it becomes listed, and the origdesc is not shown anymore. You could also give a fixeditem an origdesc. This might be useful for a fixeditem that doesn't stay in the same room, but needs the same description. The origdesc isn't surrounded by any spacing, because you might not necessarily want to print anything. You would probably want to precede the origdesc's text with a \n\t or \b. Suppose you want sandals described as being at the foot of the bed. Suppose there is also a dresser that you want to be pushable into adjacent rooms. You could write code like this: sandals: origitem, clothingItem origdesc = "\n\tA pair of sandals sits at the foot of the bed. " ; dresser: fixeditem origdesc = "\n\tA dresser rests on its wheels here. " ; This could result in a transcript like this: Bedroom This is a bedroom. A pair of sandals sits at the foot of the bed. A dresser rests on its wheels here. >TAKE SANDALS Taken. >LOOK Bedroom This is a bedroom. A dresser rests on its wheels here. You see some sandals here. c. GENITEMS AND COMPONENTS Adv.t uses dobjGen and iobjGen with e.g. distantItem to give a blanket reason why the player can't do much with the object. Advext.t implements a "genitem" class to make it very easy to implement objects that generally can't be interacted with for whatever reason. Genitem's dobjGen, iobjGen, and actorAction call a method called "general", which by default calls its "gendesc" and exits. For example, suppose you have a candy bar that is behind a sheet of glass in a vending machine. It shouldn't be possible to do much with the candy bar for the general reason that it's behind class. You might code it this way: candybar: genitem gendesc = "That's behind glass, so you can't do anything with it. " verDoLook(a) = {} ldesc = "The candy bar looks very tasty. " verDoBuy(a) = "You have nothing with which to buy it. " ; This means that the gendesc will be displayed for any interaction except for LOOK AT CANDY BAR and BUY CANDY BAR. Suppose you don't want to just display a message. Suppose you have a dragon which is easily irritated. If irritated, it will eat the player, moving him to the dragon's stomach. You might code it like this: dragon: genitem general = { "You have irritated the dragon. It eats you. "; Me.travelTo(dragonstomach); exit; } verDoLook(a) = {} //...etc. It's OK to examine the dragon. ; Finally, suppose you're in a room with your friend and a ticking bomb. Whenever you do anything with the bomb, your friend gets nervous, but your command is still executed. You might code it like this: tickingbomb: genitem general = { "Your friend looks nervous as your eyes wander towards the bomb.\b"; return; } ; Advext.t also offers a "component" class. Components redirect every command they receive to their location, except for whatever specific methods are defined within them. For example, suppose you have a desk with a drawer. Maybe you want OPEN DESK and OPEN DRAWER and almost everything else to be treated the same way. Maybe just EXAMINE DRAWER should be treated differently from EXAMINE DESK. Then you could code the drawer like this: drawer: component location = desk verDoInspect(a) = {} ldesc = "The drawer has weird designs on it. " ; d. CHATTER AND AUTO Normally a daemon has to be notified. Advext.t offers a couple of lazy ways to have code run as a daemon without having to notify it. If an object defines a method called "chatter", it will be run at the end of every turn when this object is visible to the player (that is, parserGetMe()). If an object defines "auto", this method will be run every turn. This might be useful for a daemon that runs the entire game. Chatter might be useful for actors. Suppose you have a drunk who belches with one fifth probability every turn. You might code this like this: drunk: Actor chatter = { if(_rand(5)=1) "\b\"Belch!\"\ emerges from the drunk. "; } ; Note that advext.t uses the turncount daemon to call all the chatter and auto methods. So if your game replaces turncount, or doesn't notify it, these methods won't be called. e. SCOPEACTIONS Advext.t allows visible objects to handle an action in the same way that the verb, actor, and location can in verbAction, actorAction, and roomAction, respectively. The method is called "scopeAction," and receives the standard five command parameters (actor, verb, direct object, preposition, indirect object). A scopeAction can print a preface to the command, or use exit or abort to change the behavior of the command entirely. scopeAction methods are called when actorAction calls the function "scopeActions." If you modify actorAction you'll have to make sure that scopeActions gets called. It isn't obvious when scopeActions should be called in the actorAction methods of objects other than the player (basicMe). Conceivably scopeActions could be called twice: Once with a fake "player asks object about something" to handle the action of the player issuing a command, and once with the actual action to handle that (assuming the addressee actually performs the command). For example, you might try something like this: maria: Actor actorAction(v,d,p,i) = { //witness the player making the request: scopeActions(parserGetMe(),askVerb,self,aboutPrep,self); //if that doesn't exit, we might want to: if(not self.takesorders) { "\"Er, I don't take orders,\"\ says Maria. "; exit; } //Ok, Maria will attempt this action, so witness it: scopeActions(self,v,d,p,i); } ; You could use a scopeAction method to alter the behavior of verbs that don't take objects. For example, suppose you want to print a special message when the player is holding a sword and tries to jump: sword: item scopeAction(a,v,d,p,i) = { if(self.location=Me and v=jumpVerb) { "It's really dangerous to jump with a sword! "; exit; } } ; You could also, for example, allow an actor to intercept a "yes" or "no" response and deal with it itself. f. ISAN AND ISPROPER Advext.t allows properties isAn and isProper to be defined. Is isAn is true, then the adesc will start with "an" rather than "a." If isProper is true, the adesc and thedesc will not use any article before the name. This means that you needn't define adesc and thedesc for "Maria." Just give her "isProper = true". g. AUTOTAKE, TAKETOLOOK, HAVELOOKED Using adv.t, if the player types GIVE SANDALS TO MARIA when he isn't holding the sandals, the response will be "You're not carrying the sandals." Often it would be preferred for the player to automatically try to pick up the object. Advext.t adds to the thing class a method called "autotake" which takes the actor as the parameter. It returns true if the object was already held, or if the autotake was successful. It returns nil if the object wasn't held and could not be taken. Suppose you want this behavior for a sandwich that sits on a table. If the player tries to take the sandwich, and Maria is visible, she leaps to intercede because she knows that the sandwich is poisoned. If the player wants to eat the sandwich, he should automatically take it rather than getting an error that he's not holding the sandwich. You might code it like this: sandwich: item verDoEat(a) = {} doEat(a) = { if(not self.autotake(a)) return; "You eat it up. It's gone. "; self.moveInto(nil); Me.poisoned:=true; } ; Maria: Actor scopeAction(a,v,d,p,i) = { if(a=Me and v=takeVerb and d=sandwich) { "You take the sandwich into your hand. Maria hurls herself at it with urgency. Her head bumps the sandwich safely onto the floor. \b\"I told you that sandwich was poisoned!\"\ Maria explains. "; sandwich.moveInto(self.location); exit; } } ; This would result in a transcript like this, if Maria is visible: >eat sandwich (First taking the sandwich) You take the sandwich into your hand. Maria hurls herself at it with urgency. Her head bumps the sandwich safely onto the floor. "I told you that sandwich was poisoned!" Maria explains. Advext.t implements a shortcut for examine. Just set taketolook to true, and the doInspect method will automatically attempt an autotake. doInspect also sets a new property "havelooked" to true. You can use this in an object's ldesc if you want the first appearance to be different from any subsequent examinations: ldesc = { if(not self.havelooked) "Wow! The sandwich has olives on it! "; else "The sandwich has olives on it, which surprised you earlier. "; } Havelook is not set to true when the player examines an object which is not reachable. This is because it is possible to customize the response in this case, probably to something with less detail. (This is explained under "cansee and fardesc.") h. TAKEN, TAKENFROM, DROPPED Adv.t doesn't make it especially easy to override the "Taken." text (for when you pick up an item). The method which prints this message also calculates whether you have enough room in inventory to carry the item. Advext.t adds some properties to make this easier to customize. The property "taken" by default simply prints the default "Taken." message. The property "dropped" is the same for "Dropped." (The room's roomDrop method calls the dropped method, and is still able to override it if e.g. the room is filled with water and wants to describe how dropping any item creates a splash.) The property "takenfrom(object)" allows a container to override taken. If it prints its own message, it should return true. By default it doesn't print anything and returns nil. Also, an object by default goes up the list of containers, looking to see if any of them wish to print a takenfrom message. Suppose you have a chest that can contain things, and you want a special message whenever something is removed from it. You could write it like this: chest: container, fixeditem takenfrom(o) = { "You take <> from the chest. "; return true; } ; You can define takenfrom for a room, also. i. RDESCS AND REFERRING TO ROOMS Using adv.t, you cannot refer to the room you're in because it isn't visible to you. Advext.t changes this. Give a room adjective and noun vocabulary, and you'll be able to refer to it. Mainly, this allows the player to type EXAMINE KITCHEN and get the description of the kitchen redisplayed. He can also SEARCH KITCHEN and be told that he needs to be more specific. There's also another purpose that we'll get to in the next section. And you can add any interactions that you think make sense. One issue is that it might occur that the room's sdesc is used in a sentence. Using adv.t, a room's sdesc is usually capitalized, which may make for some awkward messages. You can fix this by defining a separate "rdesc" which is capitalized (and which appears in the status line) from the "sdesc," which is in lower case like any other object. The default is that the rdesc simply points to the sdesc, so that you don't have to code your rooms any differently if you don't want to. So, both of these are fine: sdesc = "Bathroom" or rdesc = "Bathroom" sdesc = "bathroom" j. ADJACENT ROOMS Advext.t allows you to specify that certain rooms are adjacent to a given room. Then if the player tries to GO TO KITCHEN, the kitchen's doEnter method will by default simply call actor.travelTo(self). To make the kitchen adjacent to the living room, the latter needs to define a list called adjrooms which contains the kitchen. Also, of course, the kitchen will need some vocabulary. Example: livingroom: room adjrooms = [kitchen] adjective = 'living' noun = 'room' ldesc = "You're in the living room. You can get to the kitchen from here. " ; kitchen: room noun = 'kitchen' ldesc = "You're in the kitchen. You can't get back to the living room from here, because there's no adjrooms defined. " ; Allows: Living Room You're in the living room. You can get to the kitchen from here. >GO KITCHEN Kitchen You're in the kitchen. You can't get back to the living room from here, because there's no adjrooms defined. >GO LIVING ROOM I don't see any living room here. k. HASCHANGED AND CHANGENOTICES Adv.t allows you to define "firstseen" in a room object. It prints a message to be displayed after the first time you see the room's description. Advext.t allows something similar but more flexible. Rooms now have a property called "haschanged," which is either nil, or an object. When it is set to an object, and the room description is displayed, the following properties of the object are called: 1. "beforelook" is called before the room's short name is printed. 2. "duringlook" is called after the short name, but before the ldesc. 3. "afterlook" is called when the description (including visible items) is finished. Haschanged is reset to nil at the same time that "isseen" is, in enterRoom. Also, the verbose description of the room will be given, even if the game is in terse mode and the player has already seen the room. A class called "changenotice," a subclass of object, is provided. It defines the above properties but does nothing in any of them. Some formatting is assumed. Suppose you're entering a room whose haschanged is set to the following changenotice: testnotice: changenotice beforelook = "This is beforelook. " duringlook = "This is duringlook. " afterlook = "This is afterlook. " ; This is what the result would look like, assuming you go north to enter the room: >NORTH This is beforelook. Room Short Name This is duringlook. This is the room's ldesc. You see X and Y here. This is afterlook. >LOOK Room Short Name This is the room's ldesc. You see X and Y here. That is, a \n is printed after the beforelook. Duringlook is run between the call to room.dispBeginLdesc (which displays \n\t by default) and the ldesc. No special formatting occurs before afterlook. If you want to insert a blank line here and there, the changenotice will have to print it itself. l. EXITS DISPLAY Advext.t provides a way to specify exits from a given room. These are then displayed when the player types "exits" or "ex," or when the player moves in a direction that isn't available. By default a room doesn't specify any exits. In this state, typing "exits" produces "(No information is available.)" and doesn't take up a turn. Going in an invalid direction just produces "You can't go that way" without any reference to the exits. A room can specify exits in two ways: exits = 'north or east' or ex = "You might want to consider going north or east. " By default, ex checks to see whether exits is defined. If not, it does nothing and returns DTY_NIL, which tells exitsVerb to print an error. Otherwise, it prints exprefix, a space, exits, and a period. By default, exprefix is "You can go". If you wanted to change it, you could do this: modify room exprefix = "Obvious exits are:\ " ; If a room overrides ex, then exits is never regarded. Ex should always either print what the exits are, or return DTY_NIL. If it returns nothing after doing nothing, the player won't get any response to EXITS in that room. m. CANSEE AND FARDESC Sometimes an object in the next room is visible, and the player should at least be able to examine it from where he is. For example: South End of Hall You're exploring the south end of the hall. Maria is at the north end of this hall, guarding the door. >X MARIA I don't see any maria here. To avoid this behavior, and also avoid having to create a "fake" Maria object to stand in for her in this one room, you can specify in the player's room that "cansee = [maria]". This makes her visible but not reachable, so that you can EXAMINE her, but any other action will call her cantReach method (which by default says, "You can't reach that."). Thing's doInspect method will check whether an object is reachable when you examine it. If it's not reachable, it will show its fardesc rather than its ldesc, and will not attempt autotake (even if taketolook is true), and will not set havelooked to true. By default, the fardesc just shows the ldesc. You could change it to "You can't see Maria very clearly from here" if you like: modify thing fardesc = "%You% can't see <> very clearly from here. " ; One thing to note is that cansee includes not just Maria, but anything inside her. This means you can use cansee to make an entire room's contents visible from another room. But on the negative side, it means a player could refer to the flower in Maria's hair that you didn't intend to be noticed until they're in the same room. If you really don't want the player to be able to refer to the flower in a different room, you could do this: flower: item location = mariashair doVisible(a) = { if(a=Me and Me.location<>maria.location) return nil; pass doVisible; } ; It is possible to define cansee as a block of code, as long as you're careful not to overwrite your own code by trying to add or remove things from the list. For example, if you know that Maria is the only additional thing that might need to be visible from the south end of the hall, you could code this: southendofhall: room cansee = { local ret; ret:=[]; if(maria.location=northendofall) ret:=ret+maria; return ret; } ; Cansee does respect contentsVisible, so that you won't suddenly be able to see into a closed box just by moving to a different room. n. DURINGTRAVEL STAGE AND PUSHABLES Advext.t implements a stage of travel called "duringTravel." This is useful for implementing messages like, "Maria follows close behind" or "You dribble blood behind you." The function duringTravelMsgs is called by travelTo just before the player is moved to the destination. This function calls duringTravel(destination) on every object in the list dt.msgs. You can add or remove objects from this list to control who gets an opportunity to print messages during this stage. To put Maria on this list (because she's following you), you might code this: //place this line in the method that decides Maria is now following //you: dt.msgs:=dt.msgs + maria; maria: Actor duringTravel(destination) = { "Maria follows you.\b"; self.moveInto(destination); } ; This would result in exchanges like this: Room 1 Maria is here. >NORTH You can't go that way. You can go east. >EAST Maria follows you. Room 2 Maria is here. Advext.t comes with a "pushable" class which makes use of duringTravel. It's for fixeditems that you can PUSH/MOVE NORTH. Suppose you have a dresser that the player can push from room to room. All you'd need to do is make the dresser a pushable, give it an origdesc, and the following is possible: Room 1 The dresser is here. >PUSH DRESSER NORTH You can't go that way. You can go east. >PUSH DRESSER EAST You push the dresser in front of you. Room 2 The dresser is here. A pushable can customize pushmsg(destination). By default it is "You push <> in front of you.\b" o. GETTING OUT OF NESTEDROOMS Using adv.t, if you're in a chairitem, the only ways to get out are GET UP/OFF or STAND. Trying to move in any direction gives you: You're not going anywhere until you get out of the chair. Advext.t allows UP, DOWN, or OUT to function identically to GET OUT for nestedrooms. p. THINGS YOU DON'T NEED TO REFER TO Advext.t offers a class called "unnec." Unnecs produce the message, "That's not something you need to refer to in the course of this game" whenever the player tries to do anything at all with them. They are never favored as defaults, or included in "all," or in disambiguation questions. This means that you don't need to give unnecs an sdesc. Suppose a room's description mentions tall trees, puffy clouds, and passing cars, none of which are important. You could code the following: thisroomsjunk: unnec location = thisroom adjective = 'tall' 'puffy' 'passing' noun = 'trees' 'tree' 'clouds' 'cloud' 'cars' 'car' ; And the player will get "you don't have to refer to that" rather than "I don't see any trees here," or "I don't know the word 'trees'." (In technical terms, unnecs are visible as appropriate for their location, but they are not considered valid for any verb. The "you don't need to refer to that" message is displayed in their cantReach method.) q. DISAMBIGUATION SCORING TADS 2 has some tools to aid in intelligently guessing which object the player is trying to refer to when the words the player used are ambiguous. It tries to select valid objects over invalid objects, and objects that won't produce verification errors over those that do, and objects that match a word as a noun over those that only match it as an adjective. But this isn't quite enough to avoid situations like this: >X MARIA Which maria do you mean, Maria, or the picture of Maria? Advext.t implements a scoring mechanism that can be used to fine-tune selection in cases like these. deepVerb's disambigDobj/Iobj calls a potential match's "disambig" property, if it exists, with these parameters: the verb, whether a direct object is sought (as opposed to indirect), the list of the words the player used, and the list of other objects under consideration. Then "disambig" returns a number. The default is 100. (That is, if the object doesn't define a disambig property, it's treated the same as if it had one which returned 100.) You could avoid the above disambiguation with one of these: maria: Actor disambig(verb,asDobj,words,objects) = { if(length(words)=1 and words[1]='maria') return 120; return 100; } ; pictureofmaria: item disambig(v,d,w,o) = { if(find(w,'picture')=nil) return 50; return 100; } ; Either of these ensures that Maria will be selected before her picture when the player only types "maria." You might frequently want to implement scenery objects that you never want to be selected when there is ambiguity. For example: Carpeted Room You see a red book and a blue book here. >X RED Which red do you mean, the red book or the carpet? This could also be a problem if the carpet was supposed to be a secret, something that the player wasn't supposed to find out about just yet. You could solve this easily in this way: carpet: fixeditem disambig(v,d,w,o) = 0 ; This returns a very low score all the time, so the carpet will likely only be selected when the player unambiguously refers to it. r. PREVENTING OBJECTS FROM BEING DEFAULTS Another problem is that it is sometimes undesirable for an object to be considered a "default." A command like TAKE ALL could involve objects that are clearly just decorative, or not supposed to be known to the player yet. If the player doesn't supply an object for a verb, TADS tries to guess. This could inadvertently solve a puzzle for the player, if it wasn't supposed to be obvious that this is the object that needs to be (verb)ed. Advext.t allows an object to define a property called "notDefault," which takes as parameters the verb and whether it's being considered as a direct object (true or nil, with nil meaning it's as the indirect object). If it returns true, the object won't respond to ALL and won't be guessed when the command is missing an object. This makes an object never a default: carpet: fixeditem notDefault(v,d) = true ; Maybe the player has a uniform that you don't want him accidentally stripping off. Then when he's wearing the uniform, it shouldn't be a default for DROP: uniform: clothingItem notDefault(v,d) = { if(v=dropVerb and d and self.isworn) return true; return nil; } ; It's probably unnecessary to check whether the uniform is being considered as a direct object, since DROP normally can't take two objects. But if it were possible in your game to DROP KEY IN UNIFORM, this check might be useful. (Of course, ALL is never useful with indirect objects, and DROP KEY isn't likely to ask "in what?"... But hopefully you get the point.) s. SHUFFLERS Advext.t steals shufflers from TADS 3. A likely use is that an NPC chatters randomly every turn or two, and has four or five things he might possibly say. If the selection is made at random, it could be that the NPC picks the same blurb three times in a row. This could make the NPC (or even the game) appear more limited than it is. A shuffler object contains a list of strings called "msglist." When the shuffler's "getmsg" property is called, the shuffler returns one of its messages at random, but won't print a message twice until it's returned all of the options once. Then it starts over. Suppose you have a dog who barks every turn (when visible). You might code this: dog: Actor chatter = "\b<>" ; dogshuffler: shuffler msglist = [ '"Bow wow!"' '"Bark!"' '"Woof!"' '"Yip!"' ] ; Since it returns single-quoted strings, you could conceivably manipulate the strings prior to printing them. For example, you could replace DOGNAME in the returned string with the dog's name, if the dog's name could vary. 5. LIST OF NEW/CHANGED OBJECTS, FUNCTIONS, AND PROPERTIES The following functions and class properties are modified from their adv.t (or default) versions: preparse : turns PERSON, GIVE (ME) X (TO ME) to ASK PERSON FOR X; changes PERSON, TELL ME ABOUT X to ASK PERSON ABOUT X turncount : runs "afterTurn" function, which runs "chatter" and "auto" methods thing.adesc : special treatment if isAn, isProper, or isThem are true thing.thedesc : no article if isProper is true thing.actorAction : calls scopeActions; also corrected a bug in adv.t thing.doInspect : autotake if taketolook is set; set havelooked to true thing.doTake : calls methods that can customize the "Taken" text. thing.prefixDesc : don't show a prefix when "them" means one object thing.isVisible : you can see items in your top room's "cansee," and their contents movableActor.actorAction : calls scopeActions basicMe.actorAction : calls scopeActions basicMe.travelTo : calls duringTravelMsgs room.statusRoot : to print rdesc in the status bar instead of sdesc room.enterRoom : in order to display changenotices room.nrmLkAround : in order to display "origdescs" and changenotices room.roomDrop : asks dropped object to display "Dropped" text. room.noexit : in order to display exits after the error if possible room.isVisible : so that the room you're in, and adjacent rooms, are visible and can define scopeAction room.isReachable : so that you can reach the room you're in, and adjacent rooms room.dobjGen .iobjGen : You can't do much with a room. nestedroom.statusRoot : to print outer room's rdesc in the status bar nestedroom.up .down .out : attempt to get the player out of the nestedroom. nestedroom.verDoInspect .doInspect .verDoSearch .verDoEnter : reset back to the thing response, overriding room. nestedroom.dobjGen .iobjGen : undo the general "can't do that" behavior inherited from room. deepverb.validDo : "unnec" items are never valid deepverb.validDoList : now includes your room and adjacent rooms and items visible due to "cansee" deepverb.disambigDobj .disambigIobj : consider scores returned by disambig methods deepverb.doDefault .ioDefault : call trimDefaults to avoid objects that don't want to be defaults dropVerb, giveVerb, showVerb, putVerb, takeVerb.doDefault : ditto inspectVerb.validDo : "unnec" items are never valid even if visible inspectVerb.doDefault : no defaults when examining inVerb.verb : accept "go" askVerb.ioAction : allow "ask for" The following new methods and properties can be overridden: gamePreparse(s) : a function that is called at the end of preparse .fardesc : Replacement for ldesc when this object is not reachable .auto : if defined, a daemon that is run every turn of the game .chatter : if defined, a daemon that is run whenever this object is visible to the player .scopeAction(a,v,d,p,i) : if defined, is called during actorAction when the object is visible .isAn : if true, adesc will have "an" rather then "a" .isProper : if true, adesc and thedesc won't add any articles .taketolook : if true, the player tries to take this object when examining it .taken : the default "Taken." text to display for this object .takenfrom(o) : may print a message (and return true) to replace "Taken" when o is removed from self .dropped : the default "Dropped." text for this object within "movableActor" objects: .askForWord(w,l) : return true when printing text to respond to word "w" in an "ask for" .disavowAskFor : the message to show when this actor doesn't have a response for what was asked within "room" objects: .rdesc : what to show in the status bar (defaults to the sdesc) .ex : full sentence, double-quoted string describing exits ("The only exit is east.") .exprefix : double-quoted string to preface a list of exits ("You can go", "Obvious exits are") .exits : single-quoted string listing exits without punctuation ('east or north') (By default, .ex glues exprefix and exits together, adding a period.) These new methods and properties can be referred to: within "thing" objects: .autotake(a) : returns true if self is held or was successfully auto-taken .havelooked : set to true when the player has examined this object These classes are new: changenotice : an object to which room.haschanged can be set origitem : an item that has a special initial description in its room genitem : something you can't do much with for a specific reason pushable : a fixeditem that you can PUSH NORTH with good messages component : a fixeditem that redirects non-customized actions to its location unnec : something that you don't need to refer to in the course of this game shuffler : an object containing a list of strings that can be received in a random order These objects are new: dt : stores "msgs," a list of objects notified during travel exitsVerb : displays the current location's exits information if available forPrep : the preposition "for," for use with "ask for" These functions are new: trimDefaults : removes objects that don't want to be defaults duringTravelMsgs : displays relevant messages during travel afterTurn : calls chatter and auto methods 6. VERSION HISTORY v0.0 12/10/05 initial release. v0.1 12/11/05 fix: adjacent rooms improperly made their contents visible or reachable for some purposes This document is written by Kevin Venzke, stepjak@yahoo.fr, http://nodesiege.tripod.com/if/