Screeps 游戏中的两大设计模式

screeps 系列教程

简介

作为一款代码主导的游戏,有代码的地方就有设计模式。本文就作为一篇拓展阅读性质的文章,来简单介绍一下 Screeps 中出现的两大设计模式:角色驱动型任务驱动型

角色驱动型

角色驱动型设计模式是指 将 creep 划分成不同的角色,每个角色都有着固定的任务和行动模式,不同角色之间的相互协作共同维持了一个房间乃至整个殖民地的正常运行。可以非常肯定的说,几乎所有的新玩家的代码都使用了角色驱动型的设计模式。

房间运维

角色驱动的优点

角色驱动型设计容易入门、方便调试,每个 creep 的工作非常的明确,所以在代码出现问题时你可以很容易的根据报错 creep 的角色定位到出现问题的代码。

并且由于代码结构简单,角色驱动在让 creep 执行一成不变的简单逻辑时产生的基础 CPU 消耗会更少。

角色驱动的缺点

这种设计模式最大的问题在于,随着游戏进度的不断深入,就需要设计越来越多的角色来应对新的任务。而且如果你的代码抽象没有做好的话,每次新增角色都将是一次痛苦的体验。

并且,角色型设计更适合于“静态”的工作逻辑。比如 "采矿 > 建造" 或者 "采矿 > 升级"。面对复杂、多变、多目标的工作逻辑,例如后期的资源搬运任务时,角色驱动就显得力不从心了。为了处理复杂的工作任务,你可能会选择将不同的任务按照优先级“分层”:

层层叠叠的千层任务

非常的复杂,并且在每个任务之前都需要使用room.find或者其他的方法判断是不是要执行该任务,要执行的任务优先级越靠后,就会导致在前面任务的判断消耗更多的cpu

并且这个任务列表越长,其中的优先级就越难以进行排序。例如在房间内出现敌人时要优先满足 Tower 的能量需求,而在 Lab 合成所需的原料来自于 Termial 时,就需要先从 Termial 中获取资源再转移至 Lab。为了适配这种“突发性”的优先级调整,会让你的代码逻辑越来越混乱,同时增加了出现 bug 的几率。

在接触到新的游戏内容后,你会非常纠结是在现有的角色上添加新的任务还是新增一个角色。

任务驱动型

在实际开发过程中,我们很容易就能发现:如果按照身体组成进行划分的话,日常基地维护的 creep 仅仅只需要分为如下两种:

  • WORK 为主的 工作型 creep
  • CARRYMOVE 为主的 运输型 creep

任务驱动型设计模式是 将所有的行动内容划分成不同的任务,每个任务都有自己的执行方法和要达成的目标,而 creep 只划分为几个基本的角色,每个 creep 都将在一组规则的指导下领取适合自己的任务并执行。

面向任务队列的 creep

这个设计模式的核心是 每个 creep 的工作内容并不是一成不变的。在当前的任务完成后完全可以切换至其他的任务。

在角色驱动型设计中,任务的发现和执行完全是由 creep 负责的,而在任务驱动型设计中,任务的发现和执行完全被拆开了(没有人不喜欢低耦合)。creep 接受任务,然后执行任务。而任务的发布完全由其他代码完成。在大多数情况下,每个建筑都会根据自身的情况决定是否发布一个任务。

例如,Tower 会检查自己的能量是不是没有满,以此来决定是否发布一个从 Storage 到自己的能量转移任务。而 Termial 会根据自己是否收到了一笔新的资源,来决定是否要发布一个从自己到 Storage 的资源转移任务。

这些任务都会被发布到一个固定的位置 (任务队列,或是任务池)。这样 creep 完全不用关心任务是怎么产生的,只需要埋头干活就好了。

互不关心的冷漠双方

优点

由于 creep 会只有俩个基本角色(工作型 / 运输型),而且同一时刻一个 creep 只会明确的做一件事。所以角色驱动型的缺点 角色过多任务优先级混乱 在任务驱动这里完全不成问题。

而且由于任务发布逻辑和执行逻辑的解耦,代码的结构会变得更加清晰,从而方便后期的维护工作。并且因为 creep 只监听任务队列而不会主动去发现任务,所以在空闲时会带来更低的 CPU 消耗。

回想一下角色驱动,在空闲时会根据优先级执行所有任务的检查工作,从而造成了 CPU 的浪费。

两个设计模式 creep 空闲状态的 CPU 消耗

缺点

任务驱动什么都好,唯一不好的就是:开发难度大。是的,对于任务驱动型设计来说,角色驱动设计里数量众多的角色并不是被消灭了,而是转化成了体量更小,更加灵活的“任务”,你依旧需要设计每个任务的逻辑。

并且不同于角色驱动型里简单编写代码就可以让 creep 进行工作。任务驱动型需要扎实健壮的“基础设施建设”,比如任务发布逻辑、任务队列的维护和检查、任务分配调度、兼容所有任务的 creep 运行框架 等。在这一整套代码完成之前,你甚至没办法完成一个简单的 creep 采矿然后升级控制器的工作流程。

并且,由于 creep 当前的工作完全取决于自己接到了什么任务。所以一旦出现 bug。你可能很难在后续检查中重现这个问题。你可能会陷入“这个 creep 刚才一直好好的,突然就报了个错,然后又正常运行了” 的问题循环中,想要追踪、重现和进行测试,你需要额外设计一些平时用不到,但是方便检查的模块。这无疑加大了开发成本。

二者的边界

在实际的开发游玩中,角色驱动型设计和任务驱动型设计并不是二元对立的。在很多时候,你完全可以将二者融合在一个项目里。例如,整体上使用角色驱动,而在“物流运输”等难以处理的地方使用任务驱动来减轻设计和维护上的压力。

两种模式相结合

并且需要着重强调的是,不要一昧的推崇任务驱动,不要觉得任务驱动很优雅就尝试把所有功能都并入到任务系统里。

想要合并所有功能,你需要从种类繁杂的任务中抽象出统一的模型,这对你的游戏理解和编程能力是一个极大的考验(事实上,对游戏理解的考验更大,因为编程能力强的玩家更容易在一开始就进行这种超重量级的开发,最后很多都因游戏理解不足而铩羽 )。并且,复杂的框架会加重心智负担和维护成本,让你把更多的时间用在修修补补而不是新功能开发上。请记住下面两条基本原则,这适用在任何需要编程的项目里:

  • 越简单、越稳定、越美好(KISS)
  • 为了炫技的代码是坏代码,能实现功能的代码才是好代码

写在最后

本文简单介绍了一下游戏中出现的比较重要的设计模式和开发思路,希望能为你在平时的开发里增添一些灵感,当然游戏还是开心最重要,如果你认为本文不太适合你的代码设计,那按照自己的想法写就完事了!想要了解更多其他 screeps 小知识?欢迎点击 Screep 中文教程

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,042评论 6 490
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 89,996评论 2 384
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 156,674评论 0 345
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,340评论 1 283
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,404评论 5 384
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,749评论 1 289
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,902评论 3 405
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,662评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,110评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,451评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,577评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,258评论 4 328
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,848评论 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,726评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,952评论 1 264
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,271评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,452评论 2 348

推荐阅读更多精彩内容

  • 为了不让自己下线时出现 creep 都凉了的情况,你的代码里或多或少都有一个用于控制他们数量的模块。在教程中,官方...
    HoPGoldy阅读 8,524评论 9 28
  • 简介 在设计自己的角色系统的时候,很多人都会被角色越来越多的问题所困扰,本文不讨论如何去削减角色的数量,而是从“发...
    HoPGoldy阅读 9,765评论 7 21
  • 亲爱的行动派小伙伴们,大家下午好,我是威锋,目前是河南财经政法大学的一名大二学生。很荣幸能够来到郑州行动派梦...
    心声树洞阅读 210评论 0 0
  • ① 睡觉是一个人的本能,午睡、晚休都是我们生活必需的生理需求,而睡觉更有多种睡姿。比如仰睡、趴睡、左侧睡、右侧睡和...
    我是眉尾旋阅读 920评论 6 7
  • 把支付宝小程序和微信小程序的区别理清的话,把支付宝小程序和微信小程序进行相互转换,其实很简单 wxml: 把项目里...
    刘叶青阅读 4,539评论 0 5