Re: [轉載] [蟑螂賀失戀] 中階 LPC 第1~2章
看板mud_sanc (Sanctuary - 聖殿)作者laechan (小太保)時間17年前 (2009/03/06 16:39)推噓0(0推 0噓 0→)留言0則, 0人參與討論串2/2 (看更多)
其實聖殿大部份的 wiz 也都具備了中階 LPC 的 70% 能力,很多
很像知識性的東西其實不用研究的那麼深也會用,只不過要你講它
的架構啦、理論之類的就不知從何講起。
可以去研究啦..我是覺得 socket_xxx 之類的東西蠻可以研究的。
(我太懶了所以不會用,不過 nobu 會,可以問他)
這兩章講的東西,底下做一個補充說明,其實重點在第二章。
每到遊戲管理者設定的週期, driver 呼叫 reset() 函式
這個通常在 driver 存在的 bin 目錄下的 config.xxx 中設定
,但有的 mud 會自訂 reset 方式,例如聖殿在 weather_d.c
中去做的就是其中的一種。
driver 定義了一套稱為外部函式的函式
這個我稱之為「天外飛來的」函數,如 this_player(),每個
wiz 都會用,那現在你至少應該知道它的架構應該類似..
varargs object this_player(int i)
{
return 一個啥小給你;
}
若是 driver 定義的就是 efun,若是我們 wiz 自己擴充的,
就是 simul_efun,這個通常匯集在 /adm/obj/simul_efun.c
中,它的架構類似..
#include "/adm/simul_efun/xx1.c"
#include "/adm/simul_efun/xx2.c"
.
.
.
重點不是匯集了幾個 .c,而是匯集了寫在這些 .c 中的函數
,例如 chinese.c 裡頭就定了一堆跟 chinese 相關的函數
,如 skill_name、to_chinese、chinese_number、...等。
有些東西適合寫成全域函數,這個以後提到家族時會順便介紹
一旦遊戲啟動, 並且正確地執行功能, driver 就進入一個迴圈
這個我的簡易解釋是「心跳」,你可以想像一個程式被執行且
常駐了,它每一週期時間就會「跳」一下,人在每個心跳期間
會做一些事,例如打字、挖鼻孔、說一句話、看美眉、.....
同樣的 driver 在每心跳期間也會做一些事,有些是它固定會
做的,有些就看它有沒有接受到什麼額外的命令。
文裡也有提到「在週期結束時, 呼叫每一個有 heart_beat()
函式的物件」,所以解讀為 driver 的心跳應該沒啥問題XD
那,這個週期是可以控制的,聖殿原本跟其它 mud 一樣設定
每秒跳一下,但某個時間點開始就改成了每兩秒設一下。
在玩家物件中有一個叫做 "cmd_hook()" 的函式
這個東西放在 /std/user.c 中,我是最近一兩年才去瞭解它
是啥(我很懶,會用就好XD),簡單的說,我們要設定一個房間
可以在它裡頭下啥指令,用 add_action,我們會給一個指令。
問題:那有沒有更溯源的指令指定方式,我只要有下指令它都
能知道?
用的就是 cmd_hook,例如你在某房間的 init() 加上底下的
東西..
add_action("cmd_hook","",1);
然後再加上底下的函數...
int cmd_hook(string cmd)
{
string verb=query_verb();
write("cmd="+cmd+", verb="+verb+"\n");
return 0;
}
然後你在該房間下 look here
> look here
cmd=here, verb=look
上面至少學到了 query_verb() 就是讀出你現在下的指令是啥
,然後你如果要直接在「玩家下啥指令」的部份做一些過濾或
特殊處理的話,方式就類似上面那樣。
要注意的是 return 1 跟 return 0,上例是 return 0,它的
意思就是「不管你下了啥指令,我先秀出 verb 跟 cmd,然後
再執行它原先要執行的東西」,例如我下 look here,它先秀
給我看,然後才顯示下 look「原先會產生的結果」。
各位在自己測試時千萬別用 return 1 嘿,不然就要雙開進來
救自己哩。
set_heart_beat (heart_beat) 與 call_out
各位 wiz 們應該知道 call_out 用太多對聖殿不好,有些處理
方式我們都已經改在物件中使用 heart_beat 來處理了。
文裡提到「有心跳的物件越多, mud 每個週期需要處理的時間
也就越久.有心跳的物件已知是 mud 貪求 CPU 時間最主要的
因素.」
有個 mud 的 imm 曾問過我怎麼讓 mud 的負荷人數可以提高,
我給它的其中一個建議,就是「怪物不一定都要有心跳」,我
忘了哪個 mud 了,不過它說那樣做之後確實產生了明顯的效果
聖殿某些戰爭採用底下的寫法..
call_out("call_mob_group1",5);
call_out("call_mob_group2",10);
call_out("call_mob_group3",15);
我沒記錯的話在聖殿,dfire 第一次採用這樣的寫法,我之後的
世紀末戰爭也使用類似的寫法。程式執行到上面時,它就一次排
了三個排程:五秒後怎樣、十秒後怎樣、十五秒後又怎樣
早期的寫法則是串接式的,我們知道 5 秒後它會呼叫 group1,
所以我們在 group1 的最底下加上..
call_out("call_mob_group2",5);
這樣 5 秒後它先執行 group1,「再五秒後」才執行 group2。
這兩種寫法的差異就是「一次」被寫入 driver 記憶區的量,後
者會比較少,而且 5 秒後呼叫 mob_group1 後,原先被寫入的就
釋出,然後才寫入新的東西。
按 callouts 指令時就可以顯示目前有幾個 call_out 排程。
兩者依目前電腦的規格來說其實差別已經不太大,要採用簡易的
寫法自然以 dfire 的寫法較好,但根據理論,它對 driver造成
的負擔會比較大一點點。
而以目前來說其實給予戰爭系統「心跳」,就可以很大一部份取
代掉 call_out 的大量使用,這也不失為一個好的方式。
Laechan
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 218.170.228.153
討論串 (同標題文章)
完整討論串 (本文為第 2 之 2 篇):
mud_sanc 近期熱門文章
PTT遊戲區 即時熱門文章
15
19