MOBA類遊戲是如何解決網路延遲同步的?

像MOBA類的遊戲,dota2,魔獸rpg dota,英雄聯盟 等遊戲 .他們的同步非常穩定.

英雄聯盟中,人物在很短的時間內做的快速操作能很好的同步到其他客戶端上顯示出來,請問這是如何做到的呢?他們用了怎麼樣的方法實現的.


主流的同步方案有兩種:幀同步和CS同步。

正好這兩天在整理這塊的東西,就一併分享一下!也希望能夠得到一些討論的機會。

看到評論,補充一個觀點:CS和幀同步其實各有有優缺點,並不是某一項方案一定能夠取代另一項方案,當遊戲類型對實時性要求很高時(比如,實時格鬥、體育競技類遊戲(NBA2K)),幀同步可能就是唯一的方案了。

以下是正式答案

概念定義:

1 ArenaServer

  • 戰鬥核心邏輯及數據所在
  • 不關心表現
  • 由客戶端的輸入驅動運行
  • CS同步架構里,這個部分是在伺服器的
  • 幀同步架構里,這個部分是在客戶端的。

2 ArenaServer[預表現層]

  • 戰鬥的預表現層,一定在客戶端
  • 對於一些需要本地預表現的邏輯,如行走。需要先在這裡模擬實現。
  • ArenaServer的真實數據反饋到預表現層後,會修改本地數據。
  • ArenaClient只知道預表現層,並不知道真正的ArenaServer的存在。
  • 所以,當遊戲要改變同步方案時,Client層並不需要修改。

3 ArenaClient:ArenaInput+ArenaRender

  • 負責客戶端輸入和渲染
  • 只與預表現層交互。

4 FrameServer

  • 以每秒30次(假設)的頻率,收集各個客戶端上報上來的ClientInput。
  • 組裝為FrameInput,廣播給各個客戶端。
  • 即為幀同步的伺服器所有邏輯

=======一早上都在畫這三個圖,最後求個贊~~~=======


樓上大部分答主都提到了幀同步要把邏輯放在客戶端。其實我們以前在實現的時候,幀同步一樣也是把邏輯放在伺服器端的。只不過在客戶端接受完畢輸入的時候,預先播放動畫效果。在同步幀真正到來的時候做結算。

這樣的好處就是所有邏輯可控,同時可以非常完美的實現戰爭迷霧和開全圖外掛,因為迷霧裡面的單位狀態伺服器端根本就不會發送到客戶端。

當然這樣做對網路延遲的要求很高。因此我也來分享一下網路延遲的幾個解決方案。

1. 用UDP,推薦使用libenet庫。功能強大,可以分channel,支持可靠與否,順序與否的選項。合理的分channel可以大大提高性能。比如說佔比最大的移動包就可以丟到非可靠channel裡面。

2. 合包。爭取最大的壓縮比。

3. 降低移動的封包,在移動上的優化一點點都會對網路提升很大。

4. TCP和UDP雙連接。不停換埠。補充說明:不停換埠是客戶端的行為。指的是客戶端連接斷開以後,嘗試連接伺服器的另一個網關埠。這樣可以防止某些網吧或者ISP因為流量控制而斷開連接。

5. 全國部署伺服器。


網路同步問題,本質上是因為存在網路延遲而導致的,解決這個問題最終需要在 一致性和操控及時性之間尋求平衡。

追求遊戲一致性最高的經典模式是回合制遊戲的模式,所有玩家發出命令,等待回合時間到,所有客戶端統一執行回合命令。

追求操控的及時性,極致則是fps遊戲,例如CS, quake,通過客戶端預測,伺服器補償的方式,使玩家的操控可以立即得到反饋,但是會削弱表現的一致性,同時代碼複雜度大大上升。

同步問題解決思路分為幾個流派:

1:流派一 FPS遊戲, quake,cs 流派

FPS類遊戲,追求操控及時反饋,每個實體的所有狀態存儲在一個結構體中,每一幀50ms,從伺服器同步一次遊戲每個實體的狀態到客戶端,每幀同步的是客戶端和伺服器之間狀態的差diff, 因此伺服器上面需要存儲多幀對象狀態,以方便和客戶端的狀態做diff,求出差異,從而同步給客戶端。

伺服器上角色的動畫,移動,hp等狀態都是通過這種方式同步。

對於火箭炮等慣性運動物體,則可以通過客戶端預測對象的移動。

在伺服器上,做子彈碰撞判定的時候,會根據延遲,將對象位置補償插值到子彈發出的時刻,從而修正結果。

理想的客戶端實現,只對伺服器發送來的狀態做展現,而沒有其它邏輯,但是因為網路延遲的存在,單純展現的客戶端,對用戶的操作反饋不夠及時,對於FPS這種快節奏遊戲來講,是不能接受的,因此需要客戶端預測。

參考:

Source Multiplayer Networking

Latency Compensating Methods in Client/Server In-game Protocol Design and Optimization

總結:這個流派將遊戲狀態,以每50ms幀,離散化存儲,在需要的時候在幀之間進行插值,和外插值,來進行預測和補償。在客戶端上為預測,在伺服器上為補償。

這個流派在UDP協議之上,構建網路架構。通過應用層設計,使UDP可以實現可靠性,和順序性,接著通過不同報文的需求,選擇不同的特性組合,降低報文收發的延遲。

2:流派2 RTS遊戲, 帝國時代,紅色警戒, warcraft3, supreme commander

Gamasutra - 1500 Archers on a 28.8: Network Programming in Age of Empires and Beyond

https://blog.forrestthewoods.com/synchronous-rts-engines-and-a-tale-of-desyncs-9d8c3e48b2be#.4lyc937ax

RTS遊戲對操作的響應及時性比FPS低,RTS 一幀時間大概100ms左右.

在RTS遊戲,所有客戶端每一幀發出命令將會被收集起來,在所有客戶端都收到命令之後,才一起執行,例如在 帝國時代中,是隔一幀執行命令,例如,在1000幀的時候,客戶端發出命令,在1002幀所有客戶端開始執行該命令,

RTS遊戲引擎,通常需要做分層設計,下層為模擬層,幀率為10hz,上層為表現層,需要動畫,移動盡量光滑。

表現層狀態需要和模擬層狀態進行同步,表現層需要能夠對用戶的操作做出比較及時的反饋,因此表現層的實現還是相當複雜的。

RTS遊戲網路傳輸的是命令,或者事件,而不是狀態,這是和FPS遊戲不同之處,RTS只傳輸向某個位置移動,攻擊某個目標等這種命令,而狀態同步是通過遊戲引擎自身的確定性來保證的,相同的命令流,通過遊戲引擎執行,最終得到相同的結果,這個就是遊戲引擎的確定性。

RTS後期進一步發展為曲線化技術,根據存儲的離散遊戲狀態,將遊戲對象的整個生命周期,構建成一條曲線,通過調整曲線的時間,甚至可以實現遊戲的反向播放。

參考:

https://blog.forrestthewoods.com/the-tech-of-planetary-annihilation-chronocam-292e3d6b169a#feab.ii834tfxl

3:流派三 介於兩者之間 MMO, Halo, Unreal

網路同步涉及到三個問題:

複製,狀態複製和命令同步;

權屬,屬性由誰控制?

預測。

網路結構劃分為多層,

傳輸層(TCP, UDP),

信道(可靠,不可靠,順序),

複製屬性的特徵,僅服務端,僅客戶端,僅自己,其它條件複製,複製處理函數;

遊戲業務邏輯層;

狀態複製是單向從伺服器到客戶端;

事件或者RPC是不可靠的,雙向;

更多細節參考下面文章

參考:

Game Network Programming

http://downloads.bungie.net/presentations/David_Aldridge_Programming_Gameplay_Networking_Halo_final_pub_without_video.pptx

http://gamedevs.org/uploads/tribes-networking-model.pdf

https://docs.unrealengine.com/latest/INT/Gameplay/Networking/index.html

4:流派4 synchost

伺服器做消息中轉分發,不做遊戲業務邏輯

參考:

http://d3cw3dd2w32x2b.cloudfront.net/wp-content/uploads/2011/06/introductiontosynchost.pdf

5: 時空一致性

參考:

Replication in networked games: Latency (Part 2)

遊戲伺服器的架構,從傳統的單線程,到根據職職責劃分的多進程,bigworld模式,再到actor模式。

Building Halo 4, a Video Game, Using the Actor Model

Building the Halo 4 Services with Orleans

最後,根據前面的分析可以做一種簡化的網路模型:

大部分協議使用簡單的可靠性傳輸;

客戶端發起的命令,等伺服器確認之後再執行事件;

伺服器發送的同步狀態廣播給所有客戶端都是一樣的;

客戶端兩個層次,模擬層和表現層

使用RTS模式定幀同步命令和狀態

降低發送者的速度,加速接受者的速度


不管是幀同步還是狀態同步(樓上所謂cs同步),都需要考慮「低延遲高並發傳輸系統」,即如何在最短時間內同時把大量數據投遞給所有玩家。而libenet卻是上個世紀的技術了,無法承當這個重任。所以販賣一下我的 KCP 傳輸協議:GitHub - skywind3000/kcp: KCP

libenet的協議設計是非常落後的,基本上就是90年代教科書上那種標準ARQ協議實現,很難在複雜的網路條件下提供可靠的低延遲傳輸效果。而KCP具備更多現代傳輸協議的特點,諸如:

流量換延遲,快速重傳,流控優化,una/ack優化等。

在內網這種幾乎理想的環境里直接比較,大家都差不多,但是放到公網上,放到3G/4G網路情況下,或者使用內網丟包模擬,差距就很明顯了。公網在高峰期有平均接近10%的丟包,wifi/3g/4g下更糟糕,這些都會讓傳輸變卡。

asio-kcp 的作者對 KCP 與 enet, udt 做過的一次橫向評測,結論是KCP比 libenet,udt更適合實時PVP遊戲,特別是使用手機的3G,4G網路的情況下:

  • ASIO-KCP has good performace in wifi and phone network(3G, 4G).
  • The kcp is the first choice for realtime pvp game.
  • The lag is less than 1 second when network lag happen. 3 times better than enet when lag happen.
  • The enet is a good choice if your game allow 2 second lag.
  • UDT is a bad idea. It always sink into badly situation of more than serval seconds lag. And the recovery is not expected.
  • enet has the problem of lack of doc. And it has lots of functions that you may intrest.
  • kcp"s doc is chinese. Good thing is the function detail which is writen in code is english. And you can use asio_kcp which is a good wrap.
  • The kcp is a simple thing. You will write more code if you want more feature.
  • UDT has a perfect doc. UDT may has more bug than others as I feeling.

基於kcp的開源項目也不少,比如:

  • kcptun: 基於 kcp-go做的高速遠程埠轉發(隧道) ,配合ssh -D,可以比 shadowsocks 更流暢的看 youtube視頻。
  • kcp-go: 高安全性的kcp的 GO語言實現,包含 UDP會話管理的簡單實現,可以作為後續開發的基礎庫。
  • asio-kcp: 使用 KCP的完整 UDP網路庫,完整實現了基於 UDP的鏈接狀態管理,會話控制,KCP協議調度等
  • v2ray: Shadowsocks 代替者,1.17後集成了 kcp協議,使用UDP傳輸,無數據包特徵。

  • dog-tunnel: GO開發的網路隧道,使用 KCP極大的改進了傳輸速度

不管是何種同步演算法,都需要更先進的網路傳輸技術,而使用libenet這種20年前的老技術,沒法很好的解決這一問題,我們需要更加先進現代的傳輸協議,來達到這個目標。

----

本專業學通信的,閑著沒事喜歡折騰各種傳輸協議。

更多閱讀:

reliable_udp_bench_mark: Test reliable udp for situation of realtime pvp game by wireless.

通過KCP協議加速科學上網

--

另,具體同步演算法我回答過無數遍了,不再複述:

手機格鬥網遊該如何避免延遲? - 韋易笑的回答

FPS遊戲中,在玩家的延時都不一樣的情況下是如何做到遊戲的同步性的? - 韋易笑的回答

Skywind Inside - 網遊同步法則

--


RTS遊戲有很多,可能大家比較熟悉的有Warcraft III (dota)和 StarCraft,

早期西木的沙丘,紅色警戒更是rts遊戲的鼻祖,帶給我們無限的歡樂和回憶。

還有當下比較流行lol與dota2,實際上都是孫子輩的遊戲了。

那麼他們到底是怎麼做到高頻操作又同步的呢?

同步機制

假設遊戲中A,B兩個玩家移動,並同時向對方發出射擊指令

如果沒有合適的同步機制

那麼可能出現的情況有

1 A屏幕顯示B已經被殺死,B屏幕顯示A已經被殺死

2 或者在瞄準後確打不到對方

圖中玩家Plyaer1,Plyaer2在兩個不同的客戶端,表現出不同效果

因為網路是有延時的,而每個玩家的網路情況都不盡相同。

還有每幀渲染的延遲(早期的計算機性能不夠好的時候會出現這個問題)

同步機制最重要的作用就是解決延遲等可能發生不一致的情況。

同步機制的分類

Peer-to-peer模式: 沒有伺服器,每個玩家互相連接,各自模擬整個流程.典型的lockstep模式

優點:減少主機帶來的延時

缺點:容易作弊

Client-Server模式

所有的操作需經過伺服器確認後才能進行客戶端模擬,如arpg傳奇類都是此架構,如果延時高就會有明顯的卡頓。

優點:伺服器是絕對的權威,可以防止作弊,可以做更多的管理與限制

缺點:伺服器變的更複雜,伺服器斷線,所有玩家斷線,屬於伺服器依賴型。

早期的RTS遊戲大多採用Lockstep方案來設計,像羅馬帝國,沙丘之類。

Lockstep最早用于軍隊中

就是說玩家的數據每個時間段同步一次,同步的走。

標準的lockstep模式

1 每個玩家互相連接,整個遊戲過程劃分成一組turn指令幀,由玩家自我模擬

2 遊戲速度取決於網路最慢的那個玩家

3 一個玩家掉線不會影響到其他玩家

什麼是Turn?

一個turn可以理解成1個回合,相信大家都玩過回合制遊戲吧

只是這個turn非常短,大概100MS-200MS

玩家相互之間發送的指令在每個turn間隔發出

每個玩家只需要接收指令,並在本地播放指令就可以啦

War3如何運算傷害?

玩家到底是發送什麼指令到主機,主機到底參與了什麼計算呢?

實際上玩家都只需要發送基本的指令如選擇單位,移動單位,使用技能1234,點擊物品欄1-6,可以通過APM查看軟體看到一些基本操作事件

也就是說所有的一切傷害計算都是在本地計算完成的

包括傷害,暴擊,命中,刷怪等,只要初始化好隨機數種子就可以啦

玩家只是發送操作指令,如點擊坐標(0,1, 0),左鍵框選(100,100,50,50)等

每個玩家都在模擬全部的流程

那麼War3到底算不算使用lockstep模式,或者是特殊的client-server?

其實可以通過幾個問題判斷出

1 非主機玩家卡是否可以影響到其他玩家,如果不會,那麼更可能是client-server模式

2 可以通過抓包工具攔截網路數據包的流向,來判斷是否是peer to peer的連接方式還是只連接到主機(或通過主機強制掉線方式判斷)。

一個外國朋友的回答

個人也認為War3是基於Client-Server的一種的特殊模式,主機肯定需要驗證一些邏輯。

主機負責廣播每個client的指令

這存在兩個問題

  1. 本機(非主機)發出的指令,如果超時或者丟包,是否直接丟棄?

  2. 其他玩家的指令,主機轉發未成功確認,如何處理?

第一個問題

  1. 如果是本機(非主機)發出的指令超時,可以直接丟棄.(如果不丟棄,其他玩家就必須等待結果,這樣會導致掛起,而且會非常頻繁,這裡還有udp協議容易丟包的原因,但是war3好像並沒有經常性的掛起)

還有一種可能,客戶端得知之前的turn沒有發送成功,把當前這輪的指令和上一輪的指令進行合併,然後一起發出,這樣本地客戶端就不會有任何的異樣了。

例如玩家移動到A後再移動到B

上個turn的指令是移動到A點,但是沒有發成功,下個turn的指令先移動到A,再移動到B,這樣在客戶端就不會有丟失的感覺啦,還是可以正常的模擬而不會影響到其他玩家。

2. 收其他玩家的指令超時,那麼屬於我們自身網路的問題,如果丟棄必將導致遊戲進程不同步,所以伺服器必須將他們的turn指令都緩存起來,

或者緩存一部分turn指令集,在我網路穩定的時候,把丟失的那一部分turn指令集發給我,而我只需要下載那個list加快gameupdate就好啦。

有些朋友問到外掛的問題

相信玩過魔獸的人基本都用過,實際上像戰爭迷霧,顯示單位等只會保存一個狀態值在內存中,只要定位到內存地址,改一下變數值就好了,一般是伺服器是不會檢測這個的。

而攻擊力,道具數量等,由於大家都需要模擬,你本地修改了,會影響到其他人,程序就會發生蝴蝶效應。

開圖掛應該是這類遊戲最常見的了。

至於現在非常流行的 Dota2 和 英雄聯盟,會額外的加入更多伺服器來驗證和計算一些外部數據,

但內部原理是一致的,早期的遊戲與現在的網遊不可同日而語。

歡迎各遊戲圈朋友加-Q群 512746636 討論吹水


Source Multiplayer Networking

Latency Compensating Methods in Client/Server In-game Protocol Design and Optimization

Quake Source Code Review

盜圖一張,侵刪:

以上是幾個關於lag compensating 和 client prediction的資料。簡單點說就是同步的時候加個時間戳,然後根據時間戳客戶端和伺服器(wow就有server 的 lag compensating)做一下處理。

以dota2為例,原則就是保證玩家控制自己的角色時盡量流暢準確。至於別人的角色老實說玩家的感覺並沒那麼敏銳,從轉身啊動作前搖後搖啊擠點時間出來就行了,像潮汐的攻擊前搖有0.6秒(記得好像是),這一點也不「快速」,你玩潮汐也許會控制時機補刀,別人的潮汐你才不會去老老實實算他的攻擊前搖是不是搖夠了0.6秒呢。

另外就是網路環境要保證大部分玩家可以滿足遊戲設計的最大延遲了,沒做過運維,這方面不懂,之前看過資料說用靠近玩家的網關伺服器加vpn來實現,不過地址也找不到了。註:

dota2的例子純屬思維實驗,實際驗證估計要找個網路不好的地方雙開試一下。


魔獸系的是幀同步(真*同步)

LOL據說用的是狀態同步, 而不是幀同步, 為的就是在糟糕環境下, 也可以同步

大家都會有一個統一的隊列, 在同一個時間點執行同樣的操作, 所有人的操作都要進入這個隊列, 然後廣播給所有人

大概是這樣


跑個題,FPS的同步

《守望先鋒》技術分享視頻:如何處理網路同步與減少網路遲疑

遊戲開發 | Dalton"s Dev Blog

程序 Gad-騰訊遊戲開發者平台


類似星際,魔獸:選擇一個客戶端作為伺服器。

客戶端和伺服器的通信包括確認部分,完全確認完畢後再進行操作。一般每秒同步10次。任何一個客戶端cpu負載滿後,都會拖慢所有人的幀率。

類似dota2:可以選擇一個客戶端起伺服器,也可以選擇官網的獨立伺服器

客戶端和服務端的通信不包括確認,伺服器只管處理已經接受的指令,只管發送處理完畢的同步信息。同樣每秒同步10次多數。除非伺服器cpu負載滿以後影響每秒同步次數從而拖慢遊戲甚至不拖慢遊戲僅僅影響準確率,其他情況下,只有網速慢的人會有操作誤差(譬如lag)


我猜題主是想問,「那麼光輝絢爛的戰場,數據量想必是個天文數字,憑什麼能用普通的寬頻毫無遲滯地愉快玩耍」。

辦法就是:壓縮流量,只傳遞實際操作

比如牛頭跳大,非常宏大的場面,客戶端之間同步的內容僅僅是:

  • 跳:time=5:31.1234,player=1,operation=物品欄1,target=(345.55,8272.44)

  • 大:time=5:31.1456,player=1,operation=C

  • 看,我的跳刀出得很早吧?

實現上肯定有很多複雜的細節,比如有封裝,有同步節點,有master-slave,有握手確認。但數據流量確實很小,基本上所有操作都可以用10個位元組的流量搞定。網路的傳輸成本可能會翻幾番,但100位元組頂多了。

題主可以估算一下10個APM300的高手能造成的數據流量大約是多少。網路傳輸優先順序足夠高的話,300K的帶寬也基本足夠了。


war3使用的是lockstep,這個是明確的,包括星際爭霸,還有風暴英雄,從他重連的時候重頭開始計算基本可以推斷處理都是用此方式。

lol是狀態同步的,即狀態變化的時候發送消息,協議會更加複雜,不過斷線重連也會更加好做。

補充下後續答案,早期絕大部分遊戲都是每段時間發送輸入數據,由特定主機或者專屬伺服器轉發所有輸入幀數據,然後每個客戶端需要這個數據才能跑每個幀,主要原因是rts遊戲單位數量太多了,其他方案都沒這個簡單方便。這個方案即lockstep。

當然這種方案在每個遊戲中都有不一樣的實現,比如帝國時代,主機轉發輸入數據的頻率是由網路最爛的客機決定的,即主機需要收到所有客機數據數據才轉發,而在魔獸爭霸中並不是這樣的,伺服器到一定時間必然轉發所有輸入數據,如果沒有就假設你沒有輸入。

這個方案得細節還有很多,可以查詢網路,比如如何定好那個固定時間時長,保證所有機器計算確定性,做好緩衝,加速等。

對於大型網路遊戲來說,就往往不是這麼做的了,這裡就包含了樓主說的dota2和lol,找時間再細聊。


幀同步這種過時的玩意沒什麼必要去看,之所以有是因為幀同步做起來簡單而已,因為那個年代的外網環境沒那麼好,解決區域網同步幀同步就能完成。

看看新出的遊戲,都一律是服務端邏輯,誰也不會傻不拉嘰把邏輯丟客戶端了。

客戶端就管兩件事

1.發送玩家操作信息

2.響應服務端的同步數據,並表現到客戶端。

當然不可能所有數據都往下發,基於數據策略,也就有所謂的約定事件邏輯,用於減少數據量。

服務端要做的事情就多了,因為客戶端不管複雜邏輯,所有的邏輯都在服務端。按mvc模式的話,mc都在服務端。沒客戶端什麼事了。

另外說一個全球的問題,所謂的全球玩家是不可能都連一個伺服器的,這樣必然延遲高,連入最近的網關伺服器,然後通過內部伺服器轉發可以保證大部分的玩家延遲一致,畢竟機房和機房間的延遲是相當低的


遊戲中的網路同步機制——Lockstep · 寂寞的賓狗


無非就是兩個方向,邏輯放在客戶端(幀同步)和邏輯放在服務端(cs同步),如果是幀同步的話,伺服器只負責轉發用戶操作數據,並且加時間戳,客戶端接收到操作數據後進行邏輯計算。這樣可以保證每個客戶端的遊戲邏輯是相同的。如果是cs同步的話,伺服器接收操作數據,然後進行邏輯計算,將計算後的結果發送客戶端。


轉載(感覺回答的不錯):

unity是可以用幀同步來做RTS遊戲的,王者榮耀就是例子。同時你說的那些問題,深入的去研究下就好解決了。不過實現難度還是有的,我們遊戲就用了來做RPG,火影手游也是用的幀同步做的。有興趣可以私聊Re: langresser 2016-03-24 23:35發表 [回復]回復xiaofeng2543:仔細想想,我現在依然對幀同步持有一定的抵觸,我認為除了特殊情況(比如上百人的單位同步,常見於rts,或者是coc類遊戲),否則幀同步並沒有特別的好處。

幀同步的好處是客戶端之間嚴格一致,網路通信量少,伺服器不需要處理複雜的邏輯。

而壞處是客戶端複雜度高,必須要處理好嚴格一致,防外掛比較難做,手游之間的碎片化版本管理比較麻煩。

在端游自研引擎時代還可以說是個正確的選擇,但是在手游快速出產品的時代,可能就不那麼正確了。

王者榮耀這樣的MOBA,我記得屏幕中總共也沒太多單位,其實沒有必要用幀同步,而事實上不用幀同步的MOBA反而更多。端游的dota2 lol,手游的亂斗西遊、自由之戰等。

火影忍者這樣的橫版動作遊戲更是沒有必要用幀同步的,狀態同步做好客戶端預判處理能夠表現出更加優異的手感。

RPG如果是神仙道或者夢幻西遊之類的,還是狀態同步更傳統。而開房間獨立副本式的ARPG也還是狀態同步更好些,除非,幀同步無非就是npc邏輯處理可以在客戶端做,而事實上,大多數開房間的遊戲,同場景內的怪物數量並不會很多。撐死了也就二三十個。

最後就是幀同步的網路中斷重連的處理是比較麻煩的(參考風暴英雄中渣的要死的斷線重連),也不太好處理玩家中途進入的情況,所以mmo是肯定不能用幀同步的。Re: langresser 2016-03-24 22:56發表 [回復]回復xiaofeng2543:學習了,有時間我再研究研究。

我認為需要解決的問題有:

1、抽象客戶端角色為一個邏輯實體,讓它完全獨立於unity。具體動畫、特效表現無關戰鬥邏輯

2、處理好戰鬥邏輯中的浮點數。主要是坐標和角色屬性

3、注意其他依賴框架的處理,比如lua或ai框架。要保證這些框架的正確性

4、網路處理,看看是否需要用UDP

5、做好驗證機制,可以自動化的進行遊戲模擬。


現在正好在做實時同步戰鬥的遊戲,類moba吧,其實一般就是幀同步和狀態同步兩種,狀態同步大家應該都比較清楚,一般的mmo,都是這種,伺服器負責模擬整個遊戲的邏輯,客戶端只負責發送玩家的操作,接受伺服器發送的狀態改變並顯示,當然還有一些預測策略。幀同步,都說實現很複雜,我自己實現了一遍後,覺得也還好,相當於是寫一個單機遊戲,但是每一個邏輯幀都是由統一的伺服器來控制,伺服器向連接的客戶端轉發邏輯幀,並收集玩家上傳的操作,插入合適的邏輯幀,轉發給客戶端,相當於一個PS4接了幾個手柄同時玩一個遊戲。而各個客戶端要保證每一幀的執行結果都是一致的,一般在各個客戶端執行過程中可能出現不一致的點,1.浮點數,可以採取轉化為定點數,或者不使用,2. 碰撞檢測 可以自己根據項目需求,根據邏輯幀模擬,自己編寫確定性的碰撞檢測,3.容器排序,保證排序是確定.4.邏輯幀的執行一定要和渲染分離,不能因為渲染導致邏輯出現不一致,5.隨機數 由伺服器給出統一的種子就行unity 裡面實用Random.InitState 初始化6.各個客戶端的非同步操作,比如載入資源之類,一般在戰鬥開始前就完成 大概就這麼些,之前花半個月就在unity里實現了實時同步的貪吃蛇,感覺幀同步還是很舒服的。伺服器毫無壓力,流量比狀態同步少太多,而且自帶錄像回放功能,只需要使用相同的初始條件。把一局的幀操作記錄下來。再運行一次客戶端模擬就行了,魔獸爭霸3,皇室戰爭也是這麼做的


一般RTS遊戲里幀同步比較多一些,例如:WAR3,帝國時代等。

幀同步的遊戲也利於做錄像回放。所以你會發現WAR3的錄像文件都特別小,因為文件里記錄的都是玩家操作的數據:滑鼠點擊事件,技能按鍵事件等。


你google 搜索「幀同步 遊戲」可以得到一堆參考,這種遊戲的客戶端同步幾乎沒啥技術難度了,唯一困難的部分是伺服器的低延遲響應,國內網路延遲的平均時間是200ms,這個延遲對於這種類型的遊戲還是有點高的,所以降低延遲是關鍵,要做到雙線50ms左右的延遲,這涉及到機房、伺服器效率等問題。


CS和幀同步其實各有有優缺點,並不是某一項方案一定能夠取代另一項方案,當遊戲類型對實時性要求很高時(比如,實時格鬥、體育競技類遊戲(NBA2K)),幀同步可能就是唯一的方案了。

這一點真不能認同,我覺得幀同步是在流量限制和只做區域網的前提下出現的,後期LOL dota2都是用的狀態同步,客戶端的插值預算技術不斷的在完善,所以實時性很高的遊戲也不是必須用幀同步。


感覺原則性的東西已經講了不少年,具體實現與網遊架構如網路I/O性能、遊戲邏輯處理框架設計等等密切相關。

如果哪位大神能選擇其中某項來詳細展開來討論,想必大家一定會感覺非常過癮!


簡單一句話概括那就是幕前顯示與幕後計算分離不就結了?


有一次聽ob直播,說早些年龍神8老闆他們打職業的時候,eh有一種黑科技可以降低線下比賽的延遲,具體怎麼做沒講,後來8老闆也承認了。


推薦閱讀:

怎麼做硬核用戶方向的單機遊戲媒體?
龍與地下城對後世遊戲有哪些深遠的影響?
為什麼有大量的遊戲發行/製作公司選擇將旗下工作室放在加拿大魁北克省的蒙特利爾?
有沒有一種可以編譯為 Lua 運行的語言?
作為一名遊戲開發或運營人員,你在體驗時遇到過哪些對你設計思路「特別有收穫」的遊戲作品?

TAG:遊戲 | 遊戲開發 | 網路延遲 | 遊戲伺服器 | 遊戲服務端 |