0. 背景
服務器框架設計者,如果設計的好,考慮到了這幾種情況,無論是對於游戲服務器邏輯清晰度,還是對於寫業務邏輯的程序員來說,是非常友好的。游戲服務器業務邏輯寫多了,一個游戲策划提出的需求歸納到服務器業務邏輯開發上面,也就無非幾種情況需要處理。
1. 業務邏輯模板
下面給出代碼模板,無論何種語言開發,大體都類似。
-- 數據結構
-- tbPlayer 常見字段
tbPlayer = {
dSocketId = 0,
time_rec = { -- 常見時間
birth = 0,
login = 0,
offline = 0,
dailyResets = {[{H,M}] = V, ...}
weeklyReset = 0,
},
sysA = tbAInfo, -- 某系統
sysB = tbBInfo, -- 某系統
}
-- 業務系統常見字段
tbAInfo = {
lastTime = 0, -- 上一次刷新時間
}
function born(tbPlayer)
-- todo 創建
-- 初始化數據,預處理數據
end
function loadData(tbPlayer)
-- todo 獲取數據
end
function saveData(tbPlayer)
-- todo 保存數據
-- 定時?即時
end
function onLogin(tbPlayer)
-- todo 登錄數據預處理
end
function offline(tbPlayer)
-- todo 下線數據處理
-- 登出/離線
end
function sendOnLogin(tbPlayer)
-- todo 登錄協議同步
-- 通常 dailyReset也會默認調用該函數
end
function dailyReset(tbPlayer, tbTime={dHour, dMinute})
-- todo 每日重置
-- 0點,也有其他時段的需求
end
2. 數據結構
一般游戲服是將數據直接存在內存里面,可能有些做法是即時保存,有些是定時保存。也有跟傳統網站開發類似的,每次業務邏輯需要數據的時候,從數據庫取出來,修改之后再存進去。畢竟游戲類型頗多,不同的游戲采用不同的持久化策略是很常見的。以上說的三種,再項目中,筆者都見到過。
關於游戲業務的數據結構的設計,個人經驗說下。首先跟時間相關的數據主要有:
- birth 建號時間
- login 上線時間
- offline 下線時間
- dailyResets 每日重置時間,存在多個時間點
- weeklyReset 每周重置時間
大多數業務邏輯都需要圍繞在以上幾個時間點來進行。這幾個地方處理的好,是能夠大幅度提高程序員的開發效率的。
dailyResets和weeklyReset時間點記錄都是為了實現每日重置,每周重置的邏輯。
每日重置需要注意下,可能存在多個時間點。凌晨0點是進行每日重置最常見的時間點。但是也有些游戲為了照顧玩家休息,或者為了降低服務器在0點的壓力,將部分或全部重置設置為其他時間點的,例如凌晨3點,凌晨5點。
每周重置的情況比較少存在多個的,一般選擇周一凌晨0點。
很多游戲都會為了前期的七日留存做很多工作,建號時間也往往在這些地方需要。當然這是個很有用的字段,無論是對於業務邏輯,還是對於游戲數據分析,都需要建號時間。
上線時間是最常見的時間了,一般游戲只在玩家在線的時候處理邏輯。玩家一旦下線,很少再會對玩家數據進行處理。等到玩家再次上線的時候,才會對數據進行處理計算。補回那些玩家不在線,而又需要執行的數據。如每日郵件,每日獎勵這種,我們不會真的每天都會將玩家數據從數據庫取出來進行處理,而且等到玩家上線的時候再運算那些不在線時期發生的事情。而這些處理,都依賴於玩家的上次上線時間來計算。
下線時間用的沒有上線時間那么多,但是也不少。
3. 常見邏輯
3.1. 建號 born
玩家的一切都起源於建號。建號需要進行一些數據初始化,如一些基礎裝備,基礎屬性。
3.2. 持久化 loadData和saveData
玩家登錄的時候,我們需要把數據從數據庫拿出到游戲服務器的內存里面。再數據發生改變之后,又需要存儲到數據庫進行存檔,以防服務器崩潰發生數據丟失。但是每次發生改變如果都進行存儲的話,無疑對數據庫的壓力會很大。為了權衡性能和數據安全,一般需要制定存儲策略,如定時存儲,或者定時存儲加部分數據即時存儲。不同的數據重要程度不一樣,可以采用不同的存儲策略。
3.3. 玩家上線 onLogin和sendOnLogin
為什么需要將上線的操作拆分onLogin
和sendOnLogin
兩個函數。兩者的區別是,前者用於進行數據預處理。補回類似剛剛說的,每日郵件啊,每日獎勵那些處理。后者是再數據預處理執行完了之后,進行該業務邏輯的協議同步。將數據預處理和協議同步分開是非常有必要和方便的。另外如果某個系統依賴於別的系統,該系統的onLogin操作需要放在別的系統的onLogin之后。
3.4. 玩家下線和斷線重連 offline和reconnect
玩家下線往往存在非常規操作,所以下線一般沒有協議同步,只有數據處理。下線一般放在與客戶端socket斷開的地方處理。下線也可以決定是否進行存檔。需要特別注意的是,再手游里面,斷線是非常容易發生的。所以需要考慮斷線重連的情況。是否立即存庫其實也跟斷線重連的設計相關。如果保留玩家的數據再內存一段時間,如1分鍾,30分鍾,offline的操作在手游里面就會極大的變少。可以根據下線成本自行考慮把。但是操作是必不可少的,只是執行的數量的問題。
4. 結尾
以上是個人經驗總結出來的業務邏輯開發場景。只是單純將業務邏輯的常見,此處不討論游戲服務器的框架設計,如網絡,日志,協議,持久化等。這些其實才是游戲服務器設計者的大頭。
好記性不如爛筆頭。