我想从更根本的东西谈起。
LPMUD 我个人认为,它有几个重要的组成元素
1.data 资料
2.body 资料承载体(物件)
3.function 函数(方法)
4.program 程式(描述)
例如以底下的程式段为例
body function data串
↓ ↓ ↓
me->add_moneys(30000,"balance");
也就是说,LPMud 说穿了大部份的运作模式就是一句:
写 program 以便透过 functoin 对 body 进行 data 的存取。
^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^
手段 这才是最终目的
所以今天并不是因为 SetExits 这个函数表面上的意义是设定出口,
SetExits((["down":"002"])) 就等于房间多了往 down 这个出口的
资料,这是错误的。
我理解 LPMud 的组成元素,是以我能修改 tmi2_v3,也能修改 ds,
因为它们都是 LPMud,不管怎么变都是万变不离其宗,对我来说只差
在改 tmi2_v3 比改 ds 花的时间更少,也就是跟熟悉度有关罢了。
是以不熟悉 tmi2_v3_改、不熟悉 LPMud 的人,该如何从不熟悉到变
成熟悉?很简单,就是在看 code 之前,先理解 LPMud 上述的四个组
成元素就行了,这样你就会知道:
SetExits((["down":"002"]));
跟
Exits["room"]["down"]="/d/area/newbie/002";
这两个是等义的,差别在于前者透过函数存取资料,后者不透过函数
直接对本地变量资料进行操作。我的意思就是对 tmi2_v3 来说:
set("exits/down",QR"002");
跟
data["exits"]["down"]=QR+"002";
也是等义的。
既然是等义的,为什么不直接对变量资料进行操作就好,而要额外透
过函数来存取资料?
因为现实上,做任何事情都需要建立方法,就像你存在银行里的钱,
银行不允许你本人直接进金库存取,而是建立各种方法让你存取银行
里的钱一样(临柜存提款、网络银行、ATM提款机、..)。
临柜存提款 ──┐
│
网络银行 ───┼─→ 存取钱
│
ATM 提款机 ──┘
这些都是手段 它们的最终目的都是这个
所以我认为对想要熟悉 LPMud 的使用者来说,最重要的就是要先理解
资料的存在,以及很多的 code 其实说穿了都是在做资料的存取。
set("level",100); 资料的存取
SetExits((["down":"002"])); 资料的存取
vobjd->vobj_data("query","m002"); 资料的存取
new_stat(me); 资料的存取
map_delete(data,"exits"); 资料的存取
data["exits"]["down"]=__DIR__+"002.c"; 资料的存取
tmps-=({me}); 资料的存取
data["time"]+=10; 资料的存取
race=data["race"]; 资料的存取
.
.
至于建立各种方法与手段的种种考量,也并非重点,反而是要先理解
“为何要建立各种方法与手段?因为它们本来就各有考量”,才不会
让自己侷限在那些已存在的手段上,而无法去变通它。
就像世界上有各式各样的人类,它们的资料本质都是 dna,而人类或
是蟑螂,说穿了都是 dna 的载体罢了。人类在尚未了解 dna 这个东
西之前会说:人类是上帝拿泥巴造出来的。
我希望这个举例就足以充份说明,为何了解资料的存在,比了解其它
东西还要更优先的缘故。
例如以底下的房间物件来说:
void create()
{
set("short","一间房间"); 实际上在做 data["short"] 的存取
set("long","这是一间普通的房间.\n"); 实际上在做 data["long"] 的存取
set("exits/down",QR"002"); 实际上在做 data["exits"] 的存取
}
或许你会说:code 明明就没有看到 data 啊。
相同的,网络银行也没有让你看到白花花的钞票跟硬币啊,你看到的
只是数字,以及数字的改变。
那因此可以理解那些数字就是钱吗?当然不可以。
你存在银行里的钱才是“钱”。
那为什么明明是你的钱,银行却不允许你直接存取?这可以用一个很
简单的例子做说明:
void 提款(object 银行客户,int 提领金额)
{
string id=银行客户->读取("帐户ID");
银行客户->提款(提领金额);
纪录(id+" 在 "+ctime(time())+" 领出 "+提领金额);
}
那么任何透过上面的函数做提款动作的银行客户,在提款的瞬间,也
会同时被纪录。
银行客户->提款(提领金额); 类似 me->set("level",10); ─┐
├→ data["level"]=10;
提款(银行客户,提领金额); 类似 set_level(me,10); ┬┘
└→ 但是还可以做一些额
外的事情如纪录
(事实上 set() 也可以做额外的事情,只是为方便讲解就先不提)
对银行来说这样很方便,但是对银行客户来说,这样就很麻烦,因为
这本来就是相对的。为什么今天要设定一个房间非得要透过一堆 set
或是 setXXX,而不这样写就好呢:
> more /d/area/test_room.c
inherit ROOM;
void create()
{
::create();
data["light"]=1;
data["short"]="一间房间";
data["long"]="这是一间普通的房间.\n";
data["exits"]=([]);
data["exits"]["down"]="/d/area/newbie/002";
}
> update /d/area/test_room
/d/area/test_room: Updated and loaded.
> goto /d/area/test_room
You twitch briefly.
> look
[/d/area/test_room ]
一间房间
这是一间普通的房间.
明显出口有: down.
我的意思就是,你确实可以这样写。
因为重点从来就不是存取资料的手段为何,而是要理解这些手段的目
的都是为了存取资料,然后才是理解为什么要建立那些手段、以及它
们背后的原因是什么。
这才是身为一个世界的创造者所应具备的格局。
例如“人类是上帝拿泥巴造成的”,信仰者会将其奉为圭臬,但是以
我来说我接着就会问“那泥巴哪里来的?”“上帝造的?那上帝又是
从哪里来的?”...
反过来说今天如果我相信人类是上帝拿泥巴造成的,而它实际上是错
的,那会产生什么结果?
任何建立在“人类是上帝拿泥巴造成的”的种种教义,也会是错的。
就像以前人类相信天动说,并以天动说为基础建立了很多认知,可后
来才发现是地动而非天动时 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
↑
└这些通通都变成了垃圾
就像他妈的霍金讲了一辈子的黑洞,现在突然说:黑洞不存在!....
好像扯远了,总之,LPMud 说穿了就是这么回事,资料、物件、函数
、程式段,就是这些构成元素罢了,如何宣告一个资料及设定它的结
构,远比如何写房间怪物武防物品还要来的重要,对于浸润其它 mud
多年的 wiz 甚至 adm 来说,只要了解 LPMud 的本质,那上手 tmi2
mudlib 只是时间的问题而已,mud 的概念其实是差不多的,越早理
解其本质,就能越早上手使用。