Tutorial lesson #1

(c) 1999 -- Robert W. Byrd & based on HUGO and related materials (c) Kent Tessman

Getting Started

  1. One of the first things that you should be aware of is a change in the naming convention of the HUGO grammar library. In previous versions of HUGO, the library was called "grammar.g", but is now called "verblib.g". This can cause you some problems if you try to compile source code written by someone else who was using an earlier version of HUGO. The best way to fix this is to find the line in the source code that says "#include grammar.g" and replace it with "#include verblib.g".
  2. On my home system, and on my laptop, using the restart command in the HUGO engine can cause the program to lock up. I avoid this by using the "open new story" command instead, then closing the previous instance of the program. (I am using Win95)
  3. One other thing... please make sure you have downloaded "manual.txt" or "manual.pdf" or "manual.rtf" as well. If you have lots of paper, you would be well advised to print it out and put it in a binder. If you don't wish to print it out, you can load it up in your word processor of choice and use the search command to find relevant sections and keywords.

It is assumed that if you are reading this, you have knowledge of how to compile HUGO source code, and load the resultant ".hex file" to run in the HUGO engine.

Due to the way this document is written, some of the lines of example code are wrapped around to the beginning of the next line (like long lines of quoted text). When you see this, remember that in your text editor, it should in fact be all one line.

Your First Program

I am going to assume that when you downloaded the HUGO package for your system, you also took the time to download the two short example programs "vault.hug" and "shell.hug". If you didn't, please download them before continuing, because they are required for these tutorial lessons. Also... it would probably be an excellent idea if you printed out "vault.hug" so that you can refer to it later on.

Start up your text editor of choice (notepad, wordpad (in text mode), eoedit, ultraedit) and read in "shell.hug". Then, before doing anything else, save it as "tut01.hug" in your HUGO directory (for the sake of convenience, I will assume you installed to C:\Hugo). Now that you have a clean slate to work with, let's get to it.

Right at the bottom of the file, you will see that an empty room has been created with the following code:

room emptyroom "empty room"
{}

Not much of a room is it? You can compile this program, then run it to see exactly how bare this room is. Let's make a few changes and see if we can give this room a bit more to show for itself. First off though, let’s change the room to "start_room".

room start_room "empty room"
{
  short_desc
  {
    "A small empty room."
  }
  long_desc
  {
    "A very small, cramped room. Just large enough to hold
    a tutorial lesson in."
  }
}

Now we have something that will allow a bit of looking around. Compile and run your modified program to see the changes you have made to the room.

As you can see, it’s not much of a room. But that’s okay. We only need the room so we’ll have someplace to take the lesson in.

For this lesson we are going to create a can of pop. Why? Because that is the first thing I ever created with HUGO. Subsequent lessons will also most likely be based on my experiences with HUGO as well.

We’ll start adding the code for our pop can after the end of the code for the room. Using your text editor, go to the bottom of the file and type:

! --------------------------------------------------
! Code for our first object, a can of pop
! --------------------------------------------------
object can_pop "can of pop"
{
  in start_room
  article "a"
  nouns "can"
  adjectives "coke", "pop", "soda"
  short_desc
  {
    "A cold can of pop."
  }
  long_desc
  {
    "A refreshing can of cold pop. Just the thing for
    the thirsty IF player."
  }
  is openable, not open
}

And there you have it! A fully functional can of pop. The code is fairly self-explanatory :

It appears in the start_room, its name as a noun is a "can", and its adjectives are "coke, pop" and "soda". This means we can refer to it as "can, coke, pop, soda, can of coke, can of pop" and "can of soda". This is important, as there may be more than one can of pop in the room at a later date. If this happens, we may wish to delete "pop" and "soda" from the adjective list, and just stick with "coke" (and perhaps "cola").

You can compile your program (hcwin.exe if you’re using Win95), assuming you didn’t make any errors in the code, and start it up in the HUGO engine (hewin.exe).

You can open and close the can. You can pick it up and drop it. You can look at it. And… hmmm… that seems to be about all you can do with it. Although this may suffice for the casual pop can creator, we are a little more demanding about our pop cans. For one thing, in the real world, you can’t close a can of pop back up again. Let’s look at how we can address this problem.

In order for us to be able to manipulate that status of whether or not the can is open, we are going to have to intercept the normal handling of the "open" verb. Because we want this to happen before the normal handling of the verb, we use the "before" clause. Makes a certain amount of sense doesn’t it?

Move your cursor to the line before the "is openable, not open" line and insert the following code:

! -------------------------------------------------------------------
! Replacement handling of verbs for "before" actions
! -------------------------------------------------------------------
before
{
  ! "before" code to handle opening of the can starts here
  object DoOpen
  {
    if self is open
    {
      "It's already open!"
    }
    else
    {
      return false  ! for normal verbroutine processing
    }               ! which sets the "open" attribute
                    ! to be true
  }
  ! "before" code to handle opening of the can ends here
}
! -------------------------------------------------------------------
! Replacement handling of verbs for "after" actions of our pop can
! -------------------------------------------------------------------
after
{
  ! "after" code to handle opening of the can ends here
  object DoOpen
  {
    "You hear a slight fizz as the can is opened."
  }
  ! "after" code to handle opening of the can ends here
}

Save, compile and run your program. You should now be able to open the can and enjoy the sound of the "slight fizz" as you open it. Trying to open it a second time will let you know that you have, in fact, already completed that step. Those of you who think about such things will probably be disappointed to hear that we are not going to be checking to see if you shook the can of pop before you opened it (not a recommended procedure in any event).

As you can see from the code, the line "if self is open" sets up the if statement by checking to see if the can is or is not currently open. If it is not, the we "return false" so that the normal verb processing routine takes place (which actually sets the "open" bit on). If it the can is already open, the other message is displayed. In the "after" section the appropriate can being opened message is displayed, and the "open" attribute is set to be true.

We now need to add another block of code to handle the interception of the normal "close" verb handling. This is very similar to the way that we handled the "open" verb as shown by the following code:

! code to handle closing of the can starts here
object DoClose
{
  if self is not open
  {
    "The can hasn’t been opened yet."
  }
  else
  {
    "Sorry... this can is open for good."
  }
}
! code to handle closing of the can ends here

Add the above block of code to your program just after the ending comment for the "DoOpen" block of code. Save, compile and run your program. As you can see, the can is able to be opened (once), and cannot be closed. Trying to close it before it has been opened will remind you that you need to have a better look at that can you’re holding.

For our next trick (ta, da!), we are going to modify the descriptions of the can to reflect whether or not the can is opened or closed. As you can imagine, this is not terribly difficult and requires only that we change the "short_desc" and the "long_desc" of the can.

Here is the code snippet that we currently have for the can:

short_desc
{
  "A cold can of pop."
}
long_desc
{
  "A refreshing can of cold pop. Just the thing for the thirsty IF player."
}

All we need do to modify this code is to add a couple of "if" statements like this:

short_desc
{
  if self is open
  {
    "An opened cold can of pop."
  }
  else
  {
    "A closed cold can of pop."
  }
}
long_desc
{
  if self is open
  {
    "An opened, refreshing can of cold pop. Just the thing for 
    the thirsty IF player."
  }
  else
  {
    "A closed, refreshing can of cold pop. Just the thing for 
    the thirsty IF player."
  }
}

Although the above code is fully functional as to our needs, you have probably noticed that there is a certain amount of redundancy in it. In both sets of descriptions, most of the description is repeated. We can cut this out by using the semi-colon and a "print" statement, as illustrated below:

short_desc
{
  if self is open
  {
    "An opened ";
  }
  else
  {
    "A closed ";
  }
  print "cold can of pop."
}
long_desc
{
  if self is open
  {
    "An opened, ";
  }
  else
  {
    "A closed, ";
  }
  print "refreshing can of cold pop. Just the thing for the
  thirsty IF player."
}

Now he have eliminated the duplication and cut down on the size of the code a bit. Both good qualities when writing code. You will notice the use of the semi-colon ";" to indicate that we wish whatever is printed next to continue on the same line. You will also notice the trailing space before the closing quote mark so that we don’t end up with something like "A closedcold can of pop."

Make the changes outlined above to your code. Save, compile and run it. You should be able to see the different descriptions for the can in effect. If you pick up the can, open it, then drop it again, the new "short_desc" will be visible.

Now then... we have handled opening and closing the can, and have changed the descriptions to match the state of can with regards to being opened or closed.

But what about the player being able to open and close the can if the can is not currently in the player’s inventory? In order to open and close the can, the player needs to be holding the can (unless of course, he or she is endowed with telepathic abilities we are not currently aware of).

To check whether or not a player has picked something up, we use the "if" statement again like this:

if self in player
{
  [some code...]
}
else
{
  [some code...]
}

When the player picks up an object (assuming the object can be picked up!) it is added to the inventory of the player, and can be checked against using the above sort of code.

What this means to us is that we now have to modify the code for both of our replacement actions of opening and closing the can to check on whether or not the player has picked the can up first.

Lets start with the code for opening the can, which is now modified to look like this:

! code to handle opening of the can starts here
object DoOpen
{
  if self not in player
  {
    "You aren't holding the can."
  }
  elseif self is open
  {
    "It's already open!"
  {
  else
  {
    return false  ! for normal verbroutine processing
  }               ! which sets the "open" attribute
                  ! to be true
! code to handle opening of the can ends here
}

As you can see, we only modified the portion of the code that deals with actually opening the can. If the can is already opened, it really doesn’t matter to us if the can is in the inventory of the player or not.

The modified code for closing the can however, will need to check if the player is holding the can or not, as shown below:

! code to handle closing of the can starts here
object DoClose
{
  if self is not open
  {
    if self in player
    {
      "The can hasn’t been opened yet."
    }
    else
    {
      "Even though you aren't holding it, you can see that
      that the can is in fact, not currently open."
    }
  }
  else
  {
    if self in player
    {
      "Sorry... this can is open for good."
    }
    else
    {
      "You look down at the can and realize that once opened
      is the same as always opened... it won't close."
    }
  }
}
! code to handle closing of the can ends here

And so we have handled all the things that a person is apt to do with a can of pop. Or have we? What if the player takes a drink? What if the player drops the open can and it tips over? What if Garfield really is only a cartoon?

In our next tutorial, we will add more code to our program to allow the player to take a pre-determined number of drinks from the can before it runs dry. We will also explore having the pop run out of the can if the player drops it before it is empty.

Questions or comments? E-mail me at

Copyright © 1999, Robert w. Byrd