面向地圖編輯器編程—— 一個在客戶端或者服務器中運行的 RTS 框架構思

早在03年第一次玩魔獸爭霸的時候就贊嘆它強大地圖編輯器,并且也自己試著去改一些地圖自娛自樂,可以這么說,這個編輯器可以實現(xiàn)非3A游戲的絕大部分游戲。DOTA就是用這個編輯器做出來的一張地圖,才有了后面的LOL與王者榮耀,塔防類也是如此。后從事游戲開發(fā),就一直在想如果可以復刻一個那該多有成就感啊!這個想法也隨著后面的忙碌與不遇,一直等到了年初終于有這么一個契機可以做這個事情,項目的整體需求基本類似 rts 游戲。2D 45度角 偏單機,游戲引擎用了 unity3d + lua 所以我開始了這個工作。這篇文章主要是講述思路(我要回上家公司做服務端,給小伙伴講框架的思想),適合有基礎對相同項目沒有頭緒的小伙伴提供思路,后續(xù)如果有時間我會把和項目無關的代碼放到GitHub上。

首先是 AI 部分,要求是敵我雙方都可以在玩家不進行干預的情況下按照設定自己去做各種事情,諸如:休息、閑逛(巡邏)、追逐、攻擊、釋放技能等等行為,在玩家進行干預的時候可以按照玩家的意愿做出相應的回應,如:點選、群選、組隊、攻擊某一個目標、走到某一個地方等等。這塊涉及的內容說多也不算太多。主要是在代碼設計上需要做到幾點

1.使用行為都需要可以復用,就像編輯器做的可視化編輯一樣,可以給某個單位添加上,它就擁有這個行為的能力。

這塊最終使用了決策樹+行為樹+行為池去實現(xiàn)

2.高效的尋路機制,畢竟在地圖比較大的情況下同時尋路還是有比較大壓力的。

尋路后面用了 JPS (Jump Point Search,跳點搜索)來解決,當然如果是純 3D 可以直接使用 NavMesh,地圖如果太大,可能要做局部和全局尋路。目前尋路還是一個簡單的常規(guī)尋路,事實上魔獸爭霸冰封王座3還有群體尋路,需要用到 RVO 之類算法。

3.合理的驅動機制,因為單位自身去感知世界,本質就是在一堆條件中去找特定的條件然后進行決策執(zhí)行某種行為。

這里就涉及到一個平衡的問題,如果驅動的 tick 很快,則性能消耗大,太慢則單位反映遲鈍,后面想到了某種空調的變頻原理,對某些狀態(tài)下,我調低了它的驅動頻率,只再戰(zhàn)斗狀態(tài)下用最高的頻率去執(zhí)行 AI ,的確獲得了很好的效率

4.感知和速度,單位需要感知周圍,還要能精準的控制攻擊速度、移動速度等。

感知范圍就是用的類似九宮格的思想,以減少對身邊單位遍歷的代價,攻擊距離就是兩個單位之間距離,移動和攻擊速度這些都沒什么好說的。

page_1.jpg

再有就是空間部分,這里就涉及到邏輯坐標和屏幕坐標,2D和3D空間。因為在服務器中是不會去關注攝像頭的角度的。一般 2D 45度的顯示大部分是使用菱形地圖,只要把邏輯坐標(正方形地圖)轉換為屏幕坐標(菱形地圖)就好了,所以需要對這塊進行設計,最終是把空間這塊做成可以是2D/3D 通用的,譬如:獲取以自身為中心一定半徑內的單位等等接口。如果換 3D 就是把接口和地圖模塊換成適合3D的就可以了。

page_2.png

圖中單位周圍格子就是感知范圍,左邊2個單位相互感知對方的存在,右邊則沒有發(fā)現(xiàn)其他單位,其他單位也沒發(fā)現(xiàn)他的存在。每個單位一定時間內遍歷自己周圍格子就可以了,那么理論上來說性能消耗就和地圖大小沒關系了(這是邏輯位置,45度角在顯示的時候是要做空間轉換為菱形地圖的)

接下來就是各種 技能、buff、被動、光環(huán)、等功能了,這塊的設計,我把他們定義為“特性”,因為單位類的設計無非就是抽取各種共有屬性的聚合,譬如:陣營、類型、血量、力量、移動速度、攻擊速度等等的集合,這塊的設計遵循的就是常規(guī)的 OOP 思想,但是”特性“依然是要面向編輯器,事實上也是 OOP 思想中的“面向接口編程”,那么最后無非就是抽出就是各種可以脫離單位的邏輯單元,它并不會關心它附著在哪個單位身上,你給一個單位加一個扣血的debuff,那么它就應該持續(xù)扣血,你給它加一個提升攻擊速度的光環(huán),那么它和符合條件的單位,就應該可以提升攻擊速度,你賦予它什么能力它就可以做什么事情,因為這些“特性” 如光環(huán)是隨時會得到的和失去的,理論上來說所有單位都可以被加上所有的“特性”,如果在 c++ 等編譯型語言中實現(xiàn),則需要寫很多的接口,如:加血的接口、扣血的接口、光環(huán)接口。。。需要加上已有“特性“全部接口,而在 lua 這種腳本中不需要設計一堆的接口就可以快捷實現(xiàn)。(當然這里不是說動態(tài)腳本多好,只是開發(fā)起來便捷很多,但是同時會存在定義模糊,代碼不好閱讀的代價) 而且隨著項目的推進和不斷迭代,抽出通用的“特性”,最終它就可以成為一個通用的,類魔獸爭霸的 rts 框架。這就是我常常在思考的問題,我們做了那么多的項目,最終我們的技術得到提升和積累了嗎?再開一個新項目,可以在之前的基礎上做嗎?

還有就是數(shù)據(jù)的恢復和數(shù)據(jù)合法性的校驗,這塊內容了,因為是偏單機,邏輯是放在了客戶端進行推演,勢必需要做準確性的校驗,所以在開始寫這個項目的時候,我就把邏輯和渲染分開去做,上面所述的功能都是沒有涉及到渲染的,最后加了一個叫UnitGameObject 的對象,它用于把邏輯算出來的結果通過事件派發(fā)給顯示層去處理,例如在某個坐標上創(chuàng)建單位、播放休息動畫、閑逛到某個坐標、追逐、戰(zhàn)斗等等。這樣設計好處有幾點:

1.代碼可以跨平臺,也可以直接在服務器上跑,因為只要隨機種子是相同的話,那么不管是在客戶端中執(zhí)行,還是服務器中執(zhí)行,結果都是一樣的。
2.UnitGameObject 的事件改為 TCP 或者 UDP 傳輸,就可以在服務器上跑,客戶端就只是按消息去做動畫就好了。
3.并且因為是和渲染沒有耦合,在做數(shù)據(jù)恢復和一段時間后的現(xiàn)場恢復也是很容易的,無非就是加快 tick 的頻率就好了(后面采用類似cpu中斷的計數(shù)方式替換掉正常的定時器,而且推演時長不能太長,否則運算需要很長時間,比較適合掉線重連,或者退出游戲后一天內重開游戲的推演,超過這個時間就需要通過設計數(shù)值規(guī)則來重現(xiàn)了)。當然也不是每一個用戶的每一次數(shù)據(jù)都需要進行校驗,原則上是發(fā)現(xiàn)數(shù)據(jù)異常的情況下,把他的存檔拿出來跑一遍。如果最后的數(shù)值和跑出來的數(shù)值相差太大,則加入到監(jiān)控中重點觀察,如果多次和理論值相差太多,則大概率就是作弊,這樣既可以保證服務器沒有消耗過多性能,也可以相對防作弊。

最后就是其他一些常規(guī)的慣例和手法了,諸如:對象池、事件機制、測試模式、配置管理、地圖遮擋配置、透明區(qū)域配置、和這個項目獨有的需求。這些和地圖編輯器沒有太大的關聯(lián),就不一一枚舉了。

這個框架可以用于各類基于地圖世界的游戲,如:塔防類、策略游戲、即時戰(zhàn)略游戲、回合制、等等。當然目前只是一個雛形,離編輯器還非常遠,后面需要完善的東西還非常多。

感恩遇到一幫有理想有能力的小伙伴,特獻上親自創(chuàng)作Q版畫像一副,你們未來前途無限。以后你們會成為我口中認識的大佬,未來還要仰仗你們的光芒,只因每個人都使命不一樣,選擇不一樣,我們后會有期!

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

友情鏈接更多精彩內容