Screeps 游戲中的兩大設(shè)計(jì)模式

screeps 系列教程

簡(jiǎn)介

作為一款代碼主導(dǎo)的游戲,有代碼的地方就有設(shè)計(jì)模式。本文就作為一篇拓展閱讀性質(zhì)的文章,來(lái)簡(jiǎn)單介紹一下 Screeps 中出現(xiàn)的兩大設(shè)計(jì)模式:角色驅(qū)動(dòng)型任務(wù)驅(qū)動(dòng)型。

角色驅(qū)動(dòng)型

角色驅(qū)動(dòng)型設(shè)計(jì)模式是指 將 creep 劃分成不同的角色,每個(gè)角色都有著固定的任務(wù)和行動(dòng)模式,不同角色之間的相互協(xié)作共同維持了一個(gè)房間乃至整個(gè)殖民地的正常運(yùn)行。可以非??隙ǖ恼f(shuō),幾乎所有的新玩家的代碼都使用了角色驅(qū)動(dòng)型的設(shè)計(jì)模式。

房間運(yùn)維

角色驅(qū)動(dòng)的優(yōu)點(diǎn)

角色驅(qū)動(dòng)型設(shè)計(jì)容易入門(mén)、方便調(diào)試,每個(gè) creep 的工作非常的明確,所以在代碼出現(xiàn)問(wèn)題時(shí)你可以很容易的根據(jù)報(bào)錯(cuò) creep 的角色定位到出現(xiàn)問(wèn)題的代碼。

并且由于代碼結(jié)構(gòu)簡(jiǎn)單,角色驅(qū)動(dòng)在讓 creep 執(zhí)行一成不變的簡(jiǎn)單邏輯時(shí)產(chǎn)生的基礎(chǔ) CPU 消耗會(huì)更少。

角色驅(qū)動(dòng)的缺點(diǎn)

這種設(shè)計(jì)模式最大的問(wèn)題在于,隨著游戲進(jìn)度的不斷深入,就需要設(shè)計(jì)越來(lái)越多的角色來(lái)應(yīng)對(duì)新的任務(wù)。而且如果你的代碼抽象沒(méi)有做好的話,每次新增角色都將是一次痛苦的體驗(yàn)。

并且,角色型設(shè)計(jì)更適合于“靜態(tài)”的工作邏輯。比如 "采礦 > 建造" 或者 "采礦 > 升級(jí)"。面對(duì)復(fù)雜、多變、多目標(biāo)的工作邏輯,例如后期的資源搬運(yùn)任務(wù)時(shí),角色驅(qū)動(dòng)就顯得力不從心了。為了處理復(fù)雜的工作任務(wù),你可能會(huì)選擇將不同的任務(wù)按照優(yōu)先級(jí)“分層”:

層層疊疊的千層任務(wù)

非常的復(fù)雜,并且在每個(gè)任務(wù)之前都需要使用room.find或者其他的方法判斷是不是要執(zhí)行該任務(wù),要執(zhí)行的任務(wù)優(yōu)先級(jí)越靠后,就會(huì)導(dǎo)致在前面任務(wù)的判斷消耗更多的cpu

并且這個(gè)任務(wù)列表越長(zhǎng),其中的優(yōu)先級(jí)就越難以進(jìn)行排序。例如在房間內(nèi)出現(xiàn)敵人時(shí)要優(yōu)先滿(mǎn)足 Tower 的能量需求,而在 Lab 合成所需的原料來(lái)自于 Termial 時(shí),就需要先從 Termial 中獲取資源再轉(zhuǎn)移至 Lab。為了適配這種“突發(fā)性”的優(yōu)先級(jí)調(diào)整,會(huì)讓你的代碼邏輯越來(lái)越混亂,同時(shí)增加了出現(xiàn) bug 的幾率。

在接觸到新的游戲內(nèi)容后,你會(huì)非常糾結(jié)是在現(xiàn)有的角色上添加新的任務(wù)還是新增一個(gè)角色。

任務(wù)驅(qū)動(dòng)型

在實(shí)際開(kāi)發(fā)過(guò)程中,我們很容易就能發(fā)現(xiàn):如果按照身體組成進(jìn)行劃分的話,日?;鼐S護(hù)的 creep 僅僅只需要分為如下兩種:

  • WORK 為主的 工作型 creep
  • CARRY、MOVE 為主的 運(yùn)輸型 creep

任務(wù)驅(qū)動(dòng)型設(shè)計(jì)模式是 將所有的行動(dòng)內(nèi)容劃分成不同的任務(wù),每個(gè)任務(wù)都有自己的執(zhí)行方法和要達(dá)成的目標(biāo),而 creep 只劃分為幾個(gè)基本的角色,每個(gè) creep 都將在一組規(guī)則的指導(dǎo)下領(lǐng)取適合自己的任務(wù)并執(zhí)行。

面向任務(wù)隊(duì)列的 creep

這個(gè)設(shè)計(jì)模式的核心是 每個(gè) creep 的工作內(nèi)容并不是一成不變的。在當(dāng)前的任務(wù)完成后完全可以切換至其他的任務(wù)。

在角色驅(qū)動(dòng)型設(shè)計(jì)中,任務(wù)的發(fā)現(xiàn)和執(zhí)行完全是由 creep 負(fù)責(zé)的,而在任務(wù)驅(qū)動(dòng)型設(shè)計(jì)中,任務(wù)的發(fā)現(xiàn)和執(zhí)行完全被拆開(kāi)了(沒(méi)有人不喜歡低耦合)。creep 接受任務(wù),然后執(zhí)行任務(wù)。而任務(wù)的發(fā)布完全由其他代碼完成。在大多數(shù)情況下,每個(gè)建筑都會(huì)根據(jù)自身的情況決定是否發(fā)布一個(gè)任務(wù)。

例如,Tower 會(huì)檢查自己的能量是不是沒(méi)有滿(mǎn),以此來(lái)決定是否發(fā)布一個(gè)從 Storage 到自己的能量轉(zhuǎn)移任務(wù)。而 Termial 會(huì)根據(jù)自己是否收到了一筆新的資源,來(lái)決定是否要發(fā)布一個(gè)從自己到 Storage 的資源轉(zhuǎn)移任務(wù)。

這些任務(wù)都會(huì)被發(fā)布到一個(gè)固定的位置 (任務(wù)隊(duì)列,或是任務(wù)池)。這樣 creep 完全不用關(guān)心任務(wù)是怎么產(chǎn)生的,只需要埋頭干活就好了。

互不關(guān)心的冷漠雙方

優(yōu)點(diǎn)

由于 creep 會(huì)只有倆個(gè)基本角色(工作型 / 運(yùn)輸型),而且同一時(shí)刻一個(gè) creep 只會(huì)明確的做一件事。所以角色驅(qū)動(dòng)型的缺點(diǎn) 角色過(guò)多任務(wù)優(yōu)先級(jí)混亂 在任務(wù)驅(qū)動(dòng)這里完全不成問(wèn)題。

而且由于任務(wù)發(fā)布邏輯和執(zhí)行邏輯的解耦,代碼的結(jié)構(gòu)會(huì)變得更加清晰,從而方便后期的維護(hù)工作。并且因?yàn)?creep 只監(jiān)聽(tīng)任務(wù)隊(duì)列而不會(huì)主動(dòng)去發(fā)現(xiàn)任務(wù),所以在空閑時(shí)會(huì)帶來(lái)更低的 CPU 消耗。

回想一下角色驅(qū)動(dòng),在空閑時(shí)會(huì)根據(jù)優(yōu)先級(jí)執(zhí)行所有任務(wù)的檢查工作,從而造成了 CPU 的浪費(fèi)。

兩個(gè)設(shè)計(jì)模式 creep 空閑狀態(tài)的 CPU 消耗

缺點(diǎn)

任務(wù)驅(qū)動(dòng)什么都好,唯一不好的就是:開(kāi)發(fā)難度大。是的,對(duì)于任務(wù)驅(qū)動(dòng)型設(shè)計(jì)來(lái)說(shuō),角色驅(qū)動(dòng)設(shè)計(jì)里數(shù)量眾多的角色并不是被消滅了,而是轉(zhuǎn)化成了體量更小,更加靈活的“任務(wù)”,你依舊需要設(shè)計(jì)每個(gè)任務(wù)的邏輯。

并且不同于角色驅(qū)動(dòng)型里簡(jiǎn)單編寫(xiě)代碼就可以讓 creep 進(jìn)行工作。任務(wù)驅(qū)動(dòng)型需要扎實(shí)健壯的“基礎(chǔ)設(shè)施建設(shè)”,比如任務(wù)發(fā)布邏輯、任務(wù)隊(duì)列的維護(hù)和檢查、任務(wù)分配調(diào)度、兼容所有任務(wù)的 creep 運(yùn)行框架 等。在這一整套代碼完成之前,你甚至沒(méi)辦法完成一個(gè)簡(jiǎn)單的 creep 采礦然后升級(jí)控制器的工作流程。

并且,由于 creep 當(dāng)前的工作完全取決于自己接到了什么任務(wù)。所以一旦出現(xiàn) bug。你可能很難在后續(xù)檢查中重現(xiàn)這個(gè)問(wèn)題。你可能會(huì)陷入“這個(gè) creep 剛才一直好好的,突然就報(bào)了個(gè)錯(cuò),然后又正常運(yùn)行了” 的問(wèn)題循環(huán)中,想要追蹤、重現(xiàn)和進(jìn)行測(cè)試,你需要額外設(shè)計(jì)一些平時(shí)用不到,但是方便檢查的模塊。這無(wú)疑加大了開(kāi)發(fā)成本。

二者的邊界

在實(shí)際的開(kāi)發(fā)游玩中,角色驅(qū)動(dòng)型設(shè)計(jì)和任務(wù)驅(qū)動(dòng)型設(shè)計(jì)并不是二元對(duì)立的。在很多時(shí)候,你完全可以將二者融合在一個(gè)項(xiàng)目里。例如,整體上使用角色驅(qū)動(dòng),而在“物流運(yùn)輸”等難以處理的地方使用任務(wù)驅(qū)動(dòng)來(lái)減輕設(shè)計(jì)和維護(hù)上的壓力。

兩種模式相結(jié)合

并且需要著重強(qiáng)調(diào)的是,不要一昧的推崇任務(wù)驅(qū)動(dòng),不要覺(jué)得任務(wù)驅(qū)動(dòng)很優(yōu)雅就嘗試把所有功能都并入到任務(wù)系統(tǒng)里。

想要合并所有功能,你需要從種類(lèi)繁雜的任務(wù)中抽象出統(tǒng)一的模型,這對(duì)你的游戲理解和編程能力是一個(gè)極大的考驗(yàn)(事實(shí)上,對(duì)游戲理解的考驗(yàn)更大,因?yàn)榫幊棠芰?qiáng)的玩家更容易在一開(kāi)始就進(jìn)行這種超重量級(jí)的開(kāi)發(fā),最后很多都因游戲理解不足而鎩羽 )。并且,復(fù)雜的框架會(huì)加重心智負(fù)擔(dān)和維護(hù)成本,讓你把更多的時(shí)間用在修修補(bǔ)補(bǔ)而不是新功能開(kāi)發(fā)上。請(qǐng)記住下面兩條基本原則,這適用在任何需要編程的項(xiàng)目里:

  • 越簡(jiǎn)單、越穩(wěn)定、越美好(KISS)
  • 為了炫技的代碼是壞代碼,能實(shí)現(xiàn)功能的代碼才是好代碼

寫(xiě)在最后

本文簡(jiǎn)單介紹了一下游戲中出現(xiàn)的比較重要的設(shè)計(jì)模式和開(kāi)發(fā)思路,希望能為你在平時(shí)的開(kāi)發(fā)里增添一些靈感,當(dāng)然游戲還是開(kāi)心最重要,如果你認(rèn)為本文不太適合你的代碼設(shè)計(jì),那按照自己的想法寫(xiě)就完事了!想要了解更多其他 screeps 小知識(shí)?歡迎點(diǎn)擊 Screep 中文教程

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 為了不讓自己下線時(shí)出現(xiàn) creep 都涼了的情況,你的代碼里或多或少都有一個(gè)用于控制他們數(shù)量的模塊。在教程中,官方...
    HoPGoldy閱讀 9,358評(píng)論 9 28
  • 簡(jiǎn)介 在設(shè)計(jì)自己的角色系統(tǒng)的時(shí)候,很多人都會(huì)被角色越來(lái)越多的問(wèn)題所困擾,本文不討論如何去削減角色的數(shù)量,而是從“發(fā)...
    HoPGoldy閱讀 10,646評(píng)論 7 21
  • 親愛(ài)的行動(dòng)派小伙伴們,大家下午好,我是威鋒,目前是河南財(cái)經(jīng)政法大學(xué)的一名大二學(xué)生。很榮幸能夠來(lái)到鄭州行動(dòng)派夢(mèng)...
    心聲樹(shù)洞閱讀 257評(píng)論 0 0
  • ① 睡覺(jué)是一個(gè)人的本能,午睡、晚休都是我們生活必需的生理需求,而睡覺(jué)更有多種睡姿。比如仰睡、趴睡、左側(cè)睡、右側(cè)睡和...
    我是眉尾旋閱讀 1,105評(píng)論 6 7
  • 把支付寶小程序和微信小程序的區(qū)別理清的話,把支付寶小程序和微信小程序進(jìn)行相互轉(zhuǎn)換,其實(shí)很簡(jiǎn)單 wxml: 把項(xiàng)目里...
    劉葉青閱讀 4,822評(píng)論 0 5

友情鏈接更多精彩內(nèi)容