Imperial Programmable Mud Shop Owner's guide I. Introduction Congratulations! Since you're reading this document, you now play a very important role in this mud -- being a businessman. In this guide, you'll find out how to run an imperial shop. Mind you, this is NOT an easy business. You will found yourself involved not only in economic decision, but also in the realm of programming a language -- Lpmud Stack Compiler(LSC). But don't worry, although it is not easy, it isn't difficult, and you'll probably find the complexity amazing and enjoyable. By using this language, YOU decide how the shopkeeper react to transaction requests from players. YOU decide whether or not to accept the transaction requests. YOU decide what your profit margin is. YOU decide whether or not to give a discount for your favorite customers. YOU can do all sorts of economic decision... even when YOU ARE NOT INSIDE THE GAME! II. How this works There'll be a separate document which explains in more details how to code in LSC. But here only the basics which enable you to run your shop smoothly will be discussed. Paragraphs which are marked with * should be read after consulting the LSC programming guide. Basically, the shop will still have the standard commands: "list", "value", "ask", "buy", "sell". They are fixed, but you decide what's in them. (If you don't, the shop will still run by using default routines, but you might lose customers because of inflexibilities.) We'll talk about each one individually. LIST It's the simplest. The player is requesting a list of your goodies. Normally you can just ignore writing the routine -- the default one probably suffices, but there're cases when you want more control over it: /list { enemy member_array 0 ge { (Go to hell) say end } if (Oh, let me see... ) say show_goods (That's it.) say end } def 'enemy' is a predefined (assume you've defined it beforehand) array variable contain the name of players you don't like. If the customer's name does appear in it, make the shopkeeper refuse to help. and end the routine. Otherwise, just do the normal built-in routine, show_goods. * When the "list" is called, the stack already contains the name of the customer. You can just ignore it, but in our example the name is matched against the array stored in 'enemy' variable. Also, you may notice the reserved word 'say' . They help you to customize the tone of your shopkeeper and give a flavor of your shop. Also, note that the reserved word 'end'. THIS IS VERY IMPORTANT. YOU MUST HAVE THIS WHEN YOU ARE DONE WITH THE ROUTINE. This let the shopkeeper know that the transaction is all over so that he/she can serve another customer. It also resets the stack. If you don't do that, the shopkeeper will not respond to any further transaction request. VALUE It's just slightly more complicated. /myvalue { /item exch def /name exch def item evaluate 3 mul 4 div dup set_desired_buy_price } def /value { myvalue convert_amount_str (I'd pay ) exch add say end } def 'myvalue' is called directly when a customer bypass the value->sell process and do the sell directly. 'value' will be the one being accessed by the 'value' command in the shop. You can see that 'value' draws on the return value of 'myvalue'. IMPORTANT: note that 'myvalue' DOES NOT have reserved word 'end' at the end of it. It's because myvalue leave important information on the stack, which will be immediately used by 'value' and you don't want to erase it. The reserved word 'evaluate' gives an estimate on the value of the object. 'set_desired_buy_price' save the price for future reference if the customer is willing to sell that to you. 'convert_amount_str' convert the integer value into more comprehensible string like "2 platinum coins..." The others are similar stuff. It's your responsibility to make sure the valued price is the same as the true deal price. WE DON'T CHECK IT FOR YOU. That means you can cheat the players by not giving the exact amount when the player wants to sell the item, but it also means you may pay more than you want if you have a bug in your code ... that may mean bankrupcy... Also, you may note that an item's value is in terms of different coins, but the result regenerated by 'evaluate' is always an integer. It's because we have taken much pain in filtering this trivilities from you, so all the calculating you need to make is at the same unit. But of course, in true transaction, the shop's coins stock is taken into account, so you should make sure the shop has various kinds of coins to meet customer's need. Say if an item is worth 25 golds but you only have 100 platinum and 2 golds, the transaction is impossible although you have far more wealth than needed to buy the item from the customer. SELL In order to have your own 'sell' to work, you must already have 'myvalue' properly defined. % a normal sell routine /sell { /item exch def /name exch def buy_price dup gt 1000 { (I can't give you that much.) say pop 1000 } if buy_it 0 eq { (thankyou.) say } { (too bad.) say } ifelse end } def * buy_price pushes the most recent desired_buy_price evaluated by thy 'myvalue' function. In our example, the desired_buy_price is matched against 1000. If it's larger, the selling price is actually truncated to 1000, quite similar to the old generic shop. Reserved word 'buy_it' actually performs the transaction, i.e, grab the item, pay the customer. The stack will have 0 when everything is OK, and -1 otherwise. Now you can see how myvalue doesn't have to agree actual transaction price. But you know, if you do that unreasonably you will risk a certain chance of pissing off players.... You don't have the worry about the coins. The shopkeeper will look for a possible way to complete transaction. (If the shop doesn't have 1 gold, it'll see whether it has 10 silver; if not, the shop will see if giving you 1 platinum (if available again) and getting back changes is possible) ASK /myask { /item exch def /name exch def 3 mul 2 div dup 0 eq { pop 1 } if dup set_desired_sell_price } def /ask { myask convert_amount_str (I'd sell at ) exch add say end } def Same thing like 'value' and 'myvalue'. BUY /buy { /item exch def /name exch def sell_price sell_it 0 eq { (thankyou.) say } { (too bad.) say } ifelse end } def Again, it's just analogous to /sell