日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

服务端构架干货:快节奏多人游戏的技术实现

發布時間:2024/8/26 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 服务端构架干货:快节奏多人游戏的技术实现 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

stanleyluo編譯

一、簡介



本文是探索如何制作快節奏多人游戲相關技術和算法的系列文章中的第一章。如果你熟悉多人游戲背后的概念,可以放心跳過本章 - 接下來是一些介紹性的討論。

作弊問題

一切都始于作弊。

做為游戲開發者,通常不會關心是否有人在你的單人游戲中作弊,因為他的行為只會影響他自個兒。作弊的玩家可能不會按照你設計的過程來體驗游戲,但這已經是他自己的游戲,他們有權利想怎么玩就怎么玩。

多人游戲則不同。在所有競技游戲中,作弊玩家不僅只提升自己的體驗,同時也破壞了其它玩家的體驗。做為開發者你得避免這種行為,因為這將導致玩家離開你的作品。

有許多辦法能防止作弊,但最重要的一點(也可能是唯一真正有意義的一點)很簡單:不信任玩家。做好最壞的打算 - 玩家會嘗試作弊。

權威服務器和啞客戶端 (Authoritative servers and dumb clients)

這是一個看似簡單的解決方案 - 所有的游戲邏輯在你的服務端實現,客戶端僅做游戲表現。換句話說,就是游戲客戶端向服務器上送輸入(玩家的按鍵,指令),服務端運行游戲邏輯并下發運行結果給客戶端。這種做法可稱之為“權威服務器(authoritative server)”,因為游戲中發生的一切都由服務器控制。

當然,你的游戲服務端可能有能被利用的漏洞,那超出了我們的討論范圍。但使用權威服務器這種模式能防止大部分的攻擊。比如,玩家的血量以服務器的為準,被攻擊的客戶端能在本地將玩家的血量改大100倍,但服務器那還是只剩10%的血量 - 當玩家被攻擊時還是會死掉,客戶端怎么改也沒有用。

玩家游戲中的位置信息也不能相信客戶端。否則,被攻擊的客戶端通過上報位置給服務器說“我在(10,10)”并在一秒后上報“我在(20,10),達到穿墻或行動快于其它玩家的目的。相反,服務器知道玩家的位置在(10,10),客戶端上報指令說“向右移動一格”,服務器運行更新內部狀態計算出玩家新的位置在(11,10),并返回客戶端“你現在在(11,10)”:
?


總而言之:游戲狀態完全由服務端管理。客戶端上送操作給服務器,服務器定期更新游戲狀態,并下發新的游戲狀態給客戶端進行表現渲染。

網絡處理

上述啞客戶端(dumb client)的方案在慢節奏的回合制游戲上工作得很好,如策略或者是牌類游戲。在局域網、或是無延遲的通訊環境下也運行良好。但用于快節奏網絡游戲特別是在互聯網環境下就完蛋了。

先說物理環境。設想你在舊金山,連到位于紐約的服務器,大概4000公里或者2500英里(大概是兩倍北京到香港的距離)。字節在Internet上傳輸接近光速(達到低級別的光脈沖、電纜中的電子,或電磁波的速度),光速大概30萬公里/秒,所以這個距離大概需要13毫秒。

這聽起來非常快,而且是非常樂觀的設置 - 假設了數據能以光速直線傳輸,其實不然。在實際情況下,數據需要從路由器到路由器之間通過一系列的中轉(網絡術語稱之為hops),達不到光速;因為數據包必須復制、檢查、重新路由,所以路由器本身會造成一些延遲。

為求說法,我們假設數據在客戶端到服務器耗時50毫秒,這比較接近最佳場景。如果你從紐約接入位于東京的服務器呢?如果出于某種原因導致網絡擁塞?延遲100,200甚至500甚至更大。

回到我們的例子,你的客戶端上送指令給服務器說“我按了右方向鍵”,服務器在50毫秒后收到 ,如果服務器立即處理完請求更新狀態并回應,客戶端也得在50毫秒后收到新的游戲狀態“你現在在(1,0)”。

這樣看來,你按下右方向鍵后有一小會沒有任何效果,然后游戲角色才會右移一格。這種處于你的輸入指令和響應之間的卡頓不多,但非常明顯。當然,半秒的卡頓已經不是明顯,會直接導致游戲沒法玩。

總結

多人網絡游戲如此好玩,但面臨全新的挑戰。權威服務器的架構能很好的防止作弊,但僅僅這樣簡單實現將造成游戲響應遲鈍。

后續內容我們將嘗試基于權威服務器架構來構建一個系統,讓玩家得到最小的延遲的體驗,達到幾乎和本地單機游戲一樣的效果。

二、快節奏多人游戲:客戶端預測+服務器比對

前言

在本系列的第一章中,我們探討過一種權威服務器與啞客戶端的C/S模型:僅上送輸入指令到服務器,然后在服務器更新游戲狀態并在響應之后由客戶端展現效果。
?


此原始實現方案會導致玩家操作到屏幕響應之間的延遲:玩家按下右方向鍵,游戲角色過一秒才開始移動。這是因為客戶端輸入必須先傳輸到服務器,服務器必須處理輸入并計算出新的游戲狀態,然后新的游戲狀態才能回應給客戶端表現。

在Internet這樣的網絡環境中,如果延遲達到十分之一秒,游戲操作就會感覺反應遲鈍,最糟的情況則沒法玩兒。在這部分內容中,我們得尋求改善并消除這個問題的方法。

客戶端預測

盡管會存在一些作弊玩家,但大多數時間里游戲服務器處理的是有效的請求。這意味著游戲狀態會按照預期更新;比如在你按了右方向鍵后角色就會走到(11,10)這個位置。

我們可以利用這一特點,在游戲世界是足夠的可預測的情況下(即,給予的游戲狀態和一系列輸入,運行結果是完全可預測的)。假設存在著100毫秒的滯后,并且游戲角色移動一個格子的動畫也需要100毫秒和話。使用之前的實現,整個動作得花200毫秒。
?


由于游戲世界是確定性的,我們可以假設玩家上送到服務器的指命都能成功執行。基于這個假設,客戶端可以預測指令在處理之后游戲世界的狀態,而且預測幾乎能完全正確。

相比上送指令然后等待新的游戲狀態再開始表現,手機靚號買賣現在客戶端可以在上送指令后就立即展現效果,如果上送的指令正確處理那么等待得到的新游戲狀態將與客戶端本地計算的狀態相一致。


這樣下來,使用權威服務器模式,玩家操作與屏幕表現的效果將完全沒有延遲(如果被攻擊的客戶端發出無效的指令,也能看到相應的效果,但不會影響服務器的狀態和其他玩家的表現)。

同步問題

上面的例子里,我專門選的數值讓游戲運行得非常好。但是,如果稍微改動一下場景:服務器響應延遲達到250毫秒,移動一格動畫消耗100毫秒,玩家連續按了兩次右方向鍵,想向右移動兩格。

繼續使用上述方法后,會是這個樣子:
?


問題開始變得有趣。收到游戲新狀態的時間t=250ms,而客戶端此時預測產生的狀態是x=12,但服務器返回的狀態卻是x=11。因為服務器權威,這樣客戶端必須把角色退回到x=11的位置。但此時,在t=350時又收到了服務器更新狀態,并通知說x=12,因為角色這時又得跳回去。

以玩家的角度看,他按了兩次右方向鍵,角色向右移動了兩格,站在那50毫秒后又跳回左邊一格,停了100毫秒后再次跳到右邊。這顯然是無法接受的。

服務器校對

解決此問題的關鍵在于理解客戶端看到的游戲世界是現在時,但由于滯后,從服務端取得的更新實際上是過去時的狀態。服務器下發的游戲更新狀態,還不是處理完所有客戶端上送指令后的狀態。

解決這個問題不難。首先,客戶端在每個請求中增加序列號;上例中,第一個按鍵請求序列號為 #1,第二次按鍵為請求 #2。然后服務器的回應也帶上相應的序號:
?


這樣的話,當t=250,服務端說 “按請求#1,你的位置在x=11”,然后將服務器中角色位置設置為x=11。現在假設客戶端留有發往服務器請求包的所有備份,按照收到的回應,客戶端得知服務器處理完請求#1,所以扔掉本地對應的拷貝,客戶端知道后續還有#2的回應,所以本地預測會繼續。即使有些請求服務器還沒處理到,客戶端仍能根據服務端最后下發的狀態計算出游戲的“當前”狀態。

因此,當t=250,客戶端收到“x=11,已處理請求#1”,就扔掉請求包備份中的#1,但保留服務端尚未確認的#2的備份,然后將游戲內部狀態按服務器的響應設置為x=11,并且會繼續表現服務器尚未收到的所有請求,即“向右移”的#2指令,得到的最終正確結果x=12。

之后,當在t=350時收到服務端的游戲新狀態時,服務端指示“x=12,已處理請求#2”,這時客戶端扔掉#2指令備份,并更新狀態為x=12。此時備份中已經沒有未處理的指令,所以客戶端處理以正確的結果停在這兒。

其它

上面討論的是移動的處理,但同樣的原理適用于其它所有內容。比如回合制戰斗游戲,當玩家攻擊一個其它角色時,可以展現掉血和傷害數值,但在服務器回應之前還不應該更新那個角色的生命值。

因為游戲狀態的復雜性,不是總能簡單的應對,可能你得在收到服務器確認前避免一個角色被殺掉,哪怕當前客戶端狀態中它的生命值低于0,比如這個角色正好在你的致命攻擊之前使用了回血包,但服務器還沒下發給你。

這又引入一個有趣的問題,即便游戲世界是完全確定的并且沒有任何客戶端作弊,還是有可能出現客戶端預測的狀態與服務端下發的狀態在比對后不一致。這個情形在單人游戲不可能出現,但在服務器上同時連接了多個玩家時很常見。這將是下一篇文章的主題。

總結

使用權威服務器,需要在客戶端等待服務器實際處理上送指令的過程中,給予玩家即時響應的錯覺,客戶端按玩家的操作模擬出效果,當收到服務端的新狀態時,客戶端會使用收到的更新和其后上送服務器但還沒確認的輸入重算之前已預算的狀態。

三、實體插值

簡介

在本系列第一章,討論的是權威服務器的概念及其防作弊的作用,但過于簡單得使用這個方案會帶來可玩性和響應能力相關的問題;到第二章中則提到運用客戶端預測來克服這些問題。

這兩篇文章的最終結論是一系列關于讓一個玩家在互聯網有傳輸延遲的環境下連接權威服務器的情況下,操作游戲角色達到單機游戲體驗的概念和技巧。

在本章,我們討論在相同的服務器有多個玩家控制的角色接入的情況。

服務器時步(Server time step)

上一章,我們把服務器的行為描述的非常簡單:讀取客戶端指令,更新游戲狀態,并回應給客戶端。但當多個客戶端接入時,服務器的主循環邏輯會略有不同。

此時,在快節奏游戲中的多個客戶端可能會同時上送指令(玩家飛快的操作按鍵,鼠標移動和點擊來發出指令)。每次從每個客戶端收到上送指令都處理游戲世界的狀更新和廣播的話,將消耗大量CPU和帶寬。

將收到的客戶端指令不做處理立即放到隊列中,然后以較低頻率定期處理游戲世界的更新(比如每秒更新10次)是個好辦法。這樣的話,每次更新的延遲是100毫秒,我們稱之為時步(time step)。服務器在每次循環更新時,處理掉所有未處理的客戶端指令(可能要以比時步更小的時間增量處理,方便預測物理行為),然后將新的游戲狀態廣播給客戶端。

總之,游戲世界的更新只以預期的頻率進行,而與客戶端指令的上送和數量無關。

處理低頻更新

從客戶端來看,這種方式和之前一樣能順暢的運行:客戶端預測處理與更新間隔的延遲無關,所以在相對較少的狀態更新時也能清晰的預測處理。但由于游戲狀態廣播的頻率低(如上每100毫秒一次),那么客戶端只有游戲世界中非常少量的可到處移動的那些其它實體的信息。

之前第一種實現會在收到新狀態時更新其它玩家角色的位置,那這些角色原本平滑的移動變成了每100毫秒分散的移動,成了非常斷斷續續的瞬移。如下圖:
?


根據游戲類型相應有各種針對此問題的解決方案;通常情況下,游戲中的實體越可預測就越好解決。

航位推算(Dead reckoning)

設想我們開發一款賽車游戲,車速非常快所以很好預測,比如賽車的速度每秒100米,一秒之后它將位于起點后大致100米的位置。為什么是“大致”?在一秒之間,車子可以加速或減速了一點兒,或者是左轉或右轉了一點兒,注意這個詞“一點兒”,汽車的機動性就是這樣,因為無論玩家如何實際操作,賽車在高速行駛期間其時間點所在的位置很大程度取決于其之前的位置、速度和方向。換句話說,賽車不會立即出現180度轉向。

那當服務器每100毫秒下發一次更新的話如何處理?客戶端收到下發的每臺競技賽車的速度和朝向,要下個100毫秒后才收到新的信息,仍得展現賽車繼續在行駛。最簡單的做法就是假設100毫秒內車速和朝向不變,然后通過這些參數本地運行賽車的物理表現。然后在100毫秒收到服務器更新后再修正車的位置。

修正處理可大也可小,取決于很多因素。如果玩家保持賽車直線前進并且沒有改變車速,那么預測的位置將精確的對應服務器通知要修正的位置。另一方面,如果玩家被什么東西撞毀,那預測的位置也會錯得離譜。

注意航位推算法更適用于低速場景,比如戰艦。實際上,“航位推算”就是起源于海上航行。

實體插值

有不少場景無法應用航位推算法:特別是當玩家方向和速度會隨時改變的情景下。例如3D射擊游戲,玩家們通常會高速的跑動、停止,轉彎,這時航位法幾乎無效,因為位置和速度不再能通過之前的數據進行預測。

收到服務器為準的數據時不能立即更新玩家的位置,這會讓玩家每100毫秒閃跳一段距離而使得游戲沒法玩。

那在每100毫秒得到服務端位置數據時該怎么做呢?訣竅在于在這期間如何展現玩家角色的動畫。答案的關鍵是以相對于玩家過去的狀態來展現其它玩家。

比如在t=1000這個時間點收到位置數據時,已經有了時間點t=900的數據,所以可以知道玩家在t=900和t=1000時的位置,因此,從t=1000和t=1100,展現的是其它玩家在t=900到t=1000時的行為狀態。這樣的話總是以玩家真實的移動數據進行展現,只是滯后了100毫秒。
?


從t=900到t=1000的用于插值的位置數據取決于游戲。插值處理通常效果良好,否則也可以讓服務器在每次更新時下發更多詳細的行動數據來改善插值效果,比如玩家路線的一系列直線段或者是每10毫秒的位置采樣(只需要發送小的行動的增量數據就不會放大下發的數據量,因為這種情況在數據傳輸時會被大量優化)。

需要注意,使用這種方式時,每個玩家看到的游戲世界的表現會稍微不同,因為每個玩家看到的自己是現在時但看到的其它實體是過去時,但是就算在快節奏游戲中看其它實體有100毫秒的差異感覺也不明顯。

也有例外:當處于要求大量空間和時間精度的場景中,如當某玩家槍擊其他玩家時,因為看到的其他玩家是過去時,瞄準有100毫秒滯后,這表示你正在射擊的是100毫秒之前的目標!我們會在下一章處理這個問題。

總結

在有網絡延遲并使用低頻率更新的權威服務器的C/S架構中,仍然必須為玩家提供游戲的連續性和平滑運行的錯覺。在本系列第二部分中討論過通過客戶端預測和服務器校對的方式實時展現玩家行動的方法,這樣做確保本地玩家的行為立即生效,并消除了影響游戲可玩性的延遲。但存在其它游戲實體時仍有問題,這一章則討論了解決這類問題的兩個方法。

第一個是航位推算(dead reckoning),適用于某些類型的模擬:即游戲中實體的位置可以通過如位置、速度和加速度這些已有數據估算出可用值。如果不符合這個條件這個方法就會失效。

第二個是實體插值(entity interpolation),不做預測而是使用服務器的真實數據,來展現出稍微在時間上延遲的其它實體。

最終的效果是玩家的角色處于現在時但游戲中的其它實體處于過去時,這通常能創造出極其流暢的體驗。

但一切還沒結束,在需要高精度的空間和時間的情況時以上方法就失效了,比如射擊一個運動中的目標:客戶端2展現出來的客戶端1的位置,與服務器中和客戶端1中的位置不一致,那就別想爆頭了!當然得有爆頭,下一章來解決這個問題!

四、爆頭

概要

前三章解釋的C/S方案可以總結如下:
?

  • 客戶端上送給服務器的所有請求都帶上時間戳
  • 服務器處理輸入指令并更新游戲狀態
  • 服務器定期下發游戲狀態給所有客戶端
  • 客戶端上送指令并在立即本地展現效果
  • 客戶端取得游戲狀態
  • 同步預測服務端狀態
  • 使用已有狀態為其它實體插值


從客戶端角度看,會產生兩個重要結果:
?

  • 玩家看到的自己是現在時
  • 玩家看到的其它實體是過去時


這個方法多數時有效,但在時間空間精度有要求的時候會很成問題,比如爆頭。

滯后補償(Lag Compensation)

當你端起狙擊槍完美的瞄準對手的腦袋時,你開槍了!必將一擊斃命!

但。。。沒中

怎么回事兒?!

因為在上述C/S架構中,你瞄準的位置是100毫秒前對手的頭所在的位置,就像處于某個光速非常非常慢的宇宙中,你瞄準的是敵人過去的位置,當你扣下扳機時他已經跑了。

幸運的是,這個問題也有一個簡單的應對方案,對于大部分玩家在大部分時間也是能被受的(有一個例外會討論)。

看看是怎么做到的:
?

  • 開槍時,客戶端把完整的信息上送給服務器:開槍時精確的時間戳和武器瞄準的精確位置;
  • 關鍵是這一步:因為服務器有所有帶有時間戳的客戶端指令,服務器能準確的重建游戲世界在過去任何一刻的狀態。事實上,服務器可以精確的重建任何客戶端在任何時間點的游戲世界的狀態。
  • 這意味著服務器知道在你出手的瞬間你的槍口對準的是什么 ,那個位置那一刻是對手在過去時的腦袋,而且服務器也知道他腦袋的位置對于你是現在時。
  • 服務器處理那個時間點的爆頭命中邏輯,并下發狀態給客戶端。


這個結果所有人都滿意!

服務器是老大,所以它總是滿意

你也滿意因為你瞄準對手的頭,開槍,并拿到了一個爆頭!

可能只有對手不是完全滿意,如果當他被擊中時他正站在那兒沒動,那就是他的錯,對吧?但當時他在跑。。Wow,那你真的是神狙。

但如果他正好從開放地形躲到了墻后邊,還正想著安全時就在不到一秒內被擊中了呢?

是的,就這么發生了,這是權衡的結果。因為你擊中的是過去時的他,就算那幾毫秒后他躲起來還是被命中了。

這是有點不公平,但這是所有參與者最滿意的解決方案,這比完美一槍去沒命中要好太多!

結論

快節奏多人游戲系列到此結束。這類事情要做好的確很棘手,但如果清晰的理解了事情的原理,就不再那么困難。

雖然這些文章是為游戲開發者所寫,但另一組讀者也會感興趣,那就是玩家!做為玩家肯定也想知道為什么出現這樣的情況,原因是什么。

總結

以上是生活随笔為你收集整理的服务端构架干货:快节奏多人游戏的技术实现的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 亚洲gay视频| 动漫羞羞| 色欲av永久无码精品无码蜜桃 | 天堂a√在线 | 国产色爽 | 国产精品久久久久无码av色戒 | 国产精品免费91 | 91成人福利在线 | 亚洲专区视频 | 自拍偷拍18p | 久久人人妻人人人人妻性色av | 亚洲色图av在线 | 中文一二三区 | ,一级淫片a看免费 | 亚洲国产精品激情在线观看 | 黄色1级大片 | 成人精品黄段子 | 夜夜嗨av一区二区三区 | 波多野结衣在线观看一区二区三区 | 国产真实伦对白全集 | 少妇毛片| 肉色欧美久久久久久久免费看 | 欧美视频在线观看一区二区 | av狠狠干 | 碰碰久久 | 美女成人在线 | 成人免费在线 | 中文字幕视频二区 | 天堂中文网 | 天天干天天干天天干 | 色撸撸av| 国产男女无套 | 亚洲高清视频在线播放 | 啦啦啦免费高清视频在线观看 | 永久免费黄色 | 波多野吉衣在线观看视频 | 黄色网址链接 | 中文字幕激情 | jizzjizz在线播放 | 精品国产一区在线观看 | 欧美mv日韩mv国产网站app | 青青视频免费观看 | 在线播放91灌醉迷j高跟美女 | 日韩精品极品视频免费观看 | jzjzz成人免费视频 | 九九久久精品 | 国产精品理论片 | 日日艹 | 亚洲精品久久久久久久蜜桃臀 | 桃色视频网| 在线观看成人 | 69国产精品视频免费观看 | jizz成熟丰满日本少妇 | 欧美成人三级伦在线观看 | 精品无码久久久久 | 天海翼中文字幕 | 欧美中文在线观看 | 欧美在线性视频 | 日干夜操 | 午夜毛片在线 | 欧美黑人又粗又大高潮喷水 | 欧美做爰xxxⅹ性欧美大片 | 99欧美精品 | 欧美精品a区 | 天堂在线| 成人一级黄色片 | 欧美一区二区激情视频 | 自拍在线视频 | 成人福利在线播放 | 99久久99久久久精品棕色圆 | 精品看片 | 2级黄色片 | 天堂中文网在线 | 日韩欧美视频免费在线观看 | 男女被到爽流尿 | 欧美老熟妇一区二区三区 | 美女黄视频网站 | 国产精品国产三级国产普通话蜜臀 | 疯狂伦交| 亚洲国产精品成人无久久精品 | 日韩欧美色| h片在线观看网站 | 三级小说视频 | 成人av毛片 | 一级成人免费视频 | 视频二区在线 | 婷婷调教口舌奴ⅴk | 婷婷五月综合激情 | 日韩麻豆视频 | 欧美人与禽猛交乱配 | 狠狠操狠狠爱 | 日韩成人免费观看 | 欧美精品卡一卡二 | 亚洲欧美日韩精品在线观看 | 色猫咪av | 五十路中文字幕 | 成为性瘾网黄的yy对象后 | av福利站 | 一级性生活免费视频 |