发信人: xyx (红日), 信区: Mud
标  题: wiz入门教材（一）
发信站: 重庆两江亭BBS站 (Sat Mar 21 00:46:04 1998), 转信

第一部分 巫师工作的简介

    mud 是个奇妙的世界，他文字的界面给了我们无限的想象空间，而巫师就是建
设这个世界的人，做为巫师你要完成描写，设计各种机关，引导玩家的想象之船，
一个mud 的好坏直接取决于它的巫师们的好坏。

第一章 这是一项工作

    做巫师是不是很威风？如过你这样想那你就错了！这么多素不相识的人
在一个mud中，大家为一个共同的理想而奋斗，使大家聚集到一起。应该说我
们这些人可以在一起，认识大家，这都是一种缘分，应该要好好珍惜。大家是
了一个追求而来的。没有一个mud是一帆风顺的，同人生一样巫师们遇到的坎坷
会比玩家更多，会有很多现实的障碍，我想没有什么人会愿意一辈子就开这一
个MUD；抱着MUD活。但既然是虚拟的实现，同样也是最求，同样也要认真去做。
不过，由于这里是一个小小的最求实验地，不能花费太多太多的时间在这上面
，毕竟大家都还有自己的事情。可现在在此实验场上我们的小小最求都无法坚持
，也不能不让人怀疑你是否在生活上尝试过成功的喜悦。同时也可以看出一个人
在生活上的眼光和能力。说了这么多就是为了让你在当巫师前有个心理准备这不
是一件舒服的事他远不同于玩家的生活，但这又是一件苦中有乐的工作，和同事
们共同完成一个世界一片蓝天那份喜悦也不言而愈了，确实人各有志，做玩家同
样可以有喜悦，快乐。好了，如果你准备好和大家一起工作，对大家和你自己负
责，那么就看下面一章吧。





发信人: xyx (红日), 信区: Mud
标  题: wiz入门教材（二）
发信站: 重庆两江亭BBS站 (Sat Mar 21 00:47:22 1998), 转信

第二章 巫师所用到的命令

    在mud 中，命令是以集合的方式划分的，每个等级有自己的命令集，而
    在mud 中，命令是以集合的方式划分的，每个等级有自己的命令集，而
低一级的命令集是高一级的一个子集。通俗的说就是高你一级的巫师所能用
的命令就是你能用的命令再加上他这级别的一些命令。

第一节 巫师等级的划分

下面先介绍一下一般巫师等级的划分：

最高等级(admin)------他们的任务是制作完善系统
                     admin 首先要制定整个mud 的构思、确定风格。设计出优良
                     的系统，这些也是以后工作的基础，所以对于admin 要求比
                     交高，要有高超的编程水平，对mud 的理解和一定的领导能
                     力。

第二级  (arch) ------他们的任务是督促下级们的工作，和区域的QC（见注释章）。
                     arch的任务除了制作自己的区域外，主要是要关心整个mud 的
                     进度，督促并指导wizard门完成他们的任务。一个好的arch可
                     以帮admin 分担掉很多不必要的工作，以便完成好系统。

第三级  (wizard)-----他们的任务是完成上级交给的任务，一般是区域。
                     wizard的工作可以说是给整个mud 添加血肉，他们的工作也是
                     mud 进度的体现。

第四级  (apprentice)-他们是还处于见习期的巫师，他们要边学边完成自己的任务。
                     apprentice还处于见习阶段，所以他们的任务一般不会太难，?
                     要用心去做，按时完成很快就可以晋升为正式巫师的。

第五级  (immortal)---他们是介于玩家和巫师之间的等级，一般为观察员，帮忙找
                     些bug。





发信人: xyx (红日), 信区: Mud
标  题: wiz入门教材（三）
发信站: 重庆两江亭BBS站 (Sat Mar 21 00:49:05 1998), 转信

第二节 巫师命令

首先，对于不同的lib(见注释)它的命令集也不同，以下所述为一般的mudlib所有的命令。

一、immortal,apprentice命令集
    1、cd命令
       将目前参考的目录移至指定的子目录或回到上一主目录; 亦可直接回到自己工作目?
       指令格式 : cd <子目录名>
                   进入某个目录。可以绝对路径，也可以打相对路径。
                   例:绝对路径： cd /u/zzz
                      相对路径： cd zzz (设你现在在/u目录下)
                  cd ..
                   退回上一层目录。
                  cd
                   目前所在目录。
    2、edemote命令
       这个指令可以修改, 删除 emote 或列出其内容. 加上 -d 参数会删除
       指定的 emote, -p 参数则会列出指定 emote 的内容. 列出的顺序与编
       辑 emote 时相同.
       输入 emote 讯息时有三个项目: 没有目标, 指定目标或是对自己. 若
       不想有某项讯息, 则直接在空白行输入 '.' 跳过.

       一个 emote 讯息可以有很多行, 在空白行输入 '.' 结束输入该项 emote.

       编辑 emote 时可以用以下的符号来表示:

       $N : 自己的名字.
       $n : 目标的名字.
       $P : 自己的人称代名词.
       $p : 目标的人称代名词.

    3、goto命令
       指令格式 : goto [-i] <目标>
       这个指令会将你传送到指定的目标. 目标可以是一个living 或房间
       的档名. 如果目标是living , 你会被移到跟那个人同样的环境.
       如果有加上 -i 参数且目标是 living, 则你会被移到该 living 的
       的 inventory 中.
       目标可以是room，也可以是player。
       例：移动到room: goto /d/city/chaguan  (/d/city/chaguan是一个room文件)
           移动到player: goto comm (comm是player的id)
    4、ls命令
       指令格式: ls [<路径名>]
       列出目录下所有的子目录及档案, 如果没有指定目录, 则列出所在目录
       的内容，所列出的档案中前面标示 * 号的是已经载入的物件。
       同样，路径可以是绝对路径，也可是相对路径，前面已有例子。
       'ls /' 会列出所有位於根目录下的档案及子目录.

    5、mem命令
       指令格式 : mem <物件之名称或档名>
       这个指令告诉你某个物件占用的记忆体数量　
       若没有指明物件, 则会显示目前游戏所占用的记忆体.

    6、more命令
       指令格式 : more <档案>|<物件名>
       分页显示档案内容。
       more 模式下的指令:
       q      : 离开 more.
       b      : 显示前一页的内容.
       [ENTER]: 显示下一页的内容.

    7、pwd命令
       指令格式 : pwd
       这个指令会显示出你目前的工作目录 (cwd) 及工作档案 (cwf).
       cwd和cwf是你的缺省值，在有些命令不加参数时会以此做为参数。
       'update' 不加参数时便会更新你的 cwf.
       'clone'  不加参数时便会clone你的 cwf.

    8、status命令
       指令格式 : status [detail]
       这个指令可以显示出目前游戏的一些相关资料及状况.

    9、where命令
       指令格式: where <玩家的 ID>
       这个指令是用来得知玩家目前所在的位置, 若不加 id 则会列出所有
       玩家的所在位置　

    10、which命令
       指令格式: which <指令>
       找出指令所在的目录　

    11、smash命令
       指令格式: smash <生物>
       将生物杀死。




发信人: xyx (红日), 信区: Mud
标  题: wiz入门教材（四）
发信站: 重庆两江亭BBS站 (Sat Mar 21 00:50:09 1998), 转信

二、wizard命令集
    1、analyze命令
       指令格式：analyze [<对象>]
       这个指令会列出一些有关指定对象的能力值，不指定对象时则列出你自己的
       能力值。

    2、call命令
       指令格式 : call <物件>-><函数>(<参数>, ...... )
       呼叫<物件>里的<函数>　传入相关<参数>.
       例：对自己运行set函数，改变int值
           call me->set(int,10)
           如想改变comm的int值
           call comm->set(int,10)

    3、cat命令
       指令格式 : cat <档案>
       此指令可让你(你)直接读取某档案之程式　

    4、clone命令
       指令格式 : clone <档名>
       利用此指令可复制任何能移动之物件(含怪物)　

    5、cost命令
       指令格式：cost <指令> [<参数> .... ]
       这个指令让你测量另一个指令执行所需的时间。

    6、cp命令
       指令格式 : cp <原档名> <目标档名>
       此指令可让你(你)拷贝档案　

    7、daemon命令(使用不多)
       指令格式 : cp <原档名> <目标档名>
       此指令可让你(你)拷贝档案　

    8、dest命令
       指令格式 : dest [-r] <物件之名称或档名>
       利用此一指令可将一个物件(object)或物件定义(class)从记忆体中清除，若清除物
       件定义(即：指定档名的情况下)则下一次参考到这个物件的时候会重新将它编译　
       具有 (admin) 身分的巫师可以用 -r 选项以 ROOT_UID 身分来清除被保护的物件如
       使用者　
       若物件在被清除过程中发生了错误，除使用者以外的物件仍然会被强制清除( 使用?
       物件只有在使用 ROOT_UID 身份时才能强制清除 )，而其错误讯息会被写至
       /log/destruct 中　
       参考资料： destruct()

    9、edit命令
       指令格式 : edit <档名>, edit here
       利用此一指令可直接在线上编辑档案　
       一般使用ftp来进行工作，所以不推荐使用此命令。

    10、ff命令
        指令格式：ff <物件> <函数名称>
        这个指令可以找出指定物件中的某个函数定义在哪一个档案里

    11、home命令
        利用此一指令可直接回到自己的工作室　
        如果你有 'msg_home' 这个设定, 则在场的人都会看到那个讯息.

    12、ilist命令
        指令格式：invis [on|off]
        打开或关闭巫师的隐形功能
    
    15、localcmds命令
        命令格式：localcmds
        列出你身上及四周的物品与所在的环境提供的所有指令　

    16、log命令
        指令格式: log <msg>
        将所做过的改变记录在该目录下的 .ChangeLog 里
        如果所要超过的一行, 可用 to log 来记录　

    17、mkdir命令（一般wizard没有写的权限）
        指令格式 : mkdir <子目录名>
        建立一个子目录　

    18、mudlist命令
        指令格式：mudlist [<Mud 名称>]
        这个指令让你列出目前跟这个 Mud 取得联系中的其他 Mud
        此命令需要mud与其他mud连网。

    19、mv命令
        指令格式 : mv <原档名> <目标档名>
        此指令可让你(你)修改某个档案或目录名称　
    20、qload命令
        指令格式 : qload
        这个指令显示出目前 CPU 的负担, cmds/s 是每秒编译几个 cmds
        comp lines/s 是每秒几行　

    21、rm命令
        指令格式 : rm <档名>
        此指令可让你(你)删除有权修改的档案　

    22、rmdir命令
        指令格式 : rmdir <子目录名>
        删除一个子目录　

    23、snoop命令
        指令格式：snoop <某人>|none
        监听其他使用者所收听的讯息，snoop none 则取消监听　

    24、summon命令
        指令格式 : summon <某人>
        此指令可让你(你)将某人抓到你面前　

    25、tail命令
        指令格式 : tail <档案>
        此指令可让你(你)直接读取某档案最末尾的几行　
    26、ulist命令
        指令格式 : ulist
        将线上所有玩家的/obj/user number 显示出来　

    27、update命令(此命令是调试时常用的命令)
        指令格式 : update <档名|here|me|玩家名>
        这个指令可以更新档案, 　将新档的内容载入记忆体内. 若目标为
        'here' 则更新所在环境. 若目标为 'me' 则更新自己的人物. 若目
        标为玩家则可更新玩家物件.

    28、whoami命令
        指令格式 : whoami
        Show 出你的 User ID 及 Effective User ID 　




发信人: xyx (红日), 信区: Mud
标  题: wiz入门教材（五）
发信站: 重庆两江亭BBS站 (Sat Mar 21 00:51:01 1998), 转信

三、arch命令集
    1、callouts命令
       指令格式：callouts [<函数名称>]
       缺省将列出系统中所有的延迟呼叫函数
       否则列出指定的延迟呼叫函数.

    2、chinese命令
       指令格式：chinese <英文>==<中文>
       设定中英文等价关系

    3、cleanup命令
       指令格式：cleanup <档名>
       对所有指定档名的物件呼叫 clean_up，且清除所有被复制出来的，但是又没有
       被放在另一个物件中的散失物件
　
    4、force命令
      指令格式：force <某人> to <指令>
       强迫某人做某事, 但你的巫师等级必须比对方高, 而且必须是在同一个房间里　

    5、overview命令
       指令格式：overview <主题>
       纵观整个mud中的情况
       主题有:
       user                     共有几个使用者物件
       living                   共有几个生物(含使用者)物件
       char                     共有几种人物物件 master copy 被载入
       npc                      共有几个 NPC 物件
       combat                   共有几个人物正在战斗状态
       kill                     共有几个人物正在性命相搏的战斗状态
       hunt                     共有几个人物正和其他人物互相仇恨
       heart beat               共有几个物件的 heart beat 为有效状态
       virtual                  共有几个虚拟物件
       room                     共有几个房间
       special room             共有几个物件继承标准房间
       equip                    共有几个物件继承标准装备
       object                   共有几个物件被载入　

    6、possess命令
       指令格式：posssess <目标生物>
       附身到另一个生物上，这个生物必须和你有相同的 EUID　
       附身後用 quit 指令会回到原来的身体　

    7、promote命令
       指令格式 : promote <某人> (权限等级)
       用来提升权限等级, (player) (immortal) (apprentice) (wizard)
       (arch) (admin)

    8、purge命令
       指令格式：purge [<未上线天数>] | <使用者姓名> because <原因>
       清除一个使用者或清除超过一定天数不曾上线地使用者　

    9、reboot命令
       指令格式: reboot
       重新起动游戏, 系统会开始倒数计时, 十五分钟後重新起动　

    10、reclaim命令
        指令格式 : reclaim
        用处 : 将存在於记忆体里无用的变数清除掉, 以减少记忆体的使用　

    11、rehash命令
        指令格式：rehash <目录名称>
        这个指令会更新系统内部的指令表，如果你新增或删除了某个目录下的指令，必杏?
        这个指令更新该目录才能使用　

    12、wizlock命令
        指令格式: wizlock <巫师等级>
        限制某个等级以下的使用者进入游戏　
        其中巫师等级分别为 (immortal) (apprentice) (wizard) (arch) (admin), 若?
        消限制, 则输入 (player).





发信人: xyx (红日), 信区: Mud
标  题: wiz入门教材（六）
发信站: 重庆两江亭BBS站 (Sat Mar 21 00:51:51 1998), 转信

四、admin命令集

    1、disassemble命令
       指令格式：disassemble <物件> <输出档名>
       反组译一个物件并输出至指定文件。

    2、dump命令
       指令格式 : dump
       将所有物件的状态记录至根目录下的文件OBJ_DUMP中。

    3、profile命令
       指令格式: profile

    4、shutdown命令
       指令格式: shutdown
       马上重新起动游戏　





发信人: xyx (红日), 信区: Mud
标  题: wiz入门教材（七）
发信站: 重庆两江亭BBS站 (Sat Mar 21 00:52:37 1998), 转信

第三章 做巫师的必备工具

由于巫师要做比玩家多得多的工作，而涉及到的东西有很多，所以有一些工具是必须的。
一、你要有一个ftp工具，因为一般等级的巫师是无权用edit等在线编辑的，所以必须
    通过ftp来完成。我们推荐的ftp工具是ws_ftp。

二、由于mud系统基于unix，所以系统上的文件多为unix的8位格式，如果没有一个支持
    unix系统的编辑器将来你会遇到很多麻烦的。我们推荐使用ultraedit。
三、由于mud是一个共同完成的项目，所以巫师间的联系就非常重要，推荐使用icq，以编
    同事们之间的联系。





发信人: xyx (红日), 信区: Mud
标  题: wiz入门教材（八）
发信站: 重庆两江亭BBS站 (Sat Mar 21 00:53:34 1998), 转信

第四章 用LPC编程

以下由 MudOS driver v21 版里的说明文件翻译而得
* 什麽是 LPC ?

    LPC 是由 MudOS 所定义出来的语言, 用来写作 LP mud 中的物件,
LPC 是由 Lars pensj| C. 所建立起来的. LPC 它提供了 C 语言的
"while", "for" 等??圈, "if", "switch" 等选择, 甚至是 sscanf 等等
的函数, int, char 等等的资料型态(LPC 也提供 C 没有提供的其他资料
型态, 如物件跟对应). LPC 使用了 C 的语法来定义跟呼叫函数, 定义跟
使用变数等等. 不过 LPC 所定义出来的字串变数的行为跟 C 有很大的不
同. 可以叁考 LPC 的其他教学说明.

    底下是一些 LPC 跟 C 的相异处:

   a) 物件以 create() 函数取代 main() 函数.

   b) 系统函数(或称为 efun)提供一组函数, 却又跟 C 的系统函数库(如 libc.a)
      不一样.
   c) 没有提供 malloc() 这一类的函数, 而是用有点类似的 allocate(int 个数)
      取代, 注意, allocate() 中的大小单位不是位元组, 而是阵列元素的大小.

   d) 记忆体从来不会很明显的释放, MudOS 驱动程式会保持这些记录, 以
      方便下次的使用. 它的使用方式俗称为 "垃圾搜集法"(garbage collected).
   e) LPC 所提供的字串不像 C, 反而比较类似 BASIC. 在 LPC 里, 字串不是字元
      阵列, 而是内定的型态, 可以使用 + 运算子, 底下举例说明:

        LPC 的下列叙述是合法的:

        string ack;
        ack = foo + bar;

        约相等於下列的 C 叙述:

        char *ack;
        ack = (char *)malloc(strlen(foo) + 1);
        strcpy(ack,foo);
        ack = (char *)realloc(strlen(ack) + strlen(bar) + 1);
        strcat(ack,bar);
   f) LPC 是一种解译是语言, 在执行前先翻译成中间符号.

   g) LPC 没有结构(struct) 跟联集(union). 事实上, "->" 运算子用来
      指示呼叫物件中的函数, 而不是跟 C 相同的用法. LPC 所提供的对
      应型态在某些状况下会比使用结构更有效.

   h) LPC 的 sscanf() 跟 C 所提供的 sscanf() 工作方式不太一样. LPC 里的
      sscanf() 的叁数不必是指标型态, 因为 LPC 就是用指标的方式引用物件.
      此外, sscanf(arg,"%s %s",str1,str2) 这样的用法跟 C 的结果可能会很
      不一样. C 里面, 第一个"字"会被丢到 str1 中, 第二个字会被指定到 str2
      中, 然而, 在 LPC 中, 第一个字会被丢到 str1 中, 其馀的字串会被指定
      到 str2 中.






发信人: Trill (飞鸟), 信区: creator
标  题: 新巫师入门
发信站: 天地创造 (Sun Oct  5 18:02:32 1997), 转信

此文是lnwm发于technology板 

嗯，下面是我给6666的新巫师们的一篇入门读物，大家可以看看。
是我从清华BBS巫师版弄来的，是台湾人写的，有些词语我改
成大家比较熟悉的，很多地方加了注，可能更好懂一些。


       这篇说明是为了新上任的巫师所写的, 我假设读著这篇说明文件的
新巫师已经读过 help new_wiz 中的内容, 并对巫师专有的指令如 clone,
update, cd, ls, cp... 等能熟练地加以使用, 但对如何开始写作自己
的区域感到茫然, 不知所措的新进巫师　

[在开始制作之前]

    让我们大略看一下在 LP MUD 中, 世界的构成方式　这个世界是由
                      (目前大陆上玩的 mud ，包括 xkx,fy,es2 都是 lp mud
                       即所谓战斗 mud。---lnwm 注。)
一个个的对象 (object) 所组成, 每个对象有一个对应的程序来描
           (比如你在mud里见到的每个房间，每个npc，每个物品，甚至
            你自己，都是一个 object，都是一段程序。----lnwm 注。)
述它的特性　我们可以藉由写作一段程序来创造出一个全新的对象, 可
以利用 update 来更新对象所属的程序, 用 clone  来实际造出一个可
       (比如你敲 update here，就是将你现在所在的房间更新，这里需要强调
        的是，所谓更新，就是将硬盘里这个文件编译后形成一段代码，这段代
        码是存在在内存中的。因此当你修改了一个房间，那只表明你在硬盘上
        改动了这个文件，你必须做一下 update ，将它编译放入内存，你的修
        改才正式生效。hehe，当然，编译有错误例外。----lnwm 注。)
用的对象　.
       (clone其实就是 update，只不过它update的是一个物品或npc，这个物品
        或npc还需要有地方放，所以clone就是 update+move。---lnwm注。)

    在这里, 我们有各式各样的对象, 但是可以将之区分为三大类: 房
间 (ROOM), 物品 (OBJECT), 与生物 (LIVING)　 在我们制作区域的惯
               (这个OBJECT不过是个名词以和ROOM LIVING区分，和我们mud的
                object是两码事。---lnwm 注。) 
例上, 我们习惯将房间的档案直接摆在区域的目录下, 生物与物品则摆
               (区域的习惯放置位置是根目录下的 /d 目录。特别是大陆的，
                你可以在 /d下找到所有的房间和npc-------lnwm 注.)
在这个区域中名为 npc 及 obj (也有人喜欢用 object 或 item
为名, 看个人习惯　) 的子目录中　。

      以下我将以这三大类对象来分别说明该如何实作出区域

[如何制作房间]

   一个房间必定继承了 ROOM (inherit ROOM), 这是在
               (对，如果你要写一个房间，那么首先要做的就是在这个程序
                的开头写上 
                       inherit ROOM;
                在有些时候，比如在xkx里，你
                可能还要加上一句 
                       #include <room.h>
                因为房间的门是定义在那里的。---lnwm注。)
mudlib.h中被 #define 好的一个档案, 它表示一个特别的档案, 所
有的房间都必须继承它. 才能拥有属於房间的一切特性　
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^!

        一个房间有三个非常重要的函数: create(), init(), 与 refresh()
这三个函数会在某些特定的时机被系统所呼叫, 并且可以由你自行改写
, 以达成千变万化的效果　。

 [create 函数]

　 create() 是房间在一被创造出来时必定要呼叫的一个函数, 通常我
         (如果你学过C语言，那么在lpc中，void create()
          就相当于 void main()，即主函数。---lnwm注。)
们都在里面做一大堆设定初值的动作　随便找一个房间来看, 我们可以
发现 create() 函数中总是有一大堆的 set("something", somevalue);
这些 set 的意义在此不详述, 你可以自己猜,  也可以问问较资深的巫
师　.
         (在我们这个mud中，你可以敲help STD_ROOM来看看这些设置是干什么
          的。---lnwm注。)

        有时你的房间并不直接继承 ROOM　而是继承了一个有继承 ROOM 的
特别房间, 像是商店或是公会房间什麽的　这时候你所写的 create()
         (在我们的mud中，钱庄就是个典型的例子，在钱庄的前面，你必须
          inherit SHOP;
          这个SHOP就是在ROOM的基础上加了钱庄的公用功能。---lnwm注。)

  [init 函数]

        init() 函数被呼叫的时机在於有生物 (npc及玩家)  进入这个房
         (这里的意思是，当有玩家或npc等活物进入房间时，可以是走进来，
          扔进来，或clone进来，房间中的这个init()函数就被触发，函数
          实现的功能就被实现。----lnwm注。)  
间的时候　这时有个常用的函数 this_player()  会传回走进房间的这
个人, 或是npc。　this_player() 的概念容後再谈, 你现在只要记住这
个函数在每个生物走进来时都会被呼叫一次就可以了　
         (这里的意思是，如果你要对进入房间的玩家做一些动作，比如弄晕他
          或给他中毒等时，那么就在init()函数里对 this_player()作操作
          就可以了，this_player()就是触发init()函数的玩家。---lnwm注。)


       在 init() 中最常见的的函数莫过於 add_action("function", "action");
了　它的作用是在进来的生物身上添加上一个指令 (注意, 系统只认指
令的第一个字), 并在玩家下达这个指令时去呼叫 "function"  中所给
定名称的函数　举例而言, 如果我们写了这样的 init():

init()
{
      add_action("do_climb", "climb");
}

当玩家走进这个房间时, 系统会帮他多出 climb 这个指令　当他下达
                                    (如果这个指令不是cmds，那么在没有
                                     add_action的房间里就不会存在。) 
了 climb tree 这个指令时, 系统会去寻找 do_climb() 这个函数, 并
                                   (do_clone()这个函数当然是你去写了
                                                       ---lnwm注。)
加以执行。　同时, 系统会将玩家所输入的 "climb"  这个指令後的所有
文字以字串类型的变量传给 do_climb()　 你可以将 do_climb 这个函
数宣告为 
         int do_climb(string arg)　 
         (注意，这个带函数类型和参数类型的函数才是完整写法。---lnwm注。)

这样一来, 当玩家下达 climb tree, 或是 climb the red wall 这种指令时, 
"tree" 或是 "the red wall" 就会被存进字串变量 arg 之中供你处理　。
   
        由 add_action() 所宣告的函数必定要是一个整数类型的函数, 因
为系统会根据这个函数的传回值采取不同的动作　如果你传回的是 0,
那麽系统会认定这个命令与你这个处理函数无关, 而对其他也有 climb
命令的函数一个一个尝试著去执行, 直到所有的 climb 命令都传回 0。

         (这段话很重要，当你要玩家在使用某个cmds时出现其他的用处，
          比如你要玩家eat一个果子不仅仅涨食物，而且涨别的东西，那么
          你就要在果子上用 add_action来给eat赋予更多的内容，然后在你
          处理eat的那个函数最后 return 0;
          这就是告诉系统，我这个指令并没有完，系统就会寻找本来的
          那个 eat 命令的功能函数，也就是加上食物。
          这称为重载。----lnwm注。)
          
        若你的函数传回值为 1, 表示这个指令已经由你所写的函数处理掉
了, 系统不会再尝试著往下面继续寻找其他的 climb 指令　
         (给出一个例子。
          void init()
          {
                add_action("do_eat","eat");
          }     

          int do_eat( string arg )
          {
                object me;
                me=this_player();//触发指令的玩家。

                if (arg!="果子") 
                return notify_fail("你要吃什么？\n");
                                     //notify_fail() 就是 return 0      
                
                me->set("str",1000); //这里是你要使这个果子与众不同的地方。
                return 0;  //这里使这个果子和其他食物一样仍然可以涨
                           //食物，你可以试试 return 1
                           //那样你发现你的果子吃了不涨食物。
          }
                            ----lnwm 注。)

         在你的函数侦测到玩家输入的变量有问题时 (例如你要他们 climb
 tree, 但他们却输入了一些错误的指令如 climb three 之类的)　 想
给他们一些特别的错误讯息时, 你可以用 notify_fail(string errormsg)
来写这个讯息, 如 notify_fail("climb what?\n");   notify_fail()
这个函数也是 int 类型, 固定会传回 0, 所以我们最常用的写法是:

if (条件不合)
        return notify_fail(错误讯息);
if (另一个条件不合)
        return notify_fail(另一个错误讯息);
.............................
<所有可能导致错误的输入都过滤光了>
开始真正干活的部份....
return 1;
          (可以参考一下上面的例子。---lnwm注。)          
 
    [refresh() 函数]

        refresh 呼叫的时机是系统定时 (约每半个小时一次) 呼叫　主
要的用途在於房间中npc　物品的再生　如果你改写了 refresh()
函数, 千万记得要串接 ::refresh(), 否则可能导致严重的後果 (门
一打开就不会自动关上, npc打死後也不会再生...

    由於有 set("objects", (["name1" : "file1", "name2" :
"file2",... ]) ); 这种写法的存在 (在 create() 里面这麽写) 所
               (set("objects",([]))用来在房间里放东西，比如
                npc或物品什么的。---lnwm注。)
以 refresh() 被用到的机会不多了　 (因为 set("objects", ) 这
个写法可以帮你作出自动定时 refresh npc　物品)  但是在制作一
些必须定时回复原始状态的小机关时, 仍然有必要用到这个函数　
     ( refresh 函数用到的地方并不是很多，因为它太僵硬，要十分
       固定的半个小时(准确的是24分钟)才被调用一次，可以用在
       一些周期较长的秘密中。---lnwm注。)

有关房间的部份就写到这里, 接下来是物品　


  [ 物品的制造]

        要制作物品, 首先必须 inherit OBJECT;　理由与做房间时必须
inherit ROOM 一样　OBJECT 是最基本的物品, 如果你要做的东西是武
器　防具　地图等, 你必须 inherit WEAPON, ARMOR, MAP 等等才能获
得这种类别的物品所拥有的特性

        物品的重要函数只有 create() 与 init(), 作用与 ROOM  中的同
名函数大致相同　

[create() 函数]

    要写 create() 函数, 最好的方法是拿现成的同类物品来修改　因
为不同类的物品往往可以 set 不同的属性, 而且特性极多, 有重量　
价格　攻击力(武器)　防御能力(防具)　使用寿命(火把)等等　很难记
得完整, 所以我劝你找一个较完整档案来修改　


[init() 函数]

    与 ROOM 中的 init 函数类似, 但是被呼叫的时机多了许多, 共有
下列的几种情况:

1. 物品摆在房间中, 有一个玩家走进来　
2. 一个物品突然出现在某个玩家所在的房间中　
3. 一个物品突然出现在某个玩家的物品栏中　

物品的 init 函数大多还是用在写 add_action 上面, 这些 action 会
生效的场合归结起来很简单, 就是:

    「玩家用 l 或是 i 指令看得到这个物品的时候」
同一个房间中他人或npc身上的东西时不算, 装在袋子的东西不算　这
点要注意一下　
     (其实既然都是object，那么实际上房间和物品并没有本质的不同，因此在
      房间上的 create() init()函数用法和房间相同，正如前面说的，可能
      有一点区别的就是物品的init()函数被触发的机会多一些而已。
                                        ---lnwm注。)

[npc]

        简单的npc很好做, 连 init 都不用写, 只需要写 create(),  唯
一的问题是属性太多了, 要一一理解得花上相当的时间才行　


        会做复杂动作的npc则需要相当的技巧, 并且了解有哪些变量可以
被拦截下来改写利用　等你有一定的程度时, 再来找个npc参考参考较
好　


        npc要 inherit NPC 也没有 refresh() 这个函数　

[程序必须的概念]

        你必须了解, 在 LPC 中最重要的一个概念是对象(object) 当你想
做任何动作时, 都要考虑到这个动作是哪一个 object 所做的, 不然很
容易导致错误　LPC 的语法并不严谨, 有些场合为了省事可以将函数是
由哪个对象所作的省略掉, 例如我们在 create() 函数中最常看到的
set(), 事实上最严谨的写法应为 this_object()->set()　write() 则
为 this_player()->write()　
        (对，我们必须弄清楚，object 的概念是整个lpc的核心。
         往深一点说，每个object无非是一个包含了数据结构和内部
         外部函数的对象，他的数据结构决定了它的属性，比如房间的
         名称，玩家的skills等等，而他的外部函数提供了修改这些
         数据结构的方法，比如 set_skill("xkx",1000)
                         比如 set("title","大侠")
         这里set_skill()和set()函数就是object和外部的接口。
         数据结构和接口函数就拼出了一个object。
                                                        ---lnwm注。)         
         
    说这麽多只是为了强调一件事: 你能抓出一个物品的 object 变量
就能让他干一切他所能做的事　

[this_object() 与 this_player()]

        这两个函数是系统所提供的函数, 也是最最好用的两个函数　在你
写作一个对象 (房间　物品...etc.)时, this_object() 表示自己这个
对象　
         (讲清object的结构后，你必须清楚object的所谓封闭性。
          当我们在程序里写 set("name","长剑")时，实际上是
          this_object()->set("name","长剑")的简略写法。
          这样set("name")的不是其他的东西，每一个object有自己独立的
          数据结构，它能与其他object严格区分开来。
          即使是同一个长剑程序，当你clone了两把时，在内存中就有两个
          完全独立的长剑object，你对其中一把做的任何处理如改名，改
          威力完全不影响另一把的数据，这就是object的封闭性。
                                 ---lnwm注。)


        this_player() 则比较复杂, 它会传回一个属於玩家类型的对象　
这个玩家在 init 中就是触发 init 的那个玩家　this_player() 会跟
著函数呼叫一直传递给所有被 init 呼叫的函数, 包括 add_action 中
所定义出来的函数, 在这些函数中, this_player() 就是表示做动作的
那个人　



[present() 函数]

        常常, 我们只知道一个对象的名字, 却不能用个 object 类型的变
量指向它
     　 object=present(string "id",object env) 
函数在此时就可以派上用场, 你给定你要找的对象的名字, 
与它的所在地 (某个房间或某个人), 函数就会传回他所找到的对象　

    简单的想, present 函数其实就是在一个房间里找出某个名字的物
品的函数　它是同类型找物品的函数中最有用的一个, 其余的函数还有
find_player(), find_living() 等等　
         (这里再强调一次，名字不过是一个object的数据结构中的一个
          部分，单单一个名字没有任何意义。
          present,find_living,find_player函数就是从名字(id)
          找到这个object，有了这个object才好对它做操作。
          在mud里你 help present
                    help find_living
                    hrlp find_player
          能看到这几个函数的详细用法。   ---lnwm注。) 

[environment(), first_inventory(), next_inventory(), all_inventory()]

        这一组函数跟对象所处在的位置有关　 environment(object ob)
传回了对象 ob 所处在的地点, 例如 ob 是个玩家或生物, 那麽这个函
数会传回 ob 所在的房间; 如果 ob 是个物品, 那麽传回的就是携带著
 ob 的生物, 或是 ob 所在的房间 (如果没有任何人带著它)

        first_inventory(object ob)  所传回的是 ob 中的第一个对象,
如果 ob 是房间, 则传回第一个物品或是生物, 如果 ob 是生物, 则传
回他身上所带的第一个物品　

        next_inventory(object ob) 通常跟著 first_inventory()  一起
使用　它的功用是传回 ob 的下一个物品, 在同一个 environment 中　

        all_inventory(object ob) 类似於 first_inventory(),  但是它
所传回的是包含了所有物品的一整个阵列　
        (上面谈的是环境问题，一个object(除房间外)都要有自己的环境，
         所谓环境就是这个object在什么地方放着，是一间房间还是一口箱子
         还是一个人身上，环境通常是另一个object。  
         比如物品A和B放在一个人M身上，那么上面的函数就给出了它们的关系
         M=environment(A);
         M=environment(B);
         A=first_inventory(M);
         B=next_inventory(M);
         A=all_inventory(M)[0];
         B=all_inventory(M)[1];
                                           ---lnwm注。)
[更进一步的提示]

    LPC 的函数群有三个, efun, lfun, simul_efun　它们提供了绝大
部分的功能。

[关於输出输入讯息的各个函数的提示]

can_read_chinese
printf, sprintf
scanf, sscanf
write, say, shout
tell_object, tell_room

[关於对象操作的函数]

clone, new                             (变出新object )
destruct, remove                       (摧毁object )
move, move_player, move_around         (移动object   ---lnwm注。)

              (这些函数不可能一一讲解了，你可以在mud里用help <函数名>
               来看(英文呦)，然后再放到程序里自己试试。  ---lnwm 注。)
