parent $has_verbs parent $named object $described var $described prose #[] var $root child_index 0 var $root owners [$described] var $root fertile 0 var $has_verbs verbs #[["l?ook at %this", ['look_vrb, 'noremote]], ["l?ook %this", ['look_vrb, 'noremote]], ["@examine|examine %this", ['examine_vrb, 'remote]]] var $root inited 1 var $root owned [$described] var $root manager $described var $root writable [$described] var $root readable ['parameters, 'methods, 'code] var $root dbref 'described var $named name ['uniq, "Generic Described Object"] var $named name_aliases [] method init_described .perms($root, caller()); prose = #[]; . method description arg actor, [exclude]; var out; // similar to MOO's :look_self() // meant to be changed by descendants, if they so desire to. return [.name('def), @.prose('short)]; . method look_vrb arg vrb, [args]; var actor; actor = sender(); actor.tell(.description(actor, actor)); . method prose arg [type]; type = [@type, 'short][1]; switch (type) { case 'literal: return prose; default: return (| prose[type] |) || ((| prose['short] |) || ["You see nothing special."]); } . method descriptionf arg actor, exclude, [args]; var out, part, type; // lists should be ['methodname, args for method] // symbols are shortcuts, to be defined on descendants. out = []; for part in (args) { type = type(part); switch (type) { case 'list: out = out + ((| .(part[1])(@sublist(part, 2)) |) || []); case 'symbol: // ignore them, they should have been dealt with by now. } } return out; . method set_prose arg ptype, new_prose; // ptype should be either 'short or 'long // prose should be a list of strings .perms(sender(), 'manager); if (type(ptype) != 'symbol) throw(~type, "Prose type can be either 'short or 'long."); if (type(new_prose) != 'list) throw(~type, "Prose must be given as a list of strings."); prose = dict_add(prose, ptype, new_prose); . method examine_vrb arg vrb, [args]; var actor; actor = sender(); actor.tell(.name()); actor.tell(.prose('long)); .