1. 程式人生 > >遊戲伺服器架構簡述--邏輯伺服器

遊戲伺服器架構簡述--邏輯伺服器

    最早的商業化的邏輯伺服器恐怕是mud系列了,國內的商用伺服器大部分都源於此。在以前簡單的說過mud,為了支援簡單的訪問模型mud的網路結構比較簡單,沒有執行緒結構。早期的擴充套件把mud作為了遊戲邏輯伺服器互動的命令一般通過一個伺服器中轉到mud.因為和客戶端互動的指令已經不限於早期的文字,大量的圖片,渲染,甚至聲音這些已經不需要mud處理的了。完全可以通過簡單的檔案壓縮然後下發客戶端,通過檔名稱等方式供邏輯系統呼叫。提到邏輯系統不得不提到一個概念心跳。目前的mud使用心跳的只是為了在定期的執行一些指令,所有的物件心跳是相同的。有一個很有趣的例子當把所有的指令通過一臺伺服器傳送的到邏輯的伺服器時。指令傳送的快慢實際變成了伺服器時間。傳送的快服務執行時間就快傳送的慢服務執行時間就慢。伺服器的心跳演變成了伺服器的時間每一次的脈動伺服器時間就加一。但每個人的時間為什麼要一樣呢。如果不考慮思維一個人單位時間內作的事情多了,他的時間就快了,如果一個人單位時間做的事情少了他的時間也就慢了。如果考慮思維一個人想得多了他的時間也相當於快了。實際不過是人的身體裡有好多的時間單位而顯得時間不那麼統一而以。當我們控制了時間的時候構造一個世界就容易多了。我們知道使用者行為是由一些列的命令產生的命令和行為的最大區別就是行為和行為間沒有因果關係而命令間會有因果關係。
   為什麼要區分命令上因果關係呢?前面我們把使用者命令放到一個命令中轉伺服器裡有中轉伺服器呼叫邏輯伺服器注意這裡的呼叫。邏輯伺服器是被動的執行指令時間在這裡被強迫的單一成一個線。容易產生一個問題就是一個使用者的指令如果有問題都會令這個世界都崩潰的尷尬局面。只有兩個指令是沒有因果關係的這才是和我們現實世界很相似的描述。一個行為只能有兩個可能,有效的和無效的,有效地指令到的結果獎勵,無效的指令無結果。在遊戲世界常用的一個判斷是隻有一個命令做完才可以引發下一個命令的行為邏輯在現實世界是的一個行為改變了某些東西可以用另一行為繼續改變這個物品。重要的概念,行為是不應該有束縛的。什麼樣的行為有什麼樣的結果。這是遊戲邏輯的行為,但又為什麼要引入命令的感念呢。因為軟體的行為是要有束縛的,在有限的資源內軟體的行為是要有前提的。例如選單的先後邏輯,模式對話的選擇。這些上下文關係是臨時的當一個行為結束例如對話結束時這些上下文的資料也就失效了。
   既然每一個人都應該有自己的心跳當心跳開始的時候他就應該執行一個行為。這裡要區分其他人的行為作用在他身上和他自己的行為。例如人家坎了他一刀,他流血這是其他人作用在他身上的行為,而不是他自己的行為。
   回過頭在說時間每個人都有自己的時間只有在自己的時間內執行行為才符合現實。所以每個人應該在自己的時間去找自己該做的行為,同一時刻可能會爆發多個行為這些行為是並行的。遊戲的多執行緒會不會有產生邏輯錯誤呢。我認為遊戲的邏輯資料不應該有多執行緒安全的問題。最簡單的多執行緒安全的問題是一片文章修改其中一部分的內容,兩個執行緒同時修改就會產生邏輯問題,或另一個情況是一個執行緒讀一個執行緒刪除,抑或一個執行緒喝藥一個執行緒減hp如何判定死亡。但我相信無論上述那種情況都不會造成困惑。遊戲不會有第一種的情況,遊戲的資料不能刪除整數都是有範圍的整數,只要在資料操作上作好互斥判定實現對單一資料的操作是沒有問題的。第三種情況先執行的喝藥就不會判定死亡,現死亡喝藥就是無效的行為。那麼服務的行為就是收集使用者的命令按心跳的頻率指示執行緒池分配執行緒執行命令,並淘汰過期的指令,排列指令的優先順序,並在指令到來的時通知物件。物件呼叫行為的指令碼程式碼執行相關的行為對資料集進行一次操作。

   捎帶說下面相物件是一個概念,其核心的原則是方法依附於相應的資料。但忽略了一個很重要的概念方法可以作用的不同的資料局集。方法和資料是相對的用那種組織形式都不能可能完美,為了解決方法的通用性有了模版的概念但他是一個編譯前的概念而不是動態的。繼承有時很好用不過超過3層以上的繼承就會讓人感到很混亂通過繼承的複用的情況也真的不是太多。面向物件完全是一個概念可以用這類的思維方式組織程式。組織的方式也並不完全依賴語言,甚至很多情況是語言無關的。我發現越是簡單的語言生命力越強,其實用C也可以完全做到面向物件只要你用面向物件的方式去寫程式。伺服器的情況和應用軟體不太一樣,以C++為例應用軟體在程序範圍內變數的使用和C++的物件變數的使用是重疊的,也就是說在編譯過程如果沒有把變數宣告為全域性變數哪麼就會報錯。伺服器的變數使用是在個個不同的執行緒甚至是跨語言跨程序,使用一個數據只有在執行的過程中才能發現是否有錯誤。在伺服器的面向物件更多的是指的是概念上面向物件的方式組織工程的開發。所以“雲風”常常提到他寫程式更喜歡C這種簡單的語言。無論概念上的面向物件還是概念上的方法複用都是執行時段報錯,把這種開發的方式提高到了工程的角度,而不是簡單的依賴編譯器來糾正工程學上的錯誤。