一步一步在北侠做机器人
本帖最后由 jarlyyn 于 2021-10-24 01:54 AM 编辑周末,带娃之余发现,日常玩的Mud当了……
想起之前已经在http://pkuxkx.net/forum/thread-46312-1-1.html 问过北侠机器人的尺度。
那么便先做一点吧。
https://github.com/hellclient-scripts/pkuxkx.noob
正好边做边说下思路,希望对别人的做机器有所启发。
这次的目标是做一个新人用机器人。
[*]能方便快速的在城市关键点(广场,醉仙楼)和门派掌门之间进行移动
[*]能补充食物,水,存取款,吃喝,修理武器
[*]能做简单的新人任务,抄书之类
[*]能做整备,恢复内力,学习消耗pot, 打坐等
[*]能让用户自定义去学习和学习回来的路径
[*]能提供工具让用户输入路径,进行遍历定位,在用户输入的路径上搜索制定目标,下命令(比如kill)停止等待用户操作
基本是一个全面的机器人,当然,功能上是受不少限制的,但架构还是比较完整的。
机器人会基于我自己的客户端开发。但我的客户端本身就是提供对mushclient的一定程度的兼容,甚至有mcl转换的工具,所以对mush机器人制作应该还是有一定的参考意义的。
进阶篇见
http://pkuxkx.net/forum/thread-46453-1-1.html
要做机器人,先要解决一个问题。什么是机器人。
单单一个触发是不能称之为机器人的。
那么很简单,机器人本质就是一个状态机罢了。
一个核心主程序,根据当前的状态,判断下一步应该进行什么操作,再加上一点意外判断。
恩,就是这么简单。
写Mud机器人是一个没什么难度的事情。当然,这不是说写机器人没意义。而是说,写机器人是一个更工程化的事情。
机器人更多要解决的问题时:
[*]长期稳定性
[*]可维护性
[*]多功能性
所以,是个复杂而不难的事情,非常需要耐心,责任心,毅力。
话题说话回来,写机器人,无非是解决这3个问题
我是谁 我在哪 我要做什么
上一楼说过了,写机器人是一个工程问题。
所以,我们先要订好机器人的架构。
首先,我把机器人分为3层,5个部分,分别是
[*]入口,main.js,用于接受游戏的时间(如断线等),并引入其他代码
[*]框架层,app.js,建立一个全局对象,所以开发将建立于这个对象之上,引入常用模块,统一管理数据,接口,模块,回调,并提供Debug工具。
[*]核心层 core,对于mud本身最核心的信息发送/接受处理,不包含义务逻辑
[*]数据层 info 路径,城市,npc,道具的信息,属于业务支撑部分。在数据层有个最特殊的地方,是和行走/移动紧密集合。
[*]业务层 bussness 实际的功能实现的部分
核心层-数据收集-我是谁
好了,来到代码阶段了。
做机器人,首先就是要做好信息收集,给状态机做决策依据
对于类侠客行mud来说,基本信息一般包括这几类
[*]当前房间信息
[*]用户状态(气血,内力等)
[*]用户信息(门派,存款)
[*]道具
[*]技能
由于我并不玩北侠,唯一的id没有道具和技能,所以今天先把前三块做了。
大师级的人物啊!!! 本帖最后由 jarlyyn 于 2021-9-6 02:38 AM 编辑
房间信息
北侠的房间信息是很好处理的,至少比我玩的mud简单。
北侠的房间信息打开是这样的
移动或look后看到
先是房间名 ,特点是顶格,后面有个减号
然后是房间描述
接着是出口信息
最后是房间内的对象,特点是连续的空两个开头的,带括号的文字
那么简单,让我们通过房间名来触发后续其他gourp,以出口信息为第二阶段,到收到第一个不是连续两个空格的信息结束,收集信息
https://github.com/hellclient-sc ... script/core/room.js
有一个特殊点是,虽然我这个机器人为了不踩线应该不使用出口信息,我还是处理了下,排了下序。
使用我app.js 自带的/Debug()函数,在查看房间后,可以看到收集到的信息如下
{
"Room": {
"Name": "中央广场",
"Desc": " 北大街 \n | \n 西大街---中央广场---东大街 \n | \n 南大街 \n 这里是扬州城的中心,一个很宽阔的广场,地面由青石铺就。一些游手好闲的人在这里溜溜达达,\n经常有艺人在这里表演。中央有一棵大榕树,盘根错节,据传已有千年的树龄,是这座城市的历史见证\n。树干底部有一个很大的洞 (shudong)。你可以看到北边有来自各地的行人来来往往,南面人声鼎沸,\n一派繁华景象,东边不时地传来朗朗的读书声,西边则见不到几个行人,一片肃静。\n 你可以看看(look):baoku,shudong,<air>,<node>。\n 「盛夏」: 起风了,空气中弥漫着燥热的气息。\n",
"Objs": [
{
"ID": "Rong shu",
"Name": "大榕树"
}
],
"ObjsMap": {
"rong shu": "大榕树"
},
"Exits": [
"down",
"east",
"north",
"south",
"up",
"west"
]
},
"HP": {},
"Score": {}
}
恩,信息还是比较全的。
这是在扬州广场,很明显有个独一无二的对象,大榕树。
之后做行走模块的时候,我应该会通过当前房间是否有Rong shu然判断是否在扬州广场。
用户信息
这个就是脏活……
北侠有一点好,描述清晰
在看到
┌───个人状态────────────┬───────────────────┐
这行话后,打开player_hp触发器组
同时player_hp的
└──────────────────────────────北大侠客行────┘
负责关闭本组
代码在
https://github.com/hellclient-scripts/pkuxkx.noob/blob/cfd483d980938d9a8fb1e3abe0fbb81290637f7b/script/core/player.js
同样的在hp命令使用 /Debug()
得到的信息如下
{
"Room": {},
"HP": {
"eff_jing": 112,
"jing": 142,
"per_jing": 100,
"eff_jingli": 100,
"jingli": 100,
"jiajing": 0,
"eff_qixue": 121,
"qixue": 121,
"per_qixue": 100,
"eff_neili": 0,
"neili": 0,
"jiali": 0,
"eff_zhenqi": 0,
"zhengqi": 330,
"eff_jingqi": null,
"jingqi": 2929,
"eff_drink": 0,
"drink": 330,
"drink_status": "饥渴",
"exp": 3,
"status": "健康"
},
"Score": {}
}
恩,我这个id饿了真实世界的好几个月了,饿不死人真是好事。
然后就是个人信息,也就是score了
传统来说,侠客行类游戏score虽然没hp那么重要,但要做人性化,特别是新人向的机器的话,也是很重要的。
score里的数据其实有3类
[*]数值型的,通过 -0进行类型转换
[*]字符型的,直接保存
[*]中文数字,这个我用我其他mud的代码,转成了阿拉伯数字
做法也一样
┌───人物详情────────────────────────┬───────┐
开启触发组
触发组里的 └────────────┴────────────┴────北大侠客行────┘
负责关闭触发组
代码也在 https://github.com/hellclient-scripts/pkuxkx.noob/blob/cfd483d980938d9a8fb1e3abe0fbb81290637f7b/script/core/player.js
同样的,/Debug()的信息为
{
"rank": "武当派第四代弟子",
"name": "杰林修",
"id": "Jarlyyn",
"bl": 23,
"wx": 17,
"gg": 21,
"sf": 19,
"fy": 15,
"rm": 18,
"lx": 30,
"ds": "?",
"country": "无国籍",
"family": "武当派",
"age": 15,
"teacher": "谷虚道长",
"gender": "男性",
"loyalty": 0,
"birthday": "戊子年十一月二十一日子时七刻",
"chushi": "无",
"marry": "未婚",
"panshi": "无",
"kill": 0,
"job": "未入职",
"saving": 0,
"killed": 0,
"morality": 0,
"wuxuepoint": 0,
"deaths": 1,
"reputation": 0,
"guojiapoint": 0,
"shaqi": "正常",
"wish": 0,
"shizhan": 0
}
}
好了,我今天的工作就是这三个部分,其实是比较脏的活了。
最后统一获取到的信息为
{
"Room": {
"Name": "中央广场",
"Desc": " 北大街 \n | \n 西大街---中央广场---东大街 \n | \n 南大街 \n 这里是扬州城的中心,一个很宽阔的广场,地面由青石铺就。一些游手好闲的人在这里溜溜达达,\n经常有艺人在这里表演。中央有一棵大榕树,盘根错节,据传已有千年的树龄,是这座城市的历史见证\n。树干底部有一个很大的洞 (shudong)。你可以看到北边有来自各地的行人来来往往,南面人声鼎沸,\n一派繁华景象,东边不时地传来朗朗的读书声,西边则见不到几个行人,一片肃静。\n 你可以看看(look):baoku,shudong,<air>,<node>。\n 「盛夏」: 夜幕笼罩著大地。\n",
"Objs": [
{
"ID": "Rong shu",
"Name": "大榕树"
}
],
"ObjsMap": {
"rong shu": "大榕树"
},
"Exits": [
"down",
"east",
"north",
"south",
"up",
"west"
]
},
"HP": {
"eff_jing": 112,
"jing": 142,
"per_jing": 100,
"eff_jingli": 100,
"jingli": 100,
"jiajing": 0,
"eff_qixue": 121,
"qixue": 121,
"per_qixue": 100,
"eff_neili": 0,
"neili": 0,
"jiali": 0,
"eff_zhenqi": 0,
"zhengqi": 330,
"eff_jingqi": null,
"jingqi": 2929,
"eff_drink": 0,
"drink": 330,
"drink_status": "饥渴",
"exp": 3,
"status": "健康"
},
"Score": {
"rank": "武当派第四代弟子",
"name": "杰林修",
"id": "Jarlyyn",
"bl": 23,
"wx": 17,
"gg": 21,
"sf": 19,
"fy": 15,
"rm": 18,
"lx": 30,
"ds": "?",
"country": "无国籍",
"family": "武当派",
"age": 15,
"teacher": "谷虚道长",
"gender": "男性",
"loyalty": 0,
"birthday": "戊子年十一月二十一日子时七刻",
"chushi": "无",
"marry": "未婚",
"panshi": "无",
"kill": 0,
"job": "未入职",
"saving": 0,
"killed": 0,
"morality": 0,
"wuxuepoint": 0,
"deaths": 1,
"reputation": 0,
"guojiapoint": 0,
"shaqi": "正常",
"wish": 0,
"shizhan": 0
}
}
很明显,这已经够制作很完善的新人机器人了。
如果我会玩pkuxkx,已经能在脑海里构想几十个机器人模块怎么做了。
可惜,我不会,我的id还饿的死去活来的。
所以,我先休息下,明天周一还要上班,剩下的慢慢弄。
然后我所有用到的触发在
https://github.com/hellclient-scripts/pkuxkx.noob/blob/cfd483d980938d9a8fb1e3abe0fbb81290637f7b/script.toml
这个相当于mush的mcl文件,只是mush是xml文件,我用的是toml。
格式,参数基本是完全一致,但我的事件和mush有所不同。我是b/s架构,没有on_focus系列,多了一个on_assist(我有个类似windows 开始按钮的工具)和broadcast(跨游戏广播)时间
触发和脚本最大的区别是
我使用的是UTF-8,不是gbk的,中文不是固定2字节的,还是每个中文/英文长度都是1。
原因么,都2021,实在不想用gbk了。