Verbs, add_action() and quests

Background

While my historical perspective on LP/LDMud practices is limited since I've only seriously played a single LDMud and I've only spent about two years and 3 months coding for it, I will speak to some more historical conditions as best I can.

Traditionally many or most local commands (and even some global ones) are implemented through the add_action(string function, string verb) efun which allows an object to publish commands to present users. This presents at least two main problems:

  1. A given MUD may have several or even dozens of implementations of common functionality (like "open" and "unlock"...) which not only wastes development time initially, but wastes maintenance time later.
  2. Many newer coders (or at least those new to the add_action) may mis-handle its return values. The driver gives every present object the chance to speak up for itself in regard to an action--given that the objects ahead of it properly return when they aren't the intended target of the action. This means an "open" function on one object might keep the "open" function on the object the player actually needs to open from firing.

Traditional solutions

One of the more common ways the above are addressed is by having standard commands (or, in the case of MudOS and variants, a natural-language command parser) which makes calls to predictable query functions to get the information it needs to know whether the command/verb is allowed to interact with a given object. The advantage of going fully to the latter option is that add_actions are (as I understand it...) disabled and builders are forced to rely on the standardized queries to provide verb functionality in their objects. Standardization by lack-of-options.

The Middle Path

In our case, we're still on LDMud, and while a jump to MudOS has been discussed and even attempted in the past, the same route wouldn't work even if we wanted it (unless we wanted to duplicate the work and functionality for ourselves). Beyond this, however, MudOS's reliance on defined public query functions in objects, while standardizing at the command level, encourages hard-coded checks in these functions for the desired behavior. See the following from the MudOS Coder's Manual:

But how can can_press_obj_on_obj() know what the direct and indirect objects are if they have not been identified yet? The answer is that it cannot. For the command "push the button on the wall", in a room with me and you in it and we carry nothing, the sequence looks like this (return in comment):

1verb->can_press_obj_on_obj(0, 0, "the button", "the wall"); (1)
2me->direct_press_obj_on_obj(0, 0, "the button", the wall"); (0)
3you->direct_press_obj_on_obj(0, 0, "the button", "the wall"); (0)
4room->direct_press_obj_on_obj(0, 0, "the button", "the wall"); (1)
5me->indirect_press_obj_on_obj(room, 0, "the button", "the wall"); (0)
6you->indirect_press_obj_on_obj(room, 0, "the button", "the wall"); (0)
7room->indirect_press_obj_on_obj(room, 0, "the button", "the wall"); (1)
8verb->do_press_obj_on_obj(room, room, "the buton", "the wall"); (1)

This assumes, of course, that the room responds positively with the id's "button" and "wall". People familiar with the parser might say, "Hey, wait, there is a lot more that happens than just that." In fact, there are many more possible permutations of this sequence. The most interesting is the ability to simply ignore the difference between prepositions like "in" and "into" which are often used interchangeably in colloquial speech. For example, if you had "put OBJ in OBJ" and "put OBJ into OBJ" verb/rules, you could handle them in a single place for each of the applies respectively liek this:

1can_put_obj_word_obj()
2direct_put_obj_word_obj()
3indirect_put_obj_word_obj()
4do_put_obj_word_obj()

If the parser found no can_put_obj_in_obj() defined, it then searches for a more generic handler, can_put_obj_word_obj(). In fact the real order it searches for a can handler is:

1can_put_obj_in_obj()
2can_put_obj_word_obj()
3can_put_rule()
4can_verb_rule()

I'm currently exploring instead a mixed option--a managed add_action wrapper which automatically handles publishing the add_action, ensures proper rejection of unviable syntax, and automatically records information about the call in a standardized API. The wrapper will be supported by standardized verb syntax with centralized support for synonyms, varied phrase order and various determiners, as well as a daemon which stores and serves and customizes pre-fab closures for use in the wrapper. I'll post in the near future about how this "activities" module plays out.

Discussing this elsewhere?
Enter 'link' for a markdown link
or 'tweet <message>' for a pre-populated Tweet :)
Want to subscribe? Enter 'rss' for a feed URL.
>