主流的moba在傳輸層協議上采用udp,上層實現tcp的一些功能,以及通過一定的冗余數據保證盡量少的重傳發生,如果非要才用tcp,也有一些對優化辦法,
其次很多都是建議moba采用定點,但是定點的數學庫麻煩,很多都要自己重寫,如果非要采用浮點也有一些辦法。
下面主要針對這2點進行討論。
網絡
由于tcp經典重傳算法是指數退避的形式,當丟失包時,重傳很慢,導致延遲很高。但是tcp也提供了快速重傳方法,dupAck幾次后,不等定時器到期就立馬傳送。但是沒在移動端找到對應api,一般客戶端只支持開啟TCP_NODELAY來關閉negal算法,其他一些tcp選項并沒移植過來,但是服務器開啟快速重傳起碼可以保證服務器到客戶端傳輸的效率提升,就可以保證總體延遲的降低。還有因為移動端的api不支持sack重傳,否則還可以繼續提升傳輸效率。用tcp限制實在很大,可優化的空間極其有限,而且現在有成熟udp的kcp+fec的解決方案,所以推薦用udp來解決。浮點定點
在幀同步中,網上很多解決方案都是基于定點的,而且校驗客戶端的作弊行為,通過把地圖中所有實體的屬性求去哈希值,發給服務器,然后服務器判定不一致的客戶端為作弊客戶端,這個是基于大部分客戶端不作弊的情況,當然如果有多個作弊客戶端匹配進入地圖,這種辦法就失效了,不過避免多個可能的作弊客戶端進入地圖,那是匹配模塊該考慮的事情,不是戰斗模塊該考慮的了。這種防作弊方法如果其中一臺機器浮點標準不一致,會把正??蛻舳苏`判成為作弊客戶端的。
做游戲本質是做工程并不是做科學,所以允許部分誤差,比如怪物血量100,最終浮點計算傷害出了99.999還是100.000,這個都算怪物死亡,并不會影響游戲的進程,除非浮點誤差積累了很多,然后導致影響游戲進程了,不過這個是小概率事件,可以不用考慮。但是一旦有了浮點誤差后,上述通過計算哈希值的辦法就失效了,所以判斷客戶端是否作弊就應該換個方法了??梢酝ㄟ^用“偽隨機數”的方法,隨機算法固定,隨機種子固定,那么產生的隨機序列一定是一樣的。
每個客戶端的隨機種子一致,因為服務器下發的,然后每次在游戲進程改變(比如怪物死亡,人物死亡,添加技能,或者添加buff之類)的地方調用一次隨機,那么在一定的幀數調用一次隨機數然后上傳給服務器,服務器來判斷作弊玩家。這種做法也是基于“有玩家作弊,一定會導致游戲進程發生變化,然后導致每個客戶端在特定幀,隨機的次數不一致,最終產生的隨機數不同”。通過這種辦法算比較完美的解決了客戶端使用定點數的問題,客戶端開發可以很開心的用各種系統自帶的數學庫了。
上述的防作弊方法是針對修改屬性之類的作弊方法,由于幀同步所有的邏輯和數據都在客戶端,但是一些只是修改客戶端顯示的作弊方法(比如moba全圖掛,fps的透明掛)就比較難防。所以特定的時刻,比如被舉報過的玩家或者ip,下次在開游戲時,服務器一定要跑邏輯,客戶端變的純顯示,當然服務器跑戰斗邏輯對服務器負擔是很嚴重的,一般一局moba中,最高的實體個數有幾十個,沒做aoi的情況,戰斗的計算以及網絡消息的廣播多會導致cpu負擔很大,戰斗用c++來編寫單cpu只能同時跑十幾局戰斗,在優化也只能通過改變更合適的戰斗算法以及使的代碼的局部性更高來優化了。不過這個也基本足夠了,16核心機器,一次可以跑幾百局邏輯了,而且這個只是針對作弊玩家的在次校驗。