幀同步與狀態(tài)同步
本文寫的是自己學(xué)習(xí)幀同步和狀態(tài)同步的一個(gè)記錄。
早期網(wǎng)絡(luò)游戲是P2P模式,常見于局域網(wǎng)。P2P的實(shí)現(xiàn)原理是對于相同的軟件系統(tǒng),同樣的操作會得到同樣的結(jié)果。P2P當(dāng)中每臺機(jī)器都在設(shè)定的時(shí)間T的末尾對收集到的各個(gè)玩家操作進(jìn)行計(jì)算。循環(huán)該過程直到最后。這樣可以保證每個(gè)玩家得到相同的結(jié)果。這種模式下每一幀所有的機(jī)器都會進(jìn)行同步,所以叫幀同步。
經(jīng)典的幀同步會在時(shí)間段T的末尾進(jìn)行排查,看看是否接受到了所有玩家的操作,包括空操作,如果沒有就會等待。你還沒來,我就等等你,頗有種俠義精神,也符合當(dāng)時(shí)局域網(wǎng)環(huán)境都是好哥們一起開黑的情景。當(dāng)然講義氣的代價(jià)就是所有人都有等待最慢的那個(gè),一個(gè)人卡大家都卡。后來為了解決這個(gè)問題出現(xiàn)了PacketServer,是一個(gè)專門用來收發(fā)操作包的服務(wù)器,大家都通把操作發(fā)給服務(wù)器,然后在末尾得到服務(wù)器發(fā)送的經(jīng)過確認(rèn)的操作合集進(jìn)行計(jì)算。在這種情況下,卡的人就只會影響自己,好哥們先行一步。(服務(wù)器卡了當(dāng)然全完蛋,這種災(zāi)害哪種同步模型都沒辦法解決)
在基本的幀同步方式中,服務(wù)器只是不加判斷地接收并轉(zhuǎn)發(fā)客戶端操作,讓各客戶端自己進(jìn)行計(jì)算,這就會導(dǎo)致外掛很多。為了解決外掛問題,除了運(yùn)行反作弊服務(wù)器對客戶端上傳的操作進(jìn)行判斷,還可以把計(jì)算提到服務(wù)器,讓服務(wù)器計(jì)算出各種對局狀態(tài)并且向客戶端發(fā)送狀態(tài)列表,這就有了狀態(tài)同步。客戶端只進(jìn)行渲染和操作上傳。當(dāng)網(wǎng)絡(luò)足夠好,帶寬足夠大,甚至連渲染都可以放到服務(wù)器,客戶端只需要接受渲染好多幀,當(dāng)做能控制的播放器,這就是云游戲。
幀同步的斷線重連是個(gè)大問題。因?yàn)橹恍枰D(zhuǎn)發(fā)操作,服務(wù)器只能拿到各個(gè)客戶端從T0時(shí)刻開始的各操作,而不知道各個(gè)時(shí)期大家的狀態(tài)。現(xiàn)在一臺機(jī)器從T1時(shí)刻開始斷線,到T2時(shí)刻重新連上,這時(shí)候從它原有的狀態(tài)到現(xiàn)在的狀態(tài)只能靠它自己拼命的去算,一直算到和大家一樣的T3狀態(tài),從T2連上到T3算完之間可能要過好久,更可怕的是大退之后啥也沒保留,要從T0開始計(jì)算,當(dāng)然如果客戶端不保留操作也要就算是大退也要從T0開始。連上后很長時(shí)間不能動,這顯然是很不好的體驗(yàn)。
放著這個(gè)問題不談,假設(shè)大家的網(wǎng)絡(luò)都比較穩(wěn)定,但是在互聯(lián)網(wǎng)上大家隔的很遠(yuǎn),就有了延時(shí)問題。為了解決延時(shí)問題,有了預(yù)測技術(shù)。預(yù)測技術(shù)讓客戶端來預(yù)測丟包中間發(fā)生了什么,比如位置間突然出現(xiàn)兩個(gè)大的跨度可以加速,達(dá)到一種比較好的體驗(yàn)。
幀同步只要記錄好操作和隨機(jī)數(shù)種子幀同步可以很容易回放出戰(zhàn)斗過程。狀態(tài)同步也能接受到操作,這里應(yīng)該可以照做。一般來講,幀同步能做到的狀態(tài)同步都可以。反過來不行。
幀同步需要得到每個(gè)玩家的操作來計(jì)算,狀態(tài)同步可以用一些算法來壓縮同步的內(nèi)容。比方說,隨著玩家數(shù)量的增加,幀同步每個(gè)人需要接受的指令都在增加,而服務(wù)器需要發(fā)送的玩家和命令都在增加,對玩家的壓力是線性增長,對服務(wù)器是多項(xiàng)式增長。而狀態(tài)同步可以只同步必要的對局狀態(tài)量以及各玩家理論視野內(nèi)的其他對象狀態(tài)給他,壓力是線性增長。也就是說對于大型游戲只能用狀態(tài)同步。