《使用MUDCORE框架从零开发LPMUD游戏》系列内容,通过教程既能熟悉 MUDCORE 框架的使用,也能学习LPCMUD游戏的开发,版权所有 mud.ren。
上一节中我们使用 mudcore 框架快速实现了最基本的游戏指令功能和帮助系统,后期根据游戏开发需要新增的指令类似实现即可。
本节我们为后续开发做一些基本的配置,说明mudcore目录结构和基本配置,包括如何自定义登录界面、如何正确的继承mudcore框架功能和如何设置预加载等。
自定义欢迎界面
自定义欢迎界面的实现非常简单,我们在 system 目录下新建 etc 目录,并新建欢迎界面文件 motd。
motd 内容如下:
+ * __ __ __ . __ __ * __ __
* . . | |__| |__| |__| |__| |__| |__| |
+ * |___.__.__.__.__.__.__.__.__.__.__.__.__
+ * . \|__|__|__|__|__|__|__|__|__|__|__|__|_
* |_|__|__|__|__|__|__|__|__|__|__|__|__
----------o o---------- |__|__/ \,__|_
`---.__ ^* \ __ / *^___,---' + |_|__| 勇者斗恶龙MUD |_|__
}_/| \_/ \/ |\_{ * |__|_| |__|_
* /^| ^,V \ \_|^{ ^ |_|__| * 游戏版权: 雪风@mud.ren |_|__
}__\ /(- -){ . + |__|_| |__|_
+ w,,w \..' . |_|__| * 游戏QQ群:285533476 |_|__
* `*||*' | \-.___ * |__|_| * 官方网站:dq.mud.ren |__|_
* {( \^ \__ '---_ + |_|__|___________________________|_|__
+ \\ \ )___ ~-. |__|__|__|__|__|__|__|__|__|__|__|__|_
)) ( ( '- \__ |_|__|_|__|__|__|__|__|__|___|_)\_|/~)
_______________/^,\_( \; DragonQuest \/~\__|___|__|_/\|____|__|_,.-~
_|__|__|__|__|_\/\/|_(_ \ , DQMUD '---` -_|_) `~(_|,.-~ .-
|_./ \,_|__|_/---\|__|_\/_ : ~-._ .___ .___
__| ||__|_/:::::\_|_|__(_ : __| _/______ _____ __ __ __| _/
|_|___|__|_|:::::::|_|__|__\ : / __ |/ ____// \| | \/ __ |
_|__|__|___|::::⭕|__|__|__\ /\_. / /_/ < <_| | Y Y \ | / /_/ |
|__|__|_|__|:::::!:|_|__|__|_^_|_( `~- \____ |\__ |__|_| /____/\____ |
|_|__|___|_|:::::::|__/~~~\__|___/ \/ |__| \/ \/
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\/\____________ ___ ________ ____________<~~~
勇者斗恶龙MUD Beta版 推荐使用 mudlet 或 tintin++ 客户端进行游戏
* 请登录游戏后输入“help tutorial”查看游戏指南^_^
提示:你可以根据自己的需要上色,具体可参考教程示例代码。
当我们在 globals.h 中宏定义 MOTD 文件位置后,会自动使用。
#define MOTD "/system/etc/motd"
现在我们再启动游戏,看看一切功能正常,而且启动界面变成我们自己定义的界面了。

你可以新建多个motd文件,命名为motd0、motd1、motd2等,然后把宏定义修改如下即可随机显示登录界面:
#define MOTD "/system/etc/motd" + random(3)
mudcore 功能继承
mudcore 框架提供了包括玩家注册登录所需的接口、守护进程和大量的函数。要充分利用框架,有必要有一些基本的了解。
| 目录 | 说明 |
|---|---|
| cmds | 框架提供的基本action指令 |
| docs | 开发者文档,包括框架模拟外部函数说明文档等 |
| include | 框架头文件,包括fluffos驱动内置头文件 |
| inherit | 框架特性继承文件 |
| system | 系统文件目录 |
| verbs | 框架提供的基本parser指令 |
| world | 框架示例世界环境 |
system系统目录
| 目录 | 说明 |
|---|---|
| system/kernel | 系统核心文件,包括master对象和simul_efun对象 |
| system/daemons | 系统守护进程 |
| system/object | 系统核心对象,包括登录对象、基本玩家对象和 VOID 环境 |
核心对象
| 名称 | 文件路径 | 核心功能 |
|---|---|---|
| CORE_MASTER_OB | /system/kernel/master | 主控对象,负责接收玩家连接请求、安全验证、日志记录等核心功能 |
| CORE_SIMUL_EFUN_OB | /system/kernel/simul_efun | 模拟外部函数对象,负责实现模拟外部函数功能 |
| CORE_LOGIN_OB | /system/object/login | 示例登陆对象,仅供参考,正式开发可继承使用 |
| CORE_USER_OB | /system/object/user | 示例玩家对象,仅供参考,正式开发可继承使用 |
| CORE_VOID_OB | /system/object/void | 临时环境,示例登录房间 |
所有核心对象有去掉CORE_前缀的同名宏定义,方便覆盖和继承,如LOGIN_OB。
系统头文件(Include Headers)
头文件在 /include/ 目录中,主要是常量宏定义和函数声明,框架基本提供如下头文件:
| 文件 | 说明 |
|---|---|
| ansi.h | 定义ANSI 色彩/游标控制码 |
| dbase.h | 数据增删改查功能(CORE_DBASE)函数声明 |
| function.h | 驱动提供,配合 functionp() 使用 |
| localtime.h | 驱动提供,配合 localtime() 使用 |
| mudcore.h | 框架全局头文件,需要在项目的 中引用 |
| mysql.h | 定义数据库配置 |
| origin.h | 驱动提供,配合 origin() 使用 |
| parser_error.h | 驱动提供,定义 parser error |
| runtime_config.h | 驱动提供,配合 get_config() 使用 |
| socket_err.h | 驱动提供,配合 socket_error() 使用 |
| socket.h | 定义 socket 类型,配合 socket_create() 使用 |
| type.h | 驱动提供,配合 typeof() 使用 |
系统函数(Simul-Efuns)
除驱动自带的 efun 外,框架提供了部分模拟外部函数,具体使用参考 /docs/simul_efun/ 目录,或查看函数源码(/system/kernel/simul_efun/)。
| simul-efun | 简介 |
|---|---|
| all_environment | 返回对象的所有环境 |
| ansi | 转换 $HIR$ 等为 ansi 颜色代码 |
| area_environment | 比較二個对象是否處在相同的區域座標中 |
| area_move | 將對象移動到指定區域的指定坐標位置 |
| area_move_side | 將who移到與me同一格的區域坐標位置 |
| array_sum | 返回数组元素的和 |
| assure_file | 建立文件目录 |
| atof | string 类型数字转 float 类型数字 |
| atoi | string 类型数字转 int 类型数字 |
| bitCheck | 检查数值指定为是否为1 |
| bitClear | 返回数值指定位为0的值 |
| bitmap_font | 处理中英文字符并点阵输出 |
| bitSet | 返回数值指定位为1的值 |
| break_string | 根据指定宽度换行显示内容 |
| cat | 输出文件内容到屏幕 |
| cecho | 随机颜色显示内容到屏幕 |
| check_control | 判断指定字符串是否包含控制字符 |
| check_return | 判断指定字符串是否包含换行符 |
| check_space | 判断指定字符串是否包含空格 |
| chinese_number | 返回中文数字 |
| chinese | 返回指定字符串的中文名称 |
| color_cat | 彩色输出内容到屏幕 |
| color_len | 统计字符串中颜色占用的长度 |
| config | 读取或设置游戏自定义配置的值(/config.json) |
| debug | 随机颜色输出内容至驱动控制台 |
| deep_path_list | 获取指定目录及子目录下的文件列表 |
| element_of_weighted | 根据权重随机返回元素,权重高机率大 |
| env | 读取或设置游戏自定义配置的值(/data/.env) |
| expand_keys | 把键为数组的映射展示 |
| file_exists | 判断文件是否存在 |
| getcid | 返回复制对象的ID |
| graph_draw | 自定义进度条绘图 |
| highest | 返回一组数值的最大值 |
| is_chinese | 判断指定字符串是否为中文 |
| is_english | 判断指定字符串是否为英文 |
| is_numeric | 判断指定字符串是否为数字 |
| log_file | 记录日志到指定文件 |
| log_time | 方便日志记录的 ctime 时间格式 |
| lowest | 返回一组数值的最小值 |
| msg | 智能区域消息 |
| number_string | 转化数字为科学计数法的字符串格式 |
| percent | 返回数字在指定基数上的百分比 |
| percent_of | 返回数据在指定倍数上的百分比 |
| print_r | 数组打印功能,格式化输出,开发调试用 |
| process_bar | 显示指定百分比的进度条 |
| pronoun | 返回中文人称代词 |
| range | 返回指定范围内符合条件的数值 |
| read_lines | 以数组的形式返回文件每一行内容,并跳过空行和#或;开头的注释行 |
| remove_ansi | 清理 ansi 颜色代码 |
| sort_string | 根据指定宽度换行显示内容,中文支持更友好 |
| sum | 返回一组数值的和 |
| tail | 输出文件尾部最多10行内容到屏幕 |
| unicode | UNICODE编码转字符,如 unicode(65) 或 unicode(0x41) 返回值为 A |
提示:因为mudcore框架持续更新,提供的接口和功能可能比教程中的更多。
在上一节中我们直接继承了框架的MASTER_OB实现了基础的登录注册,继承SIMUL_EFUN_OB让我们可以直接使用mudcore的所有系统函数。而对功能模块和守护进程,在我们的项目开发中,可灵活选择继承。
继承守护进程
守护进程是独立出来的系统服务,每个进程有自己的API可以调用,mudcore框架提供了以下守护进程方便使用:
| 名称 | 文件路径 | 核心功能 |
|---|---|---|
| CORE_AREA_PATTERN_D | /system/daemons/area_pattern_d.c | 区域模式环境样式模型管理 |
| CORE_CAMP_D | /system/daemons/camp_d.c | 游戏阵营守护进程 |
| CORE_CHANNEL_D | /system/daemons/channel_d.c | 负责处理玩家聊天功能和频道管理 |
| CORE_CHAR_D | /system/daemons/char_d.c | 负责处理角色数据,需开发者实现具体功能 |
| CORE_CHINESE_D | /system/daemons/chinese_d.c | 负责处理中、英文对照,以及一些与中文相关的功能,字典存档/data/e2c_dict.o |
| CORE_COMBAT_D | /system/daemons/combat_d.c | 负责战斗功能,需开发者实现具体功能 |
| CORE_COMMAND_D | /system/daemons/command_d.c | 负责指令及别名处理功能 |
| CORE_DBASE_D | /system/daemons/dbase_d.c | 负责系统数据存档处理,默认存储位置/data/dbase_d.o |
| CORE_EMOTE_D | /system/daemons/emote_d.c | 负责管理游戏表情动作和相应功能,默认存储位置/data/emote_d.o |
| CORE_ENV_D | /system/daemons/env_d.c | 游戏环境变量配置守护进程,默认配置文件为/data/.env |
| CORE_EVER_QUEST_D | /system/daemons/ever_quest_d.c | 随机任务守护进程 |
| CORE_HEADER_D | /system/daemons/header_d.c | 头文件自动生成系统守护进程 |
| CORE_INTERMUD_D | /system/daemons/intermud/i2d.c | MUD网际互联守护进程 |
| CORE_LOGIN_D | /system/daemons/login_d.c | 框架示例登录管理功能,可做开发参考 |
| CORE_NAME_D | /system/daemons/name_d.c | 负责角色姓名记录与检测,默认存储位置/data/name_d.o |
| CORE_NATURE_D | /system/daemons/nature_d.c | 负责控制游戏季节和天气变化 |
| CORE_QUEST_D | /system/daemons/quest_d.c | 游戏任务守护进程 |
| CORE_TIME_D | /system/daemons/time_d.c | 负责控制游戏系统时间和计划任务 |
| CORE_VERB_D | /system/daemons/verb_d.c | 自然语法谓词指令守护进程 |
| CORE_VIRTUAL_D | /system/daemons/virtual_d.c | 负责虚拟对象处理 |
所有守护进程有去掉CORE_前缀的同名宏定义,方便覆盖和继承,如LOGIN_D。
另外,在MUDCORE的/system/daemons/http/下面提供了http服务示例:
- iqa_d.c : 智能答问守护进程
- qq_d.c : QQ群聊天互通守护进程
- sms_d.c : 手机验证码短信守护进程
mudcore对所有模块如果没有需要覆盖的代码,可以直接继承不带`CORE`前缀的模块,不需要做任何配置,如直接继承`LOGIN_D`会自动继承`CORE_LOGIN_D`,当有需要调整功能时,再自己新建`login_d.c`文件重写代码,并宏定义`LOGIN_D`到自己的文件即可自动覆盖框架守护进程。
我们在 system 目录下新建 daemons 目录,并新建用户登录守护进程 login_d.c。代码如下:
// LOGIN_D:用户登录守护进程
inherit CORE_LOGIN_D;
当我们在 globals.h 中宏定义 LOGIN_D 文件位置后,会自动使用我们定义的守护进程控制提供功能。
#define LOGIN_D "/system/daemons/login_d"
预加载守护进程
关于预加载
preload中的内容可以实现自动加载,预加载的用处:1. 提前载入核心服务;2. 加载无法在游戏中自动载入的功能。示例中的登录守护进程可以不用预加载,因为在玩家登录时也会自动加载,但某些无法自动加载的服务必须从preload中载入游戏。
要实现预加载功能,直接在/system/etc/目录下新建对象预加载列表文件 preload
preload 内容如下:
/system/daemons/login_d
重要提示:如果preload文件内容是目录,则会自动加载目录下的所有文件。
如:
/system/daemons/
当我们在 globals.h 中宏定义和 PRELOAD 的文件位置后,会自动使用预加载功能。
#define PRELOAD "/system/etc/preload"
继承模块
mudcore框架提供了大量的功能模块可直接继承使用,继承文件在 /inherit/ 目录,实现了核心的功能片段,基本提供如下继承文件:
| 名称 | 文件 | 说明 |
|---|---|---|
| CORE_ACTION | /inherit/action.c | 角色行动接口,实现限制行为功能 |
| CORE_AREA | /inherit/area/area.c | 游戏区域环境标准接口,实现区域模式环境功能 |
| CORE_ATTACK | /inherit/attack.c | 角色攻击接口,实现战斗行为功能,需自己实现具体战斗方式 |
| CORE_CAMP | /inherit/camp.c | 游戏阵营接口,实现阵营声望相关功能 |
| CORE_CLEAN_UP | /inherit/clean_up.c | 自动清理接口,实现 clean_up() 方法的垃圾回收功能 |
| CORE_COMMAND | /inherit/command.c | 角色指令系统接口,实现生物对象特征功能 |
| CORE_CONDITION_MOD | /inherit/condition_mod.c | 角色增益功能接口,提供增益相关方法 |
| CORE_CONDITION | /inherit/condition.c | 角色增益状态控制接口,实现游戏BUFF功能 |
| CORE_DB | /inherit/DB.c | MySQL数据库接口,可以优雅的操作数据库的增删改查 |
| CORE_DBASE | /inherit/dbase.c | 数据存取功能接口,实现对象参数的增删改查功能 |
| CORE_DBSAVE | /inherit/dbsave.c | 系统数据存取接口,配合 DBASE_D 使用 |
| CORE_HTTP | /inherit/Http.c | HTTP客户端,方便发起http请求 |
| CORE_LIVING | /inherit/living.c | 生物对象功能接口,所有生物对接可直接继承使用 |
| CORE_MESSAGE | /inherit/message.c | 玩家信息处理功能接口,实现分页显示 |
| CORE_MOVE | /inherit/move.c | 对象移动接口,由角色、物品对象继承,方便移动 |
| CORE_NAME | /inherit/name.c | ID和名称接口,让对象可以被看见(查找)和命名 |
| CORE_NOCLONE | /inherit/noclone.c | 限制对象禁止被复制功能接口,需调用check_clone()检查 |
| CORE_ROOM | /inherit/room.c | 游戏环境标准接口,实现房间核心功能,需要继承DBASE、NAME、CLEAN_UP |
| CORE_SAVE | /inherit/save.c | 对象数据存取接口,主要是玩家角色使用存档和读档 |
| CORE_TEAM | /inherit/team.c | 角色组队功能接口,实现组队相关功能 |
| CORE_UNIQUE | /inherit/unique.c | 对象唯一性功能接口,注意和noclone不同,唯一性允许复制,但仅限一次 |
| CORE_USER_COMBAT_RECORD | /inherit/user_combat_record.c | 玩家战斗记录功能,实现玩家战斗数据记录 |
| CORE_USER_GMCP | /inherit/user_gmcp.c | 玩家GMCP功能接口,可配合mudlet客户端使用 |
| CORE_USER_QUEST | /inherit/user_quest.c | 玩家任务功能接口,实现玩家任务记录与管理 |
| CORE_USER | /inherit/user.c | 玩家对象功能接口 |
| CORE_VERB | /inherit/verb.c | 自然语法分析指令功能接口 |
| CORE_VRM | /inherit/vrm.c | 随机迷宫功能接口,实现随机迷宫功能 |
所有特征模块有去掉CORE前缀的同名宏定义,方便覆盖和继承,如_CLEAN_UP。
mudcore对所有模块如果没有需要覆盖的代码,可以直接继承不带`CORE`前缀的模块,不需要做任何配置,如直接继承`_ROOM`会自动继承`CORE_ROOM`,当有需要调整功能时,再自己新建`room.c`文件重写代码,并宏定义`_ROOM`到自己的文件即可自动覆盖框架模块。
为方便后续开发,这里演示如何继承覆盖mudcore框架模块,我们新建目录/inherit,在目录中新建二个文件living.c和room.c,每个文件的具体代码如下:
living.c
// 生物特征模块
inherit CORE_LIVING;
room.c
// 游戏标准环境模块
inherit CORE_ROOM;
这里我们自己实现了生物和环境功能模块,在globals.h中宏定义为_LIVING和_ROOM即可。
#define _LIVING "/inherit/living"
#define _ROOM "/inherit/room"
标准模板对象
除了继承模块、守护进程外,我们在开发中还应该把主要的对象标准化为模板,让游戏同类对象都继承使用。这些标准模板对象我们放在 std 目录中。这里我们细分标准环境对象 room、标准生物对象模板living和物品装备对象模板等。如:
.
├── living 标准生物对象目录
│ ├── mob.c 标准怪物对象
│ └── npc.c 标准NPC对象
└── room 标准环境对象目录
├── area.c 区域坐标模式环境
├── dungeon.c 地牢(室内危险区)
├── outdoors.c 户外(安全区)
├── room.c 室内(安全区)
└── wild.c 野外(户外危险区)
模块对象都是给游戏对象继承使用的,为了方便,我们先根据以上目录结构把所有文件建起来,内容为空,然后新建一个头文件stdoh.h,内容如下:
// 标准对象模板,继承使用
#ifndef STDOB_H
#define STDOB_H
// 标准环境对象模板
#define STD_AREA "/std/room/area"
#define STD_ROOM "/std/room/room"
#define STD_WILD "/std/room/wild"
#define STD_OUTDOORS "/std/room/outdoors"
#define STD_DUNGEON "/std/room/dungeon"
// 标准生物对象模板
#define STD_NPC "/std/living/npc"
#define STD_MOB "/std/living/mob"
// 标准物品对象模板
#endif
然后在globals.h中包含这个头文件:
// 标准继承对象
#include "stdob.h"
标准游戏对象
游戏中的基本公共对象我们放在 obj 目录中,是根据标椎对象模板生成的具体游戏对象,如装备、魔物等,主要为复制使用。另外,我们把玩家对象和连线对象也放在这里。这里先空着,等后续具体开发时再建目录和文件实现代码。
自动生成头文件
以上代码中我们为方便继承做了大量的宏定义,对守护进程和功能模块,因为这里只是简单的演示,才建了3个文件,实际开发中会有非常多的文件,为了偷懒,mudcore框架实现了自动生成头文件的功能,我们先在globals.h中定义自己的守护进程和继承模块的目录如下:
// 核心目录
#define INHERIT_DIR "/inherit/"
#define DAEMON_DIR "/system/daemons/"
然后运行create_include指令会自动在/include/目录中生成_inherit.h和_daemon.h,把这二个文件在globals.h中包含:
// 功能模块
#include "_inherit.h"
// 守护进程
#include "_daemon.h"
这样每次新建守护进程或模块后只用运行一次create_include指令即可自动更新头文件。

globals.h 配置
最后,我们看看更新后的 globals.h 文件,代码如下:
// The global include file is included automatically.
#ifndef GLOBALS_H
#define GLOBALS_H
// 游戏管理员帐号
#define WIZARD "test"
// 核心目录
#define INHERIT_DIR "/inherit/"
#define DAEMON_DIR "/system/daemons/"
// 功能模块
#include "_inherit.h"
// 守护进程
#include "_daemon.h"
// 标准继承对象
#include "stdob.h"
// 指令路径
#define CMD_PATH_WIZ ({"/cmds/wiz/", "/mudcore/cmds/wizard/"})
#define CMD_PATH_STD ({"/cmds/std/", "/mudcore/cmds/player/"})
// 其他
#define MOTD "/system/etc/motd"
#define PRELOAD "/system/etc/preload"
// mudcore框架头文件(请放在最底部)
#include <mudcore.h>
#endif
这一节主要是介绍mudcore框架的基本功能和核心模块的继承,代码上也只是演示了少量文件,通过globals.h宏定义来实现相关功能,为后续开发做准备。
最后 commit 我们当前版本:
git add .
git commit -m 'v1.2'
本节代码
附本节版本源码下载地址,如果下载使用,请在项目目录执行 git submodule update。