Skip to content

Tutorial 1

Alex May edited this page Mar 25, 2020 · 4 revisions

When the MOO is first created, it has just a few predefined objects and only a very basic language understanding.

On the very first telnet connection, the MOO creates the following objects by calling ObjectManager::luaMinimal()

0 - Root
\- 1 - System Class
 - 2 - The First Room
 - 3 - Wizard (a player object with full system control, placed into the The First Room)

Every object within the world has a numerical object id, which is generally how you reference objects within the world.

Objects usually have a parent object from which it will inherit properties and verbs.

It also adds the verb do_login_command to the System object, which just returns the Wizard id to allow immediate login by the Wizard user.

Finally, it adds a basic eval verb onto the Generic Room object that allows programmer users to evaluate MOO code.

All of this takes place without any user feedback, so you will find yourself with a blank telnet prompt waiting for user input.

MOO Commands

Verb::parse() processing:

  • " - built in alias for say
  • : - built in alias for emote
  • ; - built in alias for eval

At this point, if you try the say or emote commands, the MOO doesn't even have code for them so you will get an error message:

"Can anyone hear me?
I couldn't understand that.
:feels lonely and not understood
I couldn't understand that.

However, the eval command (to evaluate some actual code) has already been defined, so let's try something with that:

;moo.notify( "Hello, World!" )
Hello, World!

Something actually worked! We can start to investigate our tiny world:

;moo.notify( me.name )
Wizard
;moo.notify( here.name )
The First Room
;moo.notify( here.id )
2
;moo.notify( o( 2 ).name )
The First Room
;moo.notify( me.parent.name )
Root Class
;moo.notify( me.location.name )
The First Room

Here moo.notify() is a function for sending a string to a connected user. As you're the only user, and you're using the global version of notify(), you're seeing the output. You can send a string to another user too, which we'll see later.

We also introduce some key objects here, namely:

  • me - your player object
  • here - the object of the location your player object is in
  • o( 2 ) - o() is a global function for getting any object by its unique id. Here we get object #2, which is The First Room
  • me.parent - the parent object of your player object
  • me.location - the object of the location your player object is in (synonymous with here when looking at your user object)

With the above code, we are reading properties from the objects:

  • me.name - the name of the user's object (Wizard)
  • me.location.name (or here.name) - the name of the location where the user's object is (The First Room)
  • me.parent.name - the name of the parent object of the user's object (Root Object)

Perhaps it would be better to personalise your user object a little. Let's set its 'name' property:

;me.name = "bigfug"
;moo.notify( "My name is " .. me.name )
My name is bigfug

Wow, not only did we personalise our user object, we printed out a more interesting response by joining (or concatenating) two strings together using Lua's '..'

Adding Properties

Every object in the system has some built-in properties, but we can also add our own! Let's say we want to introduce the concept of money into the world. We could add a property called 'money' like so:

;moo.notify( me.money )
<nil>
;me:propadd( "money", 0 )
;moo.notify( me.money )
0
;me.money = 100
;moo.notify( me.money )
100

So now your user object has 100 in its new 'money' property. You're so rich! See how easily we can create completely new properties for objects.

Notice how we called 'propadd' differently, by using a semicolon (:) instead of a period (.)? Unlike a property, which is basically a bit of data that's attached to an object, we are calling a method, which is a function that is attached to an object. However, you may have noticed that we called moo.notify() with a period, so this needs a bit of an explanation:

"moo" is a global library of functions, and not a MOO object. When we call a function in it, we use a period.

"me" is shorthand for your player object, which is MOO object #3. When we call the 'propadd' method we want it in the context of your object. In other words, we want to add a property to your user object, rather than trying to add it as a global property, which isn't allowed in the world of MOO.

If it's still confusing (you're not alone!) then think of it like this:

;me:method( "Data" )

is equivalent to (and this also works, by the way):

;me.method( me, "Data" )

Here, we're calling 'method' as a function of 'me' and passing the 'me' user object in as the first argument, followed by "Data". This works because we're saying that we want to call the 'method' on object 'me', and telling it to operate on the 'me' object, which is usually what we want. It's possible to do very confusing things such as:

;me.method( o( 2 ), "Data" )

But this is almost certainly going to cause some big problems! Better to use the semicolon method call format!

Deleting Properties

Let's delete the money property again:

;me:propdel( "money" )
;moo.notify( me.money )
<nil>
Clone this wiki locally