子彈夠不夠,命中情況如何,對方的血量還有多少?
等到伺服器把這些東西都搞清楚,這才會把數據回傳給客戶端。
如果客戶端這邊執行的東西被伺服器否定了,那再嘗試修正。
如果服務端說目標死掉了,客戶端才會渲染出對方似掉的動畫效果。
「啊!是的,應該如此!」
卡馬克眼神一亮。
這種即時感才是聯機最欠缺的東西。
讓客戶端儘可能哄著玩家先玩著,剩下的事情由伺服器慢慢想辦法解決。
想到這兒,他便立馬要離席跑去開工。
但林立新立馬喊住了他。
「別急啊,這才哪到哪,這只是個第一重保險。」
林立新直接伸手在白板上抹出一片空白,搓了搓手把油墨蹭掉,這才繼續道, 「這樣做雖然解決了即時響應的問題,但卻會讓《quake》出現一個全新的bug。」
他在上面寫下兩行字。
【favor the shooter】(滿足射擊者)
【responsiveness】(響應性)
這兩種觀念,就對應了在fps這條道路上的兩類完全不同的優化思路。
剛才設計的這個客戶端預測,其實就是非常典型的響應性設計。
響應性設計的主張是:當玩家執行了一個操作時,他應該立刻得到反饋。
「你們看,這種設計最大的好處是什麼?當然是符合玩家的直覺,操作乾脆幹練,簡直就像是在玩本地遊戲,完全感受不到聯機的延遲。」
林立新在寫著『響應性』的位置點了點。
「可它並不是完美的,它最大的問題就是……打不中人。」
卡馬克眨巴眨巴眼,等待著林立新繼續說下去。
因為現在這兩條放在一起,完全是在左腦搏擊右腦。 剛才才說了客戶端預測不能干預伺服器判斷,這樣才能確保一致性和足夠公平。
現在卻又要把打不中人拿出來說。
「預測錯誤導致的回彈、子彈數量不對導致的只能聽見槍響但沒有開槍的情況、打中了人卻沒打中……」
林立新如數家珍地一條一條羅列著現在聯機系統的罪狀,
「為此,我們需要引入第二條優化策略。」
他的手向上移動,點在【favor the shooter】那行上,
「我們要在伺服器處理信息時,稍微……偏心一點,偏向射擊者。」
「可那樣不是又會導致……」
山姆開口道,不過還沒說完,便被林立新給打斷了。
「別急,我不是說讓射擊者完全本地化處理,命中與否仍然是伺服器負責的。」
「……」
這下不管是山姆還是卡馬克都沒招了,靜靜等著林立新給出最終的答案。 「lag compensation(延遲補償)。」
林立新解釋道,
「預測能解決手感,而延遲補償解決的是公平。」
他在板子上畫了三個方塊,讓其中兩個通過一個箭頭連接到最上面那個。
顯而易見的,這是個非常簡略的客戶端/服務端模型。
「你看,假設我們的延遲是100毫秒,那我們在遊戲中看到的畫面,實際上就是100毫秒以前的內容,而我們如果在這個時候開槍,打中的也是100毫秒以前的對手。」
這就壞菜了。
理論上來說,如果玩家是絕對精準地瞄準著目標進行開火,在這種情況下是永遠都不可能擊中正在移動的目標的。
除非這位高手能夠牛逼到精準地推算出自己的實時延遲,並根據對方現在的運動狀態、心理情況、戰術策略等各種因子,綜合推算出對方的下一步動向,並提前瞄準對應的位置。
但這顯然是不可能的。
職業選手最多也就是計算個提前量打跟槍。
真正的完全預測根本就不是人腦能解決的。 哪怕是計算機也不可能完整計算出來。
「吶,問題就在這兒了,這樣一來,玩家便會有種明明開槍了、也瞄準了、也打中了,甚至目標腦袋都飆血了,卻毛事都沒有,一點血皮子都沒掉的詭異錯位感。」
「而解決這個問題的辦法也非常簡單。」
林立新重新伸手,寫下一個單詞。
【rewind】
當然不是以撒里的那種,不過也的確是差不多的思想。
「rewind(回滾),確切地說是伺服器回滾。」
「伺服器不再實時進行計算,而是保存一份包含所有玩家最近幾百毫秒以內的所有快照。」
這才是valve的看家法寶。
比起前面的預測,這套系統的重要性完全是次世代的,徹底解決了高延遲環境下打不中人的苦惱。
「幾百毫秒內的快照……」
卡馬克喃喃道,忽然靈光一閃,似乎猜到了林立新是什麼意思, 「林你的意思是……當玩家的射擊信息發送到伺服器時,不再根據實時狀態進行處理,而是……檢查快照?」
「沒錯。」
林立新滿意地點點頭,臉上露出笑容,
「我們讓伺服器去判斷……當玩家開槍的那一刻,這個世界是什麼樣子的。」
當網絡包發送到伺服器的時候,伺服器會根據狀態調取對應的緩存,檢查命中或是其它信息。
完成計算後再將結果和必要的修正信息返回給玩家這邊。
整個過程大概會比原本增加幾毫秒的延遲,但換來的效果卻絕對值得。
「原來如此……」
卡馬克若有所思地點點頭,思路一下子便被打開了。
坐在一旁的山姆仔細看著白板上的東西。
他的技術遠遠跟不上兩人,但他卻是個實打實的資深玩家,看待問題的也會有自己的角度。
終於是努力理解了這套機制後,山姆出聲打斷了還在嘰里咕嚕深入討論算法細節的兩人。 「可是這樣的話……對被射擊者來說體驗又會變差吧?」
山姆在腦袋裡模擬了一番那個場景,一下子就抓到了其中一個最嚴重的問題。
「要是我操作著角色在牆後面跟對方打立回,不是會出現我已經躲在牆後面,卻還是被打死了的情況嗎?就像是穿牆了一樣。」
這套方案聽起來非常甜美,射擊者總能得到一個優秀的遊戲體驗,玩起來就像是在本地遊戲一樣。
但仔細一看問題同樣不少。
林立新就像是避重就輕地把問題給划過去了一樣,根本沒有治根。
聞言,林立新眉毛一挑,略帶驚異地看向他。
山姆已經觸及到了fps網絡設計的最本質的那點東西。
「你說得對,山姆,但很遺憾……這是個無解的問題,至少在目前是無解的。」
林立新輕輕搖了搖頭。
卡馬克也立馬反應了過來,幫著跟山姆解釋道:
「山姆,射擊者和被射擊者的體驗是不可能同時被滿足的,在數學角度就是不成立的。」 『我打中了就應該算』和『我躲開了就不應該算』。
兩種思想,在存在客觀的網絡延遲時,是數學角度上不可能同時成立的東西。
哪怕是現代的fps遊戲,也沒能徹底解決這個千古難題。
沒有人能做到完美地解決它。
最多也就是優化、緩解,儘可能讓這種情況少發生,至少也要變得不那麼明顯。
「我們可以通過限制回滾時間來一定程度上優化這一點,對不同武器、不同環境下都分別採用不同的處理模式,雖然我們做不到完全解決,但我們可以讓絕大多數玩家都有足夠優秀的遊戲體驗。」
在fps網絡優化這方面,那就完全是千人千面了。
幾乎每一款現代的fps作品,都擁有一套獨屬於自己的優化邏輯。
valve派的偏向射擊者處理,直接決定了cs的整個生態環境。
在valve的想法裡,寧願犧牲一部分被射擊者的遊戲體驗,也要儘可能讓玩家得到最好的射擊感。
這種方案高度適合那些低ttk的fps遊戲,也就是幾槍之內便會分出勝負的作品。
而在valve派下,還有一個另類——《瓦羅蘭特》。 riot深度研究了valve的優化策略,並在此之上加入了一些自己的理解。
它允許低延遲的玩家得到一定的優待,嚴格限制了回滾窗口的長度,並提高了伺服器修正頻率。
高ping玩家的遊戲體驗明顯下降,但換來的是更高的競技公平。
而在長ttk遊戲環境下,不管是valve還是riot,他們的方案都不合適。
這方面做得比較優秀的……說起來雖然有點抽象,不過司馬重生的《apex》的確很有說法。
respawn的思想很簡單,玩家首先應該覺得自己像個靈活的猴子。
各種機動行為和移動操作是需要最優先保證的,確保了《apex》足夠絲滑的運動體驗。
而除了這兩大派別之外,還有著一類結合了兩種風格的長ttk小地圖競技作品。
暴雪的《overwatch守望先鋒》。
要論起在網絡同步方面的設計,ow絕對是最複雜最高級的之一。
各種花里胡哨的技能和機制的加入,讓ow無法用同一套網絡策略面對所有環境。
這就實在是沒什麼參考價值了,完全是針對ow這一款遊戲做的唯一性設計。 再之外就是《逃離塔科夫》之類的服務端至上的方案了。
面對這個需求,根本就沒有一個通用的統一解,需要根據遊戲的類型進行專項對策。
嗯……
如果硬要說完美的解決方案的話,其實也的確存在。
「如果真的想要徹底解決問題,只能讓玩家升級寬帶了……」