Verbs on Objects
A verb is a named MOO program attached to an Object. Most verbs
implement player commands — look, take, drop, say — but verbs
can also be invoked as methods from other verb code (obj.title(),
this.moveto(...)). Verb authoring as a craft is covered in
Your First MOO Verb and Creating MOO Verbs;
this page is the reference for the Verb model and its dispatch
metadata.
Identity and lifecycle
Each Verb row has an origin (the Object the verb is attached to),
one or more Name aliases, source code, and optional dispatch metadata
(direct_object, indirect_objects). A verb is deleted when its
origin object is destroyed.
At dispatch time, the parser searches caller → inventory → location → dobj → pobj for a matching verb on each object, with last match winning. See Command Parser Reference for the full search order and verb-resolution rules.
Verb attributes
- Verb.pk
The unique identifying number of this Verb.
- Verb.code
The Python source code for this Verb.
- Verb.repo
The
Repositoryrow identifying the dataset this verb’s source came from. Populated byload_verbs;Nonefor verbs created in-database via@edit.
- Verb.filename
Absolute filesystem path to the verb source file.
@reloaduses this to re-read the file.Nonefor in-database verbs.
- Verb.ref
Git ref of the verb source. Reserved for future Git-backed verb sources; not yet wired into the bootstrap loader.
- Verb.owner
The Object whose permissions this verb runs with. Becomes
context.callerwhile the verb is executing. Changes requireentrustpermission.
- Verb.origin
The Object the verb is attached to. Becomes
thisinside the verb body.
- Verb.direct_object
Direct object specifier. One of
this,any,none, oreither— controls how the parser matches the verb against a typed direct object.
- Verb.indirect_objects
Indirect object specifiers — one entry per accepted preposition, each with its own
this/any/nonerule.
direct_object is one of this, any, none, or either.
indirect_objects is a ManyToMany of (preposition, specifier)
pairs. Both are populated from the verb file’s shebang at load time.
Verb names
A single Verb row may have multiple Name aliases stored as separate
rows. The shebang #!moo verb @reload reload_batch creates one
Verb with two Names, so any of @reload or reload_batch will
match. verb_name inside the verb body holds the specific alias the
caller used.
Names support a single asterisk for prefix matching:
Pattern |
Matches |
|---|---|
|
|
|
|
|
Any string starting with |
|
Anything. |
The asterisk itself is not part of the matched string.
Dispatch metadata
Argument-specifier semantics:
|
Effect |
|---|---|
|
Verb fires only when the command has no direct object. |
|
A direct object must be present; any string is accepted. |
|
Verb fires only when the parsed direct object resolves to |
|
Direct object is optional. |
indirect_objects is a list of preposition/specifier pairs. The
preposition canonical forms (with, at, in, on top of, etc.)
and their synonym groups live in settings.PREPOSITIONS; see
Command Parser Reference for the full table. Each specifier is none, any,
or this (matching the direct_object semantics above).
For the shebang grammar that populates these fields, see Creating MOO Verbs.
Permissions
Permission |
Effect |
|---|---|
|
Read the verb’s source code and metadata |
|
Modify the verb’s source, dispatch metadata, or names |
|
Invoke the verb |
|
Change the verb’s owner |
|
Set permissions on the verb |
|
Wildcard — all of the above |
These checks fire automatically:
Verb.save()on a new row checkswriteon theoriginObject. On an update it checkswriteon the verb itself, plusentrustif the owner is changing.Verb.delete()checkswriteon the verb.Verb.__call__()checksexecuteon the verb when there’s an active session.passthrough()passes_bypass_execute_check=Trueinternally so a parent verb call doesn’t pay the check twice.
add_verb() requires develop permission on the target object —
that’s the gate for adding a new verb to an object you don’t own.
Verb code does not need to check permissions before invoking another
verb or modifying a property; the model layer raises AccessError
on failure and the task runner shows it as a clean error to the
player. See How Permissions Work in Verbs.
Error handling
When a verb raises an exception:
UserErrorand subclasses (includingNoSuchObjectError,NoSuchVerbError,NoSuchPropertyError,UsageError,QuotaError) — the exception’s message is shown to the player as a bold red line. Verbs should raise these rather than printing errors manually.PermissionError(includingAccessError) — same UX asUserError; the message is the model-layer guard’s “X is not allowed to ‘Y’ on Z” string.Any other exception — regular players see
"An error occurred while executing the command."; wizards see the full traceback.
Because errors propagate cleanly, parser methods like get_dobj()
can be called without defensive wrapping. If the named object
doesn’t exist, NoSuchObjectError bubbles up and the player sees
"There is no 'X' here." automatically. Catch only when you want
a different message or alternative behaviour.
See also
Your First MOO Verb — write your first verb.
Creating MOO Verbs — shebang grammar, parser methods, output mechanisms, error handling.
Advanced Verb Patterns — calling other verbs,
passthrough(), time-aware continuation.Command Parser Reference — verb search order, preposition synonym groups, the verb-name asterisk grammar.
SDK Functions —
Object.add_verb(),Object.get_verb(),Object.invoke_verb()signatures.