話題回到遊戲開發領域。我們解決新問題時,經常會用我們已經熟識的方法。比如開始寫乙個遊戲引擎——我們暫且把做遊戲還是做引擎的問題放在一邊——經常會從底層開始寫,於是先寫平台抽象,然後是圖形、聲音、網路,之後才開始寫遊戲核心,高層的模組依賴於底層的模組。這看似沒有問題,你說呢?
問題一:從敏捷方法來看,這個引擎從開發到能跑起來的週期太長了,到整合時會有乙個
bug大爆發時期,會發現模組間有各種各樣的需求不匹配問題,需要大量的返工。需求總是不明確的,很多問題只有到使用時才會發現,當最後做遊戲核心時,才會發現原來的圖形模組設計少了這種那種的功能,而這些功能需要對圖形模組從結構上做修改。
問題二:寫底層模組時,由於還沒有使用者模組,很多需求只能基於猜測或看別的引擎有什麼,往往會導致設計得過於通用,花了很多時間做了很多不需要的功能,優化的方向和最終的需求不一致。
簡單說來就是在沒有實踐檢驗的情況下容易產生過少設計(
under-engineer
)或者過度設計(
over-engineer
)。不如先盡快把架子搭起來,讓遊戲先跑起來,再添磚加瓦,在問題和需求明確了的情況下,再考慮重構。就像烏龜換殼、蛇蛻皮一樣,讓架構和引擎一起成長。
問題三:普遍的觀念是底層比上層穩定,但有時未必如此。
3d顯示技術每年都翻新,可能比遊戲核心變得還快,而且每隔若干年還會有一次結構上的大變,比如
d3d9
到d3d10
,即使已經抽象了圖形介面,仍然會導致一定的結構調整。如果連沒有抽象層,則遊戲核心都得跟著改。
地獄之門倫敦在07年
gdc展示的從
dx9到
dx10
的移植就是這樣乙個例子,雖然作為成功的移植範例。他們的遊戲是直接在
dx9上寫的,往
dx10
移植時,只能通過
typedef
、巨集和模板函式把
dx9的符號抽象出來,變成和版本無關的符號,然後用
#ifdef
在dx10
下使用dx10
模擬的dx9 api
。雖然算是移植到了
dx10
,但程式結構依然是
dx9的結構,因為
dx9的用法和結構已經遍布遊戲核心,很難分離開了。
當然,也不是說抽象底層模組是唯一解決之道,設計乙個好的抽象是困難的,除非你的需求很低,只需要通用功能的子集。問題的關鍵不在於是否做了抽象,而在於是否做到了「原則一:複雜性區域性化。」顯示輸出,說到底不過是遊戲的輸出部分而已,即使沒有顯示模組,遊戲核心應該一樣可以跑。
unreal在05
還是06
年的gdc
展示的元件化實體設計(
component-based entity
)就是一種方法,顯示元件作為遊戲實體物件的乙個可選元件,只有該元件的原始碼才引入圖形
api的標頭檔案,在客戶端執行時新增該元件,在伺服器端時則不加該元件。即使圖形
api需要重構,其影響最大也只到顯示元件而已。
python常用模組介紹之二 copy模組
簡介 copy 模組主要用於複製物件,有淺 copy 和深copy 之分。首先得清楚的理解 物件 的概念 物件 python 萬物皆是物件。物件分為可變和不可變 2類,可變物件如 list,dict 等 不可變物件如 基礎型別,元組等。物件有三大特性分別為 身份 id a 型別 type a 值 a...
核心模組程式設計入門之二
模組程式設計屬於核心程式設計,因此,除了對核心相關知識有所了解外,還需要了解與模組相關的知識。1 應用程式與核心模組的比較 為了加深對核心模組的了解,表一給出應用程式與核心模組程式的比較。表一 應用程式與核心模組程式的比較 c語言應用程式 核心模組程式 使用函式 libc庫 核心函式 執行空間 使用...
Python常用模組之二 Queue
python中,佇列是執行緒間最常用的交換資料的形式。queue模組是提供佇列操作的模組,雖然簡單易用,但是不小心的話,還是會出現一些意外。queue佇列的原則時 先進先出,後進後出 常用方法 q.put q.get q.maxsize q.qsize 返回佇列的大小 q.empty 如果隊列為空,...