Nofew

muf-tutorial

Oct 20th, 2015
276
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 25.26 KB | None | 0 0
  1.  
  2. The MUF Tutorial, by Scotfox.
  3. Revision 2.2fb4 of 28 February 1993.
  4.  
  5. "Zen and the Art of Putting Things on Top of Other Things."
  6. (Or, the Basics of MUF in ten megs or less.)
  7.  
  8. This is an introduction to MUF, a simple and easy programming language
  9. used to do really neat things with TinyMUCK 2.2. MUF is based on Forth.
  10.  
  11. This tutorial was designed to be read before any of the other MUF
  12. documentation. I'll assume you already know how to play TinyMUD games
  13. pretty well (you know what an object number is, you know how to @set
  14. things, etc.) and that you know how to program in at least one
  15. computer language (even BASIC will do).
  16.  
  17. Before we go on, let me show you how a perfectly valid MUF program looks:
  18.  
  19. : hello-world (the name of the program)
  20. me @ (first argument to the function 'notify')
  21. "Hello, world!" (second argument)
  22. notify (a function which takes two arguments)
  23. ;
  24.  
  25. When you @link an action to this and use the action, it will print
  26. "Hello, world!" to your screen. Easy as pie! It'll look easier later.
  27.  
  28. In order to try any of these examples on a real TinyMUCK, you must be
  29. allowed to program on it. Most mucks implement "mucker bits", which
  30. means that until a wizard gives you one, you can't create programs.
  31. Talk to your friendly neighborhood wizards to get a mucker bit.
  32. Usually they'll have some sort of policy about what sorts of programs
  33. you are allowed to write. Common restrictions are that you can't
  34. write a program to teleport yourself around the muck, spy on other
  35. characters, or do things that only wizards can do.
  36.  
  37. Before we get to the good parts, let's give you an overview of what
  38. MUF is all about. (Relax. This is easy stuff.)
  39.  
  40.  
  41. WHAT IS A STACK?
  42.  
  43. All MUF programs work by performing operations on a stack.
  44.  
  45. A stack is just a place to store things. You put things on top of a
  46. stack one at a time (we call that "push"), and take them off the top
  47. of the stack (that's called "pop"). The most recent thing you've
  48. pushed onto a stack is the only thing you can pop; it's like piling
  49. objects on top of each other, when the only thing you can remove from
  50. the pile is the thing on top. For example, if you were to push the
  51. number 12, then push the number 34, and then pop a value off the
  52. stack, you would get 34. If you were to pop another value off the
  53. stack after this, you would get 12.
  54.  
  55. (If you were to try and pop another value after that, you would get an
  56. error, since the stack would now be empty. This is a "stack underflow.")
  57.  
  58. There is only one stack. Things that get put onto it get left there
  59. until they get taken away, or until your program ends.
  60.  
  61. A typical stack could be represented by
  62.  
  63. ( "frotz" 123 #4567 )
  64.  
  65. which means that the MUD object #4567 is on top of the stack, the
  66. integer 123 is below it, and the string "frotz" is on the bottom of
  67. the stack. The only thing you can get to right now is #4567, but when
  68. you take that off you can get 123, and when you take that off, you can
  69. get "frotz".
  70.  
  71. See? Easy. And you used to think MUF was only for the elite!
  72.  
  73.  
  74. WHAT CAN I DO WITH A STACK?
  75.  
  76. A "procedure" or "function" in any other language is the same thing as
  77. a "word" in MUF. A word is simply a sequence of instructions that can
  78. take some stuff off the stack, put some stuff onto the stack, and
  79. print text to players' screens, if you want it to. In a MUF program,
  80. a word always starts with a colon followed by the word's name. A
  81. semicolon marks the end of a word. For example:
  82.  
  83. : detonate_explosives
  84. (the program text goes here)
  85. ;
  86.  
  87. would define a word named "detonate_explosives".
  88.  
  89. Always remember to put a space between a colon and the name of a word!
  90. Everybody (and I do mean EVERYBODY) forgets the space sometimes. If
  91. the program above began with ":detonate_explosives", it wouldn't work
  92. at all.
  93.  
  94. Parentheses are used to set aside comments. Everything inside
  95. parentheses is ignored by the muck. Thus the "detonate_explosives"
  96. word above is a perfectly valid program, but if run as shown it would
  97. do absolutely nothing, because all it contains is a comment -- it
  98. doesn't produce any output or modify the stack in any way.
  99.  
  100. In MUF, there are three types of constant values (things you can put
  101. on the stack): integers, strings, and database references (object
  102. numbers). To push a constant onto the stack, you only need to state
  103. its value. The following is a completely legitimate word:
  104.  
  105. : a-visit-to-the-zoo
  106. "Wolves"
  107. "Lynxes"
  108. "Bats"
  109. "Foxes"
  110. ;
  111.  
  112. If you were to run this word by itself, you wouldn't see anything
  113. happening. It would, however, create a stack which looks like this:
  114.  
  115. ( "Wolves" "Lynxes" "Bats" "Foxes" )
  116.  
  117. In the above stack, "Wolves" is the value on the bottom. "Foxes" is
  118. the value on top of the stack, and would be the next value retrieved
  119. by any stack operations.
  120.  
  121. Indentation and line breaks in MUF programs are arbitrary and just
  122. make the program more readable to people. You could put each MUF
  123. operator on a separate line, or the whole program on one line. Your
  124. style is your choice. Thus "a-visit-to-the-zoo" could be written as
  125. follows:
  126.  
  127. : a-visit-to-the-zoo "Foxes" "Bats" "Lynxes" "Wolfs" ;
  128.  
  129. But endlessly pushing values onto the stack is boring. Fortunately,
  130. there are 'operators' in MUF that can modify the stack: typically they
  131. take some values off the top of the stack, do some sort of calculation
  132. with these values, then put a new value on top of the stack.
  133.  
  134.  
  135. BUILT-IN MUF OPERATORS
  136.  
  137. Functions in the standard MUF library take values from the top of the
  138. stack, do things with them, and usually leave something new back on
  139. top of the stack. The words "+", "-", "swap", "pop", and "random"
  140. are good examples of this.
  141.  
  142. The "+" operator takes the top two integers from the stack, adds them
  143. together, and leaves the result on top of the stack. In order to
  144. easily describe what functions like this do, a certain stack notation
  145. is used: for +, this would be (i1 i2 -- i). What's inside those
  146. parentheses is a sort of "Before and After" synopsis; the things to
  147. the left of the double-dash are the "before", and those to the right
  148. are the "after". (i1 i2 -- i) says that the function in question uses
  149. two integers, and leaves one when it's done ("i" means "integer").
  150.  
  151. Notice that math in MUF works in "reverse Polish notation", where
  152. you'd add two and two by saying "2 2 +". (This is the same way a lot
  153. of expensive HP calculators do it.)
  154.  
  155. The letters used here to tell what kind of data a stack object can be
  156. are: "i" for integer, "d" for database object, "s" for string, "v" for
  157. variable, and "x" or "y" to mean something that can be more than one
  158. type.
  159.  
  160. Here are short descriptions of the procedures listed above so you can
  161. get the hang of how they work:
  162.  
  163. -=-=-=-=-=-=-=-=-=-
  164. + (i1 i2 -- i)
  165. Adds i1 and i2 together. The word
  166.  
  167. : add_some_stuff
  168. 2 3 +
  169. ;
  170.  
  171. will leave the integer 5 on the stack when it is finished. The word
  172.  
  173. : add_some_more_stuff
  174. 2 3 4
  175. 5
  176. + + +
  177. ;
  178.  
  179. will put 14 onto the stack. Right before "add_some_more_stuff" reaches
  180. the "+ + +" line, the stack looks like (2 3 4 5). The first + changes
  181. the stack to look like (2 3 9). The next makes it (2 12), and the
  182. final plus leaves (14).
  183.  
  184. -=-=-=-=-=-=-=-=-=-
  185. - (i1 i2 -- i)
  186. Subtracts i2 from i1.
  187.  
  188. : subtract_arbitrary_things
  189. 10 7 -
  190. ;
  191.  
  192. will put the number 3 on top of the stack.
  193.  
  194. -=-=-=-=-=-=-=-=-=-
  195. swap (x y -- y x)
  196.  
  197. Switches the top two things on the stack. This is very useful,
  198. because an operator can't just skip over the top value on the stack to
  199. get at something beneath; if you need to get at the second value from
  200. the top, you have to swap it to the top first.
  201.  
  202. : swap_stuff_around
  203. 1 5 2 (The stack is now 1 5 2)
  204. swap (Now the stack is 1 2 5)
  205. 3
  206. "Three, sir!" (Now it's 1 2 5 3 "Three, sir!")
  207. swap
  208. "Boom!" (And now it's 1 2 5 "Three, sir!" 3 "Boom!")
  209. ;
  210.  
  211. (`rot' and `pick' let you get at items deeper in the stack. Look them
  212. up in your MUF manual.)
  213.  
  214. -=-=-=-=-=-=-=-=-=-
  215. pop (x --)
  216.  
  217. Throws away the value on top of the stack. As shown by (x --), it
  218. will take any value off the top of the stack without leaving anything
  219. in return. (This is useful when you really no longer need whatever
  220. value is on the top of the stack, but you need to get at what's under
  221. it.) The word:
  222.  
  223. : needless_popping_waste
  224. "Immanuel Kant" "Heideggar" pop
  225. "David Hume" "Schoppenhauer" "Hegel" pop pop
  226. ;
  227.  
  228. would leave the stack looking like ("Immanuel Kant" "David Hume").
  229.  
  230. -=-=-=-=-=-=-=-=-=-
  231. random (-- i)
  232. Doesn't even look at the stack, but leaves a really random integer
  233. (between 1 and 2.1 million) on top. The word
  234.  
  235. : feel_lucky_punk?
  236. random
  237. random
  238. random
  239. ;
  240.  
  241. would put three random numbers onto the stack. Often you'll need a
  242. random number in a certain range; for instance, rolling dice will get
  243. you numbers from 1 to 6. Here's how you can do that:
  244.  
  245. : roll-die
  246. random (fetch a random number)
  247. 6 % (% is the 'modulo' operator; random mod 6 gets you
  248. a number between 0 and 5)
  249. 1 + (add 1 to it to get a number between 1 and 6)
  250. ;
  251.  
  252.  
  253. SO WHAT GOOD IS ALL THIS?
  254.  
  255. Not much good, yet. All the stack-manipulating we've done so far is
  256. trivial; nothing yet will produce any results you can see or feel.
  257. (We'll remedy that in the next section.)
  258.  
  259. In MUCK, you create a "program" object with the "@program" command.
  260. For example, "@prog test.muf" will create an object named "test.muf"
  261. that will contain whatever MUF program you write, and you'll be put
  262. into the built-in editor so you can type your code. (More details on
  263. this later.) You'll usually put several words into a program, then
  264. link an action (also known as an "exit") to the program. Using the
  265. action will run the very last word you defined in your program
  266. (sometimes people call it "main" for emphasis, but you don't have to).
  267.  
  268. The other way that MUF programs are used is in the desc, succ, fail,
  269. and drop properties of a MUCK object. If you write a program whose
  270. program object number is #6800, say, and you describe yourself as:
  271.  
  272. @desc me = @6800
  273.  
  274. then whoever looks at you would run the program. (Yes, that's an
  275. at-sign, not a pound-sign.) Similarly, @failing an object = @6800
  276. would run the program whenever someone tried but failed to pick up the
  277. object, and so forth. (This doesn't work in ofails, osuccs, or odrops.)
  278.  
  279. Theoretically then you could get away with only having one word in
  280. your program, but you'll find it's handy to break whatever the program
  281. does into a few smaller subtasks, each of which you'll write a
  282. separate word to handle.
  283.  
  284. You've seen how the "+" operator takes two integers and puts their sum
  285. on the stack. Well, if you find yourself adding three integers a lot,
  286. you could write a word to handle it:
  287.  
  288. : add-three (i1 i2 i3 -- i)
  289. + +
  290. ;
  291.  
  292. Pretty simple, but hey, it's an example. Notice that your new word
  293. expects some values to be on the stack before it begins? Well, if
  294. your 'main word' goes like this:
  295.  
  296. : frobnitz
  297. ...
  298. add-three
  299. ...
  300. ;
  301.  
  302. when it comes to the "add-three" operator, it'll give the stack
  303. (remember, there's only one stack!) to the "add-three" word.
  304. "add-three" will modify it and give it back to "frobnitz", which picks
  305. up where it left off. Thus before the call to "add-three", the stack
  306. might look like ("Hey, you!" 5 4 "What?" 3 2 1), and after it returns
  307. from the call to "add-three", the stack would be ("Hey, you!" 5 4
  308. "What?" 6).
  309.  
  310. Thus you can see how "taking arguments" in MUF means "grabbing values
  311. from the top of the stack", and "returning a value" means "leaving
  312. things on top of the stack when you're through".
  313.  
  314. The only other important thing to mention at this point is that you
  315. can have your programs take arguments. If you create a program named
  316. "frotz.muf", then link the action "frotz" to it, typing "frotz the
  317. troll" will run the program as usual, except that the stack will start
  318. off containing the string "the troll" rather than being empty. Think
  319. about this for a bit; it's how the popular custom 'page' program
  320. works, for example. If a program is called from an action, it will
  321. always be given a string on top of the stack to begin with; even if
  322. here you just typed "frotz" alone, the string "" (an empty string)
  323. would be placed on top of the stack for "frotz.muf" to handle.
  324.  
  325. If you use the program in a desc, succ, fail, or drop property, then
  326. whatever follows the program number will be put onto the stack:
  327.  
  328. @desc me = @6800 Your description here...
  329.  
  330. would run the program #6800 with "Your description here..." on the
  331. stack to start out with every time someone looked at you. This is how
  332. look-notify, multiline-description, morpher, and other programs are done.
  333.  
  334. Now that we have the basics down, let's do something useful!
  335.  
  336.  
  337. VARIABLES
  338.  
  339. Because of the way the stack works, variables aren't as necessary in
  340. MUF as they are in other languages, but they can be used to simplify
  341. stack-handling operations. In fact, it's not even a good thing to use
  342. variables in MUF (doing things without them forces your code to be a
  343. lot cleaner), but they're there if you need them.
  344.  
  345. There are two kinds of variables: global (defined with 'var <name>')
  346. and local (defined with 'lvar <name>'). For technical reasons, you
  347. should always use local variables instead of global ones. Just put
  348. 'lvar <name>' into your program before the first use of the variable,
  349. then any word in that specific program object can use it.
  350.  
  351. Variables are of no specific type; that is, you can assign an integer
  352. to a variable at one point in your code, then assign a string to the
  353. same variable a few lines later.
  354.  
  355. The following operators are important when dealing with variables:
  356.  
  357. ! (x v --)
  358. Pronounced "store", the ! sets variable v to hold value x. The program:
  359.  
  360. var answer
  361. : multiply-and-store
  362. 6 9 *
  363. answer !
  364. ;
  365.  
  366. will put the value 42 into the variable "answer", which can then be
  367. used anywhere in the program (that is, in any word in the same program
  368. object).
  369.  
  370. @ (v -- x)
  371.  
  372. Pronounced "fetch", this word retrieves the value of a variable and
  373. puts it on the stack. Just giving the name of the variable alone,
  374. without the @, does NOT give its value.
  375.  
  376. (The difference between "x" and "x @" is like the difference between
  377. "x" and "^x" in Pascal, "x" and "*x" in C, and "x" and "(x)" in Lisp.)
  378.  
  379. The program:
  380.  
  381. var ren
  382. var stimpy
  383. : more_silly_manipulation
  384. 1 ren !
  385. 2 stimpy !
  386. ren @ stimpy @ +
  387. ;
  388.  
  389. will return the value 3 on top of the stack. But if you make a
  390. mistake and enter the last line as:
  391.  
  392. ren stimpy +
  393.  
  394. then that will be *wrong*, and will give you a completely wrong number.
  395.  
  396. In MUF, there are a few variables which are predefined and available
  397. for use at all times (without requiring "var" declarations): You'll
  398. probably use two of them a lot: "me @" will return the object number
  399. of the player who is using this MUF program, while "loc @" will return
  400. the object number of the room he is in.
  401.  
  402. (Object numbers, also known as database references or dbrefs, are the
  403. third kind of constant value after integers and strings. The value
  404. #123 is a dbref. You can convert integers to dbrefs with the "dbref
  405. (i -- d)" operator; saying "123 dbref" is the same thing as saying
  406. "#123".)
  407.  
  408. Another useful word to know is:
  409.  
  410. name (d -- s)
  411. Where d is a db reference and s is a string, "name" returns the name
  412. of item d. Thus "me @ name" puts my name on top of the stack in case
  413. I forget it. (On a Fuzzball MUCK (2.2fb), if you only have Mucker
  414. level 1 permission, you can only get the name of someone or something
  415. in the same room as you. You may have been only given M1 access in
  416. order to learn MUF.)
  417.  
  418. And now that you know all about "me @", another MUF function becomes
  419. useful. Its synopsis is:
  420.  
  421. notify (d s --)
  422. When d is the dbref of a player, "notify" shows him string d. If I were
  423. a character named "Joe", then running
  424.  
  425. : whoami
  426. me @ (my dbref)
  427. "Your name is "
  428. me @ name (my name as a string)
  429. strcat (concatenate "Your name is" and my name into one string)
  430. notify
  431. ;
  432.  
  433. would print "Your name is Joe" on a line by itself to my screen.
  434. (Again, on a Fuzzball MUCK, having only Mucker level 1 permission
  435. means that you can only 'notify' a person in the same room as you.)
  436.  
  437. Hurrah! Finally we did a program that begins to do something useful!
  438.  
  439.  
  440. CONDITIONALS
  441.  
  442. Before you can really start writing neat stuff in Muck, there are two
  443. more things you should know about. One is "=", and the other is the
  444. "if/then" conditional.
  445.  
  446. = (i1 i2 -- i)
  447. Returns 1 if integer i1 is equal to integer i2.
  448. Otherwise, it returns 0.
  449.  
  450. : nonequals
  451. 2 3 =
  452. ;
  453.  
  454. returns 0. (In MUF, any nonzero integer means "true", while zero
  455. means "false".)
  456.  
  457. "If/then" isn't hard to figure out if you keep in mind that MUF does
  458. everything backwards compared to "normal" languages such as C or
  459. Pascal. Remember that, in other languages, if/then looks like this:
  460.  
  461. if <test>
  462. then <statement>
  463. <program continues...>
  464.  
  465. MUF does it like this:
  466.  
  467. <test> if
  468. <statement> then
  469. <program continues...>
  470.  
  471. "if" takes the top item off the stack; if it is zero or the empty
  472. string "", then everything up to the word "then" is ignored. Anything
  473. else makes it keep going.
  474.  
  475. For example, the word:
  476.  
  477. : test-computer
  478. 2 3 = if
  479. me @ "Your computer is broken!" notify then
  480. me @ "Finished the test." notify
  481. ;
  482.  
  483. will first test if 2 = 3; if so, the = operator will leave a 1 on top
  484. of the stack. "if" will grab this 1 and then print "Your computer is
  485. broken!" to you. If, however, 2 is not equal to 3, the = will leave a
  486. 0 on top of the stack to indicate falsehood, and the "if" will grab
  487. the 0 and skip the bit about broken computers. In either case, the
  488. code will finish by printing "Finished the test" to you.
  489.  
  490. If you feel like getting fancier, you could use "else" too. Remember
  491. that procedural languages have it this way:
  492.  
  493. if <test>
  494. then <statement>
  495. else <other-statement>
  496. <rest-of-program>
  497.  
  498. MUF does it like this:
  499.  
  500. <test> if
  501. <statement>
  502. else <other-statement>
  503. then
  504. <rest-of-program>
  505.  
  506. which may look a bit odd, but hey, it works (and it makes sense, if
  507. you think about it). Now you can do:
  508.  
  509. : better-test
  510. 2 3 = if
  511. me @ "Your computer is broken!" notify
  512. else me @ "Your computer works just fine." notify
  513. then
  514. me @ "Finished the test." notify
  515. ;
  516.  
  517. And if you're really smooth, you might notice that MUF has nothing
  518. like the "case" or "switch" statement of other languages to decide
  519. between plenty of choices, so you can simulate it with lots of
  520. 'if/else/then's. Here's how it works, with two new MUF operators and
  521. a Ginsu knife tossed in for a limited time only:
  522.  
  523. strcat (s1 s2 -- s)
  524. Concatenate strings s1 and s2, returning the result. (Yes, I've slipped
  525. this into another program up there; now you get to have it for real.)
  526.  
  527. dup (x -- x x)
  528. Duplicate the value on top of the stack.
  529.  
  530. : roll-die
  531. me @
  532. "You rolled a "
  533. random 6 % 1 + (Get a random number mod 6 and add 1)
  534. (to get a number in the range 1-6.)
  535. dup 1 = if (We have to duplicate the number, because = eats it.)
  536. "one!"
  537. else dup 2 = if
  538. "two!"
  539. else dup 3 = if
  540. "three!"
  541. else dup 4 = if
  542. "four!"
  543. else dup 5 = if
  544. "five!"
  545. else "six!"
  546. then then then then then (we always need a 'then' for every 'if')
  547. (The stack now looks like:)
  548. (#123 "You rolled a " 1 "one!") (for example)
  549. swap pop (get rid of the integer in there)
  550. strcat notify (put "You rolled a " and "one!" together,)
  551. (then tell me what I rolled)
  552. ;
  553.  
  554.  
  555.  
  556. A SAMPLE PROGRAM
  557.  
  558. Okay, so you've been reading this whole thing so far, and you really
  559. want to use this stuff to do something interesting. The following
  560. program fits the bill. It uses the new functions:
  561.  
  562. location (d -- d')
  563. Takes db reference d and returns d', the db reference for its location.
  564.  
  565. owner (d -- d')
  566. Returns the dbref of the character that owns object d.
  567.  
  568. dbcmp (d1 d2 -- )
  569. Works just like =, except operates on db references instead of integers.
  570.  
  571. "find" will tell you where an object of your choosing is (and who owns
  572. the room it's in) whenever you use the program.
  573.  
  574. : find
  575. #123 (Substitute here the number of whatever object you want to find.)
  576. dup (Make a copy of the dbref; we're about to use the copy.)
  577. name (Fetch the object's name -- better than hardcoding it here!)
  578. " is currently in: " strcat
  579.  
  580. (If #123 is "foo", we now have the stack:)
  581. (#123 "foo is currently in: ")
  582.  
  583. swap (Bring the dbref back to the top of the stack.)
  584. location (Where is it?)
  585. dup name (Make two copies of that room number,)
  586. (and turn one into the name of the room.)
  587.  
  588. (If it's in a bar, #456, we have:)
  589. ("foo is currently in: " #456 "bar")
  590.  
  591. (Now to find out who owns the room.)
  592. swap (Bring the room number to the top of the stack.)
  593. " (" swap (Put an open-paren before the room number.)
  594. owner (Turn the room number into the number of its owner.)
  595. name (... and get the owner's name.)
  596. "'s room)."
  597.  
  598. (If Baz owns the room, the stack is now:)
  599. ("foo is currently in: "
  600. "bar"
  601. " ("
  602. "Baz"
  603. "'s room.")
  604.  
  605. strcat strcat strcat strcat (Turn it all into one string.)
  606.  
  607. me @ (We're going to tell me where it is...)
  608. swap (... but "notify" wants my dbref to come before the string.)
  609. notify (And there it is!)
  610. ;
  611.  
  612.  
  613. Note that this program uses no variables (except for the universally
  614. defined "me" variable.)
  615.  
  616. Want to try it out? Type "@prog find.muf", then type "i" to enter
  617. insert mode, and type in the program just as you see it here. (You
  618. can leave out the comments!) Type a period on a line by itself to
  619. exit insert mode. Then make sure it's entered correctly.
  620.  
  621. Commands you can use in the editor:
  622.  
  623. <from> <to> list
  624. Display a range of lines in your program. If you wanted to see line
  625. 20, you could do "20 l". If you wanted to view the whole thing, use a
  626. really high number as the ending line: "1 999 l".
  627.  
  628. <from> <to> delete
  629. If you screwed up line 15, you can kill it with "15 15 d", then insert
  630. a new line 15 ("15 i").
  631.  
  632. <line> insert
  633. To put in lines between line 9 and line 10, type "10 i" and type away,
  634. putting a period on a line by itself to finish.
  635.  
  636. Then type "c" to compile your program, and fix any typos you might
  637. have made if it doesn't compile. ("Compiling" means "turning your
  638. easy-to-read MUF code into an internal representation that the
  639. computer can deal with and run quickly".)
  640.  
  641. When it compiles fine, type "q" to quit the editor. (You can modify
  642. the program later with "@edit find.muf".)
  643.  
  644. Create an action on yourself so you can always find whatever it is
  645. whose number you put into the program. First create the action with
  646. "@action find = me", then "@link find = find.muf". Now, whenever you
  647. want to know where that thing is, just type "find"!
  648.  
  649. If you want to see your program actually going every step of the way,
  650. then "@set find.muf = D". The D flag for programs means "DEBUG", and
  651. the top of the stack will be shown to you as each operator in the
  652. program is executed. Just remember to set it !D when you're finished
  653. debugging!
  654.  
  655. If you want to view your program without having to enter the editor,
  656. just @list it. To let other people @list your program too, @set it =
  657. L (which stands for LIST_OK). Also, your programs must be set L for
  658. other people to be able to use them.
  659.  
  660. When someone uses a program, the program has all the privileges of
  661. that person -- in other words, it can modify that person's objects,
  662. but not the objects of someone else unless a wizard is the person
  663. using the program. If your program needs to modify your own objects
  664. even when another person is using it, then you'll need to let other
  665. people run your program as you -- @set the program SETUID, which gets
  666. its name from the Unix `setuid' bit on executable files.
  667.  
  668.  
  669.  
  670. WHERE CAN I GO FROM HERE?
  671.  
  672. Oodles and oodles of other neat MUF documentation and library routines
  673. are available, including:
  674.  
  675. MUF.manual Explanations of all the MUF primitives and options
  676. forth.ref A list of all the MUF primitives
  677. MUF-examples Some useful programs to learn from
  678.  
  679. These files come with the standard TinyMUCK distribution, and may also
  680. be available elsewhere. The best way to find the best documentation
  681. currently available is to talk with the wizards and muckers on the
  682. mucks you hang out on.
  683.  
  684. Good luck, and happy muffing!
Advertisement
Add Comment
Please, Sign In to add comment