** LambdaMOO Database, Format Version 4 ** 237 2729 0 8 2 35 36 63 176 181 184 185 #0 System Object 16 184 3 -1 -1 153 -1 -1 10 set_verb_code_raw 2 173 -1 do_login_command 184 173 -1 server_started 184 173 -1 init_for_core 184 173 -1 do_out_of_band_command 184 173 -1 user_created user_connected 184 173 -1 user_disconnected user_client_disconnected 184 173 -1 user_reconnected 184 173 -1 checkpoint_finished 184 173 -1 checkpoint_started 184 173 -1 186 builder login last_huh guest_log last_restart_time biglist big_mail_recipient limbo registration_db new_player_log verb_help core_help prog_help wiz_help shutdown_task wiz_utils site_db math_utils set_utils builtin_function_help new_prog_log generic_help guest seq_utils quota_log you hacker generic_db shutdown_message shutdown_time no_one player_db player_class gender_utils trig_utils time_utils editor_help mail_recipient mail_agent mail_editor note_editor verb_editor generic_editor object_utils lock_utils gripe_recipients dump_interval list_utils command_utils player wiz prog code_utils help nothing failed_match ambiguous_match perm_utils building_utils string_utils news note container thing exit room player_start root_class recycler garbage mail_options edit_options display_options generic_options maxint minint list_options error newt_log toad_log site_log housekeeper feature pronoun_sub they login_watcher english language integration_utils network country_db jtext feature_help jaddress misc_options client_options building_options it nobody furniture sittable I everything all nowhere admin_group steering_committee db_group unix_group community_group tech_group admin_mail_recipient registrar event_dispatcher prog_group openable_container containing_object utils biglist_utils english_utils boot_log help_editor object_help tester failed_help who_options who_utils event_handler eval_options he she e we plural_you either splat gender neuter egotistical plural royal male female Spivak second second_plural singular none topic builder_help name_utils guest_help parse_utils admin core_wizard first_wizard door ftp __core_init_phase quota_utils window server_options walking_utils maxfloat checkpointer startup syslog core_extraction_time generic_biglist_home http module property_farm modules smtp cord mcp parse_options ftp_client local building_group documentation_group first_restart_time room_matching_utils policy_help admin_help jhcore_help 202 1 4 184 5 1 10 184 1 1 11 184 1 1 12 184 1 0 1029058176 184 5 1 13 184 5 1 14 184 5 1 15 184 5 1 16 184 5 1 17 184 5 1 20 184 5 1 21 184 5 1 22 184 5 1 23 184 5 3 0 184 5 1 24 184 5 1 25 184 5 1 26 184 5 1 27 184 5 1 28 184 5 1 29 184 5 1 30 184 5 1 31 184 1 1 32 184 5 1 33 184 5 1 34 35 1 1 35 184 5 1 79 184 5 2 184 5 0 0 184 5 1 36 184 1 1 37 184 1 1 6 184 5 1 38 184 1 1 26 184 5 1 39 184 5 1 40 184 5 1 41 184 5 1 42 184 5 1 43 184 5 1 44 184 5 1 45 184 5 1 46 184 5 1 47 184 5 1 48 184 5 4 1 1 2 184 5 0 3600 184 5 1 49 184 5 1 50 184 5 1 6 184 5 1 51 184 5 1 52 184 5 1 53 184 5 1 54 184 5 1 -1 184 5 1 -3 184 5 1 -2 184 5 1 130 184 5 1 19 184 5 1 18 184 5 1 141 184 5 1 9 184 5 1 126 184 5 1 5 184 5 1 7 184 5 1 3 184 5 1 70 184 5 1 1 184 5 1 55 184 5 1 56 184 5 1 57 184 5 1 58 184 5 1 59 184 5 1 60 184 5 0 2147483647 184 5 0 -2147483648 184 5 1 61 184 5 1 66 184 5 1 106 184 5 1 62 184 5 1 62 184 5 1 63 184 5 1 65 184 1 1 69 184 1 1 71 184 1 1 83 184 5 1 72 184 1 1 72 184 1 1 74 184 5 1 82 184 5 1 94 184 1 1 92 184 1 1 100 184 1 1 111 184 1 1 112 184 1 1 116 184 1 1 122 184 5 1 154 184 5 1 36 184 5 1 81 184 5 1 80 184 5 1 160 184 5 1 139 184 5 1 103 184 5 1 -1 184 5 1 163 184 5 1 137 184 5 1 148 184 5 1 147 184 5 1 165 184 5 1 164 184 5 1 107 184 5 1 108 184 5 1 110 184 5 1 124 184 5 1 8 184 5 1 145 184 5 1 146 184 5 1 13 184 5 1 72 184 5 1 85 184 5 1 171 184 1 1 173 184 5 1 99 184 1 1 127 184 1 1 89 184 5 1 89 184 5 1 133 184 5 1 136 184 5 1 156 184 5 1 157 184 5 1 158 184 5 1 159 184 5 1 161 184 5 1 162 184 5 1 166 184 5 1 64 184 5 1 154 184 5 1 160 184 5 1 71 184 5 1 159 184 5 1 156 184 5 1 157 184 5 1 158 184 5 1 34 184 5 1 161 184 5 1 154 184 5 1 167 184 5 1 178 184 5 1 155 184 1 1 177 184 1 1 168 184 1 1 117 184 1 1 170 184 1 1 184 184 1 1 2 184 5 1 121 184 1 1 233 184 5 0 0 184 1 1 174 184 5 1 179 184 5 1 188 184 1 1 182 184 1 9 1.79769313486231471e+308 184 5 1 175 184 1 1 189 184 5 1 183 184 1 0 1030475426 184 1 1 75 184 1 1 87 184 5 1 203 184 1 1 206 184 1 1 205 184 1 1 212 184 5 1 223 184 5 1 213 184 5 1 191 184 5 1 229 184 5 1 193 35 5 1 192 184 1 1 231 184 1 0 845958877 184 1 1 190 184 1 1 234 184 1 1 236 184 5 1 235 184 5 5 184 1 4 7 2 out_of_band 2 list_editor 2 waif 2 twin 2 review_group 2 macmoose_utils 2 dict 184 1 0 0 184 4 4 1 2 System Object 184 5 2 The Known Universe aka The, Known, Universe, and #0. 184 5 5 35 1 5 184 5 5 184 5 5 184 5 0 1 184 5 5 184 5 5 35 1 5 35 1 5 35 1 1 -1 184 1 4 2 0 17212 0 1030435200 185 1 #1 root class 144 184 -1 -1 -1 -1 10 -1 83 initialize 184 173 -1 recycle 184 173 -1 set_name 184 173 -1 name 35 173 -1 titlec namec 35 173 -1 set_aliases 184 173 -1 match 35 173 -1 match_object 35 173 -1 set_description 184 173 -1 description 35 173 -1 look_self 35 173 -1 notify 184 173 -1 tell 184 173 -1 tell_lines 35 173 -1 accept 35 173 -1 moveto 184 173 -1 eject 184 173 -1 is_unlocked_for 184 173 -1 huh 184 173 -1 set_message 184 173 -1 do_examine 184 173 -1 examine_key 184 173 -1 examine_names 35 173 -1 examine_desc 35 173 -1 examine_contents 184 173 -1 examine_verbs 184 173 -1 room_announce*_all_but 35 173 -1 init_for_core 184 173 -1 contents objects_for_match 35 173 -1 examine_verb_ok 184 173 -1 is_listening 35 173 -1 obvious_verbs hidden_verbs help_verbs 184 173 -1 examine_owner 35 173 -1 announce*_all_but 35 173 -1 visible 35 173 -1 integrate_room_msg integrate_container_msg 35 173 -1 dname*c iname*c 35 173 -1 where_am_i where_are_you 35 173 -1 integrate_in 35 173 -1 name_for_look_self namec_for_look_self 184 173 -1 look_in 35 173 -1 integrate_player_msg 35 173 -1 default_editing 35 173 -1 title 35 173 -1 name_for_tell_contents namec_for_tell_contents 35 173 -1 tell_lines_suspended 35 173 -1 is_hidden_verb 184 173 -1 verb_sub noun_sub adj_sub 35 173 -1 exitfunc 35 173 -1 editing_for 184 173 -1 event_* 35 173 -1 name_and_number iname_and_number dname_and_number namec_and_number inamec_and_number dnamec_and_number 35 173 -1 add_handler 35 173 -1 _add_handler 35 173 -1 remove_handler 35 173 -1 handlers_event_* 35 173 -1 ps*c po*c pr*c pp*c pq*c psu pou pru ppu pqu 35 173 -1 gender gender_name 35 173 -1 set_number set_visible set_integrate_in 35 173 -1 number 35 173 -1 is_plural are_plural plural 35 173 -1 gender_obj 35 173 -1 you 35 173 -1 modname_d 35 173 -1 modname_i 35 173 -1 modname_c 35 173 -1 modname_p 35 173 -1 base_name 35 173 -1 nominate_for_core 35 173 -1 help_text 35 173 -1 modname_u 35 173 -1 modname_titleize 35 173 -1 empty_message 184 173 -1 empty_message_integrate_room empty_message_integrate_container 35 173 -1 modname_in 35 173 -1 acceptable 35 173 -1 modname_v 35 173 -1 modname_# 35 173 -1 modname_l 184 173 -1 get_messages 184 173 -1 get_message 184 173 -1 set_proper set_unique 184 165 -1 call_from_self_* 184 173 -1 14 key aliases description visible integrate_room_msg integrate_player_msg integrate_container_msg unique proper integrate_in handlers number offered object_size 14 0 0 184 4 4 1 2 root class 184 5 2 184 5 0 1 35 1 2 184 5 2 184 5 2 184 5 0 1 184 5 0 0 184 5 4 1 1 145 35 1 4 0 35 1 0 1 35 1 1 -1 184 1 4 2 0 65627 0 1030435200 185 1 #2 Wizard 23 2 15 -1 176 51 -1 -1 1 init_for_core 184 173 -1 0 116 5 184 5 5 184 5 5 184 5 5 184 5 5 184 5 5 184 5 5 184 5 5 184 4 5 184 5 5 184 5 5 184 5 5 184 5 5 184 5 5 184 5 5 35 1 5 184 0 5 184 5 5 184 0 5 184 1 5 184 5 5 35 1 5 35 1 5 35 0 5 35 1 5 184 5 5 185 1 5 35 1 5 184 4 5 184 0 5 184 0 5 184 5 5 184 4 5 184 4 5 184 4 5 184 5 5 184 5 5 184 5 5 184 5 5 184 5 5 184 5 5 184 5 5 184 4 5 184 4 5 184 1 0 -10000 185 0 1 158 184 5 1 70 35 1 0 0 184 0 5 2 5 5 184 5 5 184 5 5 184 5 5 35 1 5 184 1 5 184 1 5 35 1 5 35 1 5 184 5 5 184 5 5 184 1 5 184 1 5 184 5 5 184 0 5 184 5 5 35 1 5 35 1 5 184 5 5 35 1 5 184 0 5 184 0 5 184 0 5 184 1 5 184 1 5 35 1 5 184 1 5 184 5 5 184 5 5 184 5 5 184 5 5 184 5 5 184 1 5 184 1 5 184 5 5 184 5 5 184 5 5 184 5 5 184 5 5 35 1 5 184 1 5 184 1 5 184 0 5 184 1 4 4 0 0 0 0 0 0 0 0 185 0 5 184 5 5 184 0 5 35 1 5 184 5 5 184 1 5 35 1 5 184 5 5 184 5 5 184 1 5 184 4 4 1 2 Wizard 184 1 5 184 5 5 35 1 5 184 5 5 184 5 5 184 5 5 184 5 5 184 5 5 35 1 5 35 1 5 35 1 5 184 1 5 185 1 #3 generic room 144 184 -1 31 -1 145 46 -1 69 confunc 35 173 -1 disfunc 35 173 -1 say 35 93 -2 emote 35 93 -2 announce 35 173 -1 match_exit match_entrance 35 173 -1 add_exit 184 173 -1 tell_contents 35 173 -1 @exits 35 29 -1 add_entrance 184 173 -1 bless_for_entry 184 173 -1 @entrances 184 9 -1 go 184 29 -1 l*ook 35 93 -2 announce_all 35 173 -1 announce_all_but 35 173 -1 enterfunc 184 173 -1 remove_exit 184 173 -1 remove_entrance 184 173 -1 @add-exit @addexit 184 25 -1 @add-entrance @addentrance 184 25 -1 recycle 184 173 -1 @lastlog 35 29 -1 e east w west s south n north ne northeast nw northwest se southeast sw southwest u up d down 35 13 -1 @eject 184 25 -1 ejection_msg oejection_msg victim_ejection_msg 35 173 -1 accept_for_abode 35 173 -1 @resident*s 184 25 -1 @remove-exit 184 25 -1 @remove-entrance 184 25 -1 moveto 184 173 -1 who_location_msg 35 173 -1 exits entrances 184 173 -1 obvious_exits 35 173 -1 here_huh 184 173 -1 room_announce*_all_but 35 173 -1 examine_commands_ok 35 173 -1 examine_key 184 173 -1 examine_contents 35 173 -1 ok_to_integrate 35 173 -1 look_self 35 173 -1 description 35 173 -1 where_am_i 35 173 -1 housekeeper_msg housekeeper_deposit_msg 35 173 -1 look_in 35 173 -1 namec_for_look_self 35 173 -1 set_integrate_unknown_objects 35 165 -1 dependents dependents_event_* 35 173 -1 reconfunc 35 173 -1 sit 35 13 -1 stand 35 9 -1 topic_msg 35 173 -1 topic 35 89 -2 set_topic_sign 181 173 -1 event_really_disconnected 184 173 -1 match_type_object 35 173 -1 party_location 35 173 -1 init_for_core 184 173 -1 acceptable 184 173 -1 is_public_location 184 173 -1 objects_for_match 35 173 -1 set_walking_cost 35 173 -1 walking_cost 35 173 -1 can_add_exit can_add_entrance 184 173 -1 can_remove_exit can_remove_entrance 184 173 -1 can_read_exits can_read_entrances 184 173 -1 terrain_delay 35 173 -1 set_terrain_delay 35 165 -1 walk_failed_source walk_failed_dest 35 173 -1 22 who_location_msg free_home victim_ejection_msg ejection_msg oejection_msg residents free_entry entrances blessed_object blessed_task exits dark integration_enabled housekeeper_msg integrate_sep_msg housekeeper_deposit_msg integrate_paragraphs integrate_unknown_objects topic_sign say_msg walking_cost terrain_delay 38 4 3 1 69 2 do 4 3 2 name 2 thing 0 1 184 5 0 0 184 5 4 7 1 69 2 do 2 You have been expelled from 4 3 2 dname 2 iobj 0 0 2 by 4 3 2 dname 2 player 0 0 2 . 184 5 4 7 1 69 2 do 2 You expel 4 3 2 dname 2 dobj 0 0 2 from 4 3 2 dname 2 iobj 0 0 2 . 184 5 4 10 1 69 2 do 4 3 2 name 2 dobj 4 1 2 dc 2 4 3 2 verb 2 dobj 2 is 2 unceremoniously expelled from 4 3 2 name 2 iobj 4 1 2 d 2 by 4 3 2 name 2 player 4 1 2 d 2 . 184 5 4 0 184 5 0 0 184 5 4 0 184 4 1 -1 184 5 0 1197213733 184 5 4 0 184 4 0 0 184 5 0 1 184 5 4 6 1 69 2 do 4 3 2 dname 2 player 0 1 2 's friends arrive to cart 4 3 2 pronoun 2 player 2 po 2 off to bed. 184 5 2 184 5 4 6 1 69 2 do 4 3 2 iname 2 player 0 1 2 's friends arrive to drop 4 3 2 pronoun 2 player 2 po 2 off, sound asleep. 184 5 4 0 184 5 0 1 35 1 1 -1 181 1 4 8 1 69 2 do 4 3 2 name 2 player 4 1 2 dc 2 4 3 2 verb 2 player 2 says 2 , " 4 3 2 string 2 argstr 0 0 2 " 184 5 0 0 35 1 0 1 35 1 5 184 5 5 184 1 0 0 184 4 4 1 2 generic room 184 5 5 184 5 0 0 35 1 5 184 5 5 184 5 5 184 5 0 1 184 5 5 184 5 5 35 1 5 35 1 5 35 1 1 -1 184 1 4 2 0 60785 0 1030435200 185 1 #4 generic builder 16 184 3 -1 9 6 52 36 32 @quota 184 25 -1 @create 184 89 -2 @recycle 184 25 -1 @recreate 184 89 13 @dig 184 89 -2 @auditDB 184 89 -2 @count 184 25 -1 @countDB 184 25 -1 @sort-owned*-objects 184 9 -1 @add-owned 184 25 -1 @verify-owned 184 9 -1 @unlock 184 25 -1 @lock 184 89 0 @newmess*age 184 89 -2 @unmess*age 184 89 -2 _messagify 184 173 -1 @kids 184 29 -1 @contents 184 25 -1 @par*ents 184 25 -1 @location*s 184 25 -1 _create 184 173 -1 _recycle 184 173 -1 @audit 184 89 -2 @building-o*ptions @buildingo*ptions 184 89 -2 set_building_option 184 173 -1 building_option 184 173 -1 options_packages 35 173 -1 @recycle! 184 25 -1 @move 184 93 1 @measure 184 89 -2 @grant 184 89 1 @set*property 184 89 1 2 recreate_enabled building_options 104 0 1 184 5 4 0 184 5 5 35 1 5 184 0 5 184 5 5 184 0 5 184 1 4 1 1 155 184 5 5 35 1 5 35 1 5 35 0 5 35 1 5 184 5 5 185 1 5 35 1 5 184 4 5 184 0 5 184 0 5 184 5 5 184 4 5 184 4 5 184 4 5 184 5 5 184 5 5 184 5 5 184 5 5 184 5 5 184 5 5 184 5 5 184 4 5 184 4 5 184 1 5 185 0 5 184 5 5 35 1 5 184 0 5 184 5 5 184 5 5 184 5 5 184 5 5 35 1 5 184 1 5 184 1 5 35 1 5 35 1 5 184 5 5 184 5 5 184 1 5 184 1 5 184 5 5 184 0 5 184 5 5 35 1 5 35 1 5 184 5 5 35 1 5 184 0 5 184 0 5 184 0 5 184 1 5 184 1 5 35 1 5 184 1 5 184 5 5 184 5 5 184 5 5 184 5 5 184 5 5 184 1 5 184 1 5 184 5 5 184 5 5 184 5 5 184 5 5 184 5 5 35 1 5 184 1 5 184 1 5 184 0 5 184 1 5 185 0 5 184 5 5 184 0 5 35 1 5 184 5 5 184 1 5 35 1 5 184 5 5 184 5 5 184 1 0 0 184 4 4 1 2 generic builder 184 1 2 You see a player who should type '@describe me as ...'. 184 5 5 35 1 5 184 5 5 184 5 5 184 5 5 184 5 5 184 5 5 35 1 5 35 1 5 35 1 1 -1 184 1 4 2 0 41877 0 1030435200 185 1 #5 generic thing 144 184 3 -1 99 1 9 60 8 g*et t*ake 184 45 -1 d*rop 184 45 -1 moveto 184 173 -1 take_failed_msg take_succeeded_msg otake_failed_msg otake_succeeded_msg drop_failed_msg drop_succeeded_msg odrop_failed_msg odrop_succeeded_msg 184 173 -1 gi*ve ha*nd 184 101 1 examine_key 184 173 -1 initialize 184 165 -1 help_text 35 165 -1 8 drop_failed_msg drop_succeeded_msg odrop_failed_msg odrop_succeeded_msg otake_succeeded_msg otake_failed_msg take_succeeded_msg take_failed_msg 22 4 5 1 69 2 do 2 You can't seem to drop 4 3 2 dname 2 thing 0 0 2 here. 184 5 4 5 1 69 2 do 2 You drop 4 3 2 dname 2 thing 0 0 2 . 184 5 4 8 1 69 2 do 4 3 2 verb 2 player 2 tries 2 to drop 4 3 2 iname 2 thing 0 0 2 but 4 3 2 verb 2 player 2 fails 2 . 184 5 4 6 1 69 2 do 4 3 2 verb 2 player 2 drops 2 4 3 2 iname 2 thing 0 0 2 . 184 5 4 6 1 69 2 do 4 3 2 verb 2 player 2 picks 2 up 4 3 2 dname 2 thing 0 0 2 . 184 5 2 184 5 4 5 1 69 2 do 2 You take 4 3 2 dname 2 thing 0 0 2 . 184 5 4 5 1 69 2 do 2 You can't pick up 4 3 2 dname 2 thing 0 0 2 . 184 5 0 0 184 4 4 1 2 generic thing 184 5 5 184 5 5 35 1 5 184 5 5 184 5 5 184 5 0 0 184 5 5 184 5 5 35 1 5 35 1 5 35 1 1 -1 184 1 4 2 0 7893 0 1030435200 185 1 #6 generic player 144 184 3 8 4 145 4 126 238 init_for_core 184 173 -1 confunc 184 173 -1 disfunc 184 173 -1 initialize 184 173 -1 recycle 184 173 -1 my_huh 184 173 -1 last_huh 184 173 -1 my_match_object 184 173 -1 tell_contents 184 173 -1 notify 184 173 -1 notify_lines 184 173 -1 linesplit 184 173 -1 linelen 35 173 -1 @more 184 25 -1 @wrap 35 9 -2 @linelen*gth 35 25 -1 @pagelen*gth 184 25 -1 tell 184 173 -1 gag_p 184 173 -1 set_gaglist set_gaglist_noisy 184 173 -1 @gag 184 89 -2 @listgag @gaglist @gagged 184 13 -1 @ungag 184 29 -1 whodunnit 184 173 -1 @paranoid 184 89 -2 @sw*eep 184 9 -1 wh*isper 184 157 1 receive_page 184 173 -1 page_origin_msg page_echo_msg page_absent_msg 35 173 -1 i inv*entory 184 9 -1 look_self 184 173 -1 home 184 9 -1 @sethome 184 9 -1 g*et take 184 45 -1 @eject 184 89 5 where*is @where*is 184 93 -2 @wizards 184 29 -1 mail_forward mail_notify 184 173 -1 receive_message 184 173 -1 display_message 184 173 -1 parse_message_seq from_msg_seq %from_msg_seq to_msg_seq %to_msg_seq subject_msg_seq body_msg_seq display_seq_headers display_seq_full messages_in_seq list_rmm new_message_num length_num_le length_date_le length_date_gt length_all_msgs exists_num_eq rm_message_seq undo_rmm expunge_rmm renumber 184 173 -1 msg_summary_line 35 173 -1 msg_text 184 173 -1 notify_mail 184 173 -1 current_message 184 173 -1 get_current_message 184 173 -1 set_current_message 184 173 -1 make_current_message 184 173 -1 kill_current_message 184 173 -1 current_folder 184 173 -1 set_current_folder 184 173 -1 parse_folder_spec 184 173 -1 parse_mailread_cmd 184 173 -1 @mail 184 93 -2 @read @peek 184 93 -2 @next @prev 184 89 -2 @rmm*ail 184 89 -2 @renumber 184 25 -1 @unrmm*ail 184 89 -2 @send 184 93 -2 @answer @repl*y 184 89 -2 @forward 184 93 -2 @gripe 184 89 -2 @typo @bug @suggest*ion @idea @comment 184 89 -2 @skip @unsub*scribe 184 89 -2 @subscribe 184 89 -2 mail_catch_up 184 173 -1 @rn check_mail_lists @subscribed 184 5 -1 mail_option 184 173 -1 edit_option 184 173 -1 set_mail_option set_edit_option set_misc_option set_client_option set_who_option set_parse_option 184 173 -1 @mailo*ptions @mail-o*ptions @edito*ptions @edit-o*ptions @misco*ptions @misc-o*ptions @cliento*ptions @client-o*ptions @whoo*ptions @who-o*ptions @parseo*ptions @parse-o*ptions 184 89 -2 set_name 184 173 -1 set_aliases 184 173 -1 @rename*# 184 89 1 @add-alias*# @addalias*# @add_alias*# 184 89 1 @rmalias*# @rm-alias*# 184 89 5 @desc*ribe 184 89 13 @mess*ages 184 25 -1 @notedit 35 25 -1 @password 184 89 -2 @last-c*onnection 184 29 -1 set_gender set_gender_name set_gender_obj 184 173 -1 @gender 184 25 -1 @ex*amine 184 29 -1 ex*amine 184 25 -1 add_feature 35 165 -1 remove_feature 35 173 -1 @add-feature @addfeature 184 25 -1 @remove-feature @rmfeature @rm-feature 184 25 -1 @features 184 93 11 @features 184 25 -1 @memory 35 9 -1 @version 35 9 -1 @uptime 35 9 -1 @quit 184 9 -1 QUIT-IN-ALL-CAPS 184 9 -1 notify(new) 184 169 -1 examine_commands_ok 184 173 -1 is_listening 184 173 -1 @quicksend @qsend 184 89 -2 !* 35 89 -2 '* 35 81 -2 @pronoun_sub @pronoun-sub 184 73 0 @set-note-string @set-note-text @set-note-value 184 25 -1 description 35 173 -1 @nn 184 9 -1 mu*rmur 184 89 -2 look_in 184 173 -1 @option*s 184 89 -2 options_packages 184 173 -1 options_command 184 173 -1 contribute_partial 184 173 -1 contribute_reset 184 173 -1 contribute_link 184 173 -1 receive_vbox 35 173 -1 contribute_title 184 173 -1 moveto 184 173 -1 ok_to_integrate 35 173 -1 visible_of 35 173 -1 @set-jtext-form 184 25 -1 idle_suffix 184 173 -1 modname_v 184 173 -1 @edit*# 184 89 -2 set_focus_object 184 173 -1 email_address 184 173 -1 misc_option client_option who_option parse_option 184 173 -1 @forward-me @forwardme 184 89 -2 ownership_quota 184 173 -1 contribute_newline 184 173 -1 set_current_object set_current_object_stack set_authentication_key 184 173 -1 client_notify 184 173 -1 brief 184 173 -1 picknew 35 25 -1 walk go 35 77 1 _find_path 184 173 -1 join 184 29 -1 pick 35 157 4 pop 35 141 4 match_command 35 173 -1 my_match_room 184 173 -1 features 184 173 -1 receive_document 184 173 -1 @co @currentobject @current-object 184 25 -1 parse_current_object 35 173 -1 @pusho*bject 184 25 -1 @popo*object 184 9 -1 @swapo*bject 184 9 -1 jdetails 184 25 -1 @@sendmail 184 89 -2 fol*low 35 41 -1 unfol*low 35 89 -2 followers 35 89 -2 following 35 9 -1 my_match_player 184 173 -1 news 184 25 -1 @helpme @911 184 89 -2 @admin*istrators @admins 184 29 -1 parse_message unparse_message 184 173 -1 @url 184 89 -2 @read-all-new*-mail 184 29 -1 send_self_netmail 184 173 -1 @add-help-db 184 25 -1 @rm-help-db 184 25 -1 @unsubscribed 184 9 -1 reconfunc 184 173 -1 @resend 184 89 -2 help ?* 184 93 -2 match_help_object 35 173 -1 @aliases 184 25 -1 contribute_newline_maybe 184 173 -1 contribute_hr 184 173 -1 set_last_player_paged 184 173 -1 visible 35 173 -1 set_number 35 173 -1 you 35 173 -1 page 184 93 -2 is_idle 184 13 -1 start_dozing 184 173 -1 start_idling 184 173 -1 idle reidle 184 93 -2 idle_msg 184 173 -1 dozing_msg 184 173 -1 start_doing 35 173 -1 doing_msg 184 173 -1 doing undoing 184 89 -2 @who 184 85 -2 debug_if_player 184 173 -1 match_type_object 184 173 -1 dependents_event_really_disconnected 184 173 -1 event_really_disconnected 184 173 -1 maybe_really_disconnected 184 173 -1 modname_c 35 173 -1 @desc*ribe 184 25 -1 @netforw*ard 184 89 -2 @register 184 89 13 @register @email-address 184 17 -1 more_string 184 173 -1 desc_idle_msg 184 173 -1 nominate_for_core 184 173 -1 sit 184 137 0 acceptable 184 173 -1 @shout 184 89 -2 set_home 35 165 -1 anyconfunc 184 173 -1 @ch*eck-full 184 89 -2 @add-handler @addhandler 184 25 -1 handlers 184 173 -1 @remove-handler @rmhandler @rm-handler 184 25 -1 @handlers 184 85 11 @handlers 184 17 -1 total_connect_times 184 173 -1 _set_mail_task 184 173 -1 add_handler 35 173 -1 remove_handler 35 173 -1 set_walking_dest set_walking_task 35 165 -1 move_by_exits 35 173 -1 walking_step 35 173 -1 begin_walking 35 173 -1 end_walking 35 173 -1 walkto walkto_blocking 35 173 -1 find_path 35 173 -1 stop 35 9 -1 timestamp_string 184 173 -1 @age 184 25 -1 +* 184 93 -2 lose 35 93 -2 display_current_object 184 173 -1 current_object_string 184 173 -1 edit_set_note_value 184 173 -1 edit_sendmail 184 173 -1 absent_for_page 35 173 -1 send_forwarded_moomail 184 173 -1 walking_delay 35 173 -1 walk_failed 184 173 -1 my_walk_failed 184 173 -1 dwim_objects 184 173 -1 @room*s 35 93 -2 86 features previous_connection mail_lists email_address last_disconnect_time help linetask linesleft linebuffer pagelen _mail_task owned_objects linelen current_folder all_connect_places last_connect_place dict messages_going responsible lines page_absent_msg page_origin_msg page_echo_msg mail_notify mail_forward edit_options mail_options current_message messages last_connect_time ownership_quota gender home password gaglist paranoid spoof_attribution_msg pronoun_sub_style last_player_paged contributed_line contributed_links followers followable integrate_sep_msg integration_enabled jtext_form focus_object misc_options authentication_key client_options link_shepherd walking_task temp_brief jaddress_stack total_started total_connect_time started_keeping_total current_object current_object_stack following walk_randomness client_features client_authkey client_disfuncs client_debug remote_emote_prefix_msg who_options last_entrance_time dozing_msg idle_start_time idle_msg idle_string dozing_string doing_string doing_msg disconnect_task last_password_time last_timestamp size_quota shout_msg contributed_document walking_dest use_do_command first_connect_time out_of_band_session parse_options 102 4 2 1 67 1 68 35 1 0 0 184 0 4 0 184 5 2 184 0 0 0 184 1 4 5 1 173 1 100 1 234 1 236 1 235 184 5 4 2 0 0 0 0 35 1 0 0 35 1 4 0 35 0 0 0 35 1 0 0 184 5 4 0 185 1 0 -79 35 1 0 1 184 4 4 0 184 0 2 ? 184 0 4 0 184 5 4 0 184 4 4 0 184 4 0 20 184 4 4 6 1 69 2 do 4 3 2 dname 2 player 0 1 2 4 3 2 verb 2 player 2 is 2 not currently logged in. 184 5 2 184 5 0 0 184 5 4 0 184 5 4 0 184 5 4 0 184 5 4 0 184 5 4 2 0 0 0 0 184 4 4 0 184 4 0 0 184 1 0 0 185 0 1 158 184 5 1 70 35 1 2 impossible password to type 184 0 4 0 184 5 0 0 184 5 2 -- 184 5 1 78 184 5 2 Everyman 35 1 2 184 1 4 0 184 1 4 0 35 1 0 1 35 1 2 184 5 0 1 184 5 2 linemode 184 1 1 -1 184 1 4 1 4 2 2 fstamp 2 [ $o:$M $p ] 184 5 0 0 184 0 4 0 184 5 1 -1 35 1 0 0 35 1 0 0 184 5 4 0 35 1 0 0 184 0 0 0 184 0 0 0 184 0 4 2 1 0 2 #0 184 1 4 0 184 1 4 0 35 1 4 2 0 1 0 8 184 1 4 0 184 5 2 184 5 4 0 184 5 0 0 184 5 4 5 1 69 2 do 2 (from 4 3 2 iname 2 location 0 0 2 ) 184 5 4 2 4 2 2 columns 4 4 2 name 2 location 2 idle 2 doing 4 2 2 order 2 idle 184 1 0 768064450 184 1 4 3 1 69 2 do 2 idling 184 5 0 0 184 5 4 3 1 69 2 do 2 real life intrusion 184 5 2 184 5 2 184 5 2 35 1 4 2 1 69 2 do 184 1 0 0 184 1 0 0 184 0 0 830677321 184 1 4 4 0 0 0 0 0 0 0 0 185 0 4 8 1 69 2 do 4 3 2 name 2 player 4 1 2 dc 2 4 3 2 verb 2 player 2 shouts 2 , " 4 3 2 string 2 argstr 0 0 2 " 184 5 3 0 184 0 1 -1 35 1 0 0 184 5 0 2147483647 184 1 1 -1 35 1 4 3 2 guess_object 2 report 2 super_room 184 5 5 184 5 5 184 1 0 0 184 4 4 1 2 generic player 184 1 2 You see a player who should type '@describe me as ...'. 184 5 5 35 1 5 184 5 5 184 5 5 184 5 0 1 184 1 0 1 184 1 5 35 1 5 35 1 5 35 1 1 -1 184 1 4 2 0 266281 0 1030435200 185 1 #7 generic exit 144 184 -1 -1 -1 110 121 145 33 recycle 184 173 -1 leave_msg oleave_msg arrive_msg oarrive_msg nogo_msg onogo_msg no_one_msg 184 173 -1 set_name 184 173 -1 set_aliases 184 173 -1 defaulting_oleave_msg 184 173 -1 moveto 184 173 -1 examine_key 184 173 -1 substitute 184 173 -1 dest_who 184 173 -1 dest_contents 184 173 -1 dest_description 184 173 -1 set_message 184 173 -1 set_description 184 173 -1 invoke 184 173 -1 integrate_in 184 173 -1 direction sub_direction 35 173 -1 description 184 173 -1 sub_who 184 173 -1 move 184 173 -1 sweep_for_followers 184 173 -1 obvious 35 173 -1 defaulting_oarrive_msg 35 173 -1 integrate_room_msg 184 173 -1 dependents_event_move_by_exit_* 184 173 -1 other_side obj_other_side 184 173 -1 set_walking_cost 35 173 -1 walking_cost 35 173 -1 obj_dest obj_source 35 173 -1 moddir_d moddir_i 35 173 -1 moddir_* 35 173 -1 through_msg 184 173 -1 where_are_you 184 173 -1 match_type_object 35 173 -1 14 obvious source dest nogo_msg onogo_msg arrive_msg oarrive_msg oleave_msg leave_msg nothing_msg no_one_msg prefix_name through_msg walking_cost 29 0 1 184 5 1 -1 184 5 1 -1 184 5 0 0 184 5 0 0 184 5 0 0 184 5 0 0 184 5 0 0 184 5 0 0 184 5 2 nothing 184 5 2 no one 184 5 0 1 184 5 4 6 1 69 2 do 4 3 2 name 4 4 2 special 2 thing 2 dest 4 0 4 3 2 d 4 1 2 in 2 c 2 , you see 4 3 2 name 4 2 2 contents 4 4 2 special 2 thing 2 dest 4 0 4 1 2 i 2 . 184 5 0 1 35 1 5 184 1 0 0 184 4 4 1 2 generic exit 184 5 2 184 5 5 35 1 5 184 5 5 184 5 5 184 5 5 184 5 5 184 5 5 35 1 5 35 1 5 35 1 1 -1 184 1 4 2 0 25049 0 1030435200 185 1 #8 generic openable container 144 35 6 126 -1 126 -1 -1 18 look_self 35 173 -1 open 35 45 -1 @lock_for_open @lock-for-open 35 109 0 is_openable_by 35 173 -1 close 35 45 -1 @unlock_for_open @unlock-for-open 35 45 -1 set_opened 35 173 -1 @opacity 35 105 12 set_opaque 35 173 -1 open_msg close_msg 35 173 -1 look_in 35 173 -1 open_fail_msg empty_msg 35 173 -1 can_put_in 35 173 -1 can_get_from 35 173 -1 is_closable_by 35 173 -1 sub_open sub_opened 35 173 -1 modname_open modname_opened 35 173 -1 set_open_key set_automatic 35 173 -1 8 close_msg open_msg opaque dark open_fail_msg opened open_key automatic 31 4 8 1 69 2 do 4 3 2 name 2 player 4 1 2 dc 2 4 3 2 verb 2 player 2 closes 2 4 3 2 name 2 thing 4 1 2 d 2 . 35 5 4 8 1 69 2 do 4 3 2 dname 2 player 0 1 2 4 3 2 verb 2 player 2 opens 2 4 3 2 dname 2 thing 0 0 2 . 35 5 0 1 35 1 0 0 35 1 4 3 1 69 2 do 2 You can't open that. 35 5 0 1 35 1 0 0 35 0 0 1 35 1 5 35 1 5 35 1 5 35 1 5 35 1 5 35 1 5 35 1 5 35 1 5 35 5 5 184 1 0 0 35 4 4 1 2 generic openable container 35 5 5 35 5 5 35 1 5 35 5 5 35 5 5 35 5 5 35 5 5 35 5 5 35 1 5 35 1 5 35 1 1 -1 184 1 4 2 0 10922 0 1002603771 185 1 #9 generic note 144 184 3 -1 5 5 -1 55 19 r*ead 184 45 -1 er*ase 184 45 -1 wr*ite 184 157 4 del*ete rem*ove 184 153 5 encrypt 184 105 0 decrypt 184 41 -1 text get_text plaintext 184 173 -1 is_readable_by 184 173 -1 set_text 184 173 -1 is_writable_by 184 173 -1 mailme 184 41 -1 show 184 105 1 default_editing 184 173 -1 deliver_to 184 173 -1 read-new 184 41 -1 description 184 173 -1 match_type_object 184 173 -1 nominate_for_core 184 173 -1 do_read 184 173 -1 3 writers encryption_key text 25 4 0 184 5 0 0 184 4 4 0 184 4 5 184 5 5 184 5 5 184 5 5 184 5 5 184 5 5 184 5 5 184 5 5 184 5 0 0 184 4 4 1 2 generic note 184 5 2 There appears to be some writing on the note ... 184 5 5 35 1 5 184 5 5 184 5 5 184 5 0 0 184 5 5 184 5 5 35 1 5 35 1 5 35 1 1 -1 184 1 4 2 0 13589 0 1030435200 185 1 #10 Login Commands 16 184 -1 -1 -1 1 -1 11 40 ? 184 93 -1 h*elp @h*elp 184 93 -1 w*ho @w*ho 184 93 -1 co*nnect @co*nnect safe-c*onnect safec*onnect 184 93 -1 cr*eate @cr*eate 184 93 -1 q*uit @q*uit 184 93 -1 up*time @up*time 184 93 -1 v*ersion @v*ersion 184 93 -1 parse_command 184 173 -1 check_for_shutdown 184 173 -1 check_player_db 184 173 -1 _match_player 184 173 -1 notify 184 173 -1 tell 35 173 -1 player_creation_enabled 184 173 -1 newt_registration_string registration_string 184 173 -1 init_for_core 184 173 -1 blacklisted graylisted redlisted 184 173 -1 blacklist_add graylist_add redlist_add spooflist_add 184 173 -1 blacklist_remove graylist_remove redlist_remove spooflist_remove 184 173 -1 listname 184 173 -1 record_connection 184 173 -1 @req*uest req*uest @register register 184 93 -1 spooflisted 184 173 -1 unescape_for_url 35 173 -1 guest 184 93 -1 bootlisted 184 173 -1 bootlist 184 173 -1 is_newted newt_message_for 184 173 -1 newt_player 184 173 -1 denewt_player 184 173 -1 t*est 184 173 -1 maybe_print_idle 184 173 -1 avg_idle 184 173 -1 i*dle 184 93 -1 notify_lines 184 173 -1 is_tester 184 173 -1 tester_disconnecting 184 173 -1 registration_text 35 173 -1 GET 184 93 -1 20 welcome_message newt_registration_string registration_string registration_address create_enabled bogus_command blank_command graylist blacklist redlist spooflist bootlist newted sitematch_guests testers max_guests registration_text who_enabled request_enabled preferred_registration_method 34 4 10 2 Welcome to the JHCore database. 2 Extracted August 27, 2002 (under LambdaMOO 1.8.1) 2 2 Type 'connect wizard' to log in. 2 2 You will probably want to change this text, which is stored in $login.welcome_message. 2 2 Before you do, though, please read `help core-copyright' (linked to `help copyright') for the exceedingly broad copyright on JHCore. 2 2 You will also want to read `help getting-started' for some more information about starting a JHCore MOO. 184 5 2 Your character is temporarily hosed. 184 5 0 0 184 5 2 184 5 0 0 184 5 2 ? 184 1 2 help 184 1 4 2 4 0 4 0 184 0 4 2 4 0 4 0 184 0 4 2 4 0 4 0 184 0 4 2 4 0 4 0 184 0 4 0 184 0 4 0 184 0 0 1 184 5 4 0 184 1 0 4 184 1 0 0 184 5 0 1 184 5 0 0 184 5 2 any 184 5 0 0 184 4 4 1 2 Login Commands 184 5 2 This provides everything needed by #0:do_login_command. See `help $login' on $core_help for details. 184 5 5 35 1 5 184 5 5 184 5 5 184 5 5 184 5 5 184 5 5 35 1 5 35 1 5 35 1 1 -1 184 1 4 2 0 38222 0 1030435200 185 1 #11 Player Last_huh Verbs 16 184 -1 -1 -1 1 -1 12 5 @* 184 173 -1 give hand 184 173 -1 get take 184 173 -1 drop 184 173 -1 QUIT 184 173 -1 0 14 0 0 184 4 4 1 2 Player Last_huh Verbs 184 5 2 A repository of last-resort player verbs to be called by $player:last_huh 184 5 5 35 1 5 184 5 5 184 5 5 184 5 0 0 184 5 5 184 5 5 35 1 5 35 1 5 35 1 1 -1 184 1 4 2 0 8041 0 1030435200 185 1 #12 Guest Log 16 184 -1 -1 -1 1 -1 15 4 enter 184 173 -1 last 184 173 -1 init_for_core 184 173 -1 nominate_for_core 184 173 -1 1 connections 15 4 0 184 0 0 0 184 4 4 1 2 Guest Log 184 5 5 184 5 5 35 1 5 184 5 5 184 5 5 184 5 5 184 5 5 184 5 5 35 1 5 35 1 5 35 1 1 -1 184 1 4 2 0 3042 0 1030435200 185 1 #13 Generic BigList Utilities 144 35 -1 -1 -1 146 -1 24 24 length 35 173 -1 find_nth 35 173 -1 find_ord 35 173 -1 set_nth 35 173 -1 kill 35 173 -1 insert_after insert_before 35 173 -1 extract_range 35 173 -1 delete_range 35 173 -1 keep_range 35 173 -1 insert_last 35 173 -1 start 35 173 -1 next 35 173 -1 _call 184 173 -1 _find_ord 35 173 -1 _skill 35 173 -1 _extract 35 173 -1 _merge 35 173 -1 _smerge 35 173 -1 _split 35 173 -1 _rmerge 35 173 -1 _scrunch 35 173 -1 _listfind_nth 35 173 -1 _insertfirst 35 173 -1 debug 35 173 -1 3 about maxfanout help_text 18 4 15 2 Implementation notes 2 -------------------- 2 Each biglist is actually a tree (a kind of B-tree, actually). 2 The routines above pass around handles of the form 2 2 {root_node, size, leftmost_ord} 2 2 where root_node is the (string) name of a property that holds the root of the tree, size is the number of leaves in the tree, and leftmost_ord is the :_ord value of the leftmost element of the list (i.e., the leftmost leaf). 2 Each node property has a value of the form 2 2 {height,list of subtrees}. 2 2 where the each of the subtrees is itself a 3-element list as above unless 2 the height is 0, in which case the subtrees are actually biglist elements of the arbitrary form determined by the home object. 2 At every level, each node except the rightmost has between this.maxfanout/2 and this.maxfanout subtrees; the rightmost is allowed to have as few as 1 subtree. 35 5 0 7 35 5 4 1 2 foo 35 5 5 35 5 0 0 35 4 4 2 2 ghblu 2 biglist_utils 35 1 4 73 2 Generic BigList Utilities 2 ------------------------- 2 2 This is a package for maintaining huge persistent (sorted) lists in a format that is less likely to spam the server (which runs into a certain amount of trouble dealing with long ordinary lists --- btw we use `biglist' to refer to the huge data structure we're about to describe and `list' to refer to ordinary MOO lists {...}). The biglist in question lives on a particular object, to which we will refer in the discussion below as the `home' object, and its various elements appear as leaves of a tree whose nodes are kept in properties of the home object. It should be noted that the home object does not need to be (and in fact should *not* be) a descendant of this one; this object merely provides utilities for manipulating the properties on the home object that are used in a particular biglist manipulation. 2 2 All of the utilities below refer to `caller' to locate the home object. Thus verbs to manipulate a given biglist must be located on or inherited by its home object itself. The home object needs to define the following verbs 2 2 :_make(@args) => new property on home object with value args 2 :_kill(prop) delete a given property that was created by :_make 2 :_get(prop) => home.prop 2 :_put(prop,@args) set home.prop = args 2 :_ord(element) given something that is of the form of a biglist element 2 return the corresponding ordinal (for sorting purposes). 2 If you never intend to use :find_ord, then this can be a 2 routine that always returns 0 or some other random value. 2 2 See $big_mail_recipient (Generic Large-Capacity Mail Recipient) for examples. 2 2 Those of the following routines that take a biglist argument are expecting 2 either {} (empty biglist) or some biglist returned by one of the other routines 2 2 :length(biglist) => length(biglist) (i.e., number of elements) 2 :find_nth(biglist,n) => biglist[n] 2 :find_ord(biglist,k,comp) => n where n is 2 the largest such that home:(comp)(k,home:_ord(biglist[n])) is false, or 2 the smallest such that home:(comp)(k,home:_ord(biglist[n+1])) is true. 2 Always returns a value between 0 and length(biglist) inclusive. 2 This assumes biglist to be sorted in order of increasing :_ord values 2 with respect to home:(comp)(). 2 Standard situation is :_ord returns a number and comp is a < verb. 2 2 :start(biglist,s,e) => {biglist[s..?],@handle} or {} 2 :next(@handle) => {biglist[?+1..??],@newhandle} or {} 2 These two are used for iterating over a range of elements of a biglist 2 The canonical incantation for doing 2 for elt in (biglist[first..last]) 2 ... 2 endfor 2 is 2 handle = :start(biglist,first,last); 2 while(handle) 2 for elt in (handle[1]) 2 ... 2 endfor 2 handle = :next(@listdelete(handle,1)); 2 endwhile 2 2 The following all destructively modify their biglist argument(s) L (and M). 2 2 :set_nth(L,n,value) => L[n] = value 2 replaces the indicated element 2 2 :insert_before(L,M,n) => {@L[1..n-1],@M,@L[n..length(L)]} 2 :insert_after (L,M,n) => {@L[1..n], @M,@L[n+1..length(L)]} 2 takes two distinct biglists, inserts one into the other at the given point 2 returns the resulting consolidated biglist 2 2 :extract_range(L,m,n) => {{@L[1..m-1],@L[n+1..]}, L[m..n]} 2 breaks the given biglist into two distinct biglists. 2 2 :delete_range(L,m,n[,leafkiller]) => {@L[1..m-1],@L[n+1..]} 2 :keep_range (L,m,n[,leafkiller]) => L[m..n] 2 like extract_range only we destroy what we don't want. 2 2 :insertlast(L,value) => {@L,value} 2 inserts a new element at the end of biglist. 2 If find_ord is to continue to work properly, it is assumed that the 2 home:_ord(elt) is greater (comp-wise) than all of the :_ord values 2 of elements currently in the biglist. 2 2 :kill(L[,leafkiller]) 2 destroys all nodes used by biglist. 2 Calls home:leafkiller on each element. 35 5 5 35 1 5 35 5 5 35 5 5 35 5 5 35 5 5 35 5 5 35 1 5 35 1 5 35 1 1 -1 184 1 4 2 0 24305 0 1002603771 185 1 #14 Generic Large-Capacity Mail Recipient 144 35 -1 -1 -1 41 17 141 41 _genprop 35 173 -1 _make 184 173 -1 _kill 184 173 -1 _get 35 173 -1 _put 35 173 -1 _ord 35 173 -1 _makemsg 35 173 -1 _killmsg 35 173 -1 _message_num 35 173 -1 _message_date 35 173 -1 _message_hdr 35 173 -1 _message_text 35 173 -1 _lt_msgnum 35 173 -1 _lt_msgdate 35 173 -1 receive_batch 35 173 -1 receive_message 35 173 -1 messages_in_seq 35 173 -1 display_seq_headers 35 173 -1 display_seq_full 35 173 -1 list_rmm 35 173 -1 undo_rmm 35 173 -1 expunge_rmm 35 173 -1 rm_message_seq 35 173 -1 renumber 35 173 -1 length_all_msgs 35 173 -1 length_num_le 35 173 -1 length_date_le 35 173 -1 exists_num_eq 35 173 -1 new_message_num 35 173 -1 from_msg_seq 35 173 -1 %from_msg_seq 35 173 -1 to_msg_seq 35 173 -1 %to_msg_seq 35 173 -1 subject_msg_seq 35 173 -1 body_msg_seq 35 173 -1 date_sort 35 173 -1 _fix_last_msg_date 35 173 -1 __fix 35 173 -1 init_for_core 184 173 -1 length_date_gt 35 173 -1 rmm_for_core 184 173 -1 4 summary_uses_body _mgr mowner _genprop 30 0 0 35 5 1 13 35 5 1 35 35 1 2 35 1 5 35 5 0 0 35 1 5 35 0 5 35 5 5 35 5 5 35 5 5 35 5 5 35 1 5 35 1 5 35 5 5 35 1 4 0 35 0 0 0 35 4 4 1 2 Generic Large-Capacity Mail Recipient 35 1 4 24 2 Generic Large Capacity Mail Recipient 2 ------------------------------------- 2 Since any modifications to large lists entail copying the entire list 2 over, operations on ordinary mail recipients having large numbers of 2 messages, that actually change the content of .messages will take 2 inordinately long. Thus we have this version which makes use of the 2 $biglist package, scattering the messages onto numerous properties so 2 that write operations involving only a few messages will not require 2 recopying of the entire list. 2 2 In nearly all respects it behaves as the ordinary Mail Recipient, 2 except that it is faster for certain kinds of operations. 2 2 Certain unimplemented verbs, like :date_sort(), and :messages() 2 currently return E_VERBNF. 2 2 To convert an existing $mail_recipient-child (call it #MR) into a 2 $big_mail_recipient-child the basic procedure is 2 2 ;;something.foo= #MR:messages(); 2 @rmm 1-$ from #MR 2 @unrmm expunge 2 @chparent #MR to $big_mail_recipient 2 ;#MR:receive_batch(@something.foo); 35 5 5 35 1 5 35 5 5 35 5 5 35 5 5 35 5 5 35 5 5 35 1 5 35 1 5 35 1 1 -1 184 1 4 2 0 26714 0 1002603771 185 1 #15 Limbo 16 184 -1 35 -1 1 -1 30 10 confunc 184 173 -1 who_location_msg 35 173 -1 contents 184 173 -1 acceptable 184 173 -1 in_name 35 173 -1 is_public_location 35 173 -1 modname_in 35 173 -1 connect_point 35 173 -1 init_for_core 184 173 -1 where_am_i 35 173 -1 2 connect_msg who_location_msg 16 4 6 1 69 2 do 4 3 2 name 2 player 2 ic 2 4 3 2 verb 2 player 2 has 2 connected. 184 5 0 0 184 5 0 0 184 4 4 2 2 Limbo 2 body bag 184 5 5 184 5 5 35 1 5 184 5 5 184 5 5 184 5 0 1 184 5 0 1 184 5 5 35 1 5 35 1 5 35 1 1 -1 184 1 4 2 0 6841 0 1030435200 185 1 #16 Registration Database 0 35 -1 -1 -1 79 -1 25 7 find(old) 35 169 -1 add 35 173 -1 init_for_core 184 165 -1 suspicious_address 184 173 -1 suspicious_userid 184 173 -1 check_address_request 184 173 -1 prohibit_lookup prohibit_modify 35 173 -1 0 21 4 2 1 35 2 35 5 0 0 35 1 0 0 35 1 5 35 5 5 35 5 4 2 0 1030475425 0 1293472328 35 1 4 4 2 2 4 0 4 0 35 1 0 0 35 4 4 1 2 Registration Database 35 5 5 35 5 5 35 1 5 35 5 5 35 5 5 35 5 5 35 5 5 35 5 5 35 1 5 35 1 5 35 1 1 -1 184 1 4 2 0 68455 0 1002603771 185 1 #17 Player-Creation-Log 0 35 42 -1 140 14 -1 -1 3 display_seq_headers 184 173 -1 msg_summary_line 184 173 -1 is_usable_by 184 173 -1 1 autoregistration_player 31 1 105 184 1 0 1 35 5 1 13 35 5 1 35 35 1 5 35 1 5 35 5 5 35 1 5 35 0 0 1 35 5 5 35 5 5 35 5 5 35 5 4 1 1 2 35 1 4 0 35 1 5 35 5 5 35 1 5 35 0 0 0 35 4 4 3 2 Player-Creation-Log 2 Player_Creation_Log 2 PCL 35 1 2 Log of player creations. 35 5 5 35 1 5 35 5 5 35 5 5 35 5 5 35 5 5 35 5 5 35 1 5 35 1 5 35 1 1 -1 184 1 4 2 0 111165 0 1002603771 185 1 #18 string utilities 16 184 -1 -1 -1 146 -1 72 86 space 184 173 -1 left 184 173 -1 right 184 173 -1 centre center 184 173 -1 columnize columnise 35 173 -1 from_list 184 173 -1 english_list 184 173 -1 names_of 35 173 -1 from_seconds 184 173 -1 trim 35 173 -1 triml 35 173 -1 trimr 35 173 -1 strip_chars 35 173 -1 strip_all_but 35 173 -1 uppercase lowercase 184 173 -1 capitalize capitalise 184 173 -1 literal_object 35 173 -1 match 184 173 -1 match_str*ing 184 173 -1 match_object 184 173 -1 match_player 35 173 -1 match_player_or_object 184 173 -1 find_prefix 184 173 -1 index_d*elimited 35 173 -1 is_numeric 35 173 -1 ordinal 35 173 -1 group_number 184 173 -1 english_number 184 173 -1 english_ordinal 35 173 -1 english_ones 184 173 -1 english_tens 184 173 -1 subst*itute 35 173 -1 substitute_d*elimited 184 13 -1 _cap_property 184 173 -1 pronoun_sub 184 173 -1 pronoun_sub_secure 35 173 -1 pronoun_quote 35 173 -1 explode 35 173 -1 words 35 173 -1 word_start 35 173 -1 to_value 35 173 -1 prefix_to_value 35 173 -1 _tolist 35 173 -1 _unquote 35 173 -1 _toscalar 35 173 -1 parse_command 184 173 -1 from_value 184 173 -1 print 184 173 -1 print_suspended 35 173 -1 reverse 184 173 -1 char_list 35 173 -1 regexp_quote 35 173 -1 connection_hostname_bsd 35 173 -1 connection_hostname 35 173 -1 from_value_suspended 184 173 -1 first_word 35 173 -1 common 184 173 -1 name_list namec_list dnamec_list inamec_list dname_list iname_list 35 173 -1 _pronoun_sub 184 173 -1 name_and_number_list iname_and_number_list dname_and_number_list 184 173 -1 to_list 184 173 -1 character_to_ascii 184 173 -1 character_to_hex_ascii 184 173 -1 ascii_to_character 184 173 -1 hex_ascii_to_character 184 173 -1 print_truncated 35 173 -1 print_truncated_recursive 35 173 -1 name_and_number nn iname_and_number dname_and_number namec_and_number inamec_and_number dnamec_and_number 35 173 -1 next_index 35 165 -1 match_room 184 173 -1 is_uppercase 35 173 -1 index_all 184 173 -1 columnize_with_headers columnise_with_headers 35 173 -1 columnize_suspended 35 173 -1 nonblank 35 173 -1 is_lowercase 35 173 -1 columnize_no_truncate 35 173 -1 print_with_names 184 173 -1 match_stringlist 184 173 -1 title_list name_for_tell_contents_list name_for_look_self_list titlec_list namec_for_look_self_list namec_for_tell_contents_list name_and_number_list iname_and_number_list dname_and_number_list namec_and_number_list inamec_and_number_list dnamec_and_number_list 35 173 -1 glob_to_regexp 35 173 -1 xglob_to_regexp 35 173 -1 match_all match_exact_or_all 184 173 -1 explode_match 184 173 -1 incr_alpha 184 173 -1 from_words 184 173 -1 7 digits ascii alphabet _character_set _character_set_in_ascii _character_set_in_hex_ascii tab 22 2 0123456789 184 5 2 !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ 184 5 2 abcdefghijklmnopqrstuvwxyz 184 5 2 !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ 184 5 4 96 0 8 0 32 0 33 0 34 0 35 0 36 0 37 0 38 0 39 0 40 0 41 0 42 0 43 0 44 0 45 0 46 0 47 0 48 0 49 0 50 0 51 0 52 0 53 0 54 0 55 0 56 0 57 0 58 0 59 0 60 0 61 0 62 0 63 0 64 0 65 0 66 0 67 0 68 0 69 0 70 0 71 0 72 0 73 0 74 0 75 0 76 0 77 0 78 0 79 0 80 0 81 0 82 0 83 0 84 0 85 0 86 0 87 0 88 0 89 0 90 0 91 0 92 0 93 0 94 0 95 0 96 0 97 0 98 0 99 0 100 0 101 0 102 0 103 0 104 0 105 0 106 0 107 0 108 0 109 0 110 0 111 0 112 0 113 0 114 0 115 0 116 0 117 0 118 0 119 0 120 0 121 0 122 0 123 0 124 0 125 0 126 184 5 4 96 2 08 2 20 2 21 2 22 2 23 2 24 2 25 2 26 2 27 2 28 2 29 2 2A 2 2B 2 2C 2 2D 2 2E 2 2F 2 30 2 31 2 32 2 33 2 34 2 35 2 36 2 37 2 38 2 39 2 3A 2 3B 2 3C 2 3D 2 3E 2 3F 2 40 2 41 2 42 2 43 2 44 2 45 2 46 2 47 2 48 2 49 2 4A 2 4B 2 4C 2 4D 2 4E 2 4F 2 50 2 51 2 52 2 53 2 54 2 55 2 56 2 57 2 58 2 59 2 5A 2 5B 2 5C 2 5D 2 5E 2 5F 2 60 2 61 2 62 2 63 2 64 2 65 2 66 2 67 2 68 2 69 2 6A 2 6B 2 6C 2 6D 2 6E 2 6F 2 70 2 71 2 72 2 73 2 74 2 75 2 76 2 77 2 78 2 79 2 7A 2 7B 2 7C 2 7D 2 7E 184 5 2 184 5 2 millions of 184 5 0 0 184 4 4 2 2 string 2 utils 184 5 4 126 2 For a complete description of a given verb, do `help $string_utils:verbname' 2 2 Conversion routines: 2 2 :char_list (string) => {"a", "b", "c"} 2 :to_list (string) => {"a", "foo", "bear"} 2 (see also :explode, below) 2 2 :from_list (list [,sep]) => "foo1foo2foo3" 2 :english_list (str-list[,none-str[,and-str[, sep]]]) => "foo1, foo2, and foo3" 2 :title_list*c (obj-list[,none-str[,and-str[, sep]]]) => "foo1, foo2, and foo3" 2 or => "Foo1, foo2, and foo3" 2 2 :[i|d]name[c]_and_number => "foo (#123)" 2 :[i|d]name[c]_list (obj-list, name-args) => english list of names 2 in appropriate style 2 :[i|d]name[c]_and_number_list(obj-list, name-args) => same, plus " (#123)" 2 :names_of (obj-list) => "foo1 (#123) foo2 (#456) foo3 (#789)" 2 2 :to_value (string) => {1, value} 2 or => {0, error message} 2 :prefix_to_value(string) => {rest-of-string, value} 2 or => {0, error message} 2 :end_expression (string) => index of expression 2 2 :from_value[_suspended] (value [,quoteflag [,maxlistdepth]]) 2 => "{foo1, foo2, foo3}" 2 :print[_suspended] (value) => "{foo1, foo2, foo3}" 2 :print_truncated (value, length, suffix) => "{foo1, fo.." 2 :print_with_names (value) => "{foo1, foo2 (#123)}" 2 2 :english_number(42 [,zero]) => "forty-two" 2 :english_ordinal(42) => "forty-second" 2 :ordinal(42) => "42nd" 2 :group_number(42135 [,sep]) => "42,135" 2 :from_seconds (num) => "an hour" or "3 days" or "15 seconds" 2 2 :glob_to_regexp("foo*b?r") => "^foo.*b.r$" 2 :xglob_to_regexp("f*ba[rz]") => "^f.*ba[rz]$" 2 2 Type checking: 2 2 :is_numeric (string) => return true if string is composed entirely of digits 2 2 String Matching: 2 2 :match_string(string, pattern, options) => * wildcard matching 2 :find_prefix(prefix, string-list) => list index of element starting 2 with prefix 2 :match_stringlist(string, string-list) => index/$ambiguous_match/$failed_match 2 :index_delimited(string,target[, case]) => index of delimited string occurrence 2 :index_all(string, target[, delimited]) => all occurrences of target in string 2 :next_index(str1, str2, prev[, case]) => index, after index `prev' 2 2 Object Matching (see also $command_utils): 2 2 :literal_object(string) => object match independent 2 of location 2 :match (string, [obj-list, prop-name]+) => matching object 2 :match_player (string-list[,me-object]) => list of matching players 2 :match_object (string, location) => default object match 2 :match_player_or_object(@string-list) => matching object or player 2 :match_room (string) => matching room object 2 2 Parsing: 2 2 :explode (string,char) -- string => list of words delimited by char 2 (see also :to_list, above) 2 :words (string) -- string => list of words (as with command line parser) 2 :word_start (string) -- string => list of start-end pairs. 2 :first_word (string) -- string => {first word, rest of string} or {} 2 2 :parse_command(cmd_line[, player]) -- string => parsed command info 2 2 Pretty printing: 2 2 :space (n/string[,filler]) => n spaces 2 :left (string,width[,filler]) => left justified string in field 2 :right (string,width[,filler]) => right justified string in field 2 :center/re (string,width[,filler]) => centered string in field 2 :columnize/se[_suspended](list,n[,width]) 2 => list of strings in n columns 2 :columnize/se_no_truncate(list,n[,linelen]) 2 => same, but will not truncate items 2 :columnize/se_with_headers(headers, fields) => columnize, plus headers 2 2 Substitutions 2 2 :substitute (string, subst_list [,case]) -- general substitutions. 2 :substitute_delimited(...) -- same, but with word boundaries. 2 :pronoun_sub (string/list[,who[,thing[,location]]]) 2 -- pronoun substitutions. 2 :pronoun_sub_secure (string[,who[,thing[,location]]],default) 2 -- substitute and check for names. 2 :pronoun_quote (string/list/subst_list) -- quoting for pronoun substitutions. 2 :regexp_quote(string) -- quoting for regexps. 2 2 Miscellaneous string munging: 2 2 :trim (string) => string with outside whitespace removed. 2 :triml (string) => string with leading whitespace removed. 2 :trimr (string) => string with trailing whitespace removed. 2 :strip_chars (string,chars) => string with all chars in `chars' removed. 2 :strip_all_but(string,chars) => string with all chars not in `chars' removed. 2 :capitalize/se(string) => string with first letter capitalized. 2 :uppercase/lowercase(string) => string with all letters upper or lowercase. 2 :reverse (string) => string, backwards. 2 2 :common(string1, string2) => length of longest common prefix. 2 :is_uppercase (string) => true iff no lowercase letters in string 2 :is_lowercase (string) => true iff no uppercase letters in string 2 :nonblank (string) => true iff any non-whitespace characters 2 2 :connection_hostname(string) => hostname part of connection identifier. 2 2 Conversions to and from common string formats: 2 2 :character_to_ascii(char) => integer ASCII rep of char 2 :character_to_hex_ascii(char) => two-digit hexadecimal string ASCII rep of char 2 :ascii_to_character(num) => character represented in ASCII by num 2 :hex_ascii_to_character(hex) => ASCII character represented by two-character hexadecimal string hex 2 2 A few useful properties: 2 2 alphabet => "abcdefghijklmnopqrstuvwxyz" 2 tab => a single tab character 184 5 5 35 1 5 184 5 5 184 5 5 184 5 5 184 5 5 184 5 5 35 1 5 35 1 5 35 1 1 -1 184 1 4 2 0 87958 0 1030435200 185 1 #19 building utilities 16 184 -1 -1 -1 146 -1 18 9 make_exit 184 173 -1 set_names 184 173 -1 recreate 184 173 -1 parse_names 184 173 -1 object_audit_string 184 173 -1 audit_object_category 184 173 -1 size_string 185 173 -1 do_audit do_prospectus 184 173 -1 do_audit_item 184 173 -1 0 15 5 184 5 0 0 184 4 4 2 2 building 2 utils 184 5 4 14 2 Verbs useful for building. For a complete description of a given verb, do `help $building_utils:verbname'. 2 2 make_exit(spec,source,dest[,don't-really-create]) => a new exit 2 spec is an exit-spec as described in `help @dig' 2 2 set_names(object, spec) - sets name and aliases for an object 2 parse_names(spec) => list of {name, aliases} 2 in both of these, spec is of the form 2 [[,:],,...] 2 (as described in `help @rename') 2 2 recreate(object, newparent) - effectively recycle and recreate object 2 as a child of newparent 2 transfer_ownership(object, old-owner, new-owner) - just what it sounds like 184 5 5 35 1 5 184 5 5 184 5 5 184 5 5 184 5 5 184 5 5 35 1 5 35 1 5 35 1 1 -1 184 1 4 2 0 14173 0 1030435200 185 1 #20 Verb Help 16 35 -1 -1 -1 197 100 21 6 find_topics 35 173 -1 get_topic 184 173 -1 topic_text 184 173 -1 set_topic_text 184 173 -1 add_topic 35 173 -1 index 35 173 -1 0 16 4 0 35 1 5 35 1 0 0 35 4 4 1 2 Verb Help 35 5 2 A `help database' that knows about all of the documented verbs. 35 5 5 35 1 5 35 5 5 35 5 5 35 5 5 35 5 5 35 5 5 35 1 5 35 1 5 35 1 1 -1 184 1 4 2 0 6118 0 1002603771 185 1 #21 Core Utility Help 16 35 -1 -1 -1 197 -1 22 5 find_topics 35 173 -1 get_topic 35 173 -1 topic_text 184 173 -1 set_topic_text 184 173 -1 nominate_for_core 184 173 -1 30 $login $openable_container $mail_agent MR-subscribing MR-naming MR-access $mail_recipient receiving-mail mail-format mail-resolve sending-mail mail-system $player_db core-index object-matching $no_one $exit $room $help $generic_db $generic_editor $generic_help $generic_options MR-sequences MR-reading MR-writing MR-searching $english $housekeeper mail-recipient 46 4 80 2 $login 2 1----- 2 2 This object manages command parsing for unconnected players and governs the initiation of an actual connection. There are verbs pertaining to registration, controlling player creation, and doing site-locks (see `help blacklist' on $wiz_help). 2 2 Commands for unconnected players 2 2------------------------------- 2 2 Recall that for each line that an unconnected player types, the server parses that line into words (the same way normal commands are parsed into a list of words that is then assigned to `args') and then #0:do_login_command is called. 2 2 :parse_command (@args) => {verb, @args} 2 given the sequence of arguments that were fed to #0:do_login_command 2 this returns the name of a verb on $login to be called together with a 2 list of arguments to be passed to it. 2 2 By default this just returns args iff args[1] names an actual verb on $login that is +x and has args {"any","none","any"}. Otherwise, it returns one of 2 2 .blank_command -- verb to call if command line is empty 2 .bogus_command -- verb to call if command line otherwise unintelligible 2 2 In both cases :parse_command returns a verbname followed by the entire args list passed to it (including the would-be verb at the beginning if any). 2 2 Currently the following verbs are availabe to non-connected players 2 2 h*elp @h*elp -- print .welcome_message 2 ? -- print a short list of available commands 2 w*ho @w*ho -- print a list of logged in players (excluding wizards) 2 co*nnect @co*nnect -- connect to an existing player 2 cr*eate @cr*eate -- create a new player 2 up*time @up*time -- tell how long the server has been running 2 version @version -- tell which version of the server is running 2 q*uit @q*uit -- logoff 2 2 Adding a new command is fairly straightforward; just create a verb on $login, making sure a previous verb doesn't already match the name you want to give it. Then give it args of "any" "none "any" and make sure it is +x. Such a verb should begin with `if (caller != #0) return E_PERM; ...' so as to prevent anyone other from a not-logged-in player from making use of it. 2 2 Customizations 2 2------------- 2 2 .welcome_message 2 -- the message for "help" to print. 2 .create_enabled 2 == 0 => @create prints .registration_string if one tries to use it 2 == 1 => anyone from a non-blacklisted site (see `help blacklist') 2 may use @create to make a new player 2 2 .registration_address 2 -- an email address for character creation requests 2 .registration_string 2 -- string to print to players to give them information about how to get 2 a character created for them, .registration_address is substituted 2 for %e, % for %% 2 .newt_registration_string 2 -- string to print to @newted players (see `help @newt'). 2 same substitutions as for .registration_string. 2 2 .sitematch_guests 2 -- use $country_db to connect guests from ".fr" as "French guest", etc. 2 2 Other verbs 2 2---------- 2 2 :registration_string() => .registration_string with substitutions 2 :newt_registration_string() => .newt_registration_string with substitutions 2 :player_creation_enabled(connection) 2 decides whether someone on connection should be allowed to create 2 a player. If you decide this shouldn't depend strictly on the blacklist 2 and on the value of .create_enabled, here's where the extra code can go. 2 :check_for_shutdown() 2 prints a warning message to append to the login banner in the event 2 that the server will be going down soon. 2 :check_player_db() 2 prints a warning message to append to the login banner in the event 2 that $player_db is being reloaded to warn players that their character 2 names might not be recognized. 2 2 Site locks 2 2--------- 2 2 See `help blacklist'. 2 35 5 4 29 2 The Generic Container (for programmers) 2 2 In addition to the command verbs described under `help containers' 2 and the _msg properties described in `help container-messages', 2 the following verbs and properties are available for use within programs 2 2 .opened == TRUE iff the container is open 2 .dark == TRUE iff the contents of the container may be seen 2 .opaque -- describes the correlation between .open and .dark 2 == 0 container is always !dark 2 == 1 container is dark iff it is closed 2 == 2 container is always dark 2 2 :set_opaque(newvalue) 2 changes the .opaque value for the container 2 => newvalue or E_PERM or E_INVARG 2 2 :set_opened(newvalue) 2 opens/closes the container (updates .open and .dark) according to newvalue 2 => newvalue or E_PERM 2 2 :is_openable_by(player) 2 what the :open command uses to test whether the player should be able to open 2 the container. By default this refers to .open_key (set by 2 @(un)lock_for_open), but the object owner is free to customize this. 2 2 N.B.: There is no way to directly set .dark; .dark can be changed only by 2 changing one of .opaque or .opened. Use :set_opaque(0) and :set_opaque(2) 2 to have .dark change independently of the value of .opened. 35 5 4 68 2 $mail_agent 2 2 This object contains a two distinct sets of routines: 2 2 1. utilities for performing basic mailsystem functions, e.g., 2 matching on recipient names, resolving mail forwarding, 2 formatting messages, sending messages 2 2 Recipient Matching 2 2 match - match on a $mail_recipient 2 match_recipient - match on either a $mail_recipient or a player 2 match_failed - print angry messages to the user for $failed/ambiguous_match 2 2 look_self - provides a list of available $mail_recipients 2 check_names 2 touch 2 accept 2 2 Message Format 2 2 make_message - produces a message in the canonical transmission format 2 name - single recipient => string for address field 2 name_list - list of recipients => string for address field 2 parse_address_field - address field string => object list 2 2 Sending Messages 2 2 send_message - advertised message sending routine. 2 raw_send - raw message sending routine 2 (only called by $mail_editor:send and this:send_message) 2 resolve_addr - converts a given list recipients into a list of actual 2 recipients and objects to be notified. 2 sends_to - Does X forward (transitively) to Y 2 2 Mail Options 2 2 option 2 option_verbose 2 2 2. canonical versions of mail_recipient verbs 2 2 Ideally, the verbs to perform operations on a given mail recipient would be located on the recipient itself, except for the fact that these verbs also need to be located on players, which for various reasons, shouldn't be children of $mail_recipient. Multiple inheritance would solve our problems, but we don't have it yet. Ergo, both $mail_recipient and $player refer to the following verbs here: 2 2 display_seq_full print entire text of messages (@read) 2 display_seq_headers print headers of messages (@mail) 2 rm_message_seq remove messages (@rmm) 2 undo_rmm undo last rm_message_seq (@unrmm) 2 expunge_rmm flush removed messages (@unrmm expunge) 2 list_rmm list removed messages (@unrmm list) 2 renumber renumber messages (@renumber) 2 msg_summary_line msg header => display_seq_headers/list_rmm summary line 2 2 parse_message_seq command line msg sequence spec => message sequence 2 new_message_num => message number of next new message 2 length_all_msgs => number of messages (total) 2 length_num_le => number of messages numbered <= some number 2 length_date_le => number of messages dated <= some date 2 exists_num_eq => true iff there exists a messsage with the given number 2 from_msg_seq => message sequence of msgs from given sender(s) 2 to_msg_seq => message sequence of msgs to given recipient(s) 2 subject_msg_seq => message sequence of msgs with subjects containing text 2 body_msg_seq => message sequence of msgs with bodies containing text 2 messages_in_seq => list of {message number, message} pairs 2 2 messages == :messages_in_seq(1,:length_all_msgs()+1) (obsolete) 2 2 The $mail_agent versions of these verbs are set_task_perms(caller_perms()) and perform their operations on caller, which in turn is assumed to have done any necessary security checks. 35 5 4 36 2 Subscribing to mail recipients 2 1----------------------------- 2 2 There are two notions of being "subscribed" to a mailing list/recipient. 2 2 o Hard subscribed == being on the recipient's .mail_forward list so that mail sent to this list is forwarded to one's own .messages as well (see `help mail-forwarding'). 2 o Soft subscribed == keeping track of a current message for this recipient and (optionally) being on the recipient's .mail_notify list. 2 2 Each player has a .current_message property that contains, for each recipient the player cares to keep track of, a current message number and a last read date. 2 2 player:current_message(rcpt) (somewhat obsolete) 2 => player's current message number for rcpt 2 2 player:get_current_message(rcpt) 2 => player's {current message number for rcpt, last-read-date for rcpt} 2 2 player:make_current_message(rcpt) 2 => adds a current_message entry for rcpt (NOOP if rcpt == player) 2 2 player:set_current_message(rcpt,n|E_NONE,[,date]) 2 => sets player's current message number for rcpt to n iff n!=E_NONE 2 updates the last-read-date for rcpt to date iff date > last-read-date 2 2 player:kill_current_message(rcpt) 2 => removes current-message info for rcpt (NOOP if rcpt == player) 2 2 On $mail_recipient, .mail_forward and .mail_notify are -c so one needs to use the following verbs to actually modify them. 2 2 :add_forward(@new_recipients) 2 :delete_forward(@recpients) 2 :add_notify(@new_notifiees) 2 :delete_notify(@notifiees) 2 2 A recipient's owner is, of course, allowed to make arbitrary changes to .mail_forward and .mail_notify. However, the default versions of these verbs also allow any player to add him/herself to a recipient's .mail_forward or .mail_notify if the recipient is readable (see `help MR-access') by him/her. 2 2 Likewise any player may use the :delete* verbs to delete him/herself from any .mail_forward/.mail_notify list, regardless of his actual access to the list. 35 5 4 15 2 One may always refer to a list by its object number. In order to refer to it by name, it must be contained in $mail_agent, which holds all mailing lists, i.e., those that you want others to be able to refer to by name. 2 2 The .aliases field holds the names by which one may refer to the list, but only those names not containing spaces actually count for anything. As with certain other types of objects (e.g., players), set_aliases() needs to be called in order to change the .aliases field. 2 2 $mail_agent:match(name) 2 is the canonical way to obtain the objectid of a mailing list 2 given the name ("*" is assumed; an initial "*" will be dropped). 2 2 $mail_agent:match_recipient(name) 2 is the canonical way to obtain the objectid of a list or player 2 matching the given name. An initial "*" indicates that this is 2 supposed to be a list. 2 2 $mail_agent:match_failed(objid,name) 2 is the mail_recipient counterpart to $command_utils:object_match_failed 35 5 4 35 2 Controlling access to mail recipients 2 1------------------------------------ 2 2 :is_writable_by(one) - one may alter/add/remove saved messages 2 2 :is_readable_by(one) - one may read messages. 2 2 :is_usable_by(one) - one may send to this list 2 2 By default, these verbs refer to the following properties: 2 2 writers - list of players other than the owner who have full privileges. 2 readers - if == 1, indicates a public mailing list. 2 list of additional readers (by default anyone who receives mail 2 sent to the list can read the saved messages). 2 moderated - if false, indicates a normal mail recipient everyone can send to. 2 otherwise this should be a list of approved senders. 2 2 Terminology: 2 2 A mailing list is "public" if everyone can read it. 2 2 A mailing list is "moderated" if not everyone can send to it. 2 2 Note that while being able to write to a recipient implies being able to read from it or send to it, neither of read-ability or send-ability implies the other. 2 2 It is highly recommended that if you are creating custom mail recipients with variable reader/sender lists, i.e., you find you need to write your own :is_readable/usable/writabe_by verbs, you are best off if such verbs are of the form 2 2 return pass(@args) || << your_test(args[1]) >> 2 2 and have .writers == .readers == {} and .moderated == 1. This will ensure 2 2 o Wizards having write access. This is necessary in order for :receive_message to work. 2 o Writers being able to read and send (the converse being a ludicrous situation. 2 o Persons on the mail_forward list of someone with reader access will also have read access (convenient). 35 5 4 17 2 Generic mail recipient 2 1--------------------- 2 2 A "mail recipient" is, by definition, an object that can be sent mail. Mail recipients must either be players or descendants of $mail_recipient. 2 2 One source of confusion is that the terms "mail recipient", "mail folder", "mailing list", and "mail collection" really all refer to the same object. It so happens that $mail_recipient serve several distinct functions and we tend to use whatever term happens to best match the application under discussion, e.g., it's a "mailing list" if we're playing with its .mail_forward property but it's also a "mail folder" if we're examining the messages that have been saved in it. 2 2 Topics 2 2===== 2 2 MR-access -- controlling read, write and send access to a recipient 2 MR-naming -- naming conventions and how to match on recipient names 2 MR-sequences -- message sequence arguments to $mail_recipient verbs 2 MR-reading -- reading messages/headers on recipients 2 MR-searching -- searching message lists for patterns in certain fields 2 MR-writing -- removing and renumbering messages 2 MR-subscribing -- updating .mail_forward, .mail_notify and the story of .current_message 35 5 4 18 2 Receiving Mail 2 1------------- 2 2 By definition a recipient "receives" a mail message when its :receive_message verb is called with that message as an argument. 2 2 :new_message_num() 2 => number that will be assigned to the next incoming message. 2 2 By default this returns the maximum of the message numbers appearing in messages or .messages_going, incremented by 1. If the recipient is a player then the value returned will be 1 higher if it conflicts with the player's current message number for him/herself. 2 2 :receive_message(msg,sender) 2 2 By default this first calls this:new_message_num to obtain a message number to assign to the incoming message and then appends {num,msg} to this.messages. `sender', the original sender, is supplied in case one wants different action depending on who is sending the message (e.g., mail-gagging). The return value should be an error or string if :receive_message is considered to have failed in some way. Otherwise, a number should be returned --- this number is given to any :notify_mail routines that are called and is expected to either be 0 or the number assigned to the incoming message. 2 2 Note that :receive_message can do arbitrary things, including resending the same message to a new destination. Hacking :receive_message to resend messages is different from using .mail_forward in the following respects 2 2 o the resent message is considered to be a distinct message having this object as its "author" --- i.e., the From: line will necessarily be different. 2 o since this "forwarding" is invisible to the mailsystem, there is no protection against loops and multiple copies. 35 5 4 35 2 Mail Transmission Format 2 1----------------------- 2 2 There is a standard message format used for transmitting messages. This is the format that $mail_editor:make_message produces, and that :receive_message verbs on players and $mail_recipients expect to see. The (currently experimental) @refile and @copy commands also use this format to transfer messages. 2 2 This *transmission* format is distinct from the *storage* format, though, for convenience this same format is often used as well for storing messages in player collections and ordinary $mail_recipient children though, in general, there is no requirement that this be the case. 2 2 A transmitted message is a list in the following form 2 2 date (number), 2 the time() value at the time the message was sent. 2 from (string), 2 the sending object (address list form) 2 if this is not a player, an additional header will indicate the 2 current ownership of the object. 2 to (string), 2 recipients (address list form) which can either be players 2 or $mail_recipient descendents. 2 subject (string), 2 subject of the message, or " " if there is no subject, 2 @additional optional headers (list of strings), 2 each header has the form ": text" where : 2 is padded out to a width of 10 columns for the convenience of 2 :display_message. Currently "Reply-to:
" is the only 2 additional header in use, 2 "", 2 @body of message (list of strings) 2 2 Note that the from, to and subject lines do *not* include a header name like "From:", "To:", or "Subject:". The @'s indicate that the lists in question get spliced in (as usual), thus the entire message is a list whose first element is a number and the rest are strings. 2 2 The address lists that appear in the from and to lines is a string in the form a sequence of object ids, each enclosed in parentheses and preceded by optional text, e.g., 2 2 "*Core-DB-Issues (#8175), Rog (#4292), and Haakon (#2)" 2 2 The text is intended to give the current name of each object for the benefit of human readers, but is actually ignored by all header parsing routines. The convention is that the text is either a player name or a * followed by a mailing list name. 35 5 4 51 2 Resolving mail forwarding and notification 2 1----------------------------------------- 2 2 For each recipient of a given mail message, the following two verbs are called to determine where the message should actually go and who should be notified about it: 2 2 :mail_forward 2 2------------ 2 2 :mail_forward([from]) should return either 2 2 o a list of objects (either players or $mail_recipients) to which mail for this recipient will be redirected. 2 o a string error message to be printed to the player sending the message. If this recipient is one of the original destinations (i.e., not the result of a previous forwarding), no mail is actually sent. 2 2 If :mail_forward returns a nonempty list, the recipient itself will *not* actually receive the mail message unless it is included in the list. #-1 is allowed to be on the list; it is ignored but does make the list nonempty. Thus, having :mail_forward() return {#-1} is the canonical way to have arriving mail disappear without being kept or forwarded. 2 2 :mail_notify 2 2----------- 2 2 :mail_notify([from]) should return a list of objects that are to be told about any mail sent to this recipient (whether or not the recipient actually receives it). Said objects must have a :notify_mail verb, but other from that, there is no restriction on what these can be. 2 2 :notify_mail 2 2----------- 2 2 object:notify_mail is called with the arguments (sender,recipients,msgnumbers) where 2 2 o recipients == list of recipients including object in .mail_notify 2 o msgsnumbers == corresponding list of :receive_message return values (or 0 if :receive_message is not actually called, which will be the case if the recipient forwards without keeping) 2 2 When called as part of a mail send, the `from' argument is the immediate predecessor on the forwarding chain. The default versions of these verbs return the values of .mail_forward and .mail_notify respectively (pronoun_subbing if the value is a string), unless this is a moderated mailing list and `from' is an unapproved sender (see `help MR-access') in which case the following verbs are called instead: 2 2 :moderator_forward 2 2----------------- 2 2 :moderator_forward(from) is what :mail_forward should return for mail coming from unapproved senders. This returns .moderator_forward (pronoun_subbed if a string) by default. 2 2 :moderator_notify 2 2---------------- 2 2 :moderator_notify(from) is what :mail_notify should return for mail coming from unapproved senders. This returns .moderator_notify (pronoun_subbed if a string) by default. 2 2 Since the :mail_forward verbs only see the previous sender in the forwarding chain, if, e.g, B is moderated but A can send to B (i.e., B:mail_forward(A) returns an actual list), then any mail sent to A goes to B even if the original sender isn't normally allowed to send to B directly. 2 2 These verbs should all allow `from' to be omitted in which case they should return as if `from' were a generic approved sender (e.g., wizard). 2 2 It should rarely be necessary to actually modify any of :*_forward/*_notify verbs, since one has a fair amount of control over their behavior via the following properties: 2 2 o .mail_forward 2 o .mail_notify 2 o .moderated (see `help MR-access') 2 o .moderator_forward 2 o .moderator_notify 35 5 4 27 2 Sending Mail 2 1----------- 2 2 $mail_agent:send_message(from,recipients,headers,body) 2 2 from: sender of the message 2 (this must be you or something you own; otherwise => E_PERM) 2 recipients: object or list of objects (must all be players or 2 $mail_recipient descendants) 2 headers: either a string (contents of the Subject: line) 2 or a list {subject,replytos} replytos is a list 2 of objects designated to receive replies. 2 Use {"",replytos} to have a Reply-to: without a Subject: 2 2 This is the canonical way to send a mail message from a program. 2 2 This calls $mail_agent:make_message to format the arguments into an actual message (see `help mail-format') and then $mail_agent:raw_send to do the actual sending which goes as follows: 2 2 (1) Call :mail_forward on all recipients add any new recipients thus obtained to final recipient list, keep calling mail:forward on the new recipients until we obtain no additional recipients. If one of the initial recipients is invalid, is not a player or $mail_recipient, or has its mail_forward return a string error, then we print the error message and abort at this point with no mail being sent. If one of the later recipients bombs similarly, error messages are printed, but in this case mail still goes out to the other recipients. 2 2 (2) Call :mail_notify on all recipients encountered in stage (1) to get a list of objects to notify. 2 2 (3) All final recipients receive the message (see `help receive-mail') 2 2 (4) All notifications are delivered (using :notify_mail()) 2 2 We return {0, @failed_recipients} if we bombed out at step 1. Otherwise return {1, @actual_rcpts} indicating what mail was sent. 35 5 4 15 2 Mail system 2 1========== 2 2 The following topics describe the guts of the LambdaCore mail system: 2 2 sending-mail -- how to send mail from a program; what happens. 2 mail-forwarding -- how to do mail forwarding/notification (the simple version) 2 mail-resolution -- how mail forwarding/notification works, in gory detail 2 receiving-mail -- what :receive_message should do 2 mail-format -- format of transmitted messages 2 2 mail-command-parsing (TODO) -- routines for parsing mail commands 2 2 $mail_recipient -- generic non-player mail recipient 2 $mail_agent -- mail utility object 35 5 4 28 2 DATABASE OF PLAYERS 2 =================== 2 2 This is an instance of the Generic Database ($generic_db) that holds the {name/alias,#objectid} pairs for every name and alias of every player in the MOO. 2 2 Verbs supplied include 2 2 :find(string) => player or $ambiguous_match or $failed_match 2 :find_exact(string) => player or $failed_match (does not do partial matches) 2 :find_all(string) => list of all matching players 2 2 :insert(string,player) 2 records that string is now a name or alias of player 2 :delete(string) 2 removes string from the db 2 :available(string) 2 returns 1 if string is available as a player name or alias, 2 an object if string is in use, or 0 if string is otherwise unavailable. 2 :load() 2 resets the db, inserting all current player names and aliases. 2 2 The internal representation and all of the above verbs (except :load() and :available()) are as described for $generic_db. 2 2 It should be noted that for any application that involves resolving a player name from a command line, you should be using $string_utils:match_player() rather than $player_db:find(), since the former will deal correctly with other ways of referring to players apart from their names and aliases (e.g., literal object numbers, "me", "$no_one"...). 2 2 :load() needs to be done periodically as it is possible for the player db to get out of synch with reality. In particular, there is currently no way to block someone writing his own player :recycle() verb that neglects to remove his names from the player db. 2 2 While a :load() is in progress the .frozen property is set to 1 to indicate that any results of :find*() are not to be trusted. 35 5 4 2 2 *index* 2 Core Utility Help Topics 35 5 4 68 2 Which :match...() verb do I call? 2 1-------------------------------- 2 2 There are many situations where one wishes to obtain an object from a room or a player's .contents whose name/aliases matches a particular string. There are four main verbs available for this and it is important to understand the distinctions between them and how they are supposed to be used. 2 2 LOC:match("X") 2 2============= 2 2 What you get looking for something that is inside LOC and named "X". By default, this looks through LOC.contents to find a unique object having a name or alias that has "X" as a prefix. 2 2 Essentially, you can think of :match as a contents-matching verb, though, e.g., for rooms you also get matches on exits as well. 2 2 :match_object and :my_match_object 2 2================================= 2 2 LOC:match_object("X", YOU) [YOU defaults to player] 2 YOU:my_match_object("X", LOC) [LOC defaults to player.location] 2 2 What YOU get being located at LOC and looking for something named "X". By default these both return $string_utils:match_object("X",LOC,YOU). 2 2 $string_utils:match_object 2 2========================= 2 2 $string_utils:match_object("X", LOC, YOU) 2 2 What you *would* get *if* YOU were a typical player, YOU were inside LOC, YOU were looking for something named "X", *and* LOC were a typical place. 2 2 In other words, $string_utils:match_object describes the :match_object() algorithm for "typical places" and the :my_match_object for "typical players": 2 2 o check for "X" being one of "", "me", "here", "$something", or "#n" 2 o try YOU:match("X") i.e., something in your inventory (maybe) 2 o try LOC:match("X") i.e., some object in the room (maybe) 2 2 The distinction between these location:match_object and player:my_match_object has to do with whether the player or the location should determine what the matching algorithm is. Which one you should use depends on the command that you are writing. If you are writing a command with a virtual-reality flavor, then you should be respecting the room owner's idea of which objects you can "see" and thus the command should be calling the location's :match_object verb. If you are writing a building/programming command where it is appropriate for the player to determine the matching algorithm --- whether because the current location is irrelevant, not to be trusted, or both --- then the player's :my_match_object verb should be called. 2 2 Examples 2 3======= 2 2 `look diamond in box' 2 2 calls box:match("diamond"). This is a match on the contents of box. 2 2 `take ball' 2 2 calls player.location:match_object("ball") to determine which "ball" to take. Note that if the room is dark, we might not be able to find any "ball". 2 2 `@program widget:foo' 2 2 calls player:my_match_object("widget") to get the player's own idea of what "widget" should be. Note that if I were carrying something named "widget" and expecting to be programming a :foo() verb on it, it would be potentially disastrous should the room where I am decide for me to be programming something else (not even necessarily called "widget"). 2 2 Object matching failures 2 2----------------------- 2 2 As with other matching routines, one gets back 2 2 o $failed_match in the case of no matching object 2 o $ambiguous_match in the case of more than one matching object 2 o $nothing in the case of a blank string argument 2 2 or an object-id. In these first 3 cases, one usually wants to translate these nonresults to the player; this is what $command_utils:object_match_failed. The standard idiom to mimic what the builtin parser does, say, with the direct object is 2 2 dobj = foo:match_???(dobjstr); 2 if($command_utils:object_match_failed(dobj, dobjstr)) 2 "...give up. nothing to do. error message has already printed..."; 2 else 2 "...dobj is something useful. Continue..."; 2 ... 2 endif 35 5 4 27 2 ..is a powerless player. He owns no objects, not even himself; nor does he own any verbs. He is, however, a programmer and thus may use eval(). In fact his sole purpose is to evaluate questionable code. 2 2 `Questionable' could be in either or both of the following senses 2 2 (1) Its origin is sufficiently uncertain so that there is no obvious way of deciding whose permissions it should run under. 2 2 (2) The code itself is potentially malicious, i.e., to the extent that one does not want to be evaluating it using one's own permissions. 2 2 set_task_perms($no_one); 2 2 is thus the canonical idiom in wizard code for rendering anything that follows mostly harmless. For use by ordinary programmers, we have: 2 2 $no_one:eval(string) 2 2 which attempts to evaluate an arbitrary string using $no_one's permissions. string is either an expression or ";" followed by one or more statements, of which the final semicolon may be omitted. return values are what eval() would return (either {1,value} or {0,@error_messages}). 2 2 Similarly, we have 2 2 $no_one:eval_d(string) 2 2 which attempts to evaluate the specified string, but does it without the debug flag turned on (so that, for example, you'll get an error as opposed to terminating by traceback). 2 2 And, as a helpful utility for calling verbs whose behavior may be unpredictable, there is 2 2 $no_one:call_verb(object, verb name, args) 2 2 which calls the specified verb with $no_one's permissions. 35 5 4 17 2 Exits 2 ----- 2 :move(object) - moves the object via this exit 2 :invoke() - equivalent to :move(player) 2 2 When an exit is invoked on a particular object (via exit:move(object)), the following occurs. 2 2 (1) The exit may be locked against the object, in which case we print the 2 nogo messages and quit. 2 2 (2) (room=exit.dest):bless_for_entry(object) is called. Assuming that exit is recognized by room as being a legitimate entrance (i.e., is in room.entrances), this will enable room:accept(object) to return true. 2 2 (3) object:moveto(room) is called and the various messages (see `help exit-messages') are :announced/:told. Note that this, in accordance with the way the builtin move() (and hence the default :moveto()) works, we get a call to room:accept(object) which checks for the room itself being locked against the object, and otherwise returns true if the blessing in the previous step worked. The move is performed, here:exitfunc(object) and room:enterfunc(object) are called. In particular, room:enterfunc clears the blessing bestowed in (2) now that it is no longer needed. 2 2 In general, the move may fail, in which case we :announce the (o)nogo_msgs. 2 2 Transparent exits (the default on this MOO) can have extra substitutions in their description and messages; the new substitutions let you put information from the exit's destination into the exit's messages. %c is replaced with a list of the contents of the destination. %w is a list of the players in the destination. %l is the description (looks) of the destination. These substitutions don't conflict with the standard pronoun substitutions; you can still use them in messages. Example: @describe my_exit as "You see %w standing in the other room.". 35 5 4 73 2 The generic room ($room) 2 1----------------------- 2 2 Announcements 2 2------------ 2 2 :announce (@text) => broadcasts to all except player 2 :announce_all (@text) => broadcasts to all 2 :announce_all_but (objects,@text) => broadcasts to all except those in objects 2 2 say, emote 2 2 2 Command recovery 2 2--------------- 2 2 :huh (verb,args) - server hook: last chance to make sense of verb 2 :here_huh (verb,args) - room's last attempt to parse something 2 :here_explain_syntax (this,verb,args) - attempts to explain usage of verb 2 2 2 Residency 2 2-------- 2 2 free_home - true => @sethome allows anyone to set his .home to be here 2 residents - objects on this list may teleport in and/or set their homes here. 2 2 :accept_for_abode(player) 2 => true iff player should be allowed to set .home to this room. 2 2 @resident*s 2 2 Looking 2 2------ 2 2 dark - true => contents are not visible 2 ctype - 1..4 for four different styles of .contents lists 2 2 :match (string) => exit or object in room's .contents 2 :tell_contents (objects,ctype) - format objects according to ctype, tell player 2 2 l*ook 2 2 2 Topology and movement via exits 2 2------------------------------ 2 2 See `help $exit' for an explanation of how the generic $exit works. 2 2 free_entry - true => `teleporting' in is allowed 2 false => only residents may teleport in 2 exits - list of invokable exits leading from this room 2 entrances - list of recognized exits leading to this room 2 blessed_object - object currently entering via an exit 2 blessed_task - task_id for entering object 2 2 :match_exit (string) => exit whose name matches string 2 :bless_for_entry (object) - set up room to accept object arriving from entrance 2 :add_exit (exit) 2 :add_entrance (exit) 2 :remove_exit (exit) 2 :remove_entrance (exit) 2 2 e/east/w/west/s/south/n/north/ne/northeast/nw/northwest/se/southeast/sw/southwest/u/up/d/down, go, @add-exit, @add-entrance, @remove-exit, @remove-entrance, @exits, @entrances 2 2 2 Ejection 2 2------- 2 2 victim_ejection_msg/oejection_msg/ejection_msg 2 :*_msg() messages 2 2 @eject 35 5 4 2 2 *forward* 2 $generic_help 35 5 4 129 2 This holds a collection of {string-key, datum} pairs, where datum can be anything. At most one datum may be associated with any given string. Data may be anything (lists, strings, numbers, objectids). If you like, you can think of this as an array indexed by strings. 2 2 Lookup Verbs 2 ------------ 2 :find(string) => datum, .ambiguous or .failed 2 :find_key(string) => full string key, .ambiguous or .failed 2 :find_exact(string) => datum or .failed (no partial matches) 2 2 :find_all(string) => list of all data corresponding to matching keys 2 :find_all_keys(string) => list of all matching keys 2 :find_all_entries(string) => list of all matching {key, datum} pairs 2 2 :find_all(string,vname) 2 does the general find_all operation, i.e., 2 2 result == {}. 2 for every {key, datum} matching string 2 result = :("accum_"+vname)(result, key, datum) 2 endfor 2 return result; 2 2 $generic_db already defines :accum_data, :accum_keys, :accum_entries 2 in order that 2 2 :find_all(string,"keys") == :find_all_keys(string) 2 :find_all(string,"data") == :find_all(string) [*] 2 :find_all(string,"entries") == :find_all_entries(string) [*] 2 2 [*] These don't hold if .no_data == 1. 2 2 Modification Verbs 2 ------------------ 2 :insert(string,datum) 2 if the string is already present in the db, 2 changes the associated datum and returns {old_datum}; 2 otherwise enters a new {string,datum} pair and return 0. 2 :delete(string) 2 if there is a datum associated with string, 2 remove this association and return {datum}; otherwise return 0. 2 :delete2(string,datum) 2 if the given datum is associated with string, 2 removes that association and return {datum}, 2 if some other datum is associated with string, just return {other datum} 2 otherwise return 0. 2 :clearall([nodata_flag[, key_case_flag]]) 2 removes all associations from the database. 2 optional arguments change 2 the .no_data flag (0 is normal, 1 see below) and/or 2 the .key_case flag (0 is normal, 1 for case-sensitive keys) 2 2 Statistics Commands 2 ------------------- 2 count [entries|chars] in this 2 provide some vague statistics about how big this thing is. 2 2 Settable Properties 2 ------------------- 2 .failed ($failed_match) return value for :find(_key) 2 .ambiguous ($ambiguous_match) return value for :find(_key) 2 .node_info ({$generic_db.owner, ""}) info for creating new properties 2 2 Access 2 ------ 2 By default anyone may do lookups (:find*), while modifications (:insert/delete(2)/clearall) may only be done by the object owner or verbs located on the object itself. You may install your own versions of 2 2 :prohibit_lookup() 2 :prohibit_modify() 2 2 to change this. The :prohibit_* verbs are expected to return true iff the operation in question is not to be allowed. 2 2 As entries get made, properties will be created on the db object itself, each having info as specified by .node_info. By default the properties created are unreadable, but you can set .node_info to {$generic_db.owner, "r"} to have these properties be readable. Changing the ownership portion of .node_info or setting the c flag is not recommended. 2 2 key_case 2 -------------- 2 This property is normally 0 indicating that key matching is case-insensitive. If you want case-sensitive key matching, specify .key_case == 1. Note, however, that .key_case can only be changed by clearing all entries using :clearall. 2 2 no_data == 1 2 ------------- 2 One may also use $generic_db to store strings without associated data (i.e., only the presence or absence of the string has any significance). .no_data can only be changed by clearing all entries using :clearall. With .no_data == 1, :find is equivalent to :find_key, and both :find_all (with no accum_ verb specified) and :find_all_entries are equivalent to :find_all_keys. 2 2 last_modify 2 ------------ 2 This property is set to a fresh value every time a modification operation actually changes the contents of the db. This is intended for use in :accum_ and other verbs that might suspend, in order that it be possible to detect that the db has been modified out from under you. Note that once you've determined this, it's best to simply raise an error; resuming a :find_all operation after a modification can lead to unpredictable results. 2 2 Implementation Notes 2 -------------------- 2 The internal representation is as a `trie', a tree in which each internal node corresponds to a prefix shared by two or more strings in the db. 2 Each internal node is kept in a property named " "+, where is a prefix shared by all strings in the subtree under this node. 2 The property value is a 4 element list 2 2 this.(" "+)[1] = 2 maximal continuation shared by all strings beginning with prefix 2 i.e., all these names actually begin with + 2 2 this.(" "+)[2] = 2 string of all characters that can follow + for which 2 there is more than one string in the db beginning with ++ 2 2 this.(" "+)[3] = 2 list of all strings in this subtree for which 2 the character (or lack thereof) following the + substring 2 suffices to determine the string. Note that these strings are not 2 guaranteed to be in any particular order. 2 2 this.(" "+)[4] = 2 list of data corresponding to the strings in [3]. 2 2 Child nodes are this.(" "+++) 2 for all in this.(" "+)[2]. 2 The root node is this.(" "). 2 If, e.g., there are 2 or more strings in the db beginning with a, 2 there will be a node this.(" a"). 2 If all of these strings actually begin with "ani", then this.(" a")[1]=="ni". 2 The db consisting of the 5 correspondences 2 2 {"animal", #1} 2 {"anime", #2} 2 {"anil", #3} 2 {"anile", #4} 2 {"banal", #5} 2 2 would be represented 2 2 this.(" ") =={"", "a", {"banal"}, {#5}} 2 this.(" a") =={"ni","lm", {}, {}} 2 this.(" anim")=={"", "", {"animal","anime"},{#1,#2}} 2 this.(" anil")=={"", "", {"anil","anile"}, {#3,#4}} 2 2 In some cases one may merely wish to hold a collection of strings without trying to associate a particular datum with each string. One may then instead set up a db without the fourth field on each of the properties. In this case the datum is taken to be the found string itself and that is what gets returned by :find*() in the event of a successful search. :find and :find_key are then equivalent as are :find_all and :find_all_keys. To setup the db this way, do a :clearall(1). :clearall(0) reverts to the above described type of db with a separately kept datum. Note that you can't change the type without emptying the db. 35 5 4 197 2 The Generic Editor enables a player to edit a list of strings. While one might contrive to use it directly, it is rather intended as a parent for some actual editor. It supplies the following commands: 2 2 say w*hat 2 emote abort 2 lis*t [] [nonum] q*uit,done,pause 2 ins*ert [] ["] 2 n*ext,p*rev [n] ["] 2 del*ete [] 2 f*ind /[/[c][]] 2 s*ubst //[/[g][c][]] 2 m*ove,c*opy [] to 2 join*l [] 2 fill [] [@] 2 2 $editor_help.(cmdname) descrbes cmdname 2 $editor_help.insert descrbes insertion points () 2 $editor_help.ranges descrbes range specifications () 2 2 You'll notice that nowhere does it say how to load in a given list of strings or how and where one may save said list away when one is done editing. These commands are supplied by the child editor object. The generic editor contains only the code for editing lines, though it defines additional functions for use by its children: 2 2 :loaded(player) 2 returns the index (player in this.active) iff text has been loaded 2 from somewhere, otherwise returns 0. 2 2 Note that, by default, there is a difference between 2 2 having nothing loaded (:text(who)==0) and 2 having loaded something with no text (:text(who)=={}). 2 2 If you don't care about this distinction in a particular case, just do (player in this.active) instead of this:loaded(player). If you don't want your editor to make this distinction at all, do 2 2 @stateprop texts={} for 2 which changes the initial value of :text() to {} 2 2 In all functions below, 'who' is the index returned by :loaded(player) 2 2 BTW, be careful about using 'player' in non-user (i.e., +x this-none-this) verbs --- much better to have the user verb get the index with :loaded() and then pass that around. For your non-user verbs, we have 2 2 :ok(who) 2 returns E_PERM if the caller is not an editor verb and E_RANGE 2 if 'who' does not point to a valid session. 2 2 which should take care of the more egregious security holes (but maybe not the less egregious ones). 2 2 For getting and loading text, we have 2 2 :text(who) 2 the current text string list or 0 if nothing loaded yet. 2 :load(who,text) 2 loads the given list of strings as the text to be edited. 2 this also resets the 'changed' flag and pushes the insertion 2 point to the end. 2 2 and various flags and properties (all of the set_* routines return E_PERM when not called from an editor verb, E_RANGE if who is out of bounds, E_INVARG if something is wrong with the 2nd arg, or the new value, which may not necessarily be the same as the 2nd arg (e.g., set_insertion(..,37) on a 5 line text buffer returns 6). 2 2 :changed(who) 2 has the text been altered since the last save/load? 2 (the child editor gets to define what "save" means). 2 :set_changed(who,value) 2 Any child editor command that is considered to save the text should do a 2 :set_changed(who,0). 2 Note that if the changed flag is 0, the session will be flushed when 2 the player leaves the editor, so you may also want certain commands to 2 do set_changed(who,1)... 2 2 :origin(who) 2 room where the player came from. 2 :set_origin(who,room) 2 can be used to change the room the player will return to when finished 2 editing. Since origin gets set even in cases where the player teleports 2 into the editor you probably won't usually need to do this. 2 2 :insertion(who) 2 current insertion point. 2 :set_insertion(who,linenumber) 2 linenumber needs to be a positive integer and will get 2 2 :readable(who) 2 whether the current editing session has been made globally readable. 2 :set_readable(who,boolean) 2 change the readability of the current editing session. 2 This is used by the publish/perish verbs. 2 2 We also provide 2 2 :invoke(...) 2 If the player has a previous unsaved (i.e., :changed()!=0) 2 session, we return to it, moving the player to the editor. 2 If the player is already in the editor, this has no effect other 2 than to print a few nasty messages. In any case a :changed() 2 session must be aborted or set_changed(,0) before anything else 2 can be started 2 2 Otherwise, we pass the arguments (which are assumed to be the 2 result of some munging of the command line) to :parse_invoke(), 2 move the player to the editor and load whatever parse_invoke() 2 specified. The only interpretation the generic editor makes on 2 the arguments is that if the boolean value of the first is true, 2 this indicates that the player wanted to load something as 2 opposed to resume a previous session. Usually a command calling 2 :invoke will have a true (i.e., nonzero number, nonempty list or 2 string) first arg iff the command line is nonempty, in which case 2 'args' works fine for this purpose. 2 2 If the command parses sucessfully (:parse_invoke() returns a list), 2 we move the player to the editor if necessary and then call 2 :init_session() to set things up. 2 2 The child editor is assumed to provide 2 2 :parse_invoke(...) 2 given :invoke()'s arguments, determines what the player wants to edit. 2 It either returns 0 and reports syntax errors to player, 2 or it returns some list that :init_session() will understand. 2 2 :init_session(who,@spec) 2 where spec is something that was returned by :parse_invoke(). 2 Loads the text and sets the stateprops (below) to indicate that 2 we are working on whatever it is we're suppose to be working on. 2 2 :working_on(who) 2 returns a string X as in "You are working on X." 2 This is called by the 'w*hat' command, among other things. 2 2 Child editors may have their own properties giving state information for the various editing sessions. The value of each such property will be a list giving a value for each player in the editor. For each such property, you should, once the editor object has been created, do one of 2 2 @stateprop for 2 @stateprop = for 2 (0 is the default ) 2 2 Henceforth, adding and deleting new editing sessions will amend the list held by the given property. 2 2 The value of the property for a given session can be obtained via this.[player in this.active] and can be changed with a corresponding indexed property assignment. The usual idiom for an editor command is 2 2 if(!(who=this:loaded(player))) 2 player:tell(nothing_loaded_msg()); 2 else 2 ... various references to this.[who] ... 2 endif 2 2 To remove such a property from the list of such state properties: 2 2 @rmstateprop from 2 2 Note that you can only do this with properties defined on the child editor itself. Using @stateprop or @rmstateprop also has the effect of flushing any editing sessions in progress and booting anyone currently in the editor. 2 2 Incidentally, the @flush command may be used at any time to clean out the 2 editor or to remove all sessions older than a given date. 2 2 There are also numerous _msg properties that may be customized 2 2 @depart announced at the origin when :invoke() is called. 2 @return announced at the origin the player is returned there. 2 @nothing_loaded printed when user attempts editing 2 before anything has been loaded. 2 @no_text response to 'list' when :text()=={} 2 @no_change printed by 'what' when :changed()==0 2 @change printed by 'what' when :changed()==1 2 @no_littering printed upon leaving the editor with :changed()==1. 2 @previous_session printed by :invoke() when player tries to start a 2 new session without aborting or saving the old one 2 2 The general procedure for creating a child editor: 2 2 . @create #5400 named 2 2 . define additional verbs/properties 2 At the very least you need 'edit' and 'save' commands. 2 Usually you can get away with just having 'edit' call :invoke(); 2 Presumably, you'll need at least a command to load text from somewhere 2 as well as a command to save it back out. 2 2 . define a verb (somewhere) to invoke the editor 2 This could be just a one-liner that calls :invoke(args,verb). 2 Either that or 2 . you have to set up an exit somewhere whose destination is 2 . you have to advertise the object number so that people can 2 teleport to it. 2 2 . @stateprop x for 2 2 . if you want the 'abort' command to boot the player from the editor do 2 .exit_on_abort = 1; 2 2 . set .commands to be the list of additional commands defined 2 by . 2 Each element of the list is itself a list of the form {name,args}. 2 set .commands2 to be the list of commands that should appear 2 in the `look' listing, and should be a list of strings appearing 2 as names in .commands on either or some editor ancestor. 2 look at $verb_editor or $note_editor for an example. 2 2 . If you want to have help text for new verbs you define, create a child of 2 $generic_help and add properties to this object for each of the topics 2 that you want to provide help text. 2 Finally, set .help = {this object} so that the help system 2 knows to consult this object. 35 5 4 118 2 The Help System 2 1-------------- 2 2 When a player types help, the following list of objects is consulted for .help properties: the player itself, all ancestors of player up to and including $player, and, if the current location is a room, the current location together with all ancestors of the current location back to and including $room. Each help property should have as value either an object or a list of objects (otherwise we just ignore it). These objects are then strung together as a list of "help databases" to be searched in order for the requested topic. 2 2 A help database (in the sense of anything that is usable by $player:help()) is any object having the following verbs: 2 2 :find_topics([string]) 2 where string is a supposed help topic, returns a list of strings, 2 i.e., actual help topics that this db knows about, or some boolean 2 false value in the event that this db is clueless... 2 If no arguments are given, this should return a list of all topics 2 in the db. However, in the case that such a list can't (reasonably) 2 be constructed, it might just return {} or another subset of all 2 available topics. 2 2 :get_topic(string,dblist) 2 given one of the strings returned by :find_topics this either 2 returns a list of strings (text to be spewed to the player) or 2 returns 1 to indicate that it has already taken care of printing 2 information to the player. 2 The second argument is the list of all help dbs that are being 2 consulted. 2 2 :topic_text(string) 2 like get_topic, but instead returns the raw contents of a help topic 2 2 :set_topic_text(string, text) 2 sets the contents of a help topic 2 2 :dump_topic(string) 2 like topic_text, but instead returns a script that can be used to 2 upload the text. this is somewhat obsolete now, as it doesn't need 2 to be customized on any help databases but instead always uses 2 :set_topic-text. 2 2 :has_topic(string) 2 returns true if and only if this db has a topic matching that name 2 exactly 2 2 :add_topic(string) 2 returns true if the topic was added 2 2 :delete_topic(string) 2 likewise with deletion 2 2 If :find_topic reports that a particular db knows about a given topic it returns the full topic name, so that :get_topic may be called on it later. 2 2 The remaining verbs are used by maintainers (see $prog:@gethelp) to edit help topics. 2 2 $generic_help and $help 2 2---------------------- 2 2 The Generic Help Database, $generic_help, is the parent class of a particular kind of help database of which $help is an instance. On help databases of this type, every help topic has a corresponding property, interpreted as follows: 2 2 this.(topic) = string 2 one-line help text. 2 2 this.(topic) = {"**",@args} 2 call this:(args,dblist) to get text; dblist is the full list of 2 help objects that are being consulted (as passed in by :get_topic). 2 2 this.(topic) = other list of strings 2 multi-line help text--see `help help-format' for more information 2 2 For the {"**",...} form, the current verbs available are 2 2 {"*forward*", topic, @rest} 2 - get help text for topic and then append the lines of `rest'. 2 rest may, in turn, begin with a "**"... 2 2 {"*pass*", topic, @rest} 2 - get help text for topic from the first help database after this one 2 that actually has help text for topic, and then append lines of `rest'. 2 As with "*forward*" rest may, in turn, begin with a "**"... 2 2 {"*unpass*", topic, @rest} 2 - get help text for topic from the first help database 2 that actually has help text for topic, and then append lines of `rest'. 2 This is identical to *pass* except that we begin the search of help 2 dbs from the beginning of the list. Care should be exercised since 2 this can cause loops... 2 2 {"*subst*", @lines} 2 - All occurences of %[exp] in lines are replaced with the value of exp 2 which is assumed to evaluate to a string. 2 All lines beginning with %;exp are replaced with the value of exp 2 which is assumed to evaluate to a list of strings. 2 Evaluation is done using $no_one's permissions so exp in either case 2 can only refer to public information. 2 2 {"*index*", title} 2 - returns a list of all topics in this database, arranged in columns. 2 title is used as a heading for this index. 2 2 {"*objectdoc*", object} 2 - gets the documentation for the given object (i.e., object:help_msg()) 2 N.B. as with all other *verb* arguments, object must be a string. 2 2 {"*verbdoc*", objec 2 N.B. as with all other *verb* arguments, object must be a string. 2 2 {"*verbdoc*", object, verbname} 2 - gets the documentation for the named verb on the given object 2 (i.e., any strings at the beginnine documentation for the named verb on the given object 2 (i.e., any strings at the beginning of said verbcode) 2 2 Individual help dbs are free to define additional verbs that may be used in this context. $help itself defines the following additional such verbs: 2 2 {"*index_list*"} 2 - returns a list of all index topics in all databases in the search list. 2 An index topic is one whose actual text is {"*index*", something}. 2 When creating a help db, you should be sure to make an index topic. 2 2 {"*full_index*"} 2 - prints indices for all help databases in the search list. 2 2 It should be noted (once again) that help databases need not be children of $generic_help, so long as they have :find_topics/:get_topic/:dump_topic working as specified above. 35 5 4 65 2 Generic Option Package 2 ---------------------- 2 If one has a command or set of commands for which one wishes to provide several options/flags that a player can set to customize how the command behaves for him. Making each option a separate property is a bit expensive, especially when the option in question is merely be a boolean flag (possibly being set to false in most cases). This package provides an alternative, as well as providing a uniform set of commands for setting these flags/options and checking that the values given are of appropriate types. 2 2 Instead of needing several properties, only one is required to store a list containing values for all of the options. An "option package" (pkg, below) is then an object of this class, which provides routines for manipulating such lists. 2 2 The set of option names is divided into a set of "real" options, those whose names will actually appear in a given list, and "extras" which are either synonyms for or represent combinations of real options. 2 2 pkg:add_name(name) adds name to .names (remove it from .extras if there) 2 pkg:add_name(name,1) adds name to .extras (remove it from .names if there) 2 => 1 - ok, 0 - already added, E_INVARG - illegal name, E_PERM 2 2 pkg:remove_name(name) remove name from either .names or .extras 2 => 1 - ok, 0 - not present, E_PERM 2 2 For setting or retrieving values we have 2 2 pkg:get(options,name) 2 => value (or 0 if name isn't a real option) 2 pkg:set(options,name,value) 2 => revised options (or string error message if something goes wrong) 2 2 By default, a given option can only be a boolean flag, having one of the values 0 (absent from the list), or 1 (present in the list). :set translates 0/""/{} to 0 and any other non-object value to 1. 2 2 One may however designate a wider range of possible values for an option "foo" by either installing one of 2 2 pkg.type_foo 2 -- list of allowed types, 2 e.g., {NUM,STR} => must be a number or a string 2 e.g., {OBJ,{OBJ}} => must be an object or a list of objects 2 for anything fancier use: 2 2 pkg:check_foo(value) 2 => string error message or {value munged as desired} 2 2 In general, the only restriction on option values is that 0 is the only false value; setting an option to "" or {} sets it to 0. Every option defaults to 0, and no matter what you install as .type_foo or :check_foo(), 0 will always be a legal value for option "foo". 2 2 When presented with an option that is in .extras, :set will typecheck the value as described, however, then :actual(name, value) will be called to obtain a list of {name-of-real-option, value} pairs indicating which combination of real options should be set. 2 2 Other verbs 2 pkg:parse(args,...) 2 parses the command line arguments of a @whatever_option command 2 => {optionname, value} if the player wants to set an option 2 => {optionname} if the player wants to view an option 2 => string error message otherwise 2 2 one may install pkg:parse_foo to parse arguments for option "foo" 2 !foo => {"foo",0} (:parse_foo not called) 2 foo= => {"foo",0} (:parse_foo not called) 2 -foo => {"foo",0} (:parse_foo not called) 2 +foo => pkg:parse_foo("foo",1) 2 foo=word => pkg:parse_foo("foo","word") 2 foo word1 word2 => pkg:parse_foo("foo",{"word1","word2"}) 2 foo is word1 word2 => pkg:parse_foo("foo",{"word1","word2"}) 2 2 If you install a .type_foo or a :check_foo verb, 2 you need to also provide :parse_foo. 2 2 pkg:show(options,name|list of names) 2 => list of strings describing the current value of the named option(s). 2 calls pkg:show_foo(options,list of names) or 2 refers to pkg.show_foo 2 to describe option "foo" 2 2 (see sources for details... at some point I'll finish writing this...) 35 5 4 25 2 Message Sequences 2 1---------------- 2 2 A "message sequence" is a handle by which one may refer to a particular subset of a mail recipient's (player or $mail_recipient-descendant) saved messages. Routines like rcpt:display_seq_headers or rcpt:display_seq_full need to be supplied with message-sequence arguments to deterimine which headers or full-messages to display. 2 2 Message sequences can in turn be obtained from routines like rcpt:parse_message_seq, which takes a command-line description of a message sequence on that particular recipient and returns the corresponding message sequence handle. 2 2 The actual form of a message sequence (though you shouldn't actually need to make use of this) is that of a set of integers in the format used by $seq_utils (see `help $seq_utils'). It should however be noted that these integers are *not* themselves message numbers, but rather indices into the list of saved messages. For example, if a particular recipient holds 5 messages numbered 1,3,5,7,9. Then the message sequence handle representing messages 3,5,7 collectively, would be {2,5} which is $seq_utils-ese for the range 2..4, namely the second, third and fourth messages saved on that recipient. 2 2 The following verbs are available for obtaining indices to use in message sequences 2 2 :length_all_msgs() => total number of messages, or equivalently, 2 => index of last message 2 :length_num_le(n) => number of messages numbered <= n, or equivalently, 2 => index of highest numbered message <= n 2 :exists_num_eq(n) => 0 unless there exists a message numbered n in which 2 case we return the index of that message. 2 :length_date_le(date) => number of messages dated <= date, or equivalently, 2 => index of most recent message dated <= date 2 2 :length_date_gt(date) => number of messages dated > date 2 2 Note that r:length_date_gt(date) == r:length_all_msgs()-r:length_date_le(date). 2 The only reason :length_date_gt is provided as a separate routine is in order 2 to do quick checks for the existence of new mail (as @rn needs to do). 35 5 4 26 2 Read verbs 2 1--------- 2 2 The following verbs may be used to extract headers/messages from readable mail recipients/players; 2 2 :display_seq_headers (message sequence, current message number, last_read_date) 2 2 Does a @mail listing of the given message sequence. If current message number is given and the sequence includes it, we mark it with a `>'. Likewise if the sequence includes any new messages (i.e., dated after last_read_date), these are also indicated as such. 2 2 display_seq_full (message sequence, preamble) 2 2 Does a @read listing of the given message sequence. Each message is preceded by preamble. 2 2 => {new current message number, new last_read_date} 2 2 :messages_in_seq (index) 2 => {n, msg} 2 2 :messages_in_seq (message sequence) 2 => {{n_1,msg_1},{n_2,msg_2},...} 2 2 where the n_i are message numbers and the msg_i are messages in transmission format (see `help mail-format') 2 2 :list_rmm () 2 2 Does an `@unrmm list' listing of messages in .messages_going 35 5 4 18 2 Write verbs 2 1---------- 2 2 The following verbs can be used to manipulate writable mail recipients/players: 2 2 :rm_message_seq (message sequence) 2 Does an @rmmail. Messages in message sequence are removed from this 2 recipient's saved .messages and written to .messages_going. 2 2 :undo_rmm () 2 Does an @unrmm. Messages in .messages_going are copied back to .messages. 2 2 :expunge_rmm () 2 Does an @unrmm expunge. Blows away .messages_going. 2 2 :renumber () 2 Does a @renumber. 2 35 5 4 26 2 Search verbs 2 1----------- 2 2 The following verbs can be used on a readable mail-recipient/player to search for messages with fields matching a given pattern. 2 2 from_msg_seq (objectid or list [,mask]) 2 => message sequence: messages from (one of) the given objectid(s) 2 2 %from_msg_seq (string or list [,mask]) 2 => message sequence: messages with (one of) the given string(s) 2 in the From: line 2 2 to_msg_seq (objectid or list [,mask]) 2 => message sequence: messages to (one of) the given objectid(s) 2 2 %to_msg_seq (string or list [,mask]) 2 => message sequence: messages with (one of) the given string(s) 2 in the To: line 2 2 subject_msg_seq (string [,mask]) 2 => message sequence: messages with given string occurring in Subject: 2 2 body_msg_seq (string [,mask]) 2 => message sequence: messages with given string occurring in body of message 2 2 In all cases `mask' is a message sequence which one may supply to limit the range of the search. One way of looking at it is that the message sequence to be returned is first intersected with mask. 35 5 4 13 2 An object for storing verbs and properties dealing with the english language. 2 2 Properties: 2 2 vowels {"a", "e", "i", "o", "u"} 2 2 [non]vowel_exceptions A list of prefixes which start with vowels [consonants] but don't take 'an' ['a'] as indefinite articles. 2 2 Verbs: 2 2 @add-[non]vowel-exc*eption to #116 2 Add an exception to the 'an' before vowel ['a' before consonant] rule. 2 Sends mail to *English if the player is not a wizard. 35 5 4 43 2 The housekeeper is an object that can help keep other objects where they belong. New MOOs may want to add their own user interface for the housekeeper; here is some information that may be helpful. 2 2 To indicate what objects should be cleaned: 2 2 :add_cleanup(object[, requestor[, where]]) 2 Ask the housekeeper to clean 'object' for 'requestor' to 'where'. 2 Requestor defaults to 'player'. 2 Where defaults to object.location. 2 2 :remove_cleanup(what[, requestor]) 2 Remove 'what' from the cleanup list at 'requestor's request. 2 Will remove it only if 'requestor' made the original request and owns 2 the object or the destination. 2 2 To actually get the housekeeper to clean stuff up: 2 2 :cleanup([insist]) 2 Clean up player's objects. Argument is 'up' or 'up!' for manually 2 requested cleanups. 'up!' means to clean things even if it's against 2 the housekeeper's better judgement. 2 2 :replace(object[, insist]) 2 Clean up the indicated object. 'insist' is as in :cleanup. 2 2 :continuous() 2 Starts the housekeeper cleaning continuously, killing any previous 2 continuous task. This should be called only when starting up a new MOO, 2 or if something has gone wrong, as normally it will just keep going 2 without any help. 2 2 :litterbug() 2 Clean up all the places in housekeeper.public_places by getting rid of 2 all contents not in their .residents lists. This is called by 2 :continuous, so it doesn't need to be called directly. 2 2 To find out what's being cleaned to where for whom: 2 2 :cleanup_list([whom]) 2 Show 'player' the personal cleanup list for 'whom', or the housekeeper's 2 complete list if no argument is given. 2 2 :clean_status() 2 Show 'player' a brief summary of eir personal cleanup list. 35 1 4 2 2 *forward* 2 $mail_recipient 35 5 4 0 35 1 5 35 1 0 0 35 4 4 1 2 Core Utility Help 35 5 2 Help database for LambdaCore utility objects and generics. 35 5 5 35 1 5 35 5 5 35 5 5 35 5 5 35 5 5 35 5 5 35 1 5 35 1 5 35 1 1 -1 184 1 4 2 0 82478 0 1030435200 185 1 #22 Programmer Help 16 35 -1 -1 -1 197 -1 23 3 errors 35 173 -1 prepositions 35 173 -1 nominate_for_core 35 173 -1 81 @check-property @check-chparent @egrep regular-expressions @show @grep prog-index help prepositions ; utilities truth tasks statements programming precedence language functions expressions eval errors @verb @setenv @rmverb @rmproperty @prospectus @property @program @list @kill @kids @forked @display @dbsize @copy @chparent @chmod @args .program @clearproperty @disown @disinherit @displayoptions @display-options @add-feature @remove-feature features examine integration events valid() @prop @addfeature @d mpl listen() unlisten() integrate exam (aliases_extra) aliases # named-args named-arguments named @eval-options fork() return while() for @copy-x @list# @program# @rmverb# @args# @rename# @addalias# @rmalias# @list-options @listoptions regexps 97 4 2 2 *forward* 2 @check-chparent 35 5 4 10 2 Syntax: @check-property . 2 @check-chparent to 2 2 You cannot add a new property to an object if an ancestor or a descendant already defines a property with the same name. @check-property will give you the list of all descendants of that that define .. 2 2 Likewise you cannot chparent an object to a new parent if the new parent has a property that is also defined on the object or some descendant. Use @check-chparent to find out all instances of conflicting properties that would interfere with @chparent in this manner. 2 2 Note that @check-property requires either that you own the object or that it be writeable, the same conditions that need to hold if you are to create new properties on the object. Similarly, @check-chparent requires that you own the object and that the new parent is either readable or likewise owned by you. 2 2 For objects with large numbers of descendants, these commands can be time-consuming. 35 5 4 2 2 *forward* 2 @grep 35 5 4 162 2 Regular expression matching allows you to test whether a string fits into a specific syntactic shape. You can also search a string for a substring that fits a pattern. 2 2 A regular expression describes a set of strings. The simplest case is one that describes a particular string; for example, the string `foo' when regarded as a regular expression matches `foo' and nothing else. Nontrivial regular expressions use certain special constructs so that they can match more than one string. For example, the regular expression `foo%|bar' matches either the string `foo' or the string `bar'; the regular expression `c[ad]*r' matches any of the strings `cr', `car', `cdr', `caar', `cadddar' and all other such strings with any number of `a''s and `d''s. 2 2 Regular expressions have a syntax in which a few characters are special constructs and the rest are "ordinary". An ordinary character is a simple regular expression that matches that character and nothing else. The special characters are `$', `^', `.', `*', `+', `?', `[', `]' and `%'. Any other character appearing in a regular expression is ordinary, unless a `%' precedes it. 2 2 For example, `f' is not a special character, so it is ordinary, and therefore `f' is a regular expression that matches the string `f' and no other string. (It does *not*, for example, match the string `ff'.) Likewise, `o' is a regular expression that matches only `o'. 2 2 Any two regular expressions A and B can be concatenated. The result is a regular expression which matches a string if A matches some amount of the beginning of that string and B matches the rest of the string. 2 2 As a simple example, we can concatenate the regular expressions `f' and `o' to get the regular expression `fo', which matches only the string `fo'. Still trivial. 2 2 The following are the characters and character sequences that have special meaning within regular expressions. Any character not mentioned here is not special; it stands for exactly itself for the purposes of searching and matching. 2 2 `.' is a special character that matches any single character. Using 2 concatenation, we can make regular expressions like `a.b', which matches 2 any three-character string that begins with `a' and ends with `b'. 2 2 `*' is not a construct by itself; it is a suffix that means that the preceding 2 regular expression is to be repeated as many times as possible. In `fo*', 2 the `*' applies to the `o', so `fo*' matches `f' followed by any number of 2 `o''s. 2 2 The case of zero `o''s is allowed: `fo*' does match `f'. 2 2 `*' always applies to the *smallest* possible preceding expression. Thus, 2 `fo*' has a repeating `o', not a repeating `fo'. 2 2 The matcher processes a `*' construct by matching, immediately, as many 2 repetitions as can be found. Then it continues with the rest of the 2 pattern. If that fails, it backtracks, discarding some of the matches of 2 the `*''d construct in case that makes it possible to match the rest of 2 the pattern. For example, matching `c[ad]*ar' against the string 2 `caddaar', the `[ad]*' first matches `addaa', but this does not allow the 2 next `a' in the pattern to match. So the last of the matches of `[ad]' is 2 undone and the following `a' is tried again. Now it succeeds. 2 2 `+' is like `*' except that at least one match for the preceding pattern is 2 required for `+'. Thus, `c[ad]+r' does not match `cr' but does match 2 anything else that `c[ad]*r' would match. 2 2 `?' is like `*' except that it allows either zero or one match for the 2 preceding pattern. Thus, `c[ad]?r' matches `cr' or `car' or `cdr', and 2 nothing else. 2 2 `[ ... ]' 2 `[' begins a "character set", which is terminated by a `]'. In the 2 simplest case, the characters between the two brackets form the set. 2 Thus, `[ad]' matches either `a' or `d', and `[ad]*' matches any string of 2 `a''s and `d''s (including the empty string), from which it follows that 2 `c[ad]*r' matches `car', etc. 2 2 Character ranges can also be included in a character set, by writing two 2 characters with a `-' between them. Thus, `[a-z]' matches any lower-case 2 letter. Ranges may be intermixed freely with individual characters, as in 2 `[a-z$%.]', which matches any lower case letter or `$', `%' or period. 2 2 Note that the usual special characters are not special any more inside a 2 character set. A completely different set of special characters exists 2 inside character sets: `]', `-' and `^'. 2 2 To include a `]' in a character set, you must make it the first character. 2 For example, `[]a]' matches `]' or `a'. To include a `-', you must use it 2 in a context where it cannot possibly indicate a range: that is, as the 2 first character, or immediately after a range. 2 2 `[^ ... ]' 2 `[^' begins a "complement character set", which matches any character 2 except the ones specified. Thus, `[^a-z0-9A-Z]' matches all characters 2 *except* letters and digits. 2 2 `^' is not special in a character set unless it is the first character. 2 The character following the `^' is treated as if it were first (it may be 2 a `-' or a `]'). 2 2 `^' is a special character that matches the empty string -- but only if at the 2 beginning of the string being matched. Otherwise it fails to match 2 anything. Thus, `^foo' matches a `foo' which occurs at the beginning of 2 the string. 2 2 `$' is similar to `^' but matches only at the *end* of the string. Thus, 2 `xx*$' matches a string of one or more `x''s at the end of the string. 2 2 `%' has two functions: it quotes the above special characters (including `%'), 2 and it introduces additional special constructs. 2 2 Because `%' quotes special characters, `%$' is a regular expression that 2 matches only `$', and `%[' is a regular expression that matches only `[', 2 and so on. 2 2 For the most part, `%' followed by any character matches only that 2 character. However, there are several exceptions: characters that, when 2 preceded by `%', are special constructs. Such characters are always 2 ordinary when encountered on their own. 2 2 No new special characters will ever be defined. All extensions to the 2 regular expression syntax are made by defining new two-character 2 constructs that begin with `%'. 2 2 `%|' specifies an alternative. Two regular expressions A and B with `%|' in 2 between form an expression that matches anything that either A or B will 2 match. 2 2 Thus, `foo%|bar' matches either `foo' or `bar' but no other string. 2 2 `%|' applies to the largest possible surrounding expressions. Only a 2 surrounding `%( ... %)' grouping can limit the grouping power of `%|'. 2 2 Full backtracking capability exists for when multiple `%|''s are used. 2 2 `%( ... %)' 2 is a grouping construct that serves three purposes: 2 2 1. To enclose a set of `%|' alternatives for other operations. Thus, 2 `%(foo%|bar%)x' matches either `foox' or `barx'. 2 2 2. To enclose a complicated expression for a following `*', `+', or `?' 2 to operate on. Thus, `ba%(na%)*' matches `bananana', etc., with any 2 number of `na''s, including none. 2 2 3. To mark a matched substring for future reference. 2 2 This last application is not a consequence of the idea of a parenthetical 2 grouping; it is a separate feature that happens to be assigned as a second 2 meaning to the same `%( ... %)' construct because there is no conflict in 2 practice between the two meanings. Here is an explanation of this 2 feature: 2 2 `%DIGIT' 2 After the end of a `%( ... %)' construct, the matcher remembers the 2 beginning and end of the text matched by that construct. Then, later on 2 in the regular expression, you can use `%' followed by DIGIT to mean 2 "match the same text matched by the DIGIT'th `%( ... %)' construct in the 2 pattern." The `%( ... %)' constructs are numbered in the order that their 2 `%(''s appear in the pattern. 2 2 The strings matching the first nine `%( ... %)' constructs appearing in a 2 regular expression are assigned numbers 1 through 9 in order of their 2 beginnings. `%1' through `%9' may be used to refer to the text matched by 2 the corresponding `%( ... %)' construct. 2 2 For example, `%(.*%)%1' matches any string that is composed of two 2 identical halves. The `%(.*%)' matches the first half, which may be 2 anything, but the `%1' that follows must match the same exact text. 2 2 `%b' matches the empty string, but only if it is at the beginning or end of a 2 word. Thus, `%bfoo%b' matches any occurrence of `foo' as a separate word. 2 `%bball%(s%|%)%b' matches `ball' or `balls' as a separate word. 2 2 For the purposes of this construct and the five that follow, a word is 2 defined to be a sequence of letters and/or digits. 2 2 `%B' matches the empty string, provided it is *not* at the beginning or end of 2 a word. 2 2 `%<' matches the empty string, but only if it is at the beginning of a word. 2 2 `%>' matches the empty string, but only if it is at the end of a word. 2 2 `%w' matches any word-constituent character (i.e., any letter or digit). 2 2 `%W' matches any character that is not a word constituent. 35 5 4 7 2 Syntax: @show 2 @show . 2 @show : 2 2 Displays quite detailed information about an object, property or verb, including its name, owner, permission bits, etc. The information displayed for an object can be quite long. 2 2 See also @display, which displays different information and is controlled differently. 35 5 4 11 2 Syntax: @grep in 2 @grep in {} 2 2 @egrep in 2 @egrep in {} 2 2 These are named for the corresponding unix utilities. 2 2 @grep searches the given object(s) for verbs whose verbcode contains the given string as a substring of one of its lines. 2 2 @egrep searches the given object(s) for verbs whose verbcode contains a substring matching the given regular expression (see `help regular-expressions'). 35 5 4 2 2 *index* 2 Programmer Help Topics 35 5 4 14 2 *pass* 2 help 2 For programmers, the help system provides the following additional forms: 2 2 help object:verbname -- prints any documentation strings that are present 2 at the beginning of the program for that verb. 2 help $_utils -- prints general information about one of the 2 $..._utils objects (e.g., $string_utils, 2 $list_utils, etc...), which are all libraries 2 of generally used verbs. 2 help builtin() -- prints documentation from the programmers manual 2 about the named primitive, for example length() 2 2 For information about how the help system itself works and about how to associate local help databases with specific rooms or player classes, see `help $help'. 35 5 4 3 2 *prepositions* 2 The complete list of prepositions recognized by the command-line parser: 2 35 5 4 2 2 *forward* 2 eval 35 1 4 17 2 The core database has a number of objects serving as libraries of useful verbs. 2 More detailed information can be obtained for (some of) these, via `help $whatever_utils' 2 2 $building_utils -- 2 $code_utils -- parsing and manipulating verb code 2 $command_utils -- reporting matching errors to the player 2 $gender_utils -- managing gendered objects 2 $list_utils -- list manipulation 2 $set_utils -- set manipulation 2 $lock_utils -- key expression manipulation 2 $match_utils -- 2 $object_utils -- object information 2 (inheritance/location hierarchy, verb/property lists) 2 $perm_utils -- permissions 2 $string_utils -- string manipulation 2 $time_utils -- time (numeric and verbal) manipulation 2 $trig_utils -- trigonometric and other numerical utilities 35 5 4 5 2 Several kinds of statements, expressions, and functions in the MOO programming language use a notion that some MOO values are 'true' and others 'false'. 2 2 The only values that are considered true are non-zero numbers, non-empty strings, and non-empty lists. 2 2 All other values (i.e., 0, "", {}, objects, and errors) are considered false. 35 1 4 18 2 A task is an execution of a MOO program. There are five ways for tasks to be created in LambdaMOO: 2 2 o Every time a player types a command, a task is created to execute that command; we call these 'command tasks'. 2 o Whenever a player connects or disconnects from the MOO, the server starts a task to do whatever processing is necessary, such as printing out 'Munchkin has connected' to all of the players in the same room; these are called 'server tasks'. 2 o The FORK statement in the programming language creates a task whose execution is delayed for at least some given number of seconds; these are 'forked tasks'. 2 o The suspend() function suspends the execution of the current task. A snapshot is taken of whole state of the execution, and the execution will be resumed later. These are called `suspended tasks'. 2 o The read() function also suspends the execution of the current task, in this case waiting for the player to type a line of input. When the line is received, the task resumes with the read() function returning the input line as result. These are called `reading tasks'. 2 2 The last three kinds of tasks above are collectively known as `queued tasks' or `waiting tasks', since they may not run immediately. 2 2 To prevent a maliciously- or incorrectly-written MOO program from running forever and monopolizing the server, limits are placed on the running time of every task. One limit is that no task is allowed to run longer than 15 seconds; this limit is, in practice, never reached. The reason is that there is a second limit on the number of operations a task may execute. 2 2 The server counts down 'ticks' as any task executes. Roughly speaking, it counts one tick for every expression evaluation (other than variables and literals), one for every `if', `fork' or `return' statement, and one for every iteration of a loop. If the count gets all the way down to zero, the task is immediately and unceremoniously aborted. All tasks begin or resume with an store of 30,000 ticks; this is enough for almost all normal uses. 2 2 Because queued tasks may exist for long periods of time before they begin execution, there are commands to list the ones that you own and to kill them before they execute. These commands are covered in the following help topics: 2 2 @forked -- listing the forked tasks that you own 2 @kill -- killing a particular forked task 35 1 4 68 2 The following kinds of statements exist in the MOO programming language: 2 2 Null 2 ==== 2 2 ; 2 2 The null statement does nothing. 2 2 Expressions 2 =========== 2 2 expression ; 2 2 The expression statement evaluates the expression and then discards the value. 2 2 Conditional 2 =========== 2 2 IF ( expression ) statements ENDIF 2 IF ( expression ) statements ELSE statements ENDIF 2 IF ( expression ) 2 statements 2 ELSEIF ( expression ) 2 statements 2 ... 2 ELSE 2 statements 2 ENDIF 2 2 The conditional statement evaluates each expression in turn and executes the statements associated with the first one to return a true value; the ELSE statements are executed if none of the expressions returns a true value. There can be any number of ELSEIF clauses and the ELSE part is optional. See 'help truth' for the definition of 'true value'. 2 2 List iteration 2 ============== 2 2 FOR name IN ( expression ) statements ENDFOR 2 2 The list iteration statement first evaluates the expression, which must return a list. It then executes the statements once for each element of that list, each time with the named variable having the value of the corresponding list element. 2 2 Numeric iteration 2 ================= 2 2 FOR name IN [ expression .. expression ] statements ENDFOR 2 2 The numeric iteration statement first evaluates the two expressions, both of which must return numbers; call those numbers N1 and N2, respectively. The statements are then executed once for each integer I such that N1 <= I <= N2, in increasing order; each time, the named variable has the corresponding value of I. 2 2 Indefinite iteration 2 ==================== 2 2 WHILE ( expression ) statements ENDWHILE 2 2 The indefinite iteration statement repeatedly evaluates the expression and, each time it returns a true value, executes the statements. The loop stops the first time that the expression returns a false value. The definitions of 'true' and 'false' values is in 'help truth'. 2 2 Return 2 ====== 2 2 RETURN ; 2 RETURN expression ; 2 2 The return statement evalautes the expression, if any, and returns the resulting value (or 0 if there is no expression) to the verb that called the current one. Execution of the current verb is immediately terminated. 2 2 Fork 2 ==== 2 2 FORK ( expression ) statements ENDFORK 2 FORK name ( expression ) statements ENDFORK 2 2 The fork statement first executes the expression, which must return a number; call that number N. It then creates a new MOO task that will, after at least N seconds, execute the statements. When the new task begins, all variables will have the values they had at the time the FORK statement was executed. The task executing the FORK statement immediately continues execution. If a variable name is given after the FORK keyword, then it is assigned the 'queue ID' of the newly-created task. The value of this variable is visible both to the task executing the fork statement and to the statements in the newly-created task. See 'help tasks' for more information about forked tasks. 35 1 4 29 2 MOO contains a rich programming language for the creation of interesting rooms, exits, and other objects. Help is available on the following topics concerning programming in MOO: 2 2 language -- a brief reference for the syntax and semantics of the MOO language 2 tasks -- a brief description of MOO tasks and their resource limits 2 2 @property -- adding a property to an object 2 @rmproperty -- removing a property from an object 2 2 @verb -- adding a verb to an object 2 @rmverb -- removing a verb from an object 2 @args -- changing the syntax of a verb 2 @copy -- copying a verb from one object to another 2 2 @program -- entering the program for a verb 2 @list -- printing a listing of the program for a verb 2 @edit -- editing verb code 2 eval -- executing MOO statements and expressions without writing a verb 2 2 @show -- looking at all the details of an object, a property, or a verb 2 @display -- a different way to look at those details 2 2 @parents -- listing the ancestors of an object 2 @kids -- listing the children of an object 2 @chparent -- changing the parent of an object 2 2 @contents -- listing the contents of an object 2 @chmod -- changing the permissions on an object, a property, or a verb 2 @rename -- changing the name of a verb or object 2 @currentobject -- specify an object to work with 35 1 4 17 2 The table below gives the relative precedence of all of the MOO operators; operators on higher lines in the table have higher precedence and those on the same line have identical precedence: 2 2 ! - (without a left operand) 2 * / % 2 +- 2 == != < <= > >= in 2 && || 2 ... ? ... | ... (the conditional expression) 2 = 2 2 Thus, the horrendous expression 2 2 x = a < b && c > d + e * f ? w in y | - q - r 2 2 would be grouped as follows: 2 2 x = (((a < b) && (c > (d + (e * f)))) ? (w in y) | ((- q) - r)) 35 1 4 5 2 The MOO programming language is described in excruciating detail in the LambdaMOO Programmer's Manual, available for FTP from parcftp.xerox.com in the file pub/MOO/ProgrammersManual.txt. The online help consists of a few quick reference guides here in the help system under the following topics: 2 2 statements -- the syntax and semantics of the various kinds of MOO statements 2 expressions -- the same for the various kinds of MOO expressions 2 functions -- a list of the primitive functions available to MOO programs 35 1 4 141 2 There are many, many built-in functions available to MOO programmers. The following list gives a brief summary of the arguments and purpose of each function; for more information, see the LambdaMOO Programmer's Manual. 2 2 pass(arg, ...) -- call same verb defined on this object's parent 2 raise(code[, msg[, value]]) -- raise code as an error 2 2 typeof(value) -- determine the data type of value 2 tostr(value, ...) -- concatenate values into a string 2 tonum(value) -- convert non-list value into a integer 2 toint(value) == tonum(value) 2 tofloat(value) -- convert non-list value into a float 2 toobj(value) -- convert non-list value into an object 2 floatstr(float, precision, scientific?) 2 -- convert float value to string 2 encode_binary(value, ...) -- values to binary string 2 decode_binary(bstring[, full]) -- binary string to list of values 2 2 binary_hash(bstring) -- MD5 hash value of binary string 2 string_hash(string) -- MD5 hash value of string 2 value_hash(value) == string_hash(toliteral(value)) 2 2 value_bytes(value) --- number of bytes required to store value 2 object_bytes(object) --- number of bytes required to store object 2 2 eval(string) -- parse and execute string as MOO code 2 toliteral(value) -- convert value to a string that evaluates to it 2 call_function(func[, arg, ...]) == func([arg, ...]) 2 2 function_info([func]) -- builtin function desc (or list of all of them) 2 2 length(list/string) -- returns the length of a string or list 2 listappend(list, value [, index]) -- adding an element at the end of a list 2 listinsert(list, value [, index]) -- adding an element at the head of a list 2 listset(list, value, index) -- updating a list at some index 2 listdelete(list, index) -- removing an element from a list 2 setadd(list, element) -- adding an element to a set represented as a list 2 setremove(list, element) -- removing an element from such a set 2 is_member(element, list) -- case-sensitive version of (element IN list) 2 equal(v1,v2) -- case-sensitive version of (v1 == v2) 2 2 min(n1, n2, ...) -- minimum of n1,n2,... 2 max(n1, n2, ...) -- maximum of n1,n2,... 2 random(n) -- random integer between 1 and n inclusive 2 time() -- current time in seconds since midnight GMT, 1 Jan 70 2 ctime([time]) -- time (or current time) converted to a human-readable string 2 2 abs(n) -- absolute value of n 2 floor(x) -- truncate x towards minus infinity 2 trunc(x) -- truncate x towards zero 2 ceil(x) -- truncate x towards plus infinity 2 sqrt(n) -- square root of n 2 exp(x) -- e to the x 2 log(x) -- natural log 2 log10(x) -- base 10 log 2 sin(a), cos(a), tan(a) -- circular trignometric functions 2 asin(y), acos(x), atan(x[,y]) -- inverse circular trignometric functions 2 sinh(a), cosh(a), tanh(a) -- hyperbolic trigonometric functions 2 2 index(str1, str2 [, case-matters]) -- index of first str2 in str1 2 rindex(str1, str2 [, case-matters]) -- index of last str2 in str1 2 strcmp(str1, str2) -- case-sensitive string comparison 2 strsub(subject, what, with [, case-matters]) -- substitution in a string 2 crypt(string [, salt]) -- one-way string encryption 2 match(str1, str2 [, case-matters]) -- match first pattern str2 in str1 2 rmatch(str1, str2 [, case-matters]) -- match last pattern str2 in str1 2 substitute(template, subs) -- perform substitutions on template 2 2 valid(object) -- testing whether an object exists 2 create(parent [, owner(*)])-- creating a new MOO object 2 recycle(object) -- destroying a MOO object 2 move(object, where) -- altering the object-containment hierarchy 2 chparent(object, new-parent) -- altering the object-inheritance hierarchy 2 parent(object) -- object's parent in the inheritance hierarchy 2 children(object) -- object's children in the inheritance hierarchy 2 max_object() -- the highest-numbered object in the MOO 2 renumber(obj) -- changes an object's number to lowest available one (*) 2 reset_max_object() -- resets max_object() to the largest valid object (*) 2 2 properties(object) -- a list of the properties defined on an object 2 add_property(object, prop-name, value, info) -- add a new property 2 delete_property(object, prop-name) -- remove a property 2 property_info(object, prop-name) -- {owner, perms} info on a property 2 set_property_info(object, prop-name, info) -- setting same 2 is_clear_property(object, prop-name) -- find out if a property is "clear" 2 clear_property(object, prop-name) -- make a property "clear" 2 2 verbs(object) -- a list of the verbs defined on an object 2 add_verb(object, info, args) -- add a verb to an object 2 delete_verb(object, verb-name) -- remove a verb from an object 2 verb_info(object, verb-name) -- {owner, perms, names} info for a verb defn. 2 verb_args(object, verb-name) -- {dobj, prep, iobj} argument info for a verb 2 verb_code(object, verb-name [, fully-paren [, indent]]) -- program listing 2 set_verb_info(object, verb-name, {owner, perms, names}) 2 set_verb_args(object, verb-name, {dobj, prep, iobj}) 2 set_verb_code(object, verb-name, {line, line, ...}) 2 disassemble(object, verb-name) -- moo bytecode for verb 2 2 notify(conn, string[, noflush]) -- output string to connection 2 read([conn]) -- read input line from connection (*) 2 flush_input(conn[, showmsg?]) -- flush pending input on connection (*) 2 force_input(conn, line[, at-front?]) -- insert line as pending input (*) 2 2 is_player(object) -- testing whether or not object is a player 2 players() -- a list of all players, active or not 2 connected_players() -- a list of all currently-connected players 2 idle_seconds(player) -- seconds since given player typed anything 2 connected_seconds(player) -- seconds given player has been logged in 2 boot_player(player) -- disconnect player from the MOO immediately(*) 2 set_player_flag(player, value) -- set/clear player bit; boot player if clear(*) 2 connection_name(player) -- a server-assigned name for player's connection 2 open_network_connection(@args) -- open a connection to another network site 2 connection_option(conn,option) -- setting of option for connection 2 connection_options(conn) -- list of {option, value} 2 set_connection_option(conn,option,value) -- change setting of option 2 output_delimiters(player) -- {prefix,suffix} set by PREFIX/SUFFIX cmds 2 buffered_output_length([conn]) -- number of bytes currently buffered on output 2 2 caller_perms() -- the player whose permissions your caller was using 2 set_task_perms(player) -- changing permissions of the running task (*) 2 callers([lineno?]) -- stack: list of {obj, verb, owner, vloc, player[,line]} 2 task_stack(taskid[,lineno?]) -- callers() stack for suspended task 2 2 seconds_left() -- number of seconds left in the current task 2 ticks_left() -- number of ticks left in the current task 2 task_id() -- id number for the currently-running task 2 suspend(secs) -- suspend current task for a number of seconds 2 resume(taskid[,value]) -- resume the specified task 2 kill_task(taskid) -- delete one of your tasks from the queue 2 queued_tasks() -- list of {taskid,start,,,owner,obj,verb,line,this} 2 queue_info([player]) -- number of tasks for player or list of tasking players 2 2 server_version() -- a string of three numbers "major.minor.release" 2 server_log(string) -- add a comment to the server log file (*) 2 listen(obj, point[, msgs?]) -- start listening, return canonicalized point (*) 2 unlisten(canonpoint) -- stop listening at canonpoint (*) 2 listeners() -- list of {object, canonpoint, msgs?} listening points (*) 2 shutdown(msg) -- print msg and kill the server (*) 2 dump_database() -- what it says (*) 2 db_disk_size() -- size in bytes of database disk file 2 memory_usage() -- {{blocksize, nused, nfree}, ...}, the server's memory stats 2 2 (*) => as you might have expected, these usually require wizard permissions. 35 1 4 120 2 The following kinds of expressions exist in the MOO programming language: 2 2 Literals 2 ======== 2 2 number 2 # number 2 # - number 2 "character string" 2 error-name 2 2 Literal expressions return the obvious values: numbers, object numbers, strings, and errors. 2 2 List construction 2 ================= 2 2 { expression , expression , ... , expression } 2 2 The list-construction expression evaluates the each of the expressions in turn and returns a list whose elements are the results of those expressions. Any of the expressions may be prefixed with an at-sign ('@'); in this case, that expression must return a list and, rather than that list becoming an element of the final list, its elements are spliced into the final list. 2 2 Variables 2 ========= 2 2 name 2 2 Variable expressions return the current value of the named variable. Variable names must start with a letter or underscore ('_') and contain only letters, digits, and underscores. The following variables are predefined: 2 2 OBJ, STR, LIST, ERR, NUM 2 player, caller, this, verb, args 2 argstr, dobj, dobjstr, prepstr, iobj, iobjstr 2 2 Their initial values are described in detail in the LambdaMOO Programmer's Manual. 2 2 Property reading 2 ================ 2 2 expression . name 2 expression . ( expression ) 2 $ name 2 2 Property-reading expressions return the current value of a named property on the object that is the value of the first subexpression. In the second form, the second subexpression must return a string, the name of the property to be read. The third form is an abbreviation for '#0.name'. 2 2 Verb calls 2 ========== 2 2 expression : name ( arguments ) 2 expression : ( expression ) ( arguments ) 2 2 Verb-call expressions invoke a named verb on the object that is the value of the first subexpression, passing the given arguments. In the second form, the second subexpression must return a string, the name of the verb to invoke. The syntax and semantics of arguments is exactly as in the list-construction expression but no initial or final curly-braces ('{' or '}') are used. 2 2 Primitive functions 2 =================== 2 2 function ( arguments ) 2 2 The function-call expression invokes one of the MOO primitive functions, as listed in 'help functions', passing the given arguments. 2 2 List indexing 2 ============= 2 2 expression [ expression ] 2 2 The indexing expression first evaluates the two subexpressions; call their values S and N, respectively. S must be a string or a list and N must be a number between 1 and the length of S, inclusive. The Nth element of S is returned. The elements of a string are themselves one-character strings. 2 2 expression [ expression .. expression ] 2 2 The subsequence expression first evaluates the three subexpressions; call their values S, N1, and N2, respecitively. S must be a string or a list and N1 and N2 must be numbers. If N1 <= N2, then both must be between 1 and the length of S, inclusive; the subsequence of S beginning at index N1 and continuing through index N2 is returned. If N1 > N2, the empty sequence of the same type as S is returned, either "" or {}. 2 2 Assignment 2 ========== 2 2 name = expression 2 expression . name = expression 2 expression . ( expression ) = expression 2 $ name = expression 2 2 Assignment expressions give new values to variables and object properties. For the second and third forms, the expressions on the left-hand side of the '=' are evaluated first. Then the right-hand side expression is evaluated and result is stored in the indicated variable or object property. 2 2 Arithemetic 2 =========== 2 2 expression + expression 2 expression - expression 2 expression * expression 2 expression / expression 2 expression % expression 2 - expression 2 2 The arithmetic expressions evaluate the subexpressions, all of which must return numbers, and then perform addition, subtraction, multiplication, division, remaindering, or negation, respectively. For addition, the subexpressions may both return strings as well; in this case, the result is the concatenation of the two strings. 2 2 Comparisons 2 =========== 2 2 expression == expression 2 expression != expression 2 expression < expression 2 expression <= expression 2 expression > expression 2 expression >= expression 2 2 The comparison expressions evaluate the subexpressions and then test whether or not the first result is equal to, unequal to, less than, less than or equal to, greater than, or greater than or equal to the second result, respectively. If the indicated relation holds then they return 1 and otherwise they return 0. Comparisons of strings are performed case-insensitively, those of lists are performed on an element-by-element basis, objects are compared by their object numbers, and errors by an ordering given in the LambdaMOO Programmer's Manual. 2 2 Logical expressions 2 =================== 2 2 expression ? expression | expression 2 expression && expression 2 expression || expression 2 ! expression 2 2 The logical expressions each return results based upon the truth value of their first subexpression; call the value of this expression X. The first of these returns the value of the second subexpression if X is a true value and that of the third expression if X is a false value; the unused subexpression is not evaluated. The definitions of 'true value' and 'false value' are given in 'help truth'. The expression 'E1 && E2' is an abbreviation for 'E1 ? E2 | E1' except that E1 is only evaluated once. The expression 'E1 || E2' is an abbreviation for 'E1 ? E1 | E2' except that E1 is only evaluated once. The expression '! E' is an abbreviation for 'E ? 0 | 1'. 2 2 List membership 2 =============== 2 2 expression IN expression 2 2 The list-membership expression first evaluates both subexpressions; call their values E and L, respectively. L must be a list. If E is an element of L, then the index of the first occurence of E in L is returned. If E is not an element of L, then 0 is returned. 2 2 The method for disambiguating the meaning of a complex MOO expression in the absence of sufficient parentheses is described in 'help precedence'. 35 1 4 29 2 Syntax: eval 2 ; 2 eval-d 2 eval+d 2 2 Evaluates the given piece of MOO code and prints the resulting value. If the MOO code begins with one of the MOO language keywords ('if', 'for', 'while', 'fork', or 'return') or with the character ';', then the entire piece of code is treated as the program for a verb, with ';' appended to the end. Otherwise, 'return' is appended to the front and ';' is appended to the end and that string is treated as the code for a verb. In either case, the resulting verb is invoked and whatever value it returns is printed. 2 2 For programmers, this is such a mind-bogglingly useful thing to do that there is a simple abbreviation for this command; any command beginning with a semicolon (';') is treated as a use of 'eval'. 2 2 Eval treats specially a duplicated semicolon at the beginning. It enables you to make multi-statement programs within eval (but does not by default print the return value). 2 2 Eval-d (no ";" abbreviation for this) evaluates the following text exactly as eval, except that the "d" debug flag (see programmer's manual for explanation) is turned off. Thus errors will cause an error return value rather than a traceback. Eval+d evaluates code with the "d" flag on. Both of these are useful for overriding `@eval-option no-debug'. 2 2 Examples: 2 eval 3 + 4 2 => 7 2 ;3+4 2 => 7 2 ;for x in (player.aliases) player:tell(x); endfor 2 Jay 2 J 2 Jay^2 2 => 0 2 ;;l = {}; for i in [1..10] l = {@l, i}; endfor return l 2 => {1, 2, 3, 4, 5, 6, 7, 8, 9, 10} 2 eval-d 8 + "foo" 2 => E_TYPE (Type mismatch) 2 2 See `help @eval-options' for various ways you can customize the `eval' command. 35 1 4 3 2 *errors* 2 The complete list of error codes: 2 35 5 4 18 2 Syntax: @verb : 2 @verb : [ []] 2 @verb : () 2 2 Adds a new verb with the given name(s) to the named object. If there are multiple names, they should be separated by spaces and all enclosed in quotes: 2 2 @verb foo:"bar baz mum*ble" 2 2 The direct and indirect object specifiers ( and ) must be either 'none', 'this', or 'any'; their meaning is discussed in the LambdaMOO Programmer's Manual. The preposition specifier () must be either 'none', 'any', or one of the prepositional phrases listed in `help prepositions' (a prepositional phrase with more than one word must be enclosed in quotes ("")). All three specifiers default to 'none'. 2 2 It is also possible to specify the new verb's permissions and owner as part of the same command (rather than having to issue separate @chmod/@chown commands) 2 2 @verb : 2 @verb : 2 2 are as with @chmod, i.e., must be some subset of "rwxd". They default to "rd" (specifying "w" for a verb is highly inadvisable). The owner defaults to the player typing the command; only members of the Core Group can create verbs with owners other than themselves. 2 2 You may also use "tnt" in place of "this none this" for the dobj prep iobj arguments. "this none this" is used to indicate non-command verbs, since the parser can't possibly interpret a command as "this none this". For these verbs, the permissions default to "rxd"; the "x" bit is set so that they can be called from other programs. (If they couldn't be used as commands, and they couldn't be called from programs, they wouldn't be good for anything!) 35 1 4 3 2 Syntax: @setenv 2 2 Defines the environment for eval (@eval-option env). See `help eval' for more information. 35 1 4 9 2 Syntax: @rmverb : 2 @rmverb : 2 @rmverb# : 2 2 Removes the named verb from the named object. 2 2 If there is more than one verb matching the given verb-name, this removes the most recently defined one. With the 2nd form of the command the verb removed is the most recent one matching both the given verb-name *and* the given dobj/prep/iobj specifiers. 2 2 The 3rd form is useful for removing verbs that are otherwise inaccessible by name (say, the 3rd verb on an object is named "*" and you want to remove the 4th verb). verb-number> is the (1-based) number of the verb to be removed, i.e., `@rmverb# object:1' removes the first verb on `object', etc... 35 5 4 3 2 Syntax: @rmproperty . 2 2 Removes the named property from the named object. '@rmproperty' may be abbreviated as '@rmprop'. 35 5 4 29 2 Usage: @prospectus player [from number] [to number] 2 2 Like @audit, but displays more information. The optional from and to arguments are for restricting the display to specific object numbers, if you happen to know the player only owns objects in the included range. 2 2 Example: 2 2 @prospectus Frand 2 Objects owned by Frand (from #0 to #31505): 2 P Frand (#47) 2 T Frand's trio of shoes (#152) 2 KfT[ 10] Frand's notifier class (#391) 2 KfT[ 11] Frand's generic game board (#775) 2 T Frand's mind bender (#894) 2 C polka-dot hole (#997) 2 R Hyperspace Hovel (#1002) 2 ... 2 2 The K in the first column indicates that the object has children owned by other players. A lowercase k indicates the object has children but owned only by the player. The second column indicates whether the object is publicly readable or publicly parentable. An r indicates readability. A lowercase f indicates the object is both readable and allows children (is fertile). An uppercase F indicates the object is not readable, yet allows children to be created. (This is usually an error.) If the object is readable by the issuer of the @prospectus command (that is, publicly readable or owned by the issuer), then the number in brackets indicates the number of verbs which have been defined on this object (not including any verbs from any parents). 2 2 The third column indicates what type of object this is. 2 2 T Thing 2 E Exit 2 R Room 2 C Container 2 N Note 2 P Player 2 p Parent object appropriate for players ("Player class") 2 blank Other 35 5 4 14 2 *subst* 2 Syntax: @property . 2 @property . 2 2 Adds a new property named to the named object. The initial value is given by the second argument, if present; it defaults to 0. 2 2 Normally, a property is created with permissions 'rc' and owned by whoever types the command. However, you may also specify these explicitly 2 2 @property . 2 @property . 2 2 Only members of %[$db_group:dname()] can create properties with owners other than themselves. 2 2 '@property' can be abbreviated as '@prop'. 35 1 4 24 2 Syntax: @program : 2 @program : 2 @program : () 2 @program# : 2 2 Changes the MOO program associated with the named verb on the named object. 2 2 If you provide and as in the second form of this command, then it is the first verb with matching direct object, preposition and indirect object specifiers that is the one getting the new program. This is useful if you have several verbs matching the same name. 2 2 In the third form of the command, the verb changed will be the first `this none this' verb, provided its named arguments match those currently set for that verb. 2 2 In the fourth form of the command, the verb is specified by number; 1 programs the first verb, 2 programs the second verb, etc... This is useful if you have inaccessibly-named verbs (e.g., the 3rd verb on an object is named "*" and you want to change the code on the 4th). 2 2 Typing the @program command always puts the server into a line-reading mode, in which each line you type is saved away without any action unless said line is one of the following: 2 2 . 2 @abort 2 . 2 2 A period on a line by itself ends the line-reading mode and continues with the command, in this case, the saved lines are considered as a program, checked for syntax errors and, if no errors are found, installed as the new program for the specified verb. 2 2 @abort causes the command to terminate immediately with no change to any verb's program. . enters literally as one of the lines to be saved, which is used for when, e.g., you want to enter the line `.' or the line `@abort'. 2 2 Note that this command *always* enters the line-reading mode, even if the indicated verb is not found. In this case, lines of text are still read but they are ignored. After any @program command, you always need to type a period or `@abort' to get back into the normal command-reading mode. 35 5 4 31 2 Usage: @list : 2 [with|without parentheses|numbers] 2 [ ] | [()] 2 [all] 2 [ranges] 2 @list# : 2 [with|without parentheses|numbers] [all] [ranges] 2 2 Prints out the code for the MOO program associated with the named verb on the named object. 2 2 Normally, the code is shown with each line numbered and with only those parentheses that are necessary to show the meaning of the program. You can e.g., specify `without numbers' to have the numbers omitted or `with parentheses' to include all parentheses or even `with parentheses without numbers' to do both. 2 2 Type `@list $room:@move' to see the code for the `@move' command, or even `@list $prog:@list' to see the code implementing @list itself... 2 2 Giving an args (dobj/prep/iobj) specification indicates that verbs whose verb_args do not matching that specification are to be ignored. 2 2 The `@list#' form of the command is available for specifying a verb by number, in case you have an object with inaccessible verbs (e.g,. say the 3rd verb is named "*" and you want to view the 4th). For example 2 2 @list# object:2 2 2 lists the second verb on `object'. 2 2 Specifying `all', indicates that all verbs on or its ancestors matching the given name (and args specification, if given) should be listed. 2 2 One may also specify one or more ranges of the form .. to indicate that only particular subranges of the lines of the verb code should be listed. 2 2 These may combined in any order, e.g., 2 2 @list frobule:burfle this in front of any without numbers all 2 2 which would be useful if `frobule' had more than one `burfle' verb and we are only interested in those that have `this' `in front of' `any' as its respective dobj/prep/iobj specifiers, and we want to see ALL such verbs on frobule or its ancestors. 35 1 4 24 2 Syntax: @kill task_id 2 @kill [object]:[verb] 2 @kill soon [number-of-seconds] 2 @kill all 2 @kill %trailing_id 2 2 2 Immediately kills one or more forked tasks. The '@forked' command is useful for finding out what tasks you have pending; see 'help @forked' for details. Only the owner of a task may kill it. 2 2 @kill task_id kills only the task with that id. 2 2 @kill object:verb kills all tasks which were scheduled by the object running the verb named. Both object and verb are optional: @kill object: kills all tasks scheduled by that object, and @kill :verb kills all tasks which were scheduled by any object running that verb. This can be useful if you have several similar objects which are running tasks from similarly named verbs. (Perversely, @kill : kills all tasks... Any object running any task.) 2 2 @kill soon kills all tasks scheduled within the next minute. @kill soon number kills all tasks scheduled within that number of seconds, e.g. @kill soon 300 would kill all tasks scheduled within the next five minutes. This can be useful if you have a runaway task you want to quickly remove, but don't want to kill you later tasks. 2 2 @kill all kills all tasks. Like @kill soon, but more dramatic. 2 2 @kill %trailing_id expects you to specify the last few digits of a task id. It then kills all tasks that end with those digits. 2 2 Example: 2 @forked 2 1359083655 Sep 16 21:45:00 1991 yduJ #5803:heartbeat (10) [#68] 2 @kill %655 2 Killed: task 1359083655, verb #5803:heartbeat, line 10, this==#68 35 1 4 8 2 Syntax: @kids object 2 2 A quick way to find out the children of an object. Prints out the names and object numbers of the found children. Note: this is not a list of all descendents, just direct children. 2 2 Example: 2 @kids #3107 2 Generic Body of Chlorinated Water(#3107) has 3 kids. 2 The Pool(#1428) The Hot Tub(#388) Deep Blue Underground Pool(#17340) 35 5 4 33 2 Syntax: @forked 2 2 Gives a list of all of the forked tasks you own, along with detailed information about each one. The information includes the following: 2 2 Queue ID 2 ======== 2 2 A numeric identifier for the task, for use in killing it (see 'help @kill'). 2 2 Start Time 2 ========== 2 2 The time after which the task will begin execution. 2 2 Owner 2 ===== 2 2 The player whose permissions under which the task is running. Unless you are in the Core Group, @forked will show only your tasks. 2 2 Verb 2 ==== 2 2 The object and verb-name of the code that forked the task. 2 2 Line 2 ==== 2 2 The line number of the first statement that the task will execute when it starts. Note that the code for the verb in question may have changed since the task was forked; the forked task will use the version that was being executed when it was forked. 2 2 This 2 ==== 2 2 The value of `this' for the forked task, in the case that it is different from (i.e., is a descendant of) the object on which the verb code lives. 35 1 4 42 2 Syntax: @display .[property] 2 ,[inherited_property] 2 :[verb] 2 ;[inherited_verb] 2 2 @display is a fancy version of @show. As @show, it can select individual verbs or properties to display. In addition, it can display all the verbs or properties defined on an object, or all the verbs or properties defined on any of the object's ancestors. Don't specify a property or verbname after the punctuation mark to get the "all" feature. Its display is more compact than that of @show (it uses a one-line format, and truncates values that don't fit in the value field). 2 2 You may mix properties and verbs on the command line, but the parser may become confused. (E.g. @display object,: displays all properties including inherited ones plus all locally defined verbs on the object.) 2 2 Examples: 2 Individual property: 2 @display poolsweep.count 2 .count yduJ (#68) r c 8 2 2 Individual verb: 2 @display poolsweep:tell 2 #3560:tell yduJ (#68) rxd this none this 2 2 All properties, including one truncated value: 2 @display poolsweep. 2 poolsweep (#3560) [ readable ] 2 Owned by yduJ (#68). 2 Child of generic thing (#5). 2 Location The Pool (#1428). 2 .gagged yduJ (#68) r c 0 2 .count yduJ (#68) r c 8 2 .messages yduJ (#68) r c {"The poolsweep stir.. 2 .index yduJ (#68) r c 2 2 .quantum yduJ (#68) r c 20 2 2 Inherited verbs, edited for brevity, showing verbs from various parents, with owners, permissions, and argument lists. 2 @d poolsweep; 2 poolsweep (#3560) [ readable ] 2 #3560:tell yduJ (#68) rxd this none this 2 #3560:description yduJ (#68) rxd this none this 2 #5:"g*et t*ake" Haakon (#2) rxd this none none 2 #5:"d*rop th*row" Haakon (#2) rxd this none none 2 #5:moveto Haakon (#2) rxd this none this 2 #1:description Haakon (#2) rxd this none this 2 #1:look_self Haakon (#2) rxd this none this 2 2 Some aspects of @display can be customized (see `help @display-options'). 35 5 4 3 2 Syntax: @dbsize 2 2 @dbsize goes through the entire database, counting the valid and invalid objects, giving a summary at the end. This information can be useful, but because this command is cpu intensive, it should be used sparingly. 35 5 4 15 2 Syntax: @copy : to [][:] 2 @copy-x : to [][:] 2 2 Copies the code of the named verb to the new object and verbname. Permissions, and arguments of the new verb are set to match those of the old verb in the event that the new verb does not already exist. One of or : must be supplied. If no new verbname is given, the old name is retained. Likewise, defaults to if not given. 2 2 @copy-x is like @copy but causes any new verb to be created with its x flag reset. 2 2 Examples: 2 @copy me:verbname to myobject 2 @copy me:test_verb to myobject:real_verb 2 @copy-x me:verbname to verbname(old) 2 2 In general, @copy'ing verbs is a bad idea. In the vast majority of cases, the desired effect can be accomplished with parenting (i.e., having be an ancestor of ), which has the advantage that if a verb is updated or fixed, this immediately becomes available to child objects that inherit this verb. In such a case, copies that were made using @copy have to be tracked down and fixed by hand. 2 2 This facility is provided for those rare occasions where one has no choice but to actually copy the verb. @copy-x is useful for making unusable backup copies of verbcode. 35 5 4 7 2 Syntax: @chparent to 2 2 Changes the parent of the named object to be the named parent. The object acquires all the verb and property definitions of its parent. Newly acquired properties are initilialized with `clear' values so that they inherit whatever values are currently assigned to the parent's corresponding properties (see `help @clearproperty'). 2 2 If the player does not own , it must have been set `fertile'. must be owned by the player. Neither nor any descendant can define any property which already exist on . Use @check-chparent (see `help @check-chparent') to list such property conflicts. 2 2 It is also sometimes the case that you will own some object and want to @chparent some child of that object that you do not own. Use @disinherit (see `help @disinherit') in such situations. 35 5 4 14 2 Syntax: @chmod 2 @chmod . 2 @chmod : 2 @chmod# : 2 2 Changes the permissions of an object, property or verb, to those given. The following table shows what permission bits are allowed for each form of the command: 2 2 r, w, f 2 r, w, c 2 r, w, x, d 2 2 See the LambdaMOO Programmer's Manual for their meanings. 2 2 To clear all of the permissions for an object, verb, or property, use "" as the second argument. 35 5 4 6 2 Syntax: @args : [ []] 2 @args : () 2 @args# : [ []] 2 @args# : () 2 2 Changes the direct object, preposition, and/or indirect object specifiers for the named verb on the named object. Any specifiers not provided on the command line are not changed. The direct and indirect object specifiers ( and ) must be either 'none', 'this', or 'any'. The preposition specifier () must be either 'none', 'any', or one of the prepositional phrases listed in `help prepositions'. 35 1 4 13 2 Syntax: .program : 2 : 2 : 2 2 : 2 : 2 . 2 2 Provides or changes the MOO program associated with the named verb on the named object. 2 2 This command is mostly obsolete. Use @program instead. The only reason this command still exists is that it is a server builtin command that will continue to work in the (unlikely) event that @program gets trashed ... 2 2 This command works differently from most other MOO commands, in that it actually changes how the server will interpret later lines that you type to it. After typing the '.program' line, you are in 'programming mode'. All lines that you type in this mode are simply saved away in the server until you type a line containing only a single period ('.'). At that point, those lines are interpreted as a MOO program and are checked for syntax errors. If none are found, a message to that effect is printed and the code you typed is installed as the program for the verb in question. In any case, after typing the '.' line, you are returned to the normal input-handling mode. 35 1 4 32 2 Syntax: @clearproperty . 2 2 This clears 's property. That is the property value becomes `clear' and all further references to this property will use the value of the same property on the parent object. Note that you can only clear inherited properties. Nor is this the same as removing a property; the property continues to exist. 2 2 `@clearproperty' can be abbreviated as `@clearp'. 2 2 Example: 2 2 @create #1 named foo 2 You now have foo with object number #42 and parent Root Class (#1). 2 [foo, as a child of #1 has a .description property which starts out clear] 2 ;#1.description 2 => "" 2 ;#1.description = "You see nothing special" 2 => "You see nothing special" 2 ;#42.description 2 => "You see nothing special" 2 ;#42.description = "Something special" 2 => "Something special" 2 [foo.description is now no longer clear; it has a value of its own] 2 ;#1.description = "Boring" 2 => "Boring" 2 ;#42.description 2 => "Something special" 2 2 @clearp foo.description 2 Property #42.description cleared; value is now "Boring". 2 [foo.description is now clear again] 2 ;#1.description = "" 2 => "" 2 ;#42.description 2 => "" 35 5 4 2 2 *forward* 2 @disinherit 35 5 4 12 2 Syntax: @disinherit 2 @disinherit [from ] 2 2 Synonym: @disown 2 2 This command is used to remove an unwanted child from an object you own. If you owned said child, you could use @chparent; this command is to cover the other case, namely where you don't own the child. 2 2 Both forms of this command chparent to its grandparent, provided you own the parent. The second form matches the string you supply for against the list of children of the given . 2 2 Turning off the fertile bit (.f) for a particular object prevents others from creating children of it or chparenting to it (see `help @chmod'). 2 2 Note also that, though the name might seem to indicate otherwise, this command does not change the ownership of any object. 35 5 4 2 2 *forward* 2 @display-options 35 5 4 26 2 Syntax: @display-option 2 @display-option