如題,關於使用虛幻4開發的遊戲,伺服器是用虛幻自帶的dedicated server還是用純自己寫的server,看官方文檔中講網路部分就是講虛幻自帶的server功能,實際項目中該怎麼使用呢

看官方的例子中,如果使用dedicated server(簡稱ds)的話,伺服器代碼和客戶端代碼是在一起的,這樣前後台工作怎麼分工

另外對於mmo這種大世界遊戲,使用ds是怎麼用的,感覺ds適合單局形式的遊戲。


正如其他答案提到的,DS出發點是解決FPS同步,對同步精度和延遲的追求是很高的。核心特性包括:客戶端預測,伺服器校驗,客戶端狀態回退,延遲補償,replay等等。乍看之下MMO不用這麼高端的特性,再加上原生DS承載量低,有的小可愛看著DS這一大坨代碼,很容易產生自己擼一個更簡單的勇氣。

下面簡要講下,如果放棄DS你損失的是什麼:

  1. 優化的網路傳輸。UE4在UDP上做了一層網路協議,專門用於DS通信。這是根據遊戲特點專門優化的,能根據頻率/重要度/數據格式等條件選擇最優的傳輸方式(可靠/非可靠),以及數據壓縮,拆合包等。網路傳輸的技術迭代很慢的,這塊可說是epic數十年沉澱,一般人很難比他寫的更好。

2. Actor的屬性同步和RPC。也就是編輯器里跟同步有關的功能都只能看不能用。實際上手擼伺服器最大的隱含代價就是:你伺服器的遊戲對象跟客戶端的Actor一定是異構的,意味著你必須放棄基於Actor的整個gameplay framework,以及相關的大量功能,導致藍圖基本不可用,導致你要實現自己的腳本方案,導致……此處太多不展開了。

3. ReplicationGraph,也就是AOI,這個簡單,小可愛擼一擼問題不大。

4. 動畫和物理同步。主要是RootMotion和碰撞同步(武器命中),以及環境動畫,破碎這些策劃喜歡的東西。

5. AI行為樹。嗯,UE4的行為樹依賴character,character同步又依賴DS。拋棄DS意味著,你將損失一顆能斷點單步可視化調試的行為樹。

如果你MMO標準很低,上述內容都不需要……那麼有一說一,你這個MMO很難活下去啊。

所以DS設計上的特點(遊戲對象同構,和引擎全層次耦合)導致了,完全拋棄DS相當於把引擎閹割成渲染器。如果你不能接受DS的高消耗/低承載缺點,理智的做法還是去了解它,改進它,根據真實的數據和需求一步步迭代,銀彈是不存在的。這裡提供幾個思路:

  1. 首先是工程層面,減少不必要的component同步,用好骨骼LOD,ReplicationGraph配置足夠的fallback層級和粒度等基操。
  2. 簡化原生的FPS同步方案,降低CPU消耗。比如DS不計算位置校驗(對應的客戶端也不需要狀態回退了),更激進的比如DS跳過大部分物理模擬,關閉動畫更新等。
  3. DS對線程的使用是謹慎的(相對於客戶端),因此物理機多開DS進程可能帶來提升,實例之間也可以實現某種程度的負載均衡。
  4. 考慮到每個DS進程都會獨立載入遊戲資源,造成內存浪費,可以實現某種單進程多位面,降低內存佔用和包廣播量。
  5. 動態負載均衡,動態AOI之類的高端玩法,可參見SpatialOS的UE4插件。

最後,關於客戶端伺服器分工也說兩句。以前很多客戶端和伺服器都搞異構遊戲對象,導致兩邊遊戲對象的生存環境完全不同,分工是為了降低心智負擔,其實挺扭曲的。DS設計上是同構的,你調的RPC你自己實現啊,這時候執著於分工是一種退步。


其他答主已經說了,ds的確是最早從FPS遊戲發展過來的模式。其同步的解決方案和MMO的方案完全不是一個東西,因為是為了解決不同問題產生的。

你要是卡牌遊戲,伺服器完全自己做一套,不用管客戶端是ue還是unity,他們只管顯示。

你要是做FPS,tps,那麼多半伺服器和客戶端共享代碼,因為需要各種客戶端預測和回溯方法。基本是對延遲要求比較敏感遊戲的統一解決方案。

你要做幾個玩家一局的rts,大量單位需要同步,那麼同步玩家輸入並鎖幀的方法就是不錯的選擇。

你要做mmo,那就是前後短分離,前端ue還是其他引擎,不重要。關鍵是你的伺服器架構。最最簡單的說,伺服器要管理遊戲世界的創建分配,ue通過任何網路協議(多半TCP)和伺服器通信玩家操作,和玩家周圍可見的實體同步。不同伺服器框架會有不同方案,很多會有多個伺服器分散式處理。

ue默認的ds模式,通常不是簡單的國內前後端分離。FPS遊戲所謂的後端,是指線上匹配,玩家的平台相關數據處理,一旦遊戲開始,遊戲的gameplay,不是後端系統,因此不存在分離。

這也是國外很多遊戲分單機部分和聯機部分的傳統導致,聯機部分可能最後幾個月才開發或者外包其他組也是可能的。


虛幻自帶的伺服器感覺上確實是做房間型的更合適,特別是那種Host-Join的(RTS),或者大廳-房間型的,本身的流程都已經建立起來了,按照示例、搭BP就可以完成絕大多數的工作,甚至包括Steam接入。複雜一點的情況,社區里之前看到過討論改自動匹配,感覺也不算很麻煩。

關於前後後台分工的問題

我參與的第一個項目(C++)就是一套遊戲對象結構,通過SERVER宏和CLIENT宏來確定是伺服器還是客戶端跑,所以後來在UE裡面遇到這套體系的時候感覺還是挺親和的。

後面也參與過那種伺服器邏輯和對象體系跟客戶端完全分離,互相完全沒有關係這種情況。這個團隊的開發模式是客戶端邏輯組和伺服器邏輯組也完全分離,實際工作時,存在客戶端程序和伺服器程序互相之間等待、推諉、甩鍋的情況。

而且後面我加功能的時候,感覺上,伺服器的核心對象體系和客戶端的核心對象體系(就是排除純表現邏輯外的數值邏輯),事實上對價。但是卻需要在維護時,在各端按照不同的對象體系和標準來維護。

無非是客戶端是個CActor-CComponent,伺服器名字改成SActor-SComponent,方法少一些多一些的區別。雖然,也不會增加太多編程心力,但是同時打開兩個VS,看著左邊寫右邊,看著右邊寫左邊,也不覺得會很舒服就是了。

就我個人而言,沒有進一步再想,但是目前沒有感覺到伺服器-客戶端邏輯代碼分離的優勢。

統一結構下工作久了,強制自己養成了思考問題時強制思考一個對象的數值邏輯和表現邏輯的習慣,習慣之後感覺還是挺舒服的。特別是沒有那種需要等待或者扯皮這樣的煩心事了。

關於MMO

很早虛幻官方就提到過,大意我印象里是,有條件能做MMO的公司,基本上各自有各自的要求和解決方案,虛幻自己專門提供一套感覺有點雞肋,因為這些公司各自項目的要求差別較大、肯定不會去用你提供的。同時,鼓勵社區提供解決方案。

很早之前的印象,可能不準,有興趣可以去論壇查找。

之前看到過KBEngine、Photon都有對應的解決方案和Samples,社區里之前也有一些其它的解決方案。

就代碼的情況來看,通過一些Network底層的擴展,可以做到伺服器邏輯跑DS,但架構更複雜。比如玩家登陸、先經過Login伺服器和World伺服器,再分配到具體的邏輯伺服器(DS)上去,但做起來想來坑也不會少。

當然也可以選擇完全拋棄DS,自己重新按照自己的方式來整合伺服器客戶端代碼。

比如打包成dll,整合進自己的伺服器架構裡面,通信不用RPC,自己寫一套新的(當然也可以選擇替代默認RPC)

甚至,可以客戶端伺服器邏輯的完全分離,伺服器完全新寫一套,通信當然也是走自己的。

大房間:ARK和Atlas

虛幻項目里這兩個項目是那種,玩家可以自己架設伺服器,伺服器支持人數一般在70~200這樣的。不追求萬人同服,追求私服遍地開花這種樣子的遊戲,有點MC那種感覺。

這兩個遊戲的伺服器是可以從Steam上作為工具下載下來的.

ARK是非常明顯的標準DS程序。

Atlas則是在DS外,自己寫World伺服器和數據伺服器,啟動時根據World配置,創建多個Ds實例,通過World伺服器進行統一管理(跨地圖遷移等)。這從結構上來說已經很接近於傳統MMO伺服器的核心結構了

這兩個遊戲單一ds承載上限不算高,這點可能跟伺服器算的東西有點多有關。雖然個人沒有嘗試,但是感覺上,自己的遊戲設計上如果能夠降低一些負載,理論上應該承載上限還能高一些。

比如一般情況下,Server載入的地圖和Client一致,但是其實可以不一致,通過設置一些標記或者改一些代碼,有些純表現的地圖(因此也可以排除純表現的Actor),可以僅客戶端載入。還有就是,NPC隨用隨刷、移動運算複雜度降低,等等,取決於遊戲需求。

許多都是個人印象,不能作數,僅供參考。

祝好運!


不管是dedicated server還是listen server,客戶端代碼與伺服器端代碼都是混合在一起的。本來客戶端邏輯和伺服器端邏輯也非水火不相容,可以共享大量的代碼。所以單機和多人遊戲模式能夠同時實現,這比之前那種強行把兩端邏輯分離來寫的開發模式高效很多,不需要為此定義一大批網路同步消息,當然調試和團隊協作也不方便。


如果大型伺服器的話可以先從基礎的底層socket套接字開始寫,這樣容易掌控,而且修bug比較方便。其實伺服器很簡單的,就是客戶端遊戲app 和 你的主機電腦相通過套接字建立連接,互發簡訊,告訴對方要做啥,剩下的無非就是速度優化咯


伺服器還是跟之前那些一樣使用 c++或者golang的遊戲伺服器。 無非就是一些 socket通信。可以學習kbengine。如果不是大型網遊 用UE4官方的DS也可以。


我個人是個獨立開發者,沒參加過什麼遊戲項目,就隨便說說自己的看法,對於我自己的遊戲,我是想用預編譯的宏來判斷是不是用在伺服器上的代碼,樓主應該學過c++懂我意思吧,預編譯就是讓編譯器執行的代碼,比方說#if dedicated server 就表示如果當前編譯的目標平台是dedicated server的話,就把下面包含的代碼編譯到這個項目里。還有一個方案就是執行的時候用一個Is dedicated server來判斷是否ds


虛幻就是一個寫射擊遊戲的引擎,所以自然需要在伺服器跑相關的gameplay,才能比如說傷害的判定。這些要是分開寫,意味著你要寫兩份一模一樣的代碼,並且跑得一模一樣。

至於分工的話,一般寫伺服器的人管類似於匹配,排名這種。寫gameplay的人也要負責把要在伺服器跑的邏輯寫好了,像一些產生粒子,這種表現的東西區分開來也就妥了。


推薦個c++高並發商業級伺服器教程乾貨,客戶端有ue4和unity3d.有興趣的看一看吧

https://www.aboutcg.org/courseDetails/869/introduce


推薦閱讀:
相关文章