從網(wǎng)絡(luò)游戲中學(xué)習(xí)如何處理延遲
前言
網(wǎng)絡(luò)延遲是客觀存在的,但網(wǎng)絡(luò)游戲行業(yè)已經(jīng)積累了大量優(yōu)質(zhì)經(jīng)驗(yàn),使用一些策略、技術(shù)手段在客戶端消除/隱藏掉延遲帶來的不便,以盡可能的掩蓋實(shí)際存在的延時,同時實(shí)現(xiàn)實(shí)時渲染,將用戶帶入快速的交互式實(shí)時游戲中,體驗(yàn)完美的互動娛樂中。
這樣處理結(jié)果,稍高延遲的玩家也不會因?yàn)榫W(wǎng)絡(luò)不是那么好,也能夠很和諧的與其它網(wǎng)絡(luò)參差不及玩家一起游戲中。
雖然延時決定了實(shí)時游戲的最低反應(yīng)時間,但最重要的是客戶端看起來要流暢。第一人稱設(shè)計(jì)游戲(FPS)可巧妙的化解與規(guī)避,最終在適合普遍用戶網(wǎng)絡(luò)環(huán)境中(200ms),實(shí)現(xiàn)實(shí)時快速互動游戲。
嗯,下面就是近期腦補(bǔ)結(jié)果。
網(wǎng)游P2P & CS結(jié)構(gòu)
早先網(wǎng)游使用P2P網(wǎng)絡(luò)拓?fù)湓谕婕抑g進(jìn)行交換數(shù)據(jù)通信。但P2P模型引起的高延遲在FPS游戲中無法被很好掩蓋,所有玩家的延遲取決于當(dāng)前玩家中延遲最爛的那個。好比木桶理論,低延遲網(wǎng)絡(luò)好的玩家會被高延遲壞網(wǎng)絡(luò)的玩家拖累。最終結(jié)果導(dǎo)致,所有玩家都不太開心了。但在局域網(wǎng)環(huán)境下,不會感覺到延遲帶來的問題。另,游戲邏輯大部分都集中在客戶端了,很難避免作弊行為。
C/S結(jié)構(gòu)網(wǎng)游:
- C/S結(jié)構(gòu)在服務(wù)器端跑所有的游戲邏輯和輸入響應(yīng),客戶端只需要渲染以及把自己需要一些狀態(tài)同步下來,把用戶輸入發(fā)給服務(wù)器端,然后顯示結(jié)果就可以了
- C/S結(jié)構(gòu)網(wǎng)游最大優(yōu)點(diǎn)就是把延遲從玩家之間最卡玩家的延遲改變?yōu)橥婕液头?wù)器連接的延遲,結(jié)果就是客戶端在帶寬上的要求也低了不少,因?yàn)橹恍枰演斎氚l(fā)給服務(wù)器端就以及接收服務(wù)器響應(yīng)就夠了
- C/S結(jié)構(gòu)網(wǎng)游雖然轉(zhuǎn)移了網(wǎng)絡(luò)延遲矛盾點(diǎn),但現(xiàn)實(shí)網(wǎng)絡(luò)環(huán)境一樣會帶來較高的網(wǎng)絡(luò)延遲。客戶端每執(zhí)行一次操作,都需要等待服務(wù)器端命令,那會用戶操作會造成操縱卡頓現(xiàn)象。如何解決呢,客戶端一般采用預(yù)測和插值等方式在渲染層隱藏網(wǎng)絡(luò)延遲
客戶端預(yù)測和插值
服務(wù)器可以允許某些情況下客戶端本地即時執(zhí)行移動操作,這種方法可以稱為客戶端預(yù)測。
比如游戲中鍵盤控制角色行走,這個時候可以在很小的時間段(時間很短,比如1-3秒)內(nèi)預(yù)測用戶行動軌跡(方向+加速度,角色行走結(jié)果),這部分的命令客戶端會全部發(fā)送到服務(wù)器端校驗(yàn)正確與否(避免瞬間轉(zhuǎn)移等外掛)。但客戶端預(yù)測有時也不是百分百準(zhǔn)確,需要服務(wù)器進(jìn)行糾正(所謂服務(wù)器就是上帝,The sever is the man!)。糾正結(jié)果可能就是游戲角色行走軌跡和客戶端預(yù)測軌跡有所偏差,客戶端可以使用插值方式(粗略來講,就是角色在兩點(diǎn)之間移動渲染的方式)渲染游戲角色在游戲世界中的位置轉(zhuǎn)移平滑一些,避免游戲角色從一個位置瞬間拉回到另一個位置,讓人有些莫名其妙。
插值,有人也稱之為路徑補(bǔ)償,都是一回事。插值的方法會涉及到很多數(shù)學(xué)公式,線性插值、三次線性插值等,比如這篇文章所講到的插值那些事。
小結(jié):客戶端預(yù)測,服務(wù)器端糾正,客戶端采用插值方式微調(diào)。
針對交互的一群玩家,網(wǎng)絡(luò)好壞層次不齊,游戲的一些操作效果可能需要”延遲補(bǔ)償“策略進(jìn)行
延遲補(bǔ)償
延遲補(bǔ)償是游戲服務(wù)器端執(zhí)行的一種策略,處理用戶命令回退到客戶端發(fā)送命令的準(zhǔn)確時間(延遲導(dǎo)致),根據(jù)客戶端的具體情況進(jìn)行修正,以犧牲游戲在傷害判定方面的真實(shí)感來彌補(bǔ)攻擊行為等方面真實(shí)感,本質(zhì)上是一種折中選擇。
主要注意,延遲補(bǔ)償不是發(fā)生在客戶端。
關(guān)于延遲補(bǔ)償?shù)囊粋€例子:
- 在FPS游戲中,玩家A在10.5秒時向目標(biāo)對象玩家B射擊并且擊中,射擊信息被打包發(fā)送(網(wǎng)絡(luò)延遲100毫秒),服務(wù)器于10.6秒收到,此時玩家B可能已跑到另外一個位置。
- 若服務(wù)器僅僅基于接收時刻(10.6秒)進(jìn)行判斷,那么玩家B沒有收到傷害,或許可能會擊中玩家B后面緊跟的玩家C(100ms后玩家C完全由可能已處于玩家A的射擊目標(biāo)位置)
- 為了彌補(bǔ)由于延遲造成的問題,服務(wù)器端需要引入“延遲補(bǔ)償”策略用于修正因延遲造成錯亂假象
- 服務(wù)器計(jì)算執(zhí)行設(shè)計(jì)命令時間,然后找出當(dāng)前世界10.5秒時刻玩家信息,根據(jù)射擊算法模擬得出是否命中判斷,以達(dá)到盡可能精確
若游戲延遲補(bǔ)償被禁用,那么就會有許多玩家抱怨自己明明打中了對方卻沒有造成任何傷害。。
有所得,有所失:但這對低延時玩家貌似有些不公平,移動速度快,可能已經(jīng)跑到角落里并且已蹲在一個箱子后面隱藏起來時被對手擊中的錯覺(子彈無視掩體,玩家隔著墻被射擊),確實(shí)有些不樂意。
延遲補(bǔ)償,網(wǎng)絡(luò)高延遲的玩家有利,低延遲的玩家優(yōu)勢可能會被降低(低延遲玩家利益受損),但對維護(hù)游戲世界的平衡還是有利的。
對時&閥值
客戶端和服務(wù)器需要對時,互相知道彼此延遲情況,比如云風(fēng)定義的某個步驟:
客戶端發(fā)送一個本地時間量給服務(wù)器,服務(wù)收到包后,夾帶一個服務(wù)器時間返回給客戶端。當(dāng)客戶端收到這個包后,可以估算出包在路程上經(jīng)過的時間。同時把本地新時間夾帶進(jìn)去,再次發(fā)送給服務(wù)器。服務(wù)器也可以進(jìn)一步的了解響應(yīng)時間。
C/S兩端通過類似步驟進(jìn)行計(jì)算彼此延時/時差,同時會對實(shí)時同步設(shè)置一個閥值,比如對延遲低于10ms(0.01秒)的交互認(rèn)為是即時同步發(fā)生,不會認(rèn)為是延遲。
UDP或TCP
不同類型的游戲會鐘愛不同的協(xié)議呢,不一而足:
- 客戶端間歇性的發(fā)起無狀態(tài)的查詢,并且偶爾發(fā)生延遲是可以容忍,那么使用HTTP/HTTPS吧
- 客戶端和服務(wù)器都可以獨(dú)立發(fā)包,偶爾發(fā)生延遲可以容忍(比如:在線的紙牌游戲,許多MMO類的游戲),那么使用TCP長連接吧
- 客戶端和服務(wù)器都可以獨(dú)立發(fā)包,而且無法忍受延遲(比如:大多數(shù)的多人FPS動作類游戲Quake、CS等,以及一些MMO類游戲),那么使用UDP吧
TCP會認(rèn)定丟包是因?yàn)楸镜貛挷蛔銓?dǎo)致(本地帶寬不足是丟包的一部分原因),但國內(nèi)ISP可能會在自身機(jī)房網(wǎng)絡(luò)擁擠時丟棄數(shù)據(jù)包,這時候可能需要快速發(fā)包爭搶通道,而非TCP窗口收縮,UDP沒有TCP窗口收縮的負(fù)擔(dān),可以很容易做到這一點(diǎn)。
要求實(shí)時性放在第一位的FPS游戲(eg:Quake,CS),廣域網(wǎng)一般采用UDP,因可容許有丟失數(shù)據(jù)包存在(另客戶端若等待一段時間中間丟包,可以通過插值等手段忽略掉),一旦檢測到可以快速發(fā)送,另不涉及到重發(fā)的時候UDP比TCP要快一點(diǎn)嘛。但會在UDP應(yīng)用層面有所增加協(xié)議控制,比如ACK等。
很多時候協(xié)議混用,比如MMO客戶端也許首先使用HTTP去獲取上一次的更新內(nèi)容, 重要信息如角色獲得的物品和經(jīng)驗(yàn)需要通過TCP傳輸,而周圍人物的動向、NPC移動、技能動畫指令等則可以使用UDP傳輸,雖然可能丟包,但影響不大。
小結(jié)
網(wǎng)游通過客戶端預(yù)測、插值和服務(wù)器端延遲補(bǔ)貼等,化解/消除用戶端網(wǎng)絡(luò)延遲造成的停頓。我們雖然可能沒有機(jī)會接觸游戲開發(fā),學(xué)習(xí)跨界的優(yōu)良經(jīng)驗(yàn)和實(shí)踐,說不準(zhǔn)會對當(dāng)前工作某些業(yè)務(wù)點(diǎn)的處理有所啟發(fā)呢。
本集由韓國宇航局贊助播出:我們要去遠(yuǎn)方看看,還有什么是我們的思密達(dá)。 ------ 《萬萬沒想到》王大錘
posted on 2014-12-23 10:02 nieyong 閱讀(13382) 評論(1) 編輯 收藏 所屬分類: Socket