在现有MUD中集成MudCore框架操作指南

关于MudCore框架的说明可看这里:泥芯(mudcore)- LPMUD游戏开发框架

此框架方便新MUD开发,但因为核心功能独立,也可以方便的集成在现有的任何MUD中,然后自己选择使用哪些模块和功能。

这里我们以侠客行100这个MUD为例,实现框架集成,让MUD功能更强大。

框架下载

因为 mudcore 是独立于MUD的框架,为了方便更新,推荐使用 git 管理,如果你的游戏本来就使用 git 管理,可以在你的游戏根目录下使用以下指令把 mudcore 做为子模块集成到你的游戏中:

git submodule add https://github.com/oiuv/mudcore

如果你的游戏没用 git 维护,也可以单独把 mudcore 使用 git 维护,在你的游戏根目录下使用以下指令下载框架:

git clone https://github.com/oiuv/mudcore

提示:如果下载速度过慢,可以使用国内镜像 https://gitee.com/mudren/mudcore.git

如果你不习惯使用 git ,最简单的方式是直接下载点击这里下载 mudcore 后解压到游戏根目录。

代码引用

我们打开侠客行100的运行时配置文件 config.ini,找到 include directories,增加 mudcore 框架的 include 路径,修改后如下:

include directories : /mudcore/include:/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

功能继承

代码引入后,我们可以根据需要继承框架的任何模块了。

模拟外部函数继承

因为框架提供了非常多实用的模拟外部函数,为了直接使用,我们可以非常简单的继承下来,在 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("测试"));

应该可以看到:file

这里 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),就能保证使用最新的功能。

京ICP备13031296号-4