游戏对战匹配逻辑小结
前言
近期接觸了到了游戲后臺的匹配邏輯,寫此文作記錄,也給后來者一些參考。
本文主要是對邏輯的一些整理,真正使用的時候還需根據實際場景來。
場景與需求
數據結構
根據上面幾個需求,得出以下初步結論:
根據這三點,目前的結構是這樣的:
//上次戰(zhàn)斗的時間private final HashMap<String,Long> battleTimeMap=new HashMap<>();//不能戰(zhàn)斗的隊列private final LinkedList<String> unableBattleList=new LinkedList<>();//根據戰(zhàn)力分區(qū)private final HashMap<Integer,LinkedList<String>> enableBattleMap=new HashMap<>();匹配邏輯
已經可以確定是從一個List中選出被對戰(zhàn)的玩家,選擇的方式其實是兩種:順序讀和隨機讀。
由于隨機匹配兩次,不能匹配到相同的玩家,所以隨機讀是很不方便的,于是就確定使用順序讀。
匹配的時候有一個場景的問題是必須解決的:
用戶匹配到的對手,不一定會選擇戰(zhàn)斗,也可能直接退出匹配界面,或者換一個匹配的對手。
這時候,被匹配到,但卻沒有戰(zhàn)斗過的用戶仍應該在可被匹配的List中。
于是結構就變成了這樣:
//上次戰(zhàn)斗的時間private final HashMap<String,Long> battleTimeMap=new HashMap<>();//不能戰(zhàn)斗的隊列private final LinkedList<String> unableBattleList=new LinkedList<>();//根據戰(zhàn)力分區(qū)private final HashMap<Integer,LinkedList<String>> enableBattleMap=new HashMap<>(); //是否可以被匹配private final HashSet<String> enableBattleSet=new HashSet<>();添加了一個enableBattleSet,如果戰(zhàn)斗過了,那么就不會在這個Set中。
于是邏輯就變成了這樣:
戰(zhàn)斗冷卻結束邏輯
簡單來說就是將戰(zhàn)斗冷卻結束的用戶放到可匹配的List中。
這個大概有兩種實現方案:
由于隨著玩家越來越多,戰(zhàn)斗匹配的邏輯觸發(fā)會越發(fā)頻繁。但是戰(zhàn)斗冷卻結束的邏輯沒有必要那么頻繁觸發(fā),所以方案一是不合適的。
筆者最終選擇的是方案二。
上鎖的邏輯
如果兩個玩家戰(zhàn)斗力類似,他們同時觸發(fā)匹配的話,可能會匹配到同樣的對手,這樣就會導致被匹配到的玩家在同一時間與兩個玩家戰(zhàn)斗。這樣顯然是不合理的,所以需要對邏輯上鎖。
上鎖也是有兩種方案:
兩種方案筆者評估下都是可行的,都各有利弊:
優(yōu)勢: 只有戰(zhàn)斗力類似的玩家同時觸發(fā)匹配邏輯才會阻塞,減小了由于“同時匹配”被阻塞的概率。
劣勢: 如果在匹配的時候觸發(fā)了“戰(zhàn)斗冷卻結束邏輯”,那么也會被阻塞,存在請求超時風險。
優(yōu)勢: 如果在匹配的時候觸發(fā)了“戰(zhàn)斗冷卻結束邏輯”,不會被阻塞。而且結束戰(zhàn)斗冷卻的玩家是被放到List尾部,所以一般情況也不會影響匹配邏輯。
劣勢: 所有玩家中,只要有有兩個人同時觸發(fā)匹配邏輯,就會有玩家被阻塞,存在請求超時風險。
一致性問題
實際操作過程中,一個服務一般都會部署在多臺服務器上,這樣才能通過負載均衡提高并發(fā),并且在有一臺服務器出故障的時候,能保證服務正常運行。
在這種情況下,匹配邏輯的中間過程就不能僅僅放在緩存中,而應該使用redis放在redis服務器上,這樣才能保證匹配數據只有一份,而不是每臺服務器都有一份。
總結
以上是生活随笔為你收集整理的游戏对战匹配逻辑小结的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: EVE-NG模拟器教程(四)——常用镜像
- 下一篇: [硬件基础] 有刷、有感和无刷无感电机对