关于MudCore框架的说明可看这里:泥芯(mudcore)- LPMUD游戏开发框架
此框架方便新MUD开发,但因为核心功能独立,也可以方便的集成在现有的任何MUD中,然后自己选择使用哪些模块和功能。
这里我们以侠客行100这个MUD为例,实现框架集成,让MUD功能更强大。
框架下载
因为 mudcore 是独立于MUD的框架,为了方便更新,推荐使用 git 管理,如果你的游戏本来就使用 git 管理,可以在你的游戏根目录下使用以下指令把 mudcore 做为子模块集成到你的游戏中:
git submodule add https://github.com/mudcore/mudcore
如果你的游戏没用 git 维护,也可以单独把 mudcore 使用 git 维护,在你的游戏根目录下使用以下指令下载框架:
git clone https://github.com/mudcore/mudcore
提示:如果下载速度过慢,可以使用国内镜像
https://gitee.com/mudcore/mudcore.git
如果你不习惯使用 git ,最简单的方式是直接下载点击这里下载 mudcore 后解压到游戏根目录。
代码引用
我们打开侠客行100的运行时配置文件 config.ini,找到 include directories,增加 mudcore 框架的 include 路径,修改后如下:
include directories : /include:/mudcore/include
现在在侠客行100全局头文件 /include/globals.h 最底部 #endif 前引入 mudcore.h,引入后代码如下:
···
···
···
// If you changed any of these defines, you'll need reboot to make it
// in effect.
#undef PROFILE_COMMANDS
// mudcore 框架头文件
#include <mudcore.h>
#endif
功能继承
代码引入后,我们可以根据需要继承框架的任何模块了。包括sefun、master_ob及各种守护进程提供的服务。
模拟外部函数继承
因为框架提供了非常多实用的模拟外部函数,为了直接使用,我们可以非常简单的继承下来,在 adm/single/simul_efun.c 文件最顶部加入以下代码:
// 继承mudcore框架的simul_efun
inherit CORE_SIMUL_EFUN_OB;
继承后mudcore框架提供的模拟外部函数都可以使用了,为了精减代码,LIB自带的同名同功能的模拟外部函数都可以删除了,比如atoi()、is_chinese()等,当然不删除也没有任何影响,游戏会优先使用你自己游戏中定义的同名函数。
我们可以启动游戏运行以下指令测试一下:
eval print_r(livings());
是不是格式化输出了所有生物对象?这里成功的直接使用了mudcore框架提供的模拟外部函数 print_r()。
再试试:
eval debug(bitmap_font("测试"));
应该可以看到:
这里 debug() 和 bitmap_font() 也都是框架提供的函数。
主控对象 master_ob 继承
master_ob 其实国内主要MUD相差不大,mudcore 框架自带的 master_ob 功能也很完善,我们可以直接引用框架的 master_ob 并清除自己 master_ob 中的同名函数,引入方式为在 /adm/single/master.c 文件最顶部加入以下代码:
inherit CORE_MASTER_OB;
不过 master_ob 非常重要,侠客行100游戏自己的 master_ob 功能是完善的,为保证安全,这里不继承框架。
守护进程继承
mudcore 框架当前版本自带的守护进程在侠客行100中都有类似的实现,我们可以选择继承框架的,也可以不继承,这里演示指南为了省事就不做继承处理,不过框架自带的 /mudcore/system/daemons/time_d.c 是一个不错的服务,我们可以引入到游戏中。继承的方式也非常简单,在游戏的 /adm/daemons/ 中新建文件timed.c,代码如下:
inherit CORE_TIME_D;
然后我们在全局头文件/include/globals.h中加入宏定义:
#define TIME_D "/adm/daemons/timed"
以后在代码中就可以使用框架的时间和计划任务守护进程啦。现在我们重启游戏后输入以下指令试试守护进程是否正常继承:
eval debug(TIME_D->real_time_description());
为什么要通过TIME_D继承使用而不是直接在代码中调用CORE_TIME_D?这是为了方便游戏自定义功能,在框架提供的方法不满足需求时可以自己在TIME_D中覆盖,保证框架功能不影响游戏功能。比如在我们自己的TIME_D中增加以下代码就能实现简单的计划任务:
inherit CORE_TIME_D;
void create()
{
// 设置真实时间计划任务
set_real_crontab(
({
"* * * * * *", (: debug("real_crontab! " + TIME_D->realtime_digital_clock()) :), "真实时间测试任务",
})
);
set_heart_beat(1);
}
关于计划任务功能可参考 CORE_TIME_D 的以下代码了解:
/* 计划任务说明 */
// 分(0-59) 时(0-23) 日(1-31) 月(0-11) 周(0-6) 年 任务(function) "备注"
// 星号(*):代表所有可能的值
// 逗号(,):可以用逗号隔开的值指定一个列表范围,例如,“1,2,5,7,8,9”
// 中杠(-):可以用整数之间的中杠表示一个整数范围,例如“2-6”表示“2,3,4,5,6”
// 正斜线(/):可以用正斜线指定时间的间隔频率,例如“21-5/2”或“*/10”
// 游戏时间计划任务
private nosave mixed *game_crontab = ({
// "5,25,45 * * * * *", ( : TIME_D->save() :), "存储游戏世界时间",
// "* * * * * *", (: debug("game_crontab! " + TIME_D->gametime_digital_clock()) :), "游戏时间测试任务",
// "5-15/3 * * * * *", (: debug("game_crontab! 5-15 " + ctime()) :), "测试任务",
});
// 真实时间计划任务
private nosave mixed *real_crontab = ({
// "*/2 * * * * *", (: debug("real_crontab! " + ctime()) :), "测试任务",
// "* * * * * *", (: debug("real_crontab! " + TIME_D->realtime_digital_clock()) :), "真实时间测试任务",
});
// 设置游戏时间计划任务
void set_game_crontab(mixed *crontab)
{
game_crontab = crontab;
}
// 设置现实时间计划任务
void set_real_crontab(mixed *crontab)
{
real_crontab = crontab;
}
功能模块继承
同理,我们可以灵活的选择是否继承使用 mudcore 框架提供的功能模块,因为侠客行功能模块相对完善,这里不继承框架的模块,也不做演示。
我们可以看出,所有功能都是通过自住选择继承的方式引入到游戏,不需要找到文件一个个的复制到自己的游戏中,而且框架本来完善的功能,我们自己的游戏中完全不需要再次写代码实现,减少不必要的重复工作。
冲突检查
框架核心代码不继承时不会冲突,但头文件 MOTD存在重复定义,因为侠客行的 MOTD 定义在 login.h 中,引入时机在框架之后,我们修改 /include/login.h 代码,在 MOTD 定义前加入以下内容:
#ifdef MOTD
#undef MOTD
#endif
集成框架后的游戏代码参考:https://github.com/MudRen/xkx100
目前框架功能还比较少,相对使用框架开发新MUD,成熟的MUD集成框架使用的优势还不足以体现,而且使用的用户过少,还需要大家多反馈和建议。后期会强化框架功能,让MUD开发者减少自己的代码量,不再去重复造轮子,在游戏集成 mudcore 框架后,你要做的是需要时更新框架(在mudcore目录下 git pull),就能保证使用最新的功能。