作者laechan (小太保)
看板mud_sanc
标题Re: [转载] [蟑螂贺失恋] 中阶 LPC 第1~2章
时间Fri Mar 6 16:39:27 2009
其实圣殿大部份的 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