跳转至内容
  • 欢迎
  • 版块
  • 最新
  • 标签
  • 热门
  • 用户
  • 群组
皮肤
  • Light
  • Brite
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • 默认(不使用皮肤)
  • 不使用皮肤
折叠
品牌标识

Hellclient 社区

  1. 主页
  2. Script脚本
  3. 深入浅出制作全自动Mud机器人-主逻辑

深入浅出制作全自动Mud机器人-主逻辑

已定时 已固定 已锁定 已移动 Script脚本
全自动机器人架构
1 帖子 1 发布者 15 浏览
  • 从旧到新
  • 从新到旧
  • 最多赞同
回复
  • 在新帖中回复
登录后回复
此主题已被删除。只有拥有主题管理权限的用户可以查看。
  • jarlyynJ 离线
    jarlyynJ 离线
    jarlyyn
    写于 最后由 jarlyyn 编辑
    #1

    对于一个机器人来说,并不需要一个主逻辑,完全可以多套逻辑并行作用。

    但对于写机器人的你我来说,大脑还是更适合单线程的模式。所以在机器的合适的地方维护一套主逻辑,即降低开发的难度,又增加维护的效率,个人认为是性价比很高的一种方式。

    主逻辑的入口

    正常情况下,主逻辑是在正常运行时不调用的调用的。所以,在写主逻辑时,从什么地方进入,调用主逻辑,是我们首先要考虑的点。

    定时器入口

    其实,通过定时器/心跳来调用主逻辑,在我看来是正道。市面上的各种机器人,自动驾驶,本质也是在每个tick计算当前的状态和应该进行的操作,从实时性,反应,效率来看,基于定时器的主逻辑都是最强的。

    但是,万恶的但是来了,对于机器来说,完全基于tick来维护太难了。这需要能很细的拆解人物,分配到每个tick,然后还要为tick建立上下文,能保证持续性动作的正常实行。

    这个难度太大了,很强,但性价比极地。

    所以我完全不建议机器人的主逻辑以tick的方式来实现。

    当然,比较简单又要求实时性的子系统可以基于tick处理,典型的就是战斗子系统。

    触发入口

    做一个特殊的触发,一般是利用Mud的回显机制,然后再执行玩任务是时候,想法让mud调用这个触发。

    怎么说的,从一般客户端的设计,很容易的就会形成一套以出发为入口的代码,而且在初期很行之有效。

    但是,如果要做一个足够复杂的机器,触发作为入口就会很勉强了,还要面对服务器本身的限制。

    回调入口

    回调作为入口,就纯靠代码来控制出发主循环。优点是不依赖mud,而且性能和可控性更高。

    缺点就是需要有一个完整的统一的架构,将回调和回调后执行的代码组织起来,所有的代码也不能简单的通过出发执行,需要进行一定的抽象。

    我的newhelljs就是利用回调入口的机制,执行完当前代码片段后,主动调用App.Next进行控制权的释放,由代码开始调用主逻辑。

    主逻辑的组织

    在决定主逻辑的调用方式后,我们就要决定主逻辑的代码怎么组织了。常见的可能有以下方法

    触发多米洛骨牌

    通过预先设置好的一系列触发,通过开关触发的形式,一步一步依次执行。

    这种组织方式,配合合适的工具,在任务的小环节上极强的,我在newhelljs里也 做一个plan/task系统来更好的保证骨牌的稳定性。

    但在宏观层面,整个机器人架构的层面,这种操作太细了,无法负担起过于复杂的机器架构

    判断if队列。

    就是收集可靠信息,然后通过一长串if(){}eleseif{} 的形式,判断当前应该做什么。

    进一步的,可以采用责任链的实际模式,为不同的判断和对应的处理代码,封装为一个个的类,然后通过id进行全局注册。

    这样可以通过一个id的数组,比如["hp","money","heal"]这样的形式,快速的定义和组合不同的工作流程了。

    if队列在简单任务里效果极好。但复杂任务的话,复杂度就有点超过if队列的承受范围了。

    在newhellljs里,我用责任链去实现了准备模块,效果非常好。

    状态机模式

    状态机模式是一个很有名的模式,但是在mud机器人里并不好用。

    因为Mud机器人里的状态太多了,互相之间的转化太多,用状态机来处理mud,需要维护的状态会指数上升,是一个天文数字。

    导致实际使用时都会进入一个中间态,而不是直接转换,很不适用。

    我在pkuxkx.noob中尝试引入状态机,结果比较失败。

    当然,状态机也有其优势,主要是可配置性强,可以显示的制定进入状态和离开状态时执行的代码。同时也的确客观存在状态这个存在。

    所以我在newhelljs里还是小范围的引入了状态机。我给不同的任务设置了不同的stance,在进入不同组的stance会出发stance-leave和stance-enter,这样用户能很方便的在不同类型的任务(比如战斗/非战斗)任务之间执行一定的指令,这也是一个很明显的简化状态机模型。

    指令队列缓冲模式。

    指令队列缓冲模式指维护一个缓冲池,在空闲时依次弹出最前面的指令执行,然后缓冲池可以进行清除,插入,追加,压入新队列,快照/还原等操作。

    这种模式,弹性很大,而且比较接近于人的思维模式,分配一系列任务,依次执行,遇到意外或者判断动态的切换之后的工作。

    缺点一样,更复杂,而且更重要的是需要有完善的异常介入模式,对整个机器的完成度要求更高。

    newhelljs中使用了Commands模块,把大部分功能都注册为Command,通过App.Next弹出新指令的方式来运行代码。

    我的建议

    我的建议是,主逻辑的入口,尽量用程序回调这种依赖最少的方式调用。

    具体的组织,根据代码的规模

    用责任链(固定流程)或者指令队列缓冲(动态维护流程)+意外处理的方式组织。

    1 条回复 最后回复
    • jarlyynJ jarlyyn 在 引用了 此主题
    回复
    • 在新帖中回复
    登录后回复
    • 从旧到新
    • 从新到旧
    • 最多赞同


    • 登录

    • 没有帐号? 注册

    • 登录或注册以进行搜索。
    Powered by Herbrhythm.
    • 第一个帖子
      最后一个帖子
    0
    • 欢迎
    • 版块
    • 最新
    • 标签
    • 热门
    • 用户
    • 群组