Skip to content

Tutorial 3

Alex May edited this page Mar 22, 2020 · 1 revision

Player and Support Classes

To begin making our world, we're going to have to add some useful object structure and basic verbs that will make building faster as we progress. Initially we'll have to enter all commands as a programmer, but we can start adding helper verbs straight away that will gradually replace these direct commands.

We start by setting up an alias for the root object and the 'nowhere' object so we can avoid using their id numbers and also make things more readable:

;moo.system:propadd( "nowhere", o( -1 ) )
;moo.system:propadd( "root", moo.root )

Create a "Generic Programmer" object that we can add helper verbs onto and set our player parent object to it so we can use the new verbs:

;moo.create()
;moo.last.name = "Generic Programmer"
;moo.last.parent = moo.root
;moo.me.parent = moo.last

Save an alias of the generic programmer to the system object:

;moo.system:propadd( "generic_programmer", moo.last )

Add the @create verb that we'll use to create objects:

;moo.last:verbadd( "@create" ):edit()

Verb code:

if #moo.args < 1 then
   moo.notify( "Usage: @create <parent object> [named name]" )
   return
end

local ParentName = moo.args[ 1 ]
local ObjectName = "New Object"

for i = 2, #moo.args, 2 do
   if moo.args[ i ] == "named" then
      ObjectName = moo.args[ i + 1 ]
   end
end

local Parent = moo.find( ParentName )

if Parent == nil then
    moo.notify( "Can't find parent object " .. ParentName  )

    return
end

local NewObj = moo.create( Parent )

NewObj.name     = ObjectName
NewObj.location = moo.player

moo.notify( "You have created a " .. moo.args[ 1 ] .. " named " .. ObjectName .. " (#" .. NewObj.id .. ")" )

Press CTRL+S to save the verb and exit the editor.

Create a "Generic Thing" and store it in the system object. Here we can use the $root alias we set up right at the beginning. We also set the new object's location to nowhere:

@create $root named "Generic Thing"
;moo.last.location = -1
;moo.system:propadd( "thing", moo.last )

Create a "Generic Character" for non-player characters (NPC's) and store it in the system object

@create $thing named "Generic Character"
;moo.last.location = -1
;moo.system:propadd( "character", moo.last )

Create a "Generic Player", a "Generic Wizard", store them in the system object, and complete the player hierarchy:

@create $character named "Generic Player"
;moo.last.location = -1
;moo.system:propadd( "generic_player", moo.last )

;moo.system.generic_programmer.parent = moo.last

@create $generic_programmer named "Generic Wizard"
;moo.last.location = -1
;moo.system:propadd( "generic_wizard", moo.last )

;moo.me.parent = moo.last

We rename the current location as "Generic Room", store it in the system object, create a new First Room, and set our location's parent to it

;moo.here.name = "Generic Room"
;moo.system:propadd( "room", moo.here )
;moo.here.parent = moo.system.thing

@create $room named "The First Room"
;moo.last.location = -1
;moo.me.location = moo.last

Add the @verbadd verb

;moo.system.generic_programmer:verbadd( "@verbadd" ):edit()

Verb code:

if #moo.args < 1 then
    moo.notify( "Usage: @verbadd <Object>:<Verb Name> [Direct Object] [Preposition] [Indirect Object]" )

    return
end

local dobj = "this"
local prep = "none"
local iobj = "this"

local ObjectName, VerbName = string.match( moo.args[ 1 ], "(.*):(.*)" )

local Object = moo.find( ObjectName )

if Object == nil then
    moo.notify( "Can't find object " .. ObjectName  )

    return
end

local Verb = Object:verbadd( VerbName )

if Verb == nil then
    moo.notify( "Can't add verb " .. VerbName .. " to " .. ObjectName )

    return
end

if #moo.args >= 2 then dobj = moo.args[ 2 ] end
if #moo.args >= 3 then prep = moo.args[ 3 ] end
if #moo.args >= 4 then iobj = moo.args[ 4 ] end

Verb.dobj = dobj
Verb.prep = prep
Verb.iobj = iobj

Verb:edit()

Now we can use this new verb to create our @edit verb:

@verbadd $generic_programmer:@edit any any any

Verb code:

if #moo.args ~= 1 then
   moo.notify( "Usage: @edit <Object>:<Verb Name>" )

   return
end

local ObjectName, VerbName = string.match( moo.args[ 1 ], "(.*):(.*)" )

local Object = moo.find( ObjectName )

if Object == nil then
    moo.notify( "Can't find object " .. ObjectName  )

    return
end

local Verb = Object:verb( VerbName )

if Verb == nil then
    moo.notify( "Can't find verb " .. VerbName .. " on " .. ObjectName )

    return
end

Verb:edit()

Add a verb to add a property:

@verbadd $generic_programmer:@propadd any any any

Verb code:

if #moo.args ~= 2 then
    moo.notify( "Usage: @propadd <Object>.<Property Name> <Property Value>" )

    return
end

local ObjectName, PropName = string.match( moo.args[ 1 ], "(.*)%.(.*)" )

local Object = moo.find( ObjectName )

if Object == nil then
    moo.notify( "Can't find object " .. ObjectName  )

    return
end

if Object:prop( PropName ) ~= nil then
    moo.notify( "Object " .. ObjectName .. " already has a property " .. PropName )

    return
end

Object:propadd( PropName, moo.args[ 2 ] )

Summary

At this point we have created a basic object hierarchy with some support verbs for creating objects, verbs, and properties.

Next we want to create some new verbs so we can create new rooms and change their description.

Clone this wiki locally