1. 程式人生 > >常見遊戲服務器業務邏輯和模板

常見遊戲服務器業務邏輯和模板

即時保存 拆分 如果 reconnect 經驗 數據初始化 安全 res loaddata

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

為什麽需要將上線的操作拆分onLoginsendOnLogin兩個函數。兩者的區別是,前者用於進行數據預處理。補回類似剛剛說的,每日郵件啊,每日獎勵那些處理。後者是再數據預處理執行完了之後,進行該業務邏輯的協議同步。將數據預處理和協議同步分開是非常有必要和方便的。另外如果某個系統依賴於別的系統,該系統的onLogin操作需要放在別的系統的onLogin之後。

3.4. 玩家下線和斷線重連 offline和reconnect

玩家下線往往存在非常規操作,所以下線一般沒有協議同步,只有數據處理。下線一般放在與客戶端socket斷開的地方處理。下線也可以決定是否進行存檔。需要特別註意的是,再手遊裏面,斷線是非常容易發生的。所以需要考慮斷線重連的情況。是否立即存庫其實也跟斷線重連的設計相關。如果保留玩家的數據再內存一段時間,如1分鐘,30分鐘,offline的操作在手遊裏面就會極大的變少。可以根據下線成本自行考慮把。但是操作是必不可少的,只是執行的數量的問題。

4. 結尾

以上是個人經驗總結出來的業務邏輯開發場景。只是單純將業務邏輯的常見,此處不討論遊戲服務器的框架設計,如網絡,日誌,協議,持久化等。這些其實才是遊戲服務器設計者的大頭。

好記性不如爛筆頭。

常見遊戲服務器業務邏輯和模板