我想從更根本的東西談起。
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 的概念其實是差不多的,越早理
解其本質,就能越早上手使用。