Page 1 of 2 12 LastLast
Results 1 to 10 of 19

Thread: Unofficial Lich + Ruby Tutorial

  1. Default Unofficial Lich + Ruby Tutorial

    A Lichin' Tutorial

    by Monotonous

    This series of tutorials is a primer for anyone interested in learning more about how scripts work in Lich. We'll be starting out with some very basic programming concepts applied to Lich and GS4.

    I will begin with the assumption that you have no idea how computer programming or Lich scripting works. These fundamental concepts are very easy to grasp, and will quickly allow you to see just how simple it is to modify and write your own scripts for Lich! You couldn't have picked a better opportunity to learn programming – Ruby is easy, and Gemstone is a fun way to apply it.

    Many times in this document I will refer to Ruby instead of Lich when talking about specific commands. Ruby is a programming language that communicates with your computer to tell it what to do. Lich was written in this language to tell Ruby what to do, which in turn tells your computer what to do. Lich is just one giant script running in the background that gives your scripts tools and access to information from Gemstone.

    This tutorial was written for Lich v4.1.34:

    This tutorial does not cover installation and troubleshooting for Lich. For this, see the documentation here:

    For a list of all Lich scripting commands and information on how to use them specifically, see:

    If you're interested in maximum information absorption you'll need to do more than just read this stuff; the best way to understand it is to DO it! Even though it may be easy to cut-and-paste my code examples, your brain can really make a lot more sense of things if you actually type it out for yourself. This made a big difference for me when I first started learning how to program.

    A great tradition amongst programmers since the '70s is the "hello world" program. It's useful as a good jumping-in point for new programmers -- this is the same program, but with a fantasy roleplay slant.

    Assume we’ll follow these steps for all of our programs in this tutorial:
    Step 1) Load up Lich and log in one of your characters.
    Step 2) Open up Window’s Notepad from the start menu.

    Now for your first program!

    Program 1:
    Step 1) In notepad, type in:
    puts "Hail Elanthia!"
    Step 2) Save this file as "Tutorial.lic" in Lich’s Scripts subfolder (.\Lich\Scripts\Tutorial.lic)
    Step 3) In GS4, use the command ";tutorial"

    What you should have seen at this point are the words "Hail Elanthia!" in the game window that our script generated. As programmers we call this "printing a string".

    Line 1 - puts "Hail Elanthia!"
    * "puts" is a Ruby command, and not a Lich command. It means "put string", and will output a string to the game window.
    * String is a term which means "a series of symbols". Basically it is just some text.

    Now we’re all officially programmers! Congrats! You’ll be pulling in $38,000 in no time to make some other guy millions.

    This next chapter is a bold step forward. We’re going to tackle Variables, which are a critical part of all programs. You already used a variable in your "Hail Elanthia!" script, and you didn’t even know it!

    In programming, a variable is simply a representation of some value. Remember your old math classes where X + Y = Z? X, Y, and Z are variables which represent some potential value. Same concept here.

    Program 2:
    Step 1) Open your Tutorial.lic file in notepad, delete everything, then type in:
    myStringVariable = "Hail Elanthia!"
    puts MyStringVariable
    Step 2) Save the file, then in GS4 use the command ";tutorial"

    You should get the same result that you had from Chapter 1. You actually wrote the exact same program, as far as the computer is concerned. The code from Chapter 1 was just a shortcut – deep in the brain of your computer it made up its own variable for the "Hail Elanthia" string. All we’ve done here is given that variable a name we understood so we can work with it.

    Let’s try something a little more useful for GS4. We’re going to use our first Lich command, "waitfor".

    Program 3:
    Step 1) Open your Tutorial.lic file in notepad, delete everything, then type in:
    myStringVariable = "Hello"
    puts "Waiting to see '#{myStringVariable}'"
    waitfor myStringVariable
    puts "I saw '#{myStringVariable}'!"
    Step 2) Save the file, then in GS4 use the command ";tutorial"
    Step 3) In the game, make your character say something like, "Hello there everyone!" -- it just needs to use the word "Hello" for the script to work.

    A lot of new things have happened here:

    Line 1 - myStringVariable = "Hello"
    * Declared the variable myStringVariable which held a value of "Hello".
    * This is just some text, but we got to use it in an interesting way in combination with other commands.

    Line 2 - puts "Waiting to see '#{myStringVariable}'"
    * In the game window we saw "Waiting to see 'Hello'".
    * This is magic that the Ruby scripting language does for us, and it is very useful!
    * You can reference any string variable you’ve declared by placing a # sign in front of the variable name surrounded by brackets.
    * When Ruby executed our script it swapped in whatever text myStringVariable held where we had said #{myStringVariable}.

    Line 3 - waitfor myStringVariable
    * This is a Lich command that will pause the script until it sees some text in the game equal to whatever value is held by myStringVariable.
    * When your character said, "Hello there everyone!", Lich saw the word "Hello", then stopped waiting since that’s what myStringVariable was equal to.
    * You could have used waitfor "Hello" and had exactly the same effect, but I wanted to demonstrate using a variable.

    Line 4 - puts "I saw '#{myStringVariable}'!"
    * This printed, "I saw 'Hello'!" to the game window after your character said it.
    * This confirms that the script stopped waiting to see "Hello", and continued on.

    You have now successfully declared and used variables in Lich!

    We’re now going to discuss arrays. Just like variables in the last chapter, you’ve already used arrays and didn’t even know it!

    An array is a collection of stuff. You can have an array of stamps, or an array of cars, or an array of letters. A string, such as "Hello" from last chapter, is exactly that! It is a collection of characters that makes up a word.

    We can declare an array just like you declared the string variable above, except you use brackets to indicate what is inside the collection.

    myStringVariable = "Hello"
    myStringArray = ["I", "want", "to", "say", myStringVariable]
    The above code will create an array called myStringArray that is a collection of strings. We just populated it with strings upon declaration, but you can also add or subtract stuff from it later on in the code.

    Ruby arrays have a method called "push", as demonstrated below.
    * Methods – Also called subroutines. A Method is an action that is performed by the code when we ask it to run.
    * puts, for example, is a Method made by the guys who designed Ruby
    * push – A method for arrays that lets us add an element to that array
    * Element – A word meaning the members of an array. An element is a single item of the array.

    myStringVariable = "Hello"
    myStringArray = []
    myStringArray.push("to", "say", myStringVariable)
    After execution myStringArray would equal ["I", "want", "to", "say", "Hello"].

    The "push" method of myStringArray in the above code is a tool that the guys who made the Ruby programming language created for us. Ruby has TONS of tools like this for all sorts of things, and sometimes it can get very confusing. This is where Google becomes your best friend. If you want to do something like remove one of those words from the array, just Google "RUBY REMOVE ELEMENT FROM ARRAY".

    That Google search returned all kinds of great information on arrays, including some on the "delete" method.

    myStringArray = ["I", "want", "to", "say", "hello"]
    Once this code executed, the value of myStringArray would be ["I", "to", "say"].

    You can access specific elements of the array with the square brackets [] and an index number. Think of it like a shopping list, and you want to know what items #2 and #3 are:

    myStringArray = ["Butter", "Ham", "Eggs", "Cheese", "Ice Cream"]
    puts myStringArray[2]
    puts myStringArray[3]
    This would print the strings "Eggs" and "Cheese" to your game window.

    String variables accessed in an array are treated like a regular variable such as what we did in Chapter 2.

    Are you paying attention? Did you notice that I said "Eggs" and "Cheese" would be the result of the above code? Aren't they the 3rd and 4th items in the array? We asked it to print #2 and #3! Shouldn't it have printed "Ham" and "Eggs"?

    Nope, it did what we asked -- Arrays in Ruby are Zero-Based. This means that they refer to the first element as [0], the second element as [1], and so forth. For people in the Western world this concept can sometimes cause confusion because we count items in lists starting with 1. Most people hate this when they first start programming in a Zero-Based programming language, but we quickly grow to love it as soon as we get into more complex operations. Personally I hate any language which uses One-Based arrays (starts counting at [1]), and have a lot of trouble using them.

    If it really confuses you, think of counting arrays the same way you count how old someone is. A baby starts at age 0 and isn't called 1 until they've been around a whole year. That first year of their life would be Element 0, the next would be Element 1, etc.

    Don't worry, it will become second nature soon enough. Let's make a script and learn about loops!

    Program 4:
    Step 1) Open your Tutorial.lic file in notepad, delete everything, then type in:
    loop {
    	waitfor "Obvious"
    	obviousExitsArray = checkpaths
    	randomIndex = rand(obviousExitsArray.size)
    	aDirectionString = obviousExitsArray[randomIndex]
    	puts "A crazy voice in your head says to move... '" + aDirectionString.upcase + "'!"
    Step 2) Save the file, then in GS4 use the command ";tutorial"
    Step 3) Look and move around with your character… Follow the crazy voice!
    Step 4) Use ";kill tutorial" to stop the script when done.

    Line 1 – loop {
    * This begins a repeating loop! The script will keep doing whatever code comes next over and over until the loop gets broken.

    Line 2 - waitfor "Obvious"
    * We know all about this one. It pauses the script until it sees the word "Obvious" in your game window, as in "Obvious exits:" or "Obvious paths:".
    * You could also trick the script by having your character say, "Obvious". This is a form of hacking – executing code contrary to what the programmer intended.

    Line 3 - obviousExitsArray = checkpaths
    * "checkpaths" is a Lich command which returns an array of strings. Each element of that array is a direction that you can go (n, s, e, w, out, etc).

    Line 4 - randomIndex = rand(obviousExitsArray.size)
    * This line declares an integer variable. Integer variables are like string variables, but they hold a number instead of text.
    * "rand" is a Ruby method which generates a random number between zero and the number that you pass it inside the parenthesis.
    * We passed the "rand" method the size of our obviousExitsArray. If the room let you go "n", "sw" and "se", obviousExitsArray.size would be 3.
    * Remember that Ruby is Zero-Based. Calling "rand(3)" can give you 0, 1, or 2 -- It would never return 3. That is called an "exclusive upper bound".

    Line 5 - aDirectionString = obviousExitsArray[randomIndex]
    * This line declares a string variable, then sets it to one of the strings held in the obviousExitsArray.
    * The element it uses is the random number we created on Line 4, giving us a random direction.

    Line 6 - puts "A crazy voice in your head says to move... '" + aDirectionString.upcase + "'!"
    * This line outputs a string to the game window.
    * Instead of using #{aDirectionString} to reference the variable, we combined three strings with + signs between them. The result is the same.

    Line 7 - }
    * This is a closing bracket which ends the contents of our loop. When the script reaches this point, it goes back to where "Loop {" was called.

    OPTIONAL: If you're feeling adventurous, try changing line 6 to: move aDirectionString
    * "move" is a Lich method that will make your character walk in a given direction. You can stop it with ";kill tutorial".
    Last edited by Monotonous; 06-04-2010 at 10:01 PM.

  2. Default

    Reserved part 2

  3. Default

    reserved part 3

  4. Default

    Let me know if you see anything wrong so I can fix it up. If you want to ask a question please feel free, but do it in this thread so everyone can learn from it.

    In the next chapters I plan on covering:


    After that I will be taking existing scripts from the Lich repository and either breaking them down line-by-line, or showing how we can improve them.
    Last edited by Monotonous; 06-04-2010 at 01:01 PM.

  5. #5
    Join Date
    Dec 2003
    Blog Entries


    I would just add a call to make this post Sticky.
    Vote for Gemstone Once a Day at The Mud Connection & Top Mud Sites

  6. #6


    I have to run, but this is getting serious attention as soon as I get back.

  7. Default is for Shaelun's version. I browsed through it, and I don't think any of it applies to the new version.

  8. Default

    Quote Originally Posted by Tillmen View Post is for Shaelun's version. I browsed through it, and I don't think any of it applies to the new version.
    Removed the link.

  9. #9



    This is exactly what I've been looking for.

  10. #10


    GameObj, Spell, and dothistimeout.

    Thanks Monotonous, we've needed a thread like this so we can tell people to RTFM.
    "You burn with hunger for food that does not exist."

    Playershops 3

    ~ GSF:Azathoth

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts