狀态同步位置和技能(适用于fps和mmorpg類遊戲)
用戶端A的同步閥值(減少同步量)
用戶端A本地會存儲一份對其他用戶端看到的A的預測狀态,當本地真實狀态和預測狀态偏差超過閥值時,則發起同步,同時更新用戶端A本地的預測狀态
玩家運動的關鍵點也會同步,例如起跳坐标點,起跳最高坐标點,落地坐标點,開始跑步的速度方向,停止跑步時的坐标點
插值算法的選擇
用戶端插值 和 航位推測的選擇
航位推測隻用于預測位移
用戶端插值(線性插值,3次樣條插值,曲線的尋路(尋路這個可能會在同步頻率低的遊戲中使用))
使用航位推測:不做服務端的延遲補償時,可以對用戶端A上的第三方代理對象做航位預測
用戶端A上看到的玩家B的移動
用戶端A看到的第三方玩家B一直向着A接收到的服務端發來的B的資料包的最新狀态插值,當用戶端B走到最新狀态,還是沒有再次接收到伺服器的資料包時,會按上一個移動操作包進行運動,直到再次收到B的資料包,則去檢測是否有錯誤
用戶端A上玩家B的移動預測錯誤時的糾正
A接收到服務端的資料包時檢測到B在用戶端A上的模拟有錯誤時,有以下處理方法
1.距離遠則瞬移表現層,适用于快節奏的遊戲
2.距離近則插值,可以用3次樣條插值,适用于快節奏的遊戲
3.如果是突然加速這種,可以加二階參數(例如加速度)去處理,例如插值時增大加速度,接近航位推測近似值時降低加速度
使用插值:做了服務端延遲補償時,服務端需要精确的計算出被射擊的玩家的位置,需要通過幀數和插值進度去計算,是以此時不能用航位預測
一般類似fps需要優化射擊方體驗的遊戲中需要延遲補償,此時遠端玩家使用用戶端插值,而不是用航位推測
在用戶端A看到的第三方對象B,例如B此時從第3幀的狀态插值到第6幀(幀狀态是服務端下發的,且用戶端更新頻率和服務端更新頻率保持一緻,一般是1秒30幀)
A開槍射擊B時,發起射擊請求,請求包内會有A在XX坐标,以XX角度,B從第3幀,插值到第5幀,目前插值進度XX
服務端收到包後,根據緩存的前幾幀的狀态和插值的幀以及插值進度去計算A開槍時看到的B所在的位置,再做命中檢測
用戶端A接受到A的狀态資料包時的處理(移動)
用戶端發起移動包,同時用戶端記錄下這個操作(用戶端utc時間和操作),用戶端本地立刻開始移動(此時是用戶端的移動預測)
RTT時間後接收到服務端發來的資料包,将這個資料包内的時間戳和整個資料包狀态存儲起來
因為接收到的資料包裡的狀态會比目前伺服器狀态慢大概半個RTT,是以需要本地模拟預測半個RTT的移動
根據資料包裡的服務端發起的utc時間 + 服務端和用戶端的時間差,得到用戶端對應的服務端發起這個資料包的時間點
然後用戶端從記錄下來的自己的移動操作清單中得到這個時間點之後所有服務端未加入計算的移動操作
通過資料包(指定時間在哪個坐标)+服務端計算出這個資料包時未計算的操作(也就是用戶端這個時間點後的其他操作)
計算出在目前時間應該在的狀态C(位置,方向,旋轉等),然後向C狀态進行插值
(如果移動的中途沒有被其他玩家影響的話就是精确的,即使有誤差也會很小(例如被技能打中暈眩之類的)),被其他玩家操作影響後也會發同步消息到用戶端,用戶端再糾正
玩家B施法,用戶端A看到玩家B是怎麼施法的
會有延遲,也就是玩家B在用戶端B按下施法,用戶端A看到的玩家B至少也是RTT時間後才會播放施法動畫
玩家A施法,用戶端A看到玩家A是怎麼施法的
按下施法按鈕,先播放前搖,前搖時間至少是RTT,接收到傳回的資料包時,如果不能施法則停止施法動畫,如果能施法則繼續動畫,以及播放後續施法效果(例如射出飛彈)
服務端延遲補償
服務端會記錄之前的n幀的世界狀态
服務端接收到玩家A的施法包時,從包中取出用戶端發起的utc時間戳t1,加上服務端和用戶端的時鐘差後得到玩家A在發起操作時服務端的時間t2
那麼用t2去取之前記錄下來的世界狀态
掩蓋不同步的技巧以及優化
優化命中表現:添加攻擊邊緣模糊的特效,資料層上會擊中的攻擊,因為表現層還在插值,是以如果沒有特效,看起來是不會擊中的,但因為有範圍模拟的特效,是以表現上就跟擊中了一樣
優化預測:前搖時間的調整
為了預測效果更好,某些情況下可以信任用戶端
降低延遲
選擇更近的伺服器節點(需要負載均很)
讓伺服器和用戶端tick的速度更高(需要衡量性能壓力)
盡量減少服務端和用戶端接收到輸入時的緩存buffering處理
用戶端平滑插值(平滑處理位移的做法會在整個同步過程中的方方面都用到)
接收到消息包(包含時間戳以及正确的位置P1)後,和本地記錄的該時間戳的位置對比,如果相同則不處理。
如果不同則,資料層從P1位置開始按已經記錄下來的這個時間戳之後的操作包進行移動,然後得到用戶端預測的資料層位置。
和目前表現層的位置進行比較,距離遠就瞬移,距離近就插值(如果是直接拉回,不進行P1+預測包的預測處理的話,表現上看起來會莫名其妙的拉回到以前的一個位置,網絡差時基本就不會移動了)
體驗上分為:對人戰鬥的體驗和單擊打怪的體驗
優化了延遲後仍然會有的問題
fps中看A玩家看到自己已經躲到了掩體後,仍然被命中。原因如下:
1是A的操作還沒發到服務端,雖然看着是進了掩體,但在服務端看來是沒有躲在掩體後的
2是fps如果做了服務端的延遲補償,則B開槍射A,B看到的A是滞後服務端半個RTT的且正在插值的對象,此時如果B的網絡很差,則A躲進掩體後,B還是能看到A且命中A
不停移動的玩家會更難射中,因為即便做了以上的優化後,仍然會有誤差
整體流程來看:
按下滑鼠到網絡packet發出--用戶端幀數越高越好
網絡延時(ping)--延時最大頭
伺服器上面buffering的時間--可以根據重要性進行取舍
伺服器上面執行時間(幀數越高越低)
伺服器執行結果下行,又是一個網絡延時(ping)--延時最大頭
用戶端buffering時間
用戶端顯示時間(敵人倒地飙血等等)
mmorpg的近戰沖刺技能
A發起沖刺請求後,本地先做前搖,服務端檢測沖刺路線上是否有障礙,沒有則通過,通知用戶端運作施法,并下發給用戶端,以XX速度,向XX方向,移動到XX坐标
mmorpg中用狀态同步+aoi視野管理
隻同步自己視野的狀态
十字連結清單
導航推測(預拉扯算法)
三次參數法
延遲補償
每秒1個包(坐标,朝向,速度)
持續模拟行進軌迹
碰撞和尋路
二叉樹空間分割法。服務端做碰撞檢測
橢圓表示collider。從四面向場景發射攝像。 1.從左邊開始往右掃,碰到collider則暫存起來,暫定為ListLeft。從右邊開始往左掃,碰到collider則暫存起來,暫定為ListRight。那麼可以這樣認為,相交的部分為可行走區域。(上下同理) 2.在可行走區域中畫出N個正方形,與後端協定正方形大小。 3.然後剩下的就是用這堆格子來實作尋路
RTO是Retransmission Time-OutD的縮寫,該時間決定了發送方在發送資料後,在多長時間内如果沒有收到ACK,就重置重傳計時器,并重傳上次發送失敗的封包
用戶端輸入預測
延遲補償(fps必須要有)
需要伺服器對遊戲世界中過往的狀态進行緩存,然後推測用戶端指令建立時候,伺服器所在的時間點,然後使用過往的緩存狀态進行計算,
擊中的判定由伺服器決定的,伺服器根據每個用戶端的延遲取曆史快照來做判定檢測
導航插值
Tick Rate:每秒同步幾個包到用戶端
用戶端和服務端的時鐘需要同步,同步包裡有實體Id,坐标位置,旋轉方向,旋轉速度,移動方向,移動速度,時間,移動加速度
相位滞後:可選參數,實體與影子保持一定距離同步,相當于保持一定車距,這樣在控制者突然停止的時候,不容易因為網絡延遲跑過了又被拉回來。
慣性移動:可選參數,開始移動或者停止或者改變方向都有加速度,這樣就不需相位滞後了
關鍵狀态進行緩存,不然如果别人向前連續跳五次,每次取得狀态都取到最高點的話,别人用戶端上的影子和跟随的實體會奇怪的持續的飛在天上,是以需要将起跳和落地這兩個關鍵狀态緩存,實體追趕時隻有追上的第一個狀态(一号影子)才能追逐第二個狀态(二号影子)。
關鍵狀态需要立即同步,比如跳躍、沖鋒、落地
模拟丢包
優化:
發送狀态更新包時,不需要每次都發送,而可以隻發送改變的狀态。什麼時候我們覺得改變了?就是當用戶端實體與自己的影子之間的誤差大于某特定數值時我們才發送更新包,這樣雖然玩家在原地做左右搖擺的小幅度移動,隻要沒有超出範圍,都不需要發送新的狀态更新,其他玩家機器上看起來,它是站着不動的。
DR同步”和“非DR同步”,前者針對 ,後者針對 RPG和普通 ARPG
1)用戶端角色先行表現,即不需等待伺服器響應即開始用戶端表現,避免網絡延遲帶來的操作手感問題;2)用戶端第三方角色進行延遲補償和預測同步,消除網絡因素引入的位置誤差;3)伺服器消息緩存重傳機制;從業務層面通常有采用技能效果和表現分離,一段傷害多段表現等;
内插值,外插值
有DR的航位推測(适用于FPS,賽車或者操作比較多的ARPG)
DR Threshold(存在的目的是為了減小同步包的數量)
玩家以速度v加速度a從pos1向方向dir移動時
用戶端本地以這些參數每隔一定時間(internalTime)模拟計算得出一個預測的位置pos2
而實際上玩家的移動可能會有微小的調整,那麼每隔internalTime的時間檢測預測的位置pos2和目前用戶端本地實際的位置pos3的距離是否大于了設定的DR閥值
隻有當pos2和pos3的距離超過這個閥值時才發同步包到服務端
DR過小會導緻同步包增多
沒有DR的航位推測
每隔一定時間進行一次同步,不進行位置偏移檢測
狀态同步中的兩種移動同步:
1是玩家進行操作後,表現層先行,等接收到服務端消息後,進行表現層插值
缺點:表現上會有點飄
優點:操作上沒有滞後感
2是玩家進行操作後,需要等接收到服務端消息後,才進行表現層插值
缺點:有滞後感
優點:開始移動時人物會感覺比較笨重,停止移動時會有慣性移動的感覺。比較符合真實移動的感覺
第三方用戶端在因為抖動而沒有接收到移動包時,會本地預測按已有的速度繼續向前跑,接收到移動包後在插值到真實位置
當誤差較小或者非常大的時候,直接瞬移,表現是有一點輕微抖動或者是瞬移
當誤差較大的時候,會根據距離控制速度進行加速跑到正确位置去
------------------------
------------------------
用戶端預測,和服務端延遲補償
爆頭
mmo很少做服務端延遲補償,fps遊戲一般會做服務端補償
如果玩家的Ping很大,伺服器會怎麼辦?
上面的例子都假設用戶端和伺服器之間的延遲無窮小,那麼當玩家Ping很大的時候會發生什麼的呢?
假設玩家A與伺服器之間存在100ms的延遲(單向,往返則是200ms),其他玩家的延遲忽略不計,伺服器的通信頻率足夠大(頻率不夠大還會造成其他很嚴重的問題,這個放在後面講)。玩家A在某一刻向伺服器發送了一個請求(比如向前走),那麼這個請求會在100ms之後到達伺服器,伺服器判定後傳回結果,再經過100ms你的用戶端會收到确認,伺服器已經把你的位置向前移動了若幹距離。
假設用戶端在沒有收到任何伺服器的更新前畫面都不會變化,那麼在這200ms内你就會覺得遊戲“卡頓”。
實際上很多遊戲裡中你會在這200ms裡看到你自己是在向前走,其實那隻是用戶端“擅自”在繪制你前進的樣子,這是一種延遲補償政策,稱為“用戶端預測法”。
即用戶端能夠大緻預測遊戲未來的走向,是以在接收到伺服器更新前會把預測到的畫面先繪制出來(比如移動、武器的開火效果、彈藥計數的變化等)。用戶端收到伺服器通信後如果資料有出入則立刻糾正為伺服器提供的資料。是以在延遲很大的時候玩家會發現“明明往前走了過了一會又瞬移回到之前的位置”的原因,或者是“明明開了好幾槍而且也都顯示了但過了一會彈藥計數隻減少了一點點”。
既然扯到這裡了那就認真的講下延遲補償政策(lag compensation),一般來講補償政策分伺服器端和用戶端兩類,上面提到的預測法屬于用戶端一類,其他的用戶端政策還有插幀法。
所謂插幀法就是用戶端會記錄之前一次從伺服器收到的資訊,然後在接受到下一次通信的時候不立刻更新遊戲畫面,而是逐漸的更新畫面(比如兩次通信間玩家B移動了10機關距離,用戶端會繪制玩家B以一定的速度移動了這10機關距離,而非立刻繪制玩家B瞬間移動了10機關距離)。
插幀法的問題在于如果玩家并未沿直線運動且其直線路徑中有本應不能通過的物體存在時(比如繞過一堵牆),用戶端會繪制出該玩家穿牆而非繞過去的動作。
伺服器端處理延時同步常用的政策
1.“眼不見為淨”法,伺服器不去補償玩家的延遲是一個合理的做法,特别是當遊戲内進行的事件非常多(想想《行星邊際2》裡面千人同圖混戰的情形)。浪費寶貴的伺服器資源去補償個别玩家的延遲是不明智的。這個政策的缺點很明顯,就是玩家有可能會對遊戲體驗不滿意。
2.“倒帶”法,采用倒帶法的伺服器會記錄剛剛過去一段時間内(比如0.5秒)遊戲内的所有資訊。當一個有延遲的玩家(比如200ms)向伺服器發送一個請求,那麼伺服器在處理這個請求的時候會調取0.2秒前遊戲的狀态然後進行判定,在把判定結果對所有用戶端進行同步,
如此一來該玩家的操作雖然有延遲但也能與他/她所看見的畫面一緻。該政策的最大問題在于它讓不同延遲之間的玩家被迫體驗較大的延遲。舉個例子,假設遊戲裡擊殺時間(TTK)足夠小,玩家A(10ms延遲)和玩家B(延遲200ms)對射,兩人都是空血(一次攻擊即死),A比B先開火(時間差很小,比如50ms)。玩家A的次攻擊很快(10ms後)就得到了處理并記錄在伺服器中,
玩家B被判死亡。然而在200ms後玩家B的請求到達,伺服器倒帶0.2秒,此時玩家AB都未死亡,是以玩家B的攻擊有效,玩家A也被判定為死亡。如果沒有延遲,那麼伺服器應該會判定玩家B死亡,是以玩家B将無法攻擊,玩家A應該存活。換句話說采用倒帶法的伺服器裡如果有一個延遲很大的玩家将會拖累其他低延遲玩家的遊戲體驗。
------------------------
------------------------
改善同步的技術,用來降低高ping用戶端的延時感受(用戶端的動态預測和延時補償技術)。
有A和B兩個用戶端,在B移動時,A的用戶端上會以一定頻率收到B的移動資訊同步。如果總是等到收到B的資訊後再去被動地移動,那就會導緻在A的機器上,B的移動總是滞後的。這一般是典型MMO如WOW的做法,而對某些類型的遊戲(fps,空戰)來講,這種延遲是難以接受的。
一個做法是,A總是通過B之前的移動去預測其接下來的移動情況(Q3的做法),這樣有極大的可能(實測至少90%以上的情況下)在伺服器把B的真實移動資訊發過來時,雙方是比對的(也就是預測準确)。在這種完美情況下,在A機器上體驗到的B的移動就沒有滞後(這個“沒有滞後”是相對伺服器而言的,因為所有的計算以伺服器為準,是以此處暫不考慮伺服器跟B之間的延時)。預測本身可以通過緩存之前若幹秒的操作隊列來實作,注意僅依靠目前的狀态是不夠的。
這種預測會在B有新的操作事件發生的時候失敗,而這裡的處理與Q3稍有不同。比如B正在往前飛,突然松開了W鍵開始減速直到停下。在未收到B的減速及停止消息前,A仍保持了B在全速往前飛的預測,此時若收到了減速的信号(同步過來的加速度突然變為負向的,速度開始變化)此時A可以意識到,自己坐标系中的B已然偏離了正确的位置。那麼可以采用一個補償算法去修正B。修正的幅度可以參考目前用戶端的延遲情況。這個算法可以是激進的(盡量迅速地校準,犧牲平滑性)或保守的(保證飛行的平滑性,犧牲修正速度)。
當然了,前文中伺服器與B(消息發送端)之間的延時,仍然對玩家體驗有決定性影響。當用戶端把自身的操作發給伺服器時,這時的延時真正的決定了用戶端的最快反應時間。這時網絡環境的好壞,會直接影響玩家(在遊戲中實際表現出)的反應速度。
補充幾句話,怎麼判斷什麼時候用這個預測和補償,用的時候強度有多大呢?仍以前面的AB用戶端為例的話,一般來講約 100ms 的阙值即可(延時越敏感,用戶端B的avatar移動速度越快,這個值應越低)。當A與伺服器之間的延時(可定期roundtrip測得)高于阙值時,就可以開始緩存操作序列來做預測了。
------------------------
------------------------
網絡時延是必然存在的,是以遊戲狀态的不同步也是必然存在的。但我們可以通過技術手段盡量減輕不同步問題對使用者體驗帶來的影響。
技術術語:
1)Latency:Latency指的是資料包從用戶端發送到服務端再收到服務端回包所用的時間,通常被稱為RTT。雖然單程的資料包傳輸時間并不總是等于RTT/2,但是簡單起見我們可以認為兩者是相等的。下文說到Latency都是說一個RTT時間,單程Latency則是指RTT/2。
80年代有個工具叫ping使用ICMP echo測試延遲,是以人們常把RTT和ping聯系起來。ping這個指令現在還在用。
2)Hit Box:角色的3D模型代表了哪些區域是參與到“命中”計算的。你看不到hit box,你隻能看到模型。hit box可能比模型大,也可能比模型小,也有可能很不精确,這都取決于具體的實作。我們知道,tick rate會影響命中判定,但是hit box不精确可能對玩家在是否命中方面的感受影響更大。
3)Tick Rate:Tick Rate指遊戲服務端更新遊戲狀态的頻率。機關是hertz。如果伺服器的Tick Rate是64,這就意味着服務端每秒鐘最多向用戶端發送64次資料包。這些同步資料包包括了遊戲狀态更新,比如player和場景對象位置等。一次tick的長度就是其持續時間,機關為ms。
比如,64 rate時tick長度是15.6ms,20 rate時是50ms,10 rate時是100ms
4)Client Update Rate:這是用戶端接收服務端更新的頻率。比如說,如果client update rate是20,而伺服器tick rate是64,那麼從體驗上來說,這個用戶端實際是在和一個tick rate為20的伺服器聯機。通常這個是配在用戶端本地的,也有可能是寫死的。
5)Framerate:這個是指用戶端每秒最多可以渲染多少幀,通常被稱為FPS
6)Refresh Rate:顯示裝置每秒鐘重新整理多少次。機關為hertz。如果framerate是30,一個顯示頻率為60的裝置将把每個畫面顯示兩次。反過來,如果framerate是120,但是顯示頻率為60,那麼顯示裝置隻能顯示每秒60幀。顯示裝置的頻率比framerate大,提升framerate才有意義。大多數顯示裝置頻率是60或120。
7)Interpolation:這是一種平滑場景對象移動的技術。實際上内插值所做的就是在場景對象的兩個位置之間做插值,以讓運動過程平滑。插值延遲通常是2tick,也不盡然。舉個内插值的例子,如果一個玩家沿着一條直線移動,在tick1的時候位置在0.5m,在tick2的時候位置在1m,内插值的作用就是讓用戶端看起來是平滑的從0.5m移到1m。但是伺服器實際看到的是離散的位置,要麼在0.5m或1m,不可能在中間的某個位置。如果沒有插值,遊戲的抖動将非常明顯,特别是在從服務端更新了一個運動對象的位置後。内插值隻在用戶端做,實際上減慢了将整個遊戲狀态繪制到螢幕上的速率。
8)Extrapolation:這是用戶端補償延遲的另一種技術。用戶端将場景對象的位置做外插值,這樣就不會導緻繪制的時候沒有更新到新資料。通常優先使用内插值,特别是FPS遊戲,因為玩家的移動是不可預期的,外插值的結果可能通常是錯的。
9)Lag Compensation:延遲補償是服務端減小用戶端延遲影響的一種方法。如果沒有延遲補償,或者延遲補償做的不好,由于用戶端看到的是經過延遲後的遊戲狀态,玩家要命中目标就必須使用一些預判技巧。實際上,延遲補償所做的,就是當伺服器從用戶端收到操作(比如開槍)後,将操作發生時間往回調一個單向時延的時間。服務端遊戲狀态和用戶端遊戲狀态的時間差異(也被稱為"Client Delay")可用下式給出:
ClientDelay = (1/2 * Latency) + InterpolationDelay
延遲補償的實際操作步驟:
Player A看到Player B向一個角落跑去
Player A開槍,其用戶端把這個操作發送給伺服器
假定A的延遲的一半是Xms,那麼Xms後伺服器将收到Player A的操作
伺服器從記錄的曆史資訊中找到A開槍時B所在的位置。一般情況下,伺服器應該往回看 (Xms + Player A's interpolation delay) 來復原到A開槍時的遊戲狀态。但是這個時間是可以調的,取決于開發者希望延遲補償算法如何工作。
伺服器判定這次的開槍是否命中。如果子彈的軌迹和目标模型的hit box相交,就認為是命中了。在這個例子中,我們假定命中了。在Player B看來,他覺得自己已經躲到牆後面了。但是Player B看到的遊戲狀态所處的時間和Server認定的開槍時間是有差異的,可以表示為:
(1/2 * PlayerALatency + 1/2 * PlayerBLatency + TimeSinceLastTick)
在下一次tick中,伺服器使用計算結果更新所有用戶端:Player A看到自己命中了目标,Player B看到自己掉血或挂掉了。
需要注意的是,如果兩個玩家對射,而且都命中了,遊戲如何處理就取決于實作了。比如說在CS:GO中,如果先收到的射擊操作命中了目标玩家,那麼後續收到的那個玩家的射擊就會被丢棄。這樣就避免了兩個玩家的射擊請求在同一幀,然後都命中,都挂掉。在Overwatch中,這種情況是可能的。這裡是有取舍的。
按照CS:GO的做法,網絡較好的玩家是有很大優勢的。經常會有“我在挂掉前打中了目标,但是他沒死”的情況。你甚至在挂掉前能聽到你的槍響和命中的聲音,卻沒對目标造成傷害。
若是在Overwatch中,玩家反應時間的差異對結果影響較小。比如說,如果伺服器tick rate是64,若Player A比Player B早15ms射擊,那麼雙方的射擊都是在同一個15.6ms tick之内,是以最終結果是雙方都命中,都死掉了。
如果延遲補償過度,就會出現“我朝目标早前的位置開槍,卻還是命中他了”。
若延遲補償不足,則會出現“我必須對目标的移動做預判,這樣才能命中”。
伺服器做延遲補償所記錄的曆史資料應該是有限的,不然高延遲的玩家會明顯拖累其他玩家的遊戲體驗。
在Overwatch中,服務端延遲補償也被稱為Favoring the shooter(https://www.vg247.com/2016/04/05/overwatch-devs-talk-netcode-and-favouring-the-shooter/, https://www.pcgamesn.com/overwatch/overwatch-netcode),也就是說,如果你在自己螢幕上瞄準了目标并射擊,那麼很大機率将命中目标。也有例外情況。比如,若你射擊目标的那一刻,目标跳躍躲開了,這時伺服器認為目标做了一個完美的閃避,可能會被判斷未命中。是以計算命中時并不總是使用射擊那一刻的資訊。這是為了玩家體驗打的更新檔。
如果你是要設計一套同步方案,根據設計目的不同可能有不同的方案。公平性、即時回報、網絡流量等都可能是重要的設計目标。可以參考以下因素:
1)網絡連結。延遲越低越好。選擇一個延遲最低的伺服器開始遊戲是很重要的。網絡上的擁塞程度也會導緻網絡延遲。延遲補償可以幫助解決“射擊和命中”的問題,但是如果你的網絡不好,更多的情況下,你可能會體驗到“已經跑到牆後面還是被打中”或者“我先射擊但還是死掉了”的情況。
2)如果你的用戶端frame rate很低(隻要低于顯示裝置重新整理頻率或跟他差不多),會導緻感受延遲變大,通常比tick rate帶來的問題更嚴重。
3)盡量使用内插值。大多數遊戲使用的内插值間隔是tick間隔的兩倍,主要考慮到如果一個資料包丢掉了,玩家的移動中斷也不會在螢幕上表現出來。如果網絡狀況很好,沒有丢包,把插值間隔設定為tick間隔是沒有問題的。但是如果有丢包,就會導緻抖動。比如在CS:GO中,這對體驗的影響比把服務端tick rate從20調高到64帶來的體驗影響更明顯。如果這個值設的太低,會導緻極大的抖動。
4)如果有可能,你應該增加遊戲的client update rate來優化體驗。其代價是CPU和帶寬消耗。對于用戶端來說,除非你家的網絡帶寬非常低,增加CPU和帶寬消耗是可以接受的。
5)如果你的顯示裝置重新整理率是60hz,那麼很有可能你根本感受不到tick rate在64和128會有什麼差異,因為由于tick rate差異導緻的改變根本無法通過你的顯示裝置展現出來。
6)通常來說,服務端tick rate越高,使用者互動就越流暢,也更準确。當然網絡同步量也越大。如果我們對比tick rate64(CS:GO比賽)和20(Overwatch Beta伺服器宣傳的幀率),兩者因為幀率差異導緻的最大可感受延遲是35ms.平均情況下是17.5ms.大多數人是察覺不到其中的差異的,但是有經驗的玩家通常是能感受到的。高的tick rate并不會影響到延遲補償的工作。是以有時候,你還是會有明明自己已經跑到牆後面了可是還是死了的體驗。把tick rate提高到64并不能解決這個問題。
7)Responsiveness: 當你按下按鍵的時候,需要能立刻看到回報。這對動作遊戲和FPS遊戲都是非常重要的。有多個因素會影響即時回報。首先,用戶端發送玩家的輸入應該是即時的。其次,用戶端不等服務端回應就根據玩家的輸入做狀态預測和插值。在Overwatch中,用戶端會維護一個曆史紀錄用于驗證用戶端預測的準确性。最後,服務端tick rate也會影響回報。投射物的模拟也應和玩家做類似處理,并加上飛行時間,讓玩家對回報産生的時間有預期。
8)處理丢包。在Overwatch中,丢包是通過在用戶端加速“指令幀”和在服務端設定指令緩存來解決的(http://www.gdcvault.com/play/1024001/-Overwatch-Gameplay-Architecture-and, http://www.gad.qq.com/article/detail/28682). 首先,系統采用确定性模拟技術,将時間量化為“指令幀”。每個指令幀都固定為16毫秒(比賽時是7毫秒)。服務端和用戶端模拟都運作在保持同步的時鐘和這個量化值之上,保持固定的更新頻率。當用戶端意識到丢包時,會比約定頻率更快的模拟,而服務端則将指令緩沖區增大。用戶端發送指令的頻率加快,而服務端緩沖變大以容忍更多的丢包。用戶端的指令資料包包含了未經服務端确認過的所有指令,這樣服務端就有機會在實際模拟并發送确認包前更新緩沖區。
----------------
https://zhuanlan.zhihu.com/p/28617637
時鐘同步,航位預測,Lag Compensation(延遲補償)
https://zhuanlan.zhihu.com/p/30520604
網絡遊戲中子彈與機關的命中判定問題
https://blog.csdn.net/weixin_33888907/article/details/91985725
http://udn.yyuap.com/forum.php?mod=viewthread&tid=121003
FPS和 賽車類遊戲(預測插值模式)
(10-30個)
位置預測及坐标內插補點的“導航推測算法(DR)
影子跟随算法(DR算法的一個改進實作)
除了狙擊這種一槍斃命的射擊外基本都是用戶端判斷,之後糾正?
https://blog.csdn.net/qq_14914623/article/details/104557226
延時補償(好文)
動态預測技術和延時補償
https://github.com/Unity-Technologies/FPSSample
unity fps sample
https://www.jianshu.com/p/c4ea9073f443
unity fps sample分析
http://www.gulu-dev.com/post/2014-03-15-dynamic-prediction-and-latency-compensation
用戶端動态預測技術和延時補償技術
https://mp.weixin.qq.com/s/1WN9rA4yK6Wi2-BhQFIn5Q
揭秘重度MMORPG手遊背景性能優化方案,jps
https://baddogzz.github.io/2020/01/07/Move-Predict/
位置同步之移動預測
https://zhuanlan.zhihu.com/p/56923109
網絡遊戲同步技術概述
https://blog.csdn.net/left_la/article/details/6346776
賽車類 持續模拟行進軌迹,預拉扯算法(也就是導航推測算法)以及加上的三次參數法
http://www.zhust.com/index.php/2014/02/%e7%bd%91%e7%bb%9c%e6%b8%b8%e6%88%8f%e7%9a%84%e7%a7%bb%e5%8a%a8%e5%90%8c%e6%ad%a5%ef%bc%88%e4%ba%8c%ef%bc%89%e7%8a%b6%e6%80%81%e6%9b%b4%e6%96%b0%e5%8f%8a%e8%88%aa%e4%bd%8d%e9%a2%84%e6%b5%8b%e6%b3%95/
網絡遊戲的移動同步(二)狀态更新及航位預測法
https://zhuanlan.zhihu.com/p/83010584
多人網絡遊戲同步探究(上)
https://zhuanlan.zhihu.com/p/62860859
三次樣條(cubic spline)插值
https://www.cnblogs.com/SiumingLearning/p/CubicInterpolateInUnity3D.html
Unity中三次樣條插值曲線的實作
http://www.zhust.com/index.php/2014/02/%E7%BD%91%E7%BB%9C%E6%B8%B8%E6%88%8F%E7%9A%84%E7%A7%BB%E5%8A%A8%E5%90%8C%E6%AD%A5%EF%BC%88%E4%B8%89%EF%BC%89%E5%B9%B3%E6%BB%91%E7%AE%97%E6%B3%95/
網絡遊戲的移動同步(三)平滑算法
https://www.zhihu.com/people/Coder27/posts
https://zhuanlan.zhihu.com/p/50440945
狀态同步demo測試(感覺像是幀同步)
https://gitee.com/fyindex/StateSync/?_from=gitee_search
基于ET架構實作狀态同步demo
https://zhuanlan.zhihu.com/p/56922476
UE4網絡同步思考(二)---大世界同步方案ReplicationGraph