1. 程式人生 > >遊戲系統開發筆記(六)——服務端架構設計

遊戲系統開發筆記(六)——服務端架構設計

.

http://blog.csdn.net/mooke/article/details/8913051

上回寫了寫服務端的分層結構,分層是比較巨集觀上的東西,至於層次間具體的互動方式還得通過各個模組的互動方式來體現,姑且把這種模組劃分以及其間的互動關係稱之為架構吧,下面就來談談MMORPG的服務端架構

        對於製作一款遊戲而言,首先要考慮的是做什麼樣的遊戲?要實現哪些功能?而為了進一步簡化問題,我們先考慮一款遊戲的核心玩法——即少了這一部分便會使得整個遊戲失去骨骼,乃至於產生一種“皮之不存毛將焉附”的感覺的部分。

        首先,對於一款MMORPG而言,角色和戰鬥是RPG遊戲中比較強調的一個部分

,其他功能會豐富整個遊戲使它增添樂趣,但不會取而代之。所以我們的系統至少應當包含有NPC模組、玩家角色模組,需要有活動的場所因此——場景模組,需要有活動的內容因此——戰鬥模組。

        其次,為了使玩家間能夠相互通訊,我們還需要網路模組;為了記錄玩家資料,我們需要資料庫模組;為了監控和記錄遊戲和程式狀態,我們需要一個日誌模組。好了,再說缺少什麼的話,我覺得是有了更好,但若沒有我們也能好歹應付下來。

        最後,羅列一下:NPC、玩家、場景、戰鬥、網路、資料庫、日誌——完整MMORPG的最小系統版圖~

接下來考慮這些邏輯如何在程式中體現的問題——

《遊戲系統開發筆記(四)——遊戲程式簡介》

中曾簡單介紹過服務端的程式結構,那麼這裡再來細化一下,先考慮最簡單的設計

直接上賈程式碼:

  1. int main(int argc, char* argv[])  
  2. {  
  3.    Init(); //初始化各種資源、環境、資料
  4.     while(g_State != GAME_EXIT)  
  5.    {  
  6.        CheckToSleep(); // 定一個迴圈間隔,沒跑滿的時間咱們讓CPU放鬆下
  7.         //GameLoop
  8.        NetMessLoop();  // 收發網路訊息,並將收到的訊息分派給各個模組(比如加到各自的訊息佇列中)
  9.         NpcAILoop();    // Npc的AI
  10.        PlayerLoop();   // 處理玩家行為
  11.         //OtherLoop     // 比如幫會、副本、任務等等等
  12.         DBLoop();       // 資料庫操作
  13.         TimeEvent();    // 定時任務
  14.     }  
  15.     Release(); // 清理和記錄工作
  16.     return 0;  
  17. }  


        這裡我們把預期遊戲的功能拆分成網路訊息、AI、玩家行為、定時任務幾塊,通過一個迴圈不斷的去重新整理各種狀態、執行各種請求,從而達到使遊戲運轉起來的目的,迴圈的間隔時間主要影響了遊戲的最小響應時間。其中日誌模組、資料庫一般會設計成一個全域性範圍的功能,各個模組直接對其進行操作。

        這個例子把各個模組功能完成理論上就可以完成任務了,而且看上去是十分清晰簡潔的。按這種方式寫下去,通常就是對每個線上玩家和NPC設定一個唯一ID,放到各個模組的表中,各個Loop維護一個訊息佇列,訊息格式可能設計成訊息ID+引數的形式。接下來實現各種訊息對應的處理函式,然後處理訊息的過程中從引數解析到物件ID,通過ID和一組操作角色行為的函式來進行控制。

        ——這是比較典型的C風格的遊戲服務端做法,過程式的風格使得結構看起來比較扁平化,相對容易快速把握住整體結構。

下面是這個簡單例子的邏輯結構:

--------------------------------------------------------------------------------------------------

        可以從中看出,我們把大部分任務都歸到了邏輯模組,這會帶來兩個顯而易見的問題:1、過於複雜 2、專案程式碼難以重用

        另外,在這個例子中我們也沒有考慮多執行緒,所有操作都在主執行緒內完成,好處當然就是簡單清晰。帶來的問題,首要的倒談不上硬體資源浪費,因為多核的伺服器其實大不了多開幾個遊戲服務端,一個核跑一個服也就沒有浪費不浪費了。更加重要的問題是現在單核的主頻因為技術制約已經很難再有所提高了,依靠單核的計算能力很可能會使得一個遊戲只能承載寥寥幾百人同時線上——多麼杯具!

        所以總的來說,對於現在的商業遊戲專案來說,專案程式碼難以重用和承載人數太少是太難以接受的,一般來說也不願意投入許多精力去做這樣的東西吧。

        所以我們需要首先針對這兩個問題對專案進行優化——

        程式碼重用問題一般而言首先會考慮根據“一般性”和“特殊性”對功能進行分離,設計一組劃分更加合理的模組。而承載人數的問題,雖然優化程式是很重要一方面,但既然結構上具有不合理性,當然先考慮從結構上解決問題——我們需要使程式能夠更加充分的利用硬體資源。具體的措施我會先從第一個問題著手,因為模組設計好了通常也就為多執行緒做好了必要準備,剩下的可能也就是把它們分別裝配到其他執行緒的事情而已了。

        因為網路、資料庫和日誌三個模組功能上非常獨立,為它們各自設計一組邏輯無關的操作介面後就已經具備了重用的條件,這個例子中主要的問題在邏輯模組。

        經過考慮,對於MMORPG來說邏輯模組的只有移動、場景相關的功能是具有比較廣泛的一般性的,其它功能都或多或少的和具體遊戲產生不可分割的聯絡。但因為移動相關的功能比較複雜、執行頻率也非常高,所以可以單獨抽出來做一個模組。說它複雜因為移動不只是簡單的從一點到另一點,還會涉及碰撞、移動路徑、同步等問題。我們把可視、可移動的這種能力——很基本的能力設計成一個獨立物件(實體物件),組合到需要這種能力的其它物件中。

        實體物件的設計包含兩個部分,其一是執行具體移動相關業務的部分,其二是邏輯模組和該模組互動的介面層,上面說的組合物件實際上是指把這裡的作為介面的物件組合進來,這樣我們才能把實體物件需要做的工作給完整的抽取出來。給這個模組賦予一個好聽點的名字,就叫引擎模組吧。

        我們的邏輯模組剩餘的還有角色、NPC、戰鬥、場景以及其它遊戲功能,它們相互之間會有比較頻繁和複雜的相互操作,最多隻能做到把各個子模組劃分的再清晰些,但若是把任何一個部分放其它執行緒去就麻煩啦!複雜的遊戲邏輯裡面還要夾雜各種非同步操作簡直要讓人發瘋。

所以最後關於執行緒劃分的設計也差不多出來啦:

-------------------------------

        這種結構說起來算是一個拆分多執行緒的雛形吧,具體操作過程中可能還要有許多調整。根據效能熱點和功能型別可以考慮進一步拆分細項,但拆分的過程中要考慮好多執行緒帶來的利弊得失,對於遊戲伺服器來說,多執行緒間過多的互動會帶來較大的訊息處理延遲,使得一些細節的遊戲表現很難做到位。另外也要考慮到開發的難度,像邏輯這邊只能說還是更多的要為開發難度著想,非同步的遊戲邏輯下實在是很容易出各種BUG,有的不好查,有的查出來又不好解決 等等等~~

        總體來說,負載問題能得到或多或少的緩解,而程式碼複用的問題,一般來說引擎層的東西寫穩定了就不需要再改了。邏輯上的東西雖然大多都很有個性,但考慮到MMORPG類遊戲總體上都長的差不多,直接拿到一個專案來修改和擴充套件也無妨,而且可以相對節約學習使用引擎的成本。考慮到擴充套件和節約程式碼的問題,我覺得可能(僅僅是可能,這方面毫無經驗)用C++來實現會更適合些。

        結合上一章的分層結構來看,系統層實際上只提供了一些底層操作供上層呼叫,相當於工具庫,沒有結構上的意義,所以它對於這套架構來說是不可見的。而引擎層在上面第二張圖裡也已經有雛形了——有個引擎執行緒,但要注意的是引擎執行緒和引擎層是不等價的,上面也說了,這裡只是“比較隨便的”稱之為引擎模組而已,其實你愛叫什麼“移動層”的也完全隨你。引擎層所指的範圍要大些,包括這裡的“引擎執行緒”在內,還有網路、資料庫、日誌模組都可以歸入引擎執行緒。而作為大頭的邏輯執行緒(主執行緒),同時也可以認為是分層意義上的邏輯層

        很晚了,先寫到這裡。


相關推薦

遊戲系統開發筆記——服務架構設計

. http://blog.csdn.net/mooke/article/details/8913051 上回寫了寫服務端的分層結構,分層是比較巨集觀上的東西,至於層次間具體的互動方式還得通過各個模組的互動方式來體現,姑且把這種模組劃分以及其間的互動關係稱之為架構吧,下

遊戲開發筆記——服務架構設計

        上回寫了寫服務端的分層結構,分層是比較巨集觀上的東西,至於層次間具體的互動方式還得通過各個模組的互動方式來體現,姑且把這種模組劃分以及其間的互動關係稱之為架構吧,下面就來談談MMORPG的服務端架構,         對於製作一款遊戲而言,首先要考慮的是做什

遊戲開發筆記——服務系統分層

        本來很想按順序寫下來,到了第五篇是打算先寫架構的,無奈這東西暫時沒辦法弄的比較通透,拖了很久也還是覺得寫起來有困難。有一個客觀因素是這陣子有點忙,很多東西要做,也沒辦法留出許多時間用來學習。         還是先寫已經有點概念的東西吧.... 關於架構:

DX11 遊戲開發筆記 體積雲 水面

 對DX11來說,紋理佔了它的半邊天空,除了其賦予的色彩外,更由於其易於為資料的載體。 如上圖,我們僅僅使用了一個球、一個矩形,一個立方體紋理,一個3D紋理、一個無關緊要的水面顏色紋理。 立方體紋理和3d紋理使用方式跟2D紋理很像。 建立c++紋理資源:

Unity3D之Mecanim動畫系統學習筆記:使用腳本控制動畫

ont nim 復制代碼 info rip esc enter machine images 控制人物動畫播放 這裏我重新弄了一個簡單的場景和新的Animator Controller來作為示例。 下面先看看Animator Controller的配置: 人物在站

Java開發筆記特殊數字的表達

world 表達 int 數據 decimal stat java語言 細節 進制數 之前的文章提到,Java語言不但支持大眾熟知的十進制數,也支持計算機特有的二進制數、八進制數和十六進制數。可是在給數值變量賦值的時候,等號右邊的數字明顯屬於十進制,那究竟要如何書寫其它進制

Cocos Creator 系統學習筆記--Label的使用

筆記 bubuko 系統 圖片 com ima 分享圖片 reat image 2,自定義字庫 3,代碼使用cc.Label 4,RichText的使用 Cocos Creator 系統學習筆記(六)--Label的使用

C語言開發筆記實參和形參

#include <stdio.h> int func(int n) { n = 1; return n; } int main(void) { int n = 0; printf("%d\n", func(n));

HTC VIVE開發筆記VRTK中實現基本抓取物體的配置

一、配置要互動的遊戲物體 Step1: 選中需要互動的物體,點選選單欄Window->VRTK->Setup Interactable Object 這裡就可以選擇配置相應的屬性,包括To

thinkphp+layui系統開發筆記——資料表格

一、參考資料:1.thinkphp: https://www.kancloud.cn/special/thinkphp5_quickstart2.layui: http://www.layui.com/doc/modules/table.html二、程式碼:主體html<

FPGA學習筆記—— 時序邏輯電路設計

code 是我 使用 param efi sof src img lse 用always@(posedge clk)描述 時序邏輯電路的基礎——計數器(在每個時鐘的上升沿遞增1)   例1.四位計數器(同步使能、異步復位) // Module Nam

談一款MOBA類遊戲《碼神聯盟》的服務架構設計與實現更新優化思路

一、前言   《碼神聯盟》是一款為技術人做的開源情懷遊戲,每一種程式語言都是一位英雄。客戶端和服務端均使用C#開發,客戶端使用Unity3D引擎,資料庫使用MySQL。這個MOBA類遊戲是筆者在學習時期和客戶端美術策劃的小夥伴一起做的遊戲,筆者主要負責遊戲服務端開發,客戶

遊戲開發筆記——技能系統

      技能系統是一個對於遊戲來說,非常重要,實現起來又有些複雜的模組了。 在這個模組的設計上,很多程式都有不同見解,以及可以想到的是,在這個模組的製作上早期的許多團隊都或多或少的走過一段彎

Nodejs學習筆記----- 模塊系統和函數

參數 spa 而且 split response 另一個 簡約 也有 方法 Node.js模塊系統------->有開發基礎很好理解 為了讓Node.js的文件可以相互調用,Node.js提供了一個簡單的模塊系統。 模塊是Node.js 應用程序的基本組成部分,文件和

操作系統筆記調度

run 轉移 queue main tex pos 多級 用戶 gpo CPU 調度 理論基礎:進程執行由CPU execution和I/O wait組成 本質:從ready queue中選擇可以執行的進程,分配給CPU 發生調度的狀態轉移:1)preemptive:

操作系統筆記頁面置換算法 FIFO法 LRU最近最久未使用法 CLOCK法 二次機會法

直接 角度 順序 覆蓋 都是 target mar 有一個 頭結點 前篇在此: 操作系統筆記(五) 虛擬內存,覆蓋和交換技術 操作系統 筆記(三)計算機體系結構,地址空間、連續內存分配(四)非連續內存分配:分段,分頁 內容不多,就不做index了。 功能:當缺頁中斷發生時,

Activiti學習筆記Activiti的流程引擎API和服務

引擎API是與Activiti互動的最常見方式。中心起點是ProcessEngine,可以通過多種方式建立,如《Activiti學習筆記(三)獲取ProcessEngine物件的多種方式》。 從ProcessEngine中,可以獲得包含工作流BPM方法的各種服務。一下是Activiti的模型圖 一共有

嵌入式核心及驅動開發之學習筆記 驅動層中斷實現

由於中斷訊號的突發性,CPU要捕獲中斷訊號,有兩種方式。一是不斷輪詢是否有中斷髮生,這樣有點傻;二是通過中斷機制,過程如下: 中斷源 ---> 中斷訊號  --->  中斷控制器 --->  CPU  中斷源有很多,CPU拿

linux筆記------程序與服務

#######系統程序及服務的控制####### ##1.什麼是程序## 程序就是系統未完成並且正在進行的工作 ##2.檢視程序## (1)圖形方式檢視 gnome-system-monitor (2)程序檢視命令 ps -A ##所有程序 -a

床頭筆記之Android開發學習

初識Acitivity 目錄: 認識acitivity 建立一個acitivity專案 新增控制元件,實現想要的功能及介面 認識acitivity: Activity 是一個應用元件。 每個 Activity 都會獲得一個用於繪製其使用者介面的視窗。 使用者