作者: Radu Privantu 譯者:pAnic 2005年5月11日 原文鏈接:http://www.devmaster.net/articles/building-mmorpg/ 譯者序:這是一篇講解如何開發一款MMORPG的入門文章,作者本人也是一款游戲的開發者,文中的內容源于實踐,有很高的參考價值。很多人都想擁有自己的游戲,這篇文章對那些想自己開發游戲的人來說可能是一紙福音,也可能是一盆冷水。無論如何,開發游戲都不是一件簡單的事情。 以下是翻譯正文:
|
[/td]
|
文章的中心是如何起步開發你自己的 大型多人在線角色扮演游戲( 原文:Massive Multiplayer Online Role Playing Games) (MMORPG)(譯者注:俗稱:網絡游戲,網游)。 針對的讀者是經驗和資源有限的開發者。 讀完文章之后,你應該懂得如何起步, 還有一些關于什么是應該做的和不應該做的忠告。第一步是評估你的能力和資源。你必須對自己誠實,因為做你力不從心的事情會浪費你的時間并讓你心灰意冷。
第一步:評估你的能力必須的技能:
- 懂至少一種編程語言。 迄今為止, C++因為性能和效率的優越性成為游戲開發者的首選。 Visual Basic, Java 或者 C# 可能也是不錯的選擇。
- 熟悉一種圖形庫。通常的選擇是SDL, OpenGL, 或者DX/D3D。(譯者注:網上也有很多免費/付費引擎下載和出售)
- 選擇一種網絡通訊庫。 你可以從WinSock, SDL_net, 或DirectPlay中選擇。(譯者注:很多人喜歡開發自己獨特的網絡庫,這并不復雜,似乎ACE也是一種選擇)
- 對游戲開發有大體的經驗。 例如,事件循環, 多線程, GUI 設計,等等。
強烈推薦的技能:
- C/S結構通訊。
- 多平臺開發。 你可能希望設計一個MMORPG, 尤其是服務器能運行在多種操作系統。為此,我推薦使用SDL, OpenGL 和SDL_net。
- 網站開發。如果你想讓用戶通過網站查看玩家統計,服務器信息和其他信息,這是必須的。(譯者注:其實網站可以交給其他人開發,如果有必要的話)。
- 安全管理。 你當然不想因為有人攻擊你的服務器而浪費時間!
- 團隊組織能力。 你需要一個你能成功領導和管理的團隊。
第二步:初步規劃我注意到很多人在不同的論壇發帖子尋找團隊開發MMORPG。他們中的大部分是這樣:“我們成立了一個公司/游戲工作室,需要3個美工,兩個程序,1個音樂制作,等等。為了創新,不要參考過去的MMORPG,你有全部的自由用來創造你想要的世界,等等。 我們會在項目完成并賺到錢的時候付給你酬勞,等等”。 不幸的是,以現有的技術和帶寬,你無法擁有一個動態的世界。 朝向無法到達的目標前進只會導致失敗。正確的做法是拿出一些小規模的,功能性強的,可擴展的設計和構架。 基本軟件構架首先,嘗試創建一個簡單的C/S模型,有如下功能:
- 創建一個新角色
- 保存那個角色(服務器端)
- 用那個角色登陸
- 能夠和其他人交談
- 能在3D空間游覽
保存角色看起來簡單,其實不然。 例如,有兩種方式保存角色:使用數據庫服務或者使用文件。兩者有各自的優缺點:
|
數據庫 |
文件 |
優點 |
- 添加新域或者修改現有的都很簡單。
- 更新玩家統計數據非常簡單(從游戲外)。
- 你可以通過SQL查詢方便的獲取不同種類的統計結果。
- 無需自行完成I/O操作,數據庫會替你做好。
- 易于更新/恢復。
|
- 高速操作(讀/寫)。
- 實現簡單。
- 無需額外的庫。
- 不依賴數據庫服務器。因此你不必擔心數據庫升級或安全問題。
|
缺點 |
- 容易出錯。 例如,做一個更新查詢的時候遺漏了'where'子句。會導致慘痛的損失,尤其是你沒有備份的時候。
- 數據庫會比打開/寫入一個玩家檔案文件慢。你查詢一些數據的時候會耗費幾個毫秒,尤其是大量玩家同時登入/登出的時候。
- 需要額外的代碼進行游戲和數據庫間的數據轉換。
- 需要操作數據庫和SQL的經驗。并且需要一個程序和數據庫之間的接口庫。
- 如果因為某些原因數據庫文件損壞,那算你倒霉,你可能會丟失所有的玩家數據(尤其是短期內沒有備份的時候)。
|
- 很難添加新的域,除非一開始就很小心的設計了文件的格式/結構。
- 沒法做全體玩家的查詢。(這可以通過每天晚上用程序把重要字段添加進一個數據庫間接實現)。
- 如果你想更新/檢查玩家狀態,你必須額外寫代碼。
- 更新和還原比較復雜。
|
現在你決定了如何存儲角色,你還得選擇C/S通訊的網絡協議:TCP 還是 UDP?,我們都知道TCP速度慢,但是更準確,并且需要額外帶寬。我實際使用TCP并沒有遇到什么問題。 如果你有充足的帶寬,TCP是個好選擇,至少對初學者是這樣。 UDP 會很麻煩,尤其是對新手。 記住,游戲或引擎的初步測試會在你的局域網進行,所有的包都會按順序依次抵達。在Internet上無法保證這一點。雖然包會按順序到達,但是有時候會丟包,這通常是個麻煩事。 當然,你可以設計你的協議使得C/S能夠從丟包中恢復。但這對初學者來說很痛苦,不值得推薦。 第三步:選擇數據傳輸協議又是看起來很簡單,其實不然。你不能只是發送'\0'結尾的串。因為你需要一個通用的協議,能同時適用字符串和二進制數據。用0(或其他字符)做結束符是不明智的,因為那個結束符可能是你要發送的數據的一部分。此外,如果你發送20字節,然后再20字節,服務器極有可能收不到兩個20字節的包。取而代之的是,它會一次性收到40字節,這是為了避免浪費帶寬在不必要的頭上。 而且,你可以發送1KB的包,但服務器會以兩個小包的形式收到它。所以你必須知道哪里是一個包的開始,哪里是結束。在 “永恒大陸”(譯者注:原文: Eternal Lands,本文的作者正在開發的一款MMORPG)中,我們用如下的方法:
- Offset 0: 1 字節 表示傳輸的命令。
- Offset 1: 2 字節,傳輸的數據長度。
- Offset 3: 變長,消息內容。
這種方法有一致的優點:所有的數據傳輸有統一的標準。缺點是有些命令有固定已知的長度,浪費了一些帶寬。以后我們會改成混合的方法。 下一件事是決定服務器模型: “非阻塞soket,不使用線程”,或者“阻塞soket,使用線程”。兩種方法(使用線程 vs 不使用線程)各有優缺點。 線程:
- 服務器響應會更加平滑,因為如果一個玩家需要大量時間(例如從數據庫中讀取數據),這會在它自己的線程中完成,不會影響其他人。(譯者注:也許作者的意思是每個玩家都有獨立的線程,但這對MMORPG不太現實)
- 難以恰當的實現和調試:你可能需要大量同步,并且一個小疏忽就會導致災難性的后果( 服務器癱瘓,物品復制,等等)。
- 可以利用多處理器。
無線程:
在我的公司,我們使用無線程的方法,因為我沒有足夠的資源和人力處理線程模式。 第四步:客戶端你打算做2D還是3D游戲?有些人認為2D游戲做起來簡單。我兩者都做過,并且我傾向于3D游戲更簡單。容我解釋。 2D下,你通常有一個幀緩沖,也就是一個巨大的象素點數組。象素點的格式會因顯卡的不同而不同。 有些是RGB模式,另一些是BGR模式,等等。每種顏色的bit數也會不同。只有在16bpp模式才有這個問題。8-bit和24-bit模式簡單一些,但有他們各自的問題(8-bit顏色數太少(256),而24-bit速度更慢)。同時,你需要制作你的精靈動畫程序,不得不自己排序所有對象,以便他們以正確的順序繪制。 當然,你可以用OpenGL或者D3D制作2D游戲,但通常這并不值得。并不是所有人都有3D加速卡,所以使用3D庫開發2D游戲一般會帶給你兩者的缺點:不是所有人都能玩,你也不能旋轉攝像機,擁有漂亮的陰影,和3D游戲炫目的效果。(譯者注,目前絕大部分顯卡都支持565的16bpp格式,這個也成為目前16位色的業界通用格式,有不少文章和代碼都是講述這一格式下圖像處理的,尤其是使用MMX技術) 3D的途徑,正如我所說,更簡單。但是需要一些數學(尤其是三角)的知識。現代的圖形庫很強大,免費提供了基本的操作(你不需要從后到前排列對象,改變物體的色彩和/或帖圖都十分簡單,對象的光照會按照光源和它的位置計算(只要你為它們計算了法向量),還有更多)。并且。3D給了你的創作和運動更多的自由度,缺點就是不是所有人都能玩你的游戲(沒有3D卡的人數可能會讓你大吃一驚的),并且,預渲染的圖片總是比實時渲染的更漂亮。(譯者注:市面上想買不支持3D的顯卡目前很困難,只是高性能的3D卡價格也不低) 第五步:安全顯然,不能相信用戶。任何時候都不能假設用戶無法破解你精巧的加密算法(如果你使用了的話)或者協議,用戶發送的任何信息都要通過驗證。極有可能,在你的服務器上,你有固定的緩沖區。例如,通常有一個小(可能是4k)緩沖區用來接收數據(從soket)。惡意用戶會發送超長數據。如果不檢查,這會導致緩沖區溢出,引起服務器癱瘓,或者更壞的,這個用戶可以hack你的服務器,執行非法代碼。每個單獨的消息都必須檢查:緩沖區是否溢出,數據是否合法(例如用戶發送“進入那扇門”,即使門在地圖的另一端,或者“使用治療藥水”盡管用戶沒有那種藥水,等等)。 我再次強調,驗證所有數據非常重要。一旦有非法數據,把它和用戶名,IP,時間和日期,和非法的原因記錄下來。偶爾檢查一下那個記錄。如果你發現少量的非法數據,并且來自于大量用戶,這通常是客戶端的bug或者網絡問題。然而,如果你發現從一個用戶或者IP發現大量非法數據,這是明顯的跡象表明有人正在欺騙服務器,試圖hack服務器,或者運行宏/腳本。同時,決不要在客戶端存儲數據。客戶端應該從服務器接收數據。換句話說,不能發送這樣的消息“OK,這是我得物品列表”或者“我的力量是10,魔法是200,生命值是2000/2000”。 而且,客戶端不應收到它不需要的數據。例如:客戶端不應該知道其他玩家的位置,除非他們在附近。 這是常識,給每個人發送所有玩家會占用大量帶寬,并且有些玩家會破解客戶端從中獲取不公平的利益(像在地圖上顯示特定玩家的位置)(譯者注:就像傳奇的免蠟燭外掛)。所有這些似乎都是常識,但,再次,你會驚奇的發現有多少人不知道這些我們認為的常識。 另一個要考慮的問題,當涉及到安全:玩家走動的速度必須在服務器計算,而不是客戶端。(譯者注:這是重要的原則,但是會耗費大量服務器資源。魔獸世界沒有這樣做,它采用類似其他玩家揭發的形式掩蓋這個事實,導致加速外掛可以用,但是在有其他玩家的時候會暴露)。服務器應該跟蹤時間(以ms為單位)當客戶最后一次移動的時候,并且,移動的請求如果比通常的極限更快到來,這個請求應該被拋棄。不要記錄這類虛假請求,因為這可能是因為網絡延遲(也就是玩家延遲,過去的10秒內發送的數據同時到達了)。 檢查距離。如果一個玩家試圖和100億公里以外的玩家交易(或者甚至在另一張地圖上),記錄下來。如果一個玩家試圖查看,或者使用一個遙遠的地圖對象,記錄它。小心假的ID。例如,正常情況下每個玩家都會分配一個ID(ID在登陸的時候分配,可以是持久的(唯一ID)。 如果ID在玩家登陸的時候賦予9或怪物被創建的時候),顯然可以用玩家數組(保存玩家)的位置(索引)作為ID。 所以第一個登陸的玩家ID是0,第二個是1,依此類推。現在,通常你會有一個限制,比如說2000個索引在玩家列表里。所以如果一個客戶端發送一條命令類似:“查看ID200000的角色”,這會使服務器當機,如果沒有防備的話,因為服務器會訪問非法的內存區域。所以,一定要檢查,就像這樣: "if actor id<0 or if actor id> max players 然后記錄非法操作并且斷開玩家。如果你使用C或者C++,注意或者定義索引為'unsigned int' 并且檢查上限,或因為某些原因定義為int(int,默認是有符號的),記得檢查 <0 and >max 。沒有做這些會嚴重挫傷你和其他用戶。類似的,要檢查超出地圖坐標。如果你的服務器有某種尋路算法,并且客戶端通過點擊地面來移動,確保他們不要點擊在地圖外部。 第六步:獲得一個團隊制作游戲需要大量的工作(除非是個Pong and Tetris游戲)。尤其是MMORPG。你無法單靠自己。理論上,一個完整的團隊組成是這樣:
- 至少3 個程序員: 1 個做服務器,兩個客戶端(或者一個客戶端,一個負責工具,例如美術插件,世界編輯器,等等)。有6個程序員是最好的,更多就沒必要了。這取決于你的領導能力。最少一個美工,2到3個更合適。如果這是個3D游戲,你需要一個3D美工,一個2D美工(制作帖圖,界面,等等),一個動畫師,和一個美術部負責人。美術部應該由有經驗的人組織和安排,除非你就是個藝術家。,
- 少數世界構建者:創建所有地圖是個漫長的過程, 并且直接關系到游戲的成敗。再次,你需要一個世界構建部的負責人。你的世界需要協調一致,所以不能只有一個意氣用事的人。
- 一個 網站管理員是必須的,除非你精通網站設計,并且愿意花時間做網站。音效和音樂不是必須的,但是有音效和音樂的游戲比沒有的會更吸引人。
- 一個游戲經濟系統 設計師.。你也許覺得那很簡單,可以自己來做,但事實上那是最復雜的工作之一。如果經濟系統設計不良(比如物品沒有平衡,資源在地圖上隨意放置,等等。)玩家會覺得無聊并且退出游戲。我們早期的進展存在很大的問題,尤其是因為經濟系統主要是由我(一個程序員)設計的,它沒有被恰當的計劃。 于是,我們花費了兩個月來重新思考和建立一整個新的經濟系統。這需要一次完全的物品清除。我告訴你,玩家會很不樂意你刪除他們的物品。幸運的是,大部分玩家贊同這個想法,但是這么多小時的爭論,妥協,解釋和時間的浪費還是讓我們喪氣。以后會更多。
如前所說,你需要一個10~15人的團隊,不包括協調員和管理者。這10~15人必須是有經驗的。如果都是新手就不值得,因為你需要花大量時間解釋要做什么,怎樣做,為什么他現在的做法不好,等等。 一開始就湊齊10~15人幾乎是不可能的。不管你在不同的論壇發多少帖,你也無法找到合適的團隊成員。畢竟,如果一個人在他/她的領域得心應手,為什么在你無法拿出任何東西的時候他/她要加入你的團隊?很多人有遠大的想法,但是實現它們需要大量時間和努力,所以他們寧可從事自己的工作也不會加入你。那如果你需要10~15人,但是無法讓他們加入你的團隊,你如何才能制作一款MMORPG呢? 好,事實上,你一開始不需要所有人都到位。你真正需要的是一個程序員和一個美工。如果你是個程序員,只要找個美工就可以了。請求懂美術的朋友幫忙,花錢請大學生/朋友做一些美術或者其他工作。 現在你有了一個美工,你期待的游戲的樣子,現在可以開始實現了。一旦你有了可以運行的C/S引擎,一些用來展示的截圖(或者更好,玩家可以登陸你的世界,四處走動,聊天),更多的人會愿意加入你的團隊。更恰當的是,除非你使用獨有的技術,否則你的客戶端可以開源。許多程序員會加入(作為志愿者)一個開源工程而不是非開源項目。而服務器不應該開源(除非你打算做一款完全開源的MMORPG)。 其他一些忠告:在有東西可展示之前,不要夸大你的游戲。最惹人煩的事情之一就是一個新手發一個“需要幫助”的請求,并且解釋這個游戲到底有多酷,最后要求一個巨大的團隊加入他的游戲制作。一旦你擁有了網站廣告(通常是在一個免費主機),你會看到一個吸引人的導航條,包含“下載”,“截圖”,“ 原畫”(譯者注,原文:Concept art,概念藝術,在游戲應該指美工的原始設計),“論壇”。你點擊下載鏈接,然后看到美妙的“建設中”頁面(或者更糟糕,一個404錯誤)。然后你點擊截圖,得到同樣的結果。如果你沒有東西給人下載,就不要放下載鏈接。如果沒有截圖展示,不要放截圖鏈接。然而更好的是,在工程進展10%(程序和美工)之前,不要浪費時間在網站上。 第七步:打破某些神話
- 你無法制作MMORPG, 只有大公司才可以。
我不同意。雖然制作一款像魔獸世界(World of Warcraft),無盡任務2(Ever Quest 2),亞瑟王的召喚2(Asheron's Call 2),血統2(Lineage 2),和其他一些游戲對一個小型的自發團隊是不可能的,但是做一款像樣的游戲還是可以的,只要你有經驗,動機,和時間。,你需要1000小時的編程來制作一個可運行的測試版,大概10~15k小時完成幾乎完整的客戶端和服務器。但是作為團隊領導者,你不能只編程。保持團隊團結,解決爭執,維護公共關系(PR),技術支持,架設服務器,懲罰搗亂分子,自由討論,等等都是你的職責。你可能會被非編程的任務淹沒。你很可能需要上班/上學,這減少了你花費在項目上的時間。我們很幸運,沒有成員離開團隊,但是如果這種事情發生,那的確是大問題。假設你的美工半途離開。或者更糟糕,他/她沒有給你使用他/她作品的許可。當然這可以通過和他們簽訂合同來解決,但找另外一個美工仍然很麻煩。一個工程中有兩種不同的美術風格也是問題。
- 需要大筆金錢(通常 4-6 位數) 用來架設一個 MMORPG 服務器.
當然,這不是真的。我見過專業服務器,1000GB/月,不到100美元/月(2~300美元的初裝費)。除非你的數據傳輸協議設計非常不合理,1000GB/月對一個1000玩家在線(平均)的服務器來說足夠了。當然,你還需要另一個服務器做網站和客戶端下載(客戶端下載會占用大量流量,當游戲變得流行的時候)。我們的客戶端有22MB,有時候會有400GB/月的傳輸量。而我們還沒有很流行(仍然)。另一件事,我們不需要另一臺專用服務器開啟這個工程。ADSL/cable服務器可以勝任,直到你的同時在線人數達到20~30。然后要么找一個友好的主機公司,用廣告交換免費主機,要么就只能自己掏腰包了。
- 制作一個MMORPG很有趣。
這不是真的。你可能認為每個人都會賞識你,玩家會支持你,你標新立異,并且,當然,很多玩家都玩你的游戲。玩家可能讓人討厭。即使是完全免費的游戲,他們也能找到理由抱怨。更糟糕的是人們經常會抱怨矛盾的事。戰士會抱怨升級太難,商人會對戰士掠奪大量錢財很失望。如果你減少怪物掉落物品,有些玩家就會威脅說要退出游戲。如果你增加,同樣的一群人會不滿新手能更簡單賺錢的事實。 真是左右為難。改革和改進是必須的。如果你決定改變某些東西,例如給加工物品增加挑戰性,有些人會說太難了。如果你不做,他們又會說太簡單無味。你會發現滿意的玩家通常不會說什么并且感到滿意,同時破壞者會怨聲載道。
MMORPG的經濟比單機版難以平衡的多。在單機游戲,你可以逐漸改良武器,只要玩家進展,他/她可以使用更好的裝備,丟棄(或者賣掉)舊的。另一方面,在多人游戲里,這種觀點不成立,因為每個人都試圖得到最好的武器,而跳過低等級武器。大部分玩家寧可空手省錢,直到他們能買游戲中最好的武器。經濟系統設計要參考相關的文章。 迄今為止我列舉的所有事情,加上額外的工作和挑戰,足以讓你在決定涉足這個工程之前三思而行。你必須知道你的決定意味著什么。 總結希望這篇文章能給你足夠的知識。我的下一篇文章將介紹如何建立一個經濟系統(更明確的,要避免哪些錯誤),還有一些調試服務器和客戶端的信息。 關于作者這篇文章作者是 Radu Privantu, 永恒大陸(Eternal Lands) www.eternal-lands.com的主程序和項目規劃, 永恒大陸是一款免費,客戶端開源的MMORPG。作者可以通過 chaos_rift at yahoo dot com 聯系。 |
posted @
2009-09-09 10:41 暗夜教父 閱讀(359) |
評論 (0) |
編輯 收藏
我不得不承認,我的能力不足以寫出一個100%不會宕機的游戲服務器程序,這也不能全怪我的能力太弱,誰讓咱國內網游玩家數量龐大,哪個游戲剛上線時沒有擠的爆滿過?還有些或是獵奇,或是謀私的個人和組織,在制造著千奇百怪,匪夷所思的數據包及操作流程來試探你的服務器。這些都曾是我在服務器宕機后向老板開脫的理由。
當WOW終于來到中國時,我一邊欣喜著終于可以在艾澤拉斯的大陸上自由翱翔,一邊卻咒罵著9C的破服務器,動不動就宕機。當然,身為游戲程序設計師的我明知道,這大部分的錯誤都不應歸罪于代理商9C,但是,誰讓blizzard是我心目中的神,誰又讓WOW成為我游戲制作的教科書呢。好吧,我知道上面這段極力追捧blizzard跟WOW的話可能早已讓你惡心連連,不堪入目了,對不起,忘了這一節,讓我們繼續。
服務器宕機后都發生了些什么?
顯然的,宕機后玩家會罵,就像我在玩WOW時那樣,罵游戲公司,罵老板,罵GM。非常抱歉,我們可愛的玩家們似乎并不清楚,這個時候最該罵的其實是我們這些程序員們。長久的遺忘被我們當成了包容,以至于游戲程序員在公司里都養成了趾高氣揚,不可一世的壞毛病:看吧,策劃們,你們做的太爛了,數值不平衡,玩法沒新意,只會照抄WOW跟大菠蘿,能怪玩家罵你們嗎?運營不得力,買服務器的錢不知道去了哪里,游戲里卡的要死,偶爾辦個活動還沒半點吸引力,能不被玩家罵你是無良運營商嗎?GM們能不天天被罵家指著罵嗎?……呃,又扯遠了。
趕緊先把服務器重啟吧。老板正站在你的身后,一臉愁容,雖然暫時還沒有發作,但看得出來:老板很生氣,后果很嚴重!
玩家們很快又回來了,不得不為玩家們的毅力和執著精神而感動,更為自己的錯誤而愧疚,凌晨時分,服務器啟了又宕,宕了又啟,如此反復,可熱情的玩家們依然陪著我在折騰。哦,當年安其拉開門的時候,我也曾這樣折騰過。
這個時候不是你一個人在戰斗。GM們在忙碌地處理著玩家不斷打來的投訴電話:剛買的裝備在宕機后消失了;花光了身上所有材料合成的武器回檔了,但材料卻沒有還給我……數據庫維護組的同事們也在緊張的恢復著數據,盡可能的將玩家的損失減到最少。
真是一件令人沮喪的事。
真的該試著做點什么了吧!
既然我們非常不愿意看到宕機的情況發生,但又無法100%保證寫出來的服務器程序一定不會出錯,那我們就在當機發生后的搶救措施上花點功夫,讓玩家的損失不至于太大,也讓我們的維護人員少些壓力吧。
一個最簡單也最有效的做法是為每一臺服務器都配備物理冗余,同步更新冗余服務器上的狀態,當宕機發生時,立即將處理切換到后備服務器上。只是,物理冗余的代價太大,從成本方面考慮,老板可能不大愿意點頭。
既然不能做硬冗余,那就再來考慮軟的吧。
如果只是簡單的啟動冗余進程,其實是換湯不換藥的做法。原來能跑1000人的服務器,由于同時運行了兩個相同的進程,使得CPU和內存開銷都翻了倍,結果是只能跑500人了。還是要加服務器。
看來只能更深一層,從架構設計上來動手了。
假設我們的游戲世界是由多個獨立場景構成的,那么在實現上我們可以讓這些場景在進程上也獨立,這樣做的好處是可以使得一個場景的宕機不會影響到其他場景的正常運行。如果我們的游戲世界物理上沒有分隔,是一個無縫的大世界,我們也可以人為的將其分成多個獨立區域,所需要做的額外工作是處理好那些站在區域邊界附近的對象。事實上,現在的無縫大世界也都是這樣實現的。
有了這樣一個前提,我們再來看這個已宕掉的場景該如何處理。
還是老辦法,趕緊先把它拉起來吧。一個具體可行的方案是,由場景管理器,或者你也有可能叫它世界服務器,來監視各個場景進程的運行狀態,當某個場景異常失去聯系時,由管理器來將其重新啟動。這里需要再花點心思的是,如何讓玩家數據正常地發送到新啟動的場景進程中,而且這個過程對于客戶端來說是透明的。
這個方案聽起來似乎不錯,只是,如果宕掉的是場景管理器進程,那該怎么辦呢?
按照前面的描述,場景管理器可以看作是整個游戲世界的中心,它以一個指揮者的身份維護著游戲世界的有序運行,所以它的宕機對整個游戲世界的影響也將會是巨大的。
有沒有什么辦法能夠使得場景管理器進程再次啟動后能夠恢復先前的狀態呢?
我們可以為管理器和場景進程定義一套協議,使得管理器不僅能夠創建并恢復一個已有場景,而且場景管理器還能通過現有的場景進程數據恢復出自己。
一個理論上可行的方案是,場景管理器與場景進程間保持TCP長連接,并以一定頻率進行心跳聯系,任意一方發現聯系中斷或長時間未收到心跳包后都會立即做出處理。
如果是管理器發現場景進程失去聯系,那就啟動新的場景,如前面所描述的那樣。如果是場景進程發現管理器失去聯系,那就立即啟動重連過程,直接再次連接上管理器,然后立即將自己當前的狀態和負責的場景ID報告給管理器。管理器通過這些上報的數據就能恢復出游戲世界內的場景對應關系表,也就是恢復出了自己原來的狀態。
進程是恢復出來了,可我們忘了最重要的內容:數據。當場景進程宕機后,上面保存的玩家屬性數據也隨之丟失了,雖然我們能夠再次將這個場景創建出來,并把原來在這個場景內的客戶端數據重新定向過來,但這些客戶端對應的玩家對象的數據卻沒有了,游戲仍然無法繼續。
也許我們可以再做一點修改,把場景內的玩家數據分離出來,保存到一個獨立的進程上,比如,我們可以把這個進程叫做數據服務器,或者數據中心之類的。一個隱含的要求是,數據服務器的邏輯實現非常簡單,簡單到你可以認為它是絕對安全的,不會宕機。所以,保存在這里的玩家數據也就是絕對安全的。
讓我們在這個問題上稍微再深入一點。
場景進程上每次執行玩家的游戲邏輯時都要異步地到數據服務器上來存取數據,這個開銷可能太大,而且會使得一些游戲邏輯的實現變的很復雜,那么,把一些會頻繁使用到的數據直接保存在場景進程中,當數據發生改變時同步更新到數據服務器上,這樣可能會比較容易接受。
老板全都滿意了嗎?
從理論上來說,我們已經解決了場景進程宕機和管理器宕機后的狀態恢復問題,并且在場景恢復后也不會因為丟失了玩家數據而無法繼續進行游戲,而且,只要處理得當,這個過程對客戶端來說可以是完全透明的,也就是玩家根本不知道服務器上有個進程意外結束,我們做了這么多的工作來將它恢復了。
事實上,這個過程的透明也是必須的,我們并不需要嚷嚷著告訴我們的用戶,也就是玩家,我們做了多少多少事情來讓你玩的更順暢,又花了多少多少精力來解決因為服務器宕機而引起的麻煩,對于最終的用戶來說,他只需要享受最好的服務。閑話少說,讓我們繼續。
真的已經完全解決了所有問題嗎?
想象這樣一個場景:我帶著幾個剛剛降臨到艾澤拉斯大陸的伙伴沖向了艾爾文森林,去開荒霍格!正在霍格只剩下一絲血的時候,服務器稍稍卡了一下,等我緩過神來,面前的霍格驟然消失,地上也不見尸體。找了一圈,它正在出生點搖頭晃腦,也在四處張望,但頭頂上的血條分明是,滿血!
怎么回事?
處理這張地圖的場景進程意外結束了,服務器的宕機處理機制很快地恢復了這個場景進程,并且把我的客戶端數據重新定向到了新場景。只是,事情并不是一切都完美。因為這個場景是完全重新創建的,這意味著所有的怪物也是重新創建并被擺放到了初始位置,所以,只剩下一絲血的霍格碰上了好運氣……
類似的還有,正在護送NPC返回營地,在稍微停頓了一會兒之后,NPC又重新回到了原來的地方,等等。
雖然這比起最初的“客戶端被迫斷開連接,服務器端數據丟失”要進步了許多,但會給我工資的老板仍然可能不太滿意,他希望,霍格應該還在我的面前,而且只有一絲血,那個跟著我的NPC也應該還在我旁邊……
我要是不能說服老板,這是“根本不可能完成的任務!”,那也就只能坐下來再試一試。
也許,可以考慮將所有對象的數據都保存到數據服務器上,當然,這要求每個怪物都跟玩家一樣,有一個唯一ID,這一點實現起來可能會有些麻煩。
再不然,為對象提供一個從已有的內存數據構造的方法,這樣便可以使用共享內存來保存現場數據,再從共享內存中恢復出原來的對象。理論上來說,這個方法是可行的,只是,這三十多個字的文字描述要用C++來實現也可能將會是一項極大的挑戰,所以,這也僅只是可供參考的一個嘗試方案。
我想,我們走的夠遠了
讓我們先暫停一會兒,回過頭來看一看最初的目的。其實我們想要的只是盡可能的讓服務器進程不要宕機,如果實在是沒有辦法,就盡可能的讓宕機后的玩家損失比較小,不需要我們做大量的工作去做善后處理。
很簡單的需求,似乎我們糾纏的有些過頭了。
寫出能夠穩定運行的程序是對程序員的最基本要求,如果一個程序連穩定性都不具備,那根本都不用再去考慮功能啊、擴展啊等其他標準了。但是,正如我最開始所說的,沒有一個人能夠100%保證他寫出來的服務器程序是絕對不會崩潰的。我們所能要求的只是盡可能的仔細,盡可能的多一些必要的測試,離安全盡可能的更近一步。
剩下的就是在宕機后如何降低損失的問題了。
對于一般的MMOG來說,玩家在進入游戲時會從數據庫中將該玩家的所有相關數據讀到內存,以便快速的進行游戲邏輯的處理,而在玩家下線時再將數據的改動存回數據庫。
顯然的,當服務器進程出現意外宕機時,內存中所有的數據都丟失了,這也就造成了玩家數據的回檔,而且玩家在游戲中呆的時間越長,回檔的損失就越大。所以,一個被廣泛采用的做法是為玩家數據實現一種定時存盤的機制,就像現在大多數的單機游戲一樣,AutoSave。比如,每5分鐘自動為玩家存一次盤,這樣就可以使得回檔的最大損失控制在5分鐘以內。
另外,對于一些重要數據的變動,比如玩家花大量游戲貨幣購買了一件貴重的武器裝備,這時可將玩家數據立即做一次存盤操作,這也將有效的減少玩家的重大損失。
聽起來這是一項不錯的技術,在意外宕機的時候最多只回檔5分鐘,而且還沒有貴重物品的損失,玩家應該是可以接受的吧。
我已經聽到了數據庫維護員的咆哮
“數據庫已經快要崩潰了,你就不能讓每秒需要執行的SQL語句少一點嗎?”
“呃………”
我一直以為我們的數據庫非常強大,可以處理任何的數據,唯一的缺點就是查詢速度比直接內存讀取要慢很多。所以我使用了異步數據存取的方法,并且開啟了多個數據庫操作線程來并行的執行我的請求,運行的效果看起來還不錯。
也許,我應該來算一算,每秒種究竟丟了多少條操作請求給數據庫。
請允許我再自私一回,我已經很久沒有提到WOW了……
大概可信的數字是,WOW一組服務器的玩家數量在3000到5000之間,去掉最大的數,再去掉最小的數,最后的平均值是,4000吧,就算4000。
4000人在線,假設也是每5分鐘定時存盤一次,再假設所有玩家的存盤時間是平均分布的。這樣算下來,每秒種就會有67個玩家向數據庫發出存盤請求操作。
才67個,數據庫維護組的同事就跟我說不堪重負了?笑話,這數據庫服務器是誰買的?
先別急,67是玩家數,但是每個玩家的存盤請求不會只有一條SQL語句。
雖然每個游戲的內容都各有差別,但是一款MMOG需要存入數據庫的數據少不了會有技能、物品、任務、寵物、好友、公會這些東西。取決于游戲的類型差異,每個游戲都會有自己的存盤方式,比如我可能會把所有的技能ID作為一條數據來存儲,但是我也有可能把每個技能作為一條單獨的記錄來存儲,這樣可以方便對技能附加數據的擴展,等等。
但是,游戲中的物品存儲大概都是相同的,只能是一件(組)物品作為一條記錄來存儲。
而且,可以說游戲中存儲量最大的就是物品數據。算一算你的角色背包有多大,50格? 100格?還是200格?不要忘了銀行、擺攤位、裝備攔、寵物背包和郵箱這些地方也能放物品。并且,在游戲進行過程中,玩家背包中物品數據的變動也是相當的頻繁,不斷的有藥品被用掉,不斷地又有些小玩意兒被撿起來,不久后,它們又被賣給了NPC。
雖然你可以使用一些巧妙的比較算法來過濾掉那些實際上沒有發生變動的物品更新,另外也不是所有的玩家物品數據變動都很頻繁,但在實際運營中,尤其是當玩家的背包格數都很多的時候,物品數據的存盤的確會成為一個很大的問題。
除了物品,還有玩家的基本屬性存盤,社會關系存盤等等,再加上全局公共數據的存盤,如公會數據,拍賣行物品數據,如果老板也要我在游戲中開上一家拍賣行的話。
這么一算下來,似乎是有些多了。
再一次的挑戰
具體的數字將取決于游戲的類型和設計的數據表結構。
而數據庫服務器能承擔的每秒查詢數則取決于數據庫服務器的軟硬件配置情況。
但是一般來說,數據庫維護人員可能會告訴我,當每秒執行的SQL語句數達到1000條時,數據庫服務器將會感受到明顯的壓力,我可能也會看到數據庫執行隊列中的請求數一直在增長,也可能會看到數據庫服務器間歇性地拒絕響應,等等。
看起來我們又一次的面對到了巨大的打冷戰。
這個問題的起因是什么?我們不希望服務器進程宕機時回檔太久,所以我們增加了一個玩家數據定時存盤的機制,結果卻導致了數據庫請求的驟然增多。
那再退回到這個起點處,將定時存盤的時間間隔延長點,比如10分鐘才存一次?數據庫的壓力會有緩解,但最初的問題卻又會有所暴露。真是個兩難的問題。
既想要玩家數據存盤間隔時間短一點,又不想給數據庫造成的壓力太大。
同樣的需求似乎出現過很多回了:在中間加一層代理做緩沖。我們姑且稱這一層代理為數據庫代理服務器,它所要完成的工作是從場景進程收集玩家的定時存盤請求數據,再以一個低一點的頻率寫入到數據庫。
聽起來這又像是一個換湯不換藥的做法,寫入數據庫的時間間隔還是變長了。但實際上在前面我們就曾經描述過,如果服務器進程不會出現意外的宕機,玩家數據只需要在他上線時讀取,在他下線時寫入即可,中間添加的這些定時存盤過程完全只是為了防范宕機回檔所造成的巨大損失。
因為這個中間代理層的加入,我們把場景進程宕機的隱患與數據丟失的后果隔離開來了,現在即使場景進程宕機,數據還在數據庫代理服務器上,當然這里又隱含了一個條件:數據庫代理服務器需要足夠穩定,不會在場景進程之前先宕掉。事實上,因為這個代理進程的工作是,我們完全有理由相信,這個進程是非常穩定的,那樣的話,多久時間才把緩存的數據真正寫入數據庫,就看你自己的喜好了。
該結束了吧
是否有些似曾相識的感覺?
沒錯,前面我們曾經描述過一個數據服務器,也是這樣說的。
所以,數據服務器,數據庫代理服務器可以合并到一起,來共同保證數據的安全。
再加上場景進程與管理器進程的恢復協議,讓服務器的重啟對玩家保持透明。
看起來這個晚上可以睡個安穩覺。
posted @
2009-09-09 10:40 暗夜教父 閱讀(306) |
評論 (0) |
編輯 收藏
Author: Fox
原文地址:http://www.shnenglu.com/Fox/archive/2007/12/16/game_world_architecture.html
一個MMORPG(Massively Multiplayer Online Role Playing Game)的架構包含客戶端和服務器兩部分。客戶端主要涉及計算機圖形學、物理學、多媒體技術等,服務器主要涉及網絡通信技術、數據庫技術,而人工智能、操作系統等計算機基礎學科知識的應用體現在MMORPG開發過程中的方方面面。
一、游戲世界的劃分
理想狀態的游戲世界僅由一個完整的場景組成,在《魔獸爭霸 III 》、《 CS 》這樣的單機游戲中,所有玩家位于該場景中,在理論上,位于該場景中的任意玩家都可以看到游戲中所有玩家并與之交互,出于公平性和游戲性(而不是技術上)的考慮,游戲中并不會這樣做。
然而,目前的 MMORPG 中,幾乎沒有任何一款可以做到整個游戲世界只包含一個場景,因為在一款 MMORPG 中,同時在線的玩家數量成百上千,甚至是數萬人同時在一個游戲世界中交互。以現在的網絡技術和計算機系統,還無法為這么多玩家的交互提供即時處理。因此, MMORPG 的游戲世界被劃分為大小不等、數量眾多的場景,游戲服務器對于這些場景的處理分為分區和無縫兩種。
在分區式服務器中,一個場景中的玩家無法看到另一個場景中的玩家,當玩家從一個場景到另外一個場景跨越時,都有一個數據轉移和加載的過程(尤其是從一個分區服務器跨越到另外一個服務器時),玩家都有一個等待的時間,在這段時間內,服務器的主要工作是實現跨越玩家數據的轉移和加載以及后一個場景中玩家、 NPC 等數據的傳輸,客戶端的主要工作是實現新場景資源的加載和服務器通信。主要時間的長短主要取決于后一個場景中資源數據的大小。分區式服務器的優點主要是各分區服務器保持相對獨立,缺點是游戲空間不夠大,而且,一旦某個分區服務器中止服務,位于該服務器上的所有玩家將失去連接。
所謂無縫服務器,玩家幾乎察覺不到場景之間的這種切換,在場景間沒有物理上的屏障,對于玩家而言,眾多場景構成了一個巨大的游戲世界。場景之間,甚至服務器之間“沒有了”明確的界線。因此,無縫服務器為玩家提供了更大的游戲空間和更友好的交互,實現了動態邊界的無縫服務器甚至可以在某個服務器中止服務時,按一定策略將負載動態分散到其他服務器。因此,無縫服務器在技術上要比分區服務器更加復雜。
目前國內上市的 MMORPG ,大多采用分區式服務器,做到無縫世界的主要有《完美世界》和《天下貳》等,國外的 MMORPG 中,像《魔獸世界》、《 EVE 》等,都實現了無縫世界。
無縫服務器與分區式服務器在技術上的主要區別是,當位于場景 S1 中的玩家 P1 處于兩個(甚至更多)場景 S1 、 S2 的邊界區域內時,要保證 P1 能夠看到場景 S2 中建筑、玩家、 NPC 等可感知對象。而且邊界區域的大小要大于等于 P1 可感知的范圍,否則就可能發生 S2 中的可感知對象突然閃現在 P1 視野中的異常。
無疑,無縫世界為玩家提供了更人性化和更具魅力的用戶體驗。
二、無縫世界游戲服務器的整體架構
MMORPG 的服務器架構從功能上主要劃分為三種:
1、 登錄服務器( Login Server )
登錄服務器用于玩家驗證登錄,并根據系統記錄玩家信息得到其所在節點服務器,并通過世界服務器為登錄玩家和對應節點服務器建立連接。
2、 世界服務器( World Server )
世界服務器將整個游戲世界劃分成不同場景,將所有場景按一定策略分配給節點服務器,并對節點服務器進行管理。世界服務器的另一功能是與登錄服務器交互。因此,世界服務器是登錄服務器、節點服務器的溝通橋梁,當然,一旦玩家登錄成功,世界服務器將主要處理節點服務器間的通信。因此,世界服務器對于玩家是透明的。
3、 節點服務器( Node Server )
節點服務器負責管理位于該節點的所有玩家、 NPC 的所有交互,在無縫世界游戲中,由于邊界區域的存在,一個節點服務器甚至要處理相鄰節點上位于邊界區域的玩家和 NPC 的信息。
在具體實現上,不同的 MMORPG 為了便于管理,可能還會具有 AI 服務器、日志服務器、數據庫緩存服務器、代理服務器等。
三、 無縫世界游戲服務器的主要技術需求
1、 編程語言( C/C++ 、 SQL 、 Lua 、 Python )
2、 圖形庫( Direct 3D 、 OpenGL )
3、 網絡通信( WinSock 、 BSD Socket ,或者 ACE )
4、 消息、事件、多線程、 GUI
5、 OS
三、無縫世界游戲服務器需要解決的主要問題
1、 資源管理
無論是服務器還是客戶端,都涉及到大量資源:玩家數據、 NPC 數據、戰斗公式、模型資源、通信資源等。當這些資源達到一定規模,其管理的難度不可忽視。而且,資源管理的好壞,直接關系到游戲的安全和生命。
2、 網絡安全
安全永遠是第一位的,我們無法指望所有的玩家及其所持的客戶端永遠是友好的。事實上,威脅到游戲的公平性和安全性的大多數問題,歸根結底,都是由于網絡通信中存在的欺騙和攻擊造成的,這些問題包含但不限于交易欺騙、物品復制。
3、 邏輯安全
邏輯安全按理說應該是游戲中最基本的考慮,覆蓋的范圍也最廣最雜。隨機數系統是一個非常值得重視的問題,隨機數不僅僅用于玩家可見的一些任務系統、戰斗公式、人工智能、物品得失等,還可用于網絡報文加密等。因此,隨機數系統本身的安全不容忽視。另外一個常見的邏輯安全是玩家的移動,最主要的就是防止加速齒輪這樣的變態操作。
4、 負載均衡
MMORPG 中的負載均衡包括客戶端及服務器資源管理和邏輯處理的負載均衡,其中最難預知的是網絡通信的負載均衡,正常情況下的網絡通信數量是可以在游戲設計時做出評估的,但因惡意攻擊造成的網絡負載是無法預測的。因此,負載均衡所要處理的主要是實時動態負載均衡和災難恢復。負載均衡需要解決的問題包括負載監控、負載分析、負載分發和災難恢復。
5、 錄像系統
錄像系統的構建,主要用于重現關鍵數據的輸入輸出,如玩家交易、玩家充值,或者當 bug 出現后,為邏輯服務器(泛指上文提到的所有類型服務器,主要是節點服務器)相應部分啟動錄像系統。待收集到足夠數據后,通過錄像系統重現 bug 。為了使邏輯服務器不受自身時間(如中斷調試等)的影響,還可以專門設計心跳服務器來控制數據傳輸。
四、總結
在 MMORPG 中,真正的 bug 永遠存在于將來。從這一點出發,關于 MMORPG 中游戲世界的構建,怎樣苛刻的思考都不為過。
參考資料:
1、 [美] Kim Pallister編, 孟憲武 等譯. 游戲編程精粹5, P467-474, P516. 人民郵電出版社, 2007年9月. 北京.
2、 [美] Thor Alexander編, 史曉明 譯. 大型多人在線游戲開發, P174-185. 人民郵電出版社, 2006年12月. 北京.
3、 [美] Dante Treglia編, 張磊 譯. 游戲編程精粹3, P117-122. 人民郵電出版社, 2003年7月. 北京.
4、 [美] Mark DeLoura編, 王淑禮 等譯. 游戲編程精粹1, P90-93. 人民郵電出版社, 2004年10月. 北京.
5、 [美] Douglas 等著, 於春景 譯. C++網絡編程 卷1. 中國電力出版社, 2004年11月. 北京.
6、 [美] Stephen D. Huston 等著, 馬維達 譯. ACE程序員指南. 中國電力出版社, 2004年11月. 北京.
7、 [美] Erich Gamma等著, 李英軍 等譯. 設計模式. 機械工業出版社, 2000年6月. 北京.
8、 游戲引擎全剖析. http://bbs.gameres.com/showthread.asp?threadid=101293.
9、 服務器結構探討:登錄服的負載均衡. http://gamedev.csdn.net/page/351491d0-05ad-48a4-85e1-77870bc1eef3.
10、服務器結構探討:最終的結構. http://gamedev.csdn.net/page/28695655-974c-4291-8ac4-2589c4e770d3.
posted @
2009-09-09 10:38 暗夜教父 閱讀(369) |
評論 (0) |
編輯 收藏
目前在做一個超大地圖MMORPG的場景管理部分,客戶端通過動態預讀解決了超大圖量的動態加載,但是在做人物行走的時候遇到了一些問題:
一張地圖上的PLAYER和NPC等是存放在一個list中的,地圖超大那么上面的PLAYER就可能超多(預計大于200),這樣的話每個行走動作都要發送200條以上的消息,這對于服務器是一種很大的負擔,而且這種負擔是呈級數增長(10個玩家都走一步服務器將發送10*10=100條消息,而200個的話就是200*200=40000條消息!),可能任何服務器都無法負擔。
肯定有很多朋友都遇到了類似的問題,很想知道大家是怎么解決的?
方案一:
·服務器上每個場景用一個list來保存上面的player和NPC
·玩家行走、進入和離開等事件發給list中的所有player
·客戶端的list保有該場景上的所有player和npc
優點:處理起來簡單直接
缺點:發送的消息會隨玩家數量的增加而暴增、客戶端負擔很重
方案二:
·服務器上每個場景用一個list來保存上面的player和NPC
·玩家行走、進入和離開等事件只發給該玩家一定范圍內的Player
·客戶端的list只保有本玩家附近的player和npc
·在服務器可以考慮使用hash表來優化查詢速度
優點:減少了服務器發送消息的數量、減輕了客戶端的負擔
缺點:實現相對復雜,服務器負擔大大加重(因為要不斷判斷玩家間的位置關系)
方案三:
·在服務器上把場景劃分為小區域(大于屏幕大小)。每個區域對應一個list,場景中的所有對象按他們的位置加入到對應區域的list中,那么每次行走只需要把消息發送給最多4個相臨區域的Player
·客戶端的list只保有本玩家附近的player和npc
優點:大大減輕了服務器遍歷list的負擔、減少了發送消息的數量、減輕了客戶端的負擔
缺點:實現非常復雜、而且在服務器需要不斷判斷玩家是否跨越區域
方案四:
·服務器上場景的每個TILE保存一個Object指針用來綁定該格子上的player或NPC
·玩家行走、進入和離開等事件發給玩家周圍一定范圍內的player
·客戶端保有該player周圍一定范圍內的player和npc
優點:處理起來極為直接、避免了耗時鏈表遍歷(典型的以空間換時間)
缺點:地圖每個TILE都要加入一個指針變量(管理不善容易出錯)、每次發送場景廣播要遍歷所有TILE
方案五:
·服務器上每個場景用一個list來保存上面的player和NPC
·不使用事件通知,而使用狀態位置通知的方式通過定時發送狀態來更新客戶端的player和npc狀態
·客戶端保有該player周圍一定范圍內的player和npc
優點:處理比較簡單
缺點:實時性太低,對于要求同步比較精確的ARPG不太適合
posted @
2009-09-09 10:36 暗夜教父 閱讀(1372) |
評論 (1) |
編輯 收藏
說起高性能的網絡游戲,有2個典范,1個是暴雪的WOW,另外一個要數騰訊的QQGame了,因為對于MMPRPG的體系接觸不深,幾乎屬于文盲,沒有太多的發言權,而自己又是搞休閑游戲開發的所以本文就主要談談QQGame了。
前些天通過朋友得到了QQGame的一個系統分析的文檔,看完后很是震驚,徹底被QQ的設計所折服了,到底是千萬人在線系統經驗的擁有者,牛!
通過資料了解到QQGame目前有以下讓我欣賞的特性:
1.單機最高容納35,000人同時在線,對沒有看錯是這么多,由于它適用了Linux下高性能的網絡處理模型ePoll技術,并且一系列高超的優化技術輕松破萬人,當然為了穩定性考慮單機保持了2萬人的容量,此時的帶寬消耗為近30M;
2.采用共享內存方式高速完成進程間高速通訊;
3.服務器的擴充方式不是平面的方式,而是裂變式的擴充方式,形成負載均衡陣列樹狀結構;
4.所有的游戲服務器不是直接和數據庫聯系,而是和數據proxy(qq管叫數據交換機和路由器)進行聯系,由此帶來的就是游戲用戶數據的分布存儲,我分析著應該是proxy上記錄著這個用戶數據所在的實際的dbserver的信息,然后定時的將最新的用戶信息寫回到db中去,這樣就大大緩解了數據庫服務器的壓力,而且可以非常平滑的將數據分裂開來,數據庫服務器也就可以無限的擴充,當然我覺得肯定有個數據庫信息索引了用戶的id和對應的存儲地點的關聯關系,這點就類似于google的原理了,所以對于數據庫的硬件要求也就不是那么高了,qqgame的一組服務器通常是7臺服務器,可以容納5萬人,其中就包含了數據庫服務器,這點就不是棋牌游戲所常使用的數據集中存儲了;
5.游戲服務器的網絡和邏輯分開,不僅僅是層次上的分開,而是在進程上分開,然后中間通過共享通道進行管理和協調,并且增加了輔助線程,在主線程處理大壓力的異步的操作的時候直接交給輔助線程處理,保障了游戲服務器的高效性運轉。
作為游戲服務器的結構方面(以下只討論休閑游戲部分,MMORPG服務器不屬于討論范圍)的設計已經相對于成熟并且統一,結構方面和3年前我所接觸的中游系的那套平臺沒有太大的差異,無非是服務器群采用星狀的結構,以1個中心節點作為核心,然后向四周擴散出一些應用服務器,如負責登陸的LoginServer,負責具體游戲邏輯的GameServer等等,當然最精簡的結構是這樣的,這樣的結構可以滿足50萬以下同時在線的容量,如果為了滿足更大的容量,如QQGAME這樣的目前已經有200萬以上同時在線的超大容量的應用則需要額外的優化,從這個結構中分離出一些子應用獨立開發出一些服務器端來處理,一方面降低偶合度,另外一方面作為高可用性系統為負載均衡提供條件.
關于負載均衡,作為整個游戲平臺的所有服務器.我覺得除了具體的游戲邏輯服務器以外都是可以采用負載均衡,多點分擔的方式來處理,惟獨邏輯服務器不可以,因為休閑游戲,都是分層次的,不管泡泡堂也好,QQGAME也好這些游戲其實在客戶端的表現形式都是分層次的,如QQGAME就是LOBBY-HALL-ROOM這樣的結構,LOBBY這層就是游戲廣場了,可以看到所有的游戲類別,游戲服務器和具體的游戲大廳,比如:牌類–斗地主–新手場–新手場1 這樣的順序,傳統的設計中新手場1就是屬于一個獨立的游戲邏輯服務器擁有一個獨立的IP以及偵聽端口,在服務器端通常也是一個獨立的進程.一般的游戲服務器允許的連接數通常都是300-600人之間超過的就提示服務器已滿了,這樣做的原因并不是因為進程的限制因為一個進程完全可以做到同時讓3000以上的玩家同時游戲,而是人為設計的考慮,因為在游戲邏輯服務器中有很多需要廣播的消息,如游戲玩家的聊天信息,某個房間的開始信息,結束信息,某人進出的信息等,而對于廣播來說,給300個人廣播和給3000個人廣播所消耗的資源是絕對沒有可比性的。但是通過從進程上獨立來處理這個傳統的方式也有個缺陷,比如通過開10個進程來達到3000人和1個進程達到3000人,如果不考慮廣播的因素在內的話前者的資源是要高與后者的資源的,并且進程間的通訊也要比進程內的通訊要耗費資源和復雜度方面要高很多,比如說如果要實現一個需求讓玩家可以在同一類游戲中可以使用小喇叭類或者跨游戲服務器找人之類的功能的話,同一個進程的優勢就顯示出來了,為此QQGAME所使用的是Channel(頻道)的概念,即一個游戲邏輯服務器的進程可以容納5000人左右,然后服務器端通過設置分割出很多的Channel如新手1,新手2,新手3之類的傳統意義上的游戲大廳,將消息的分發范圍進行隔離,節約了資源。這一點可以通過查看連接屬性看到,連接QQGAME的同類型靠近的幾個游戲大廳其實端口和IP都是一致的。
我們目前的游戲服務器類型主要有3類:CenterServer,管理著所有的服務器連接,LoginServer 負責處理用戶的登陸、注冊,并且用來給用戶傳遞游戲邏輯服務器列表等功能, GameServer具體邏輯服務器,根據不同的邏輯來實現不同的游戲需求。
當然,根據業務的發展需要,我們正準備把用戶的狀態在服務器端保存,并且增加一個類似IM服務器的功能來滿足玩家跨服務器聊天和查詢其他玩家狀態的需要。以及GM服務器實現多功能的網管室的需求,這些將在以后慢慢寫。
今天開始寫些技術的題材,一方面記錄一些自己的本分工作的東西,另外一方面也是充實一下BLOG,工作太忙也沒有什么太多的思緒來一直寫其他的題材,所以就拿工作來填充了.同時如果有人有幸看到了這些文章,并且也有興趣的話也希望多多探討.
先簡單介紹一下,由于本人的工作就是游戲開發公司的,一直與游戲開發打交道,主要做休閑類的游戲,目前又以棋牌游戲為主,在這個行業中摸爬滾打了整3年了,從運營開始做起,運營過當時國內一流的游戲平臺中游系列的產品,然后由于合作方面的原因又自主開發過一套游戲平臺,然后由于發展方向上的分歧出來單獨做,目前在開發并運維一套全新的產品.
這篇主要是對于游戲服務器的一些想法,結合目前自身的產品的一些問題延伸開來的.
目前我們的服務器還是屬于Windows平臺的架構,暫時還沒有考慮到跨平臺,主要原因有2:
1.成本:作為公司來說首先得考慮的就是成本了,雖然說Linux類的平臺存在著操作系統成本低廉,性能優異,穩定性高這幾個特色,但是作為全局考慮來說,一個Linux的系統管理員,以及開發人員的成本要比Windows平臺要高很多,并且作為操作系統方面是免費的,但是支持幾乎是沒有的只有一些不適合商業應用的開源社區作為支撐,要得到更加好的服務或者額外的支持還是得通過大廠商的高額的產品或服務來實現,而Windows平臺則不同,雖然操作系統貌似價格不扉,但是本身就帶了很多的模塊,比如組件服務,日志服務等等,加上平臺上各種軟件的數量也和Linux下的不是同一量級的,可選擇性要大的多,而讓Linuxer所詬病的Win32的安全性其實完全可以通過另外獨立的安全模塊,如硬件防火墻等來完善,畢竟操作系統不是專門做安全防護的Linux也存在很多的漏洞,并且隨著Linux發行版的日益增多,用戶的逐漸了解,漏洞也日益的增多.
2.開發效率.無疑Visual Studio系列開發套件是目前開發領域最方便最強大的IDE環境,這已是不爭的事實,而如果用VI + GCC的模式去開發LINUX下面的服務器其效率和質量至少從我目前的水平(可以部分代表國內目前中小游戲軟件開發商實際現狀)要徹底的領悟并轉換需要一定的時間,并且還沒有成熟的開發平臺作為保證, JAVA好象有 但是C++還沒有聽說有超過VC++的.
posted @
2009-09-09 10:35 暗夜教父 閱讀(859) |
評論 (0) |
編輯 收藏
Scrum,這只敏捷家族中的生力軍,現在正被越來越多的人認識并且接受。在游戲開發領域中,近年來國內的許多企業也開始嘗試采用Scrum進行游戲開發。Scrum這種強調頻繁交付緊密溝通的開發方式似乎證明了比它的前輩們更適合游戲開發領域。但正如人月神話中的那句老話“No silver bullet”。那么對于如今國內占主流的大型多人在線游戲(MMO)開發領域而言,Scrum是否就是那枚傳說中的銀彈,一經發射,就能讓擺在你面前的所有問題都瞬間灰飛煙滅?我們在具體的執行層面又應該怎么去控制和管理它呢?筆者希望以下的文字能幫助你解答以上兩個問題。
Scrum與傳統方式之間的不同
在使用Scrum之前,公司或者開發團隊多多少少已經有一些成型并且大家都已經習慣的開發模式。打個比方說,策劃先行,然后召集大家討論策劃案,之后得出程序和美術的工作量再定義出里程碑擬訂好開發計劃,然后大家開始正式分頭動工。在這個開發流程中,開發人員面臨的最大困難是策劃案也就是需求的變化量非常大,并且這種變更,很大一部分情況可能是直到里程碑快結束的時候,大家才一起意識到有些功能壓根就無法實現或者勉強實現的效果并不理想。這時似乎只剩下修改策劃案這一條路。于是大家對于無論如何嚴格的審核策劃案,到中途總是會以這樣那樣的理由變更的情況已經習以為常。因為需求變更而導致產品推出時間可能一推再推,以至于最后不得不砍掉一些功能才能確保產品在可以接受的時間之內被推出。
盡管傳統的開發方式可能有些地方老是出問題,但大多數情況下大家也會比較傾向于下次注意點,而不是嘗試一套新的開發方法。在MMO的開發模式的選擇上,Scrum在許多地方的確可以解決傳統模式所遇到的問題,比如Scrum能在擁抱變化這一點上極大的幫助開發者。類似這樣的優點,在Scrum的擁護派看來,可以列出好幾頁來。但是,要說服一個原有的團隊選擇一種新的開發模式來代替大家已經熟悉的方式,光列舉優點是不夠的,我們也需要直面Scrum與現有模式的其他差別,有些甚至是Scrum的劣勢。
1. 每次提交可運行的版本
Scrum的精髓在于擁抱變化,并強調通過頻繁的交付來獲得及時的反饋,以便于盡可能快的調整不合理的需求。但對于某些大型MMO而言,比如MMORPG,系統的復雜度往往超出我們的想象。如果沒有一款已經使用過的引擎,光是前期對低層技術的開發就是一個漫長的過程,如果采取Scrum的方式,要求每一小段時間提供一個可運行的版本無疑是一個噩夢。而對于同時進行的策劃案的撰寫,要求提供一個反應策劃內容的版本更是困難。Scrum在這個階段如何開展,是需要克服的一個問題。
2. Sprint的劃分
相對于傳統的基于里程碑的開發,Scrum要求劃分出一個個相對較短的Sprint。并且每個Sprint需要有可以提交的版本,以及一個比較明確的可以體驗的目標。而在MMO的開發中許多工作,比如系統架構設計,數據庫設計,美術概念討論等都很難在Sprint中體現出來,也就無法通過Sprint Review的形式獲得反饋。但是這些東西又跟所有的人的工作息息相關。Scrum如何在能夠保持緊密溝通的同時,對類似的相對獨立的部分也照顧周全?
3. Scrum的管理
Scrum是一個強調自我管理的開發方式。無論是Stand Up Meeting還是Sprint Planning的時候都要求少干涉多聆聽。對于項目經理來說,某些時候參與感很差,總是好像找不到自己在團隊中合適的位置。但是項目經理又不得不對進度負責,面對各個并行的小組,每天都可能有大量新的task提出,又有大量task被否決,如果你這個時候去問項目經理“我們到底能不能按時完成,如果推遲,那還需要多久”這樣的問題的話,他也許只能對你搖搖頭。我們在使用Scrum的時候,進度管理上的缺失也是我們需要直接面對的問題。
類似的問題,在我們推廣Scrum的時候可能會遇到很多。為什么會有如此的問題歸納一下,原因可能如下:
1. Scrum最早來自于軟件工程,雖然現在擴展到開發的各個方面,由于其自身的限制性,注定要面臨許多困難。(筆者曾經聽說過某公司號稱用Scrum進行管理,要求銷售,HR部門都實行Scrum方式,很難想象這是一種怎么樣的Scrum。)
2. MMO開發本身結合了跨平臺,分布式,周期長,變動大等多個開發難題, Scrum能夠很好的解決一些問題,但對需要長期規劃的問題明顯缺乏控制力。
融合:和其光 避其塵
在筆者看來,Scrum是一種優秀的開發方法,許多特征的確證明了它比它的前輩們更好的解決了游戲開發中所遇到的諸多問題。可是,如同它的前輩一樣,Scrum并不是游戲開發中的那顆Sliver Bullet,再次應征了Brooks大師所言。所幸的是,我們可以使用Scrum與傳統開發方式“混血”式執行的辦法,根據自身情況,靈活的選擇有利的方面執行,對不適應的地方進行改進,從而能最大限度的在MMO游戲的開發中發揮出Scrum的威力。
筆者有幸在參與的一些項目中使用過Scrum方法,同樣也經歷了Scrum與本土MMO開發結合時候遭遇的種種尷尬。筆者認為,Scrum對于MMO游戲的開發,有其利也有其弊,對于整體進度的把握以及對于文檔工作的控制Scrum做得并不是十分到位。對于任何一種開發方法論而言,執行團隊都需要從自身實際的條件出發,選擇性的使用。最怕的是盲目執行,暴力式地推行,而其他軟件的工作卻不跟上,執行的團隊并不明其所以,最后可能搞得人人談敏捷而色變,失敗當然是一個必然的結果。筆者始終認為,工具,方法始終是死的,如何使用才是真正出學問的地方,只有從自己實際出發,冷靜分析,在合適的地方用合適的工具,才能做到庖丁解牛,游刃有余。
那么Scrum應該如何結合傳統的MMO開發方式呢?我們從項目開發的各個階段來一一分析,如何讓Scrum發揮自己的威力。
項目前期
項目前期我們面臨的問題有哪些?首先是產品尚未成型,團隊也許對將要制作的產品并沒有一個十分清晰的概念,更談不上對項目規模的預估。其次有一大堆技術性的難題擺在團隊面前。這些難題能否解決,如何解決,都勢必會對策劃案的成型有決定性的影響。這個時候,我們可以分兩頭采取不同的開發模式。
對于將面對的技術難題,這個時候目標明確,團隊規模較小。比較適合采用Scrum的形式一一攻克這些問題。我們可以把大家公認會遇到的難題列舉出來,通過Scrum Planning的形式分解成一個個User Story再劃定各個問題的優先級和互相的依賴關系,然后分別組建Scrum團隊。這個時候的目標很明確,即得到這些難題的解決方案。我們希望在這個階段結束的時候,程序對所要面對的技術問題心中有數,策劃也對哪些能做哪些不能做有一個清楚的認識。同時我們還希望對一些我們必須要克服的東西,在這個階段已經能產生一些行之有效的工作流程。
對于Scrum小組的組建,這個階段我們可以以程序為主,策劃和美術作為某些User Story的Customer,負責對程序工作成果的審查。為避免過早的陷入需求更改的陷阱,這個時候策劃除了驗收成果之外,不應過多的干涉程序實現的方法,而僅僅在設計User Story的時候提出自己的意見(事實上很多User Story應該由策劃和美術直接提出)。在Sprint的劃分上,我們可以以2~4周的標準劃分。盡量將這個階段控制在2~4個Sprint之內(這取決于團隊的大小和技術基礎)。對于一些經過驗證存在困難的User Story可以在每個Sprint Review結束后的Planning Meeting上經大家討論做少許更改,讓下一個Sprint向更接近我們的目標(切實可行的解決方案)的方向上前進。對于Scrum的范圍,筆者建議盡量不涉及高耦合的工作,將涉及多個方面的User Story拆分成相對獨立的部分再分頭進行。舉個例子來說,可以將服務器端和客戶端的技術難題分開進行,對于涉及服務器端和客戶端交互的功能再單獨提出來作為一個Scrum,盡量保證工作的粒度比較小,減少互相依賴的關系。我們的首要目標是證明技術可行性,這對整個流程的開展有一定的好處。
對于策劃案以及美術風格的概念設計,這個時候則采取較為傳統的方式,由策劃和美術師內部產生。策劃在對程序的Scrum小組提出User Story的同時即提出了自己的疑問,在程序執行Sprint的過程中獲得對自己提出問題的反饋,進而決定自己的策劃案如何撰寫。美術則在這個時候確定美術風格,以及在與程序Scrum小組合作的過程中確定某些美術工作的工作流程。筆者不建議這個時候就加入程序對策劃案進行討論,這也許和某些團隊采取的方式不同。這種方式對策劃和美術的要求較高,既需要向程序的Scrum小組提出User Story,并從審查中獲得反饋;也需要保持設計工作的相對獨立,做好策劃案的前期工作。這需要策劃或美術在前期就對中期可能發生的問題有所預見,向程序有針對性的提出需要測試的地方而不是等待程序來告訴你不可行。如果這個時候能有富有經驗的產品經理或者制作人來負責這兩方面的協調工作,也是一個確保這個過程可以順利進行的有效因素。對于程序美術在前期就加入討論,筆者是持保留意見的。比如曾經經歷過的一個項目就因為太早凍結策劃案以至于美術和程序花了幾天來討論每個UI元素的具體坐標是多少,但最后卻不得不尷尬的面臨因為用戶體驗不友好而更改UI方案的情況。
在這個階段結束的時候,我們應該得到一個策劃案的初稿,起碼完成了整個系統以及世界的架構,可以估計出項目將來在程序,美術和策劃工作上的規模。還應該有幾套行之有效的工作流程,能根據項目的預計規模估計出將要投入的人力和項目需要進行的時間,以便于之后的市場等多項工作的計劃和開展。接著,我們就便可以投入更多資源進入正式開發的階段。
項目中期
在MMO項目中期,我們面對的主要問題是對整體進度的把握,確保能按時推出我們需要的版本。其中面臨最主要的難題就是對需求變更的控制。這個方面Scrum有其決定性的優勢,但如何在高度擁抱變化的同時又不失對進度的把握是Scrum在這個階段所要面臨的問題。筆者建議這個時候需要根據團隊對Scrum的熟悉程度來選擇不同的解決辦法,分別采取以Scrum方式為主導傳統方式為輔的方式,或者反之。
對于一個熟悉Scrum的團隊而言,筆者的建議是在正式開發之前,整個團隊坐在一起,討論策劃案。將策劃案中劃分的各種系統分解為不同階段的User Story,再通過團隊之間的討論以及各組之間的工作配合需要制定出優先級。現在我們有了一大堆由策劃案分解出來的User Story,這些User Story有一定的依賴關系和不同的優先級,這時候根據我們的需要將這些User Story組合成不同的Sprint,再視這些Sprint的目標和內容組合成不同組合,每個組合我們可以視之為一個里程碑。如果你的項目的時間預算非常有限,你可能會傾向于將一些不是很重要但如果不完成其他部門就無法開展工作的User Story先行制作;如果你的時間充裕,你則可能更傾向于先有一個完備的系統設計以及一個方便擴充的靈活架構,讓其他部門暫時等待或者做其他的事情。總之,這一切取決于項目具體的需要和團隊資源,并沒有孰是孰非之分。
由User Story來構建里程碑這對團隊的Scrum能力而言是一個考驗,需要團隊對User Story乃至Sprint的劃分有一定經驗,并且能夠預見整個過程中可能面臨的風險。選擇合適,制定好的,可實現的User Story可以規避很多由于后期Sprint變更時候帶來的連鎖反應。這也是為什么筆者建議有一定Scrum經驗的團隊選用該方法的原因。
對于初次嘗試Scrum的團隊,可以嘗試采取相對保守的方法。通過傳統的方式對策劃案進行技術評估后,劃分出里程碑,然后根據每個里程碑的目標制定User Story,再劃分Sprint。這在一定程度上降低了對User Story制定上的要求。同時在每個Sprint結束的時候根據Sprint完成情況結合里程碑的目標對User Story進行修正。聽起來似乎和上個方式大同小異,但執行過程中可以省略對Sprint篩選和組合的過程,可以說目標更加明確,對嘗試達成這個目標的團隊來說也相對輕松一些。
無論采取什么樣的方式,對于進度的管理上都是需要按照傳統的方式劃分里程碑。這可以方便我們把握項目整體進度,防止由于Sprint過多并且更改過快以至對項目整體進度沒有概念。每個里程碑就像一扇扇保險門,明確里程碑所要達到的目的以后就不再輕易變更,嚴格控制好里程碑中間Sprint的變更范圍。從某種意義上講,這種互相結合的方式能夠有效降低項目中期由于變更過多而造成進度失控的風險。
這個階段的Scrum團隊的組建也不同于項目前期。這時一個Scrum團隊是一個包含程序,美術,策劃乃至市場人員的復合小組。這個階段中的Sprint的之間的變更乃至小組成員的身份的變化也會更加復雜。同一個Sprint中一個User Story的執行者可能是另一個User Story的Customer,需要在開發過程中保持高效的溝通。小組成員也并不是固定不變,在一個Sprint結束之后根據下個Sprint的目標可能組合成不同的小組。比如這2周做NPC交易的小組成員,可能下個Sprint會和其他人組成擺攤系統的Scrum小組。重要的是我們作為一個整體的團隊如何達成每個Sprint的目標,而不是保持單個Scrum小組的獨立性,畢竟靈活性也是Scrum的一大優勢。
這是一個頻繁迭代的階段,也是游戲內容不斷增加和修正的過程,在每個Sprint結束的時候,我們都應該得到一個可以運行的版本用于衡量該Sprint的目標是否達到。策劃要在每個Sprint review之后總結更正自己的設計,美術也隨著一個個Sprint的完成,看到自己的作品一批批導入到游戲中的效果。所有這些都需要建立在團隊成員之間高效的溝通,以及默契的合作之上。這也對團隊的自我管理能力也提出考驗。
在項目中后期,我們會面對成批從QA部門反饋的bug以及為配合市場活動而臨時增加的開發需求。Scrum的靈活性在這個時候可以得到進一步的發揮,隨著投入資源的增多,我們可以對這些工作內容建立單獨的Scrum團隊,用于解決這些瑣碎但龐大的新增需求。別忘了,Scrum是最善于解決目標相對明確的短周期需求。
隨著Sprint的一個個進行,里程碑的一個個完成,我們終于走到項目交付和維護的時候,這個時候我們面對的是單機游戲不曾經歷的維護和運營階段。
項目后期
一個MMO的開發并不隨著產品發行的結束而結束,無休止的維護和資料片的推出是團隊必須要面對的現實。同時團隊人員的更迭也需要在這個時候開始進行。我們慢慢要把原來開發團隊的部分人員抽離出來,以便于開始新的項目。對現有項目的維護和對新加入人員的培訓是我們在項目后期需要面對的主要問題。
項目后期的工作,筆者看來分為兩大類,一是原有系統的BUG,運營商的2次開發需求以及來自于市場或者策劃方面的活動需求,二是并行的資料片開發。先說資料片開發,開發量和內容都基本上相當于項目中期的一個或兩個里程碑,對于Scrum的處理方式可以按照項目開發中期的方式通過復合的Scrum團隊來處理。通常會在版本控制系統中建立一個平行的分支進行開發,值得注意的是需要隨時準備集成對原有版本的改動。對于第一類問題,則通常不會涉及太多原有系統的改動,可以單獨建立程序或者美術+程序的Scrum小組進行有針對性的開發。通常這個時候,進度已經不會再成為壓力,對積累了開發階段Scrum經驗的團隊來說,不會有太大問題。值得一說的是如果不是自主營運,對來自運營方的需求如果要對方來適應Scrum的開發模式可能有點強人所難。好消息是來自運營方的需求并不會像我們可愛的策劃案一樣頻繁變更。Scrum小組定義好一個接口人以后可以仍然按照自己習慣的方式進行開發,把哪些惱人的外部溝通工作扔給接口人吧,這樣可以在一定程度上降低我們溝通的成本。
Scrum的過程控制工具
在使用Scrum的過程中,尤其是周期比較長的項目,對于負責項目進度控制的人來說,整體進度把握和對基礎架構工作的控制都是比較頭痛的問題。這時,有許多工具可以幫助我們對目前的風險和進度有一個清楚的認知。
可交付物件列表(Deliverable Check List)
不同于其他采取Scrum方式進行開發的軟件項目,MMO的開發過程中,文檔還是扮演著相當重要的角色。一個MMO可能產生上萬甚至百萬字的文檔工作量,我們既需要保證開發的高速和靈活,也要保證這些文檔的創建和維護。在項目的各個階段我們需要有一個或者多個可交付物件列表。這個列表可以方便我們跟蹤策劃案,美術工作量,以及諸多程序設計的文檔的制作情況。
列表中的每一項都是一個可提交的物件,每個物件都需要設定相關的負責人,審批人以及預計完成時間。這種列表是傳統開發方式的產物,然后在Scrum進行的過程中,這些物件可以作為一個個User Story分布在各個階段的Sprint中,也可以獨立在Scrum之外。通常這些文檔可以作為某個階段結束的標志,然后再以這些文檔為基礎來做下個Sprint的Planning。通過維護這樣的一個列表,我們可以對一定范圍內的整體工作量有所控制,能夠彌補原本Scrum在這點上的不足。
每天編譯 (Daily Build)
存在著多個并行的Scrum小組就意味著會可能同時存在多個不同的版本。前面建議大家在Scrum過程中盡量將不同Scrum小組目標的耦合度降低正是為了減少系統集成的時間。有不少團隊采取分頭開發,然后在一個約定的時間統一進行系統集成的辦法。然而筆者并不建議采用這種方式,主要原因是隨著分頭開發的持續,各個小組之間并不清楚對方在做什么,代碼上產生的差異會累積下來。等到做系統集成的時候,有時候會被迫面對二者只能取其一或者又要花費大量的時間來修改已經完成的系統的尷尬情況。這個時候,建立一套每天自動編譯最新版本的系統可以幫助你化解這個方面的危機。
這個系統每天會從版本控制系統中更新最新的代碼來編譯一個可運行的版本,并自動做一些簡單的系統測試工作。這里的測試工作相當簡單,往往只要能保證啟動程序或者連上服務器端這樣的基本功能。當編譯出錯或者系統測試無法通過的時候,該系統能夠通知相關人員,從而迫使程序員在上傳代碼的時候做好merge工作。為了合并好代碼,不同的Scrum小組之間也需要經常溝通,以了解對方的工作進展,幫助程序員養成符合Scrum精神的工作習慣。
向下燃燒進度表(Burn down Chart)
對于Sprint與Sprint之間,乃至里程碑與里程碑之間的完成情況,通過Burn down chart這個工具我們可以隨時了解任務的完成情況以及和計劃的偏差。同時Burn down chart也能很好的反映在項目進行過程之中,user story的變更情況。
拿下面的一個burn down chart來說。
這是一個持續了3周的sprint,這個表反應的是在這個sprint過程中所有任務每天的完成情況。這里每天的完成百分比是由從第二天在每日起立會議以后收集到的任務完成情況決定的。我們可以看到在4-28和5-2這兩天的計劃曲線有一個起伏,這是由于當天有新增加的任務,這對我們Sprint review的時候評估這個Sprint的完成情況可以起到參考作用。
其他的比如告示板,索引卡,Sprint Planning等工具和方法,一般的Scrum的書籍都有介紹,筆者在這里就不再一一列舉。筆者主要列舉的是基于MMO的Scrum開發過程各個層面上的簡單進度控制工具,以幫助團隊及早發現風險,并得出應對之策。
推廣Scrum過程中要注意的問題
向一個已經有過開發經驗團隊推廣Scrum的方式并不是一件輕松的事情。沒注意好的話,往往最后流于形勢,不僅團隊的積極性沒有調動起來,甚至會讓人產生反感。
環境的營造
使用一個類似Scrum這樣自組織式的開發方式的時候,需要特別注意的是對于整個Scrum環境的營造。尤其不要流于形式,不然就真的是費力不討好的事情了。筆者遇到的一個很典型的例子是:Sprint Review之前,程序的版本并沒有集成編譯過。于是為了準備Review中需要演示的東西,花了大半天的時間來合并代碼并修改,演示結果可想一般。更糟糕的是,在user story被否決了以后,團隊的積極性受到打擊,對Scrum也頗有微詞。
讓團隊真正理解什么是Scrum并不是簡單跟大家宣讀一下章程這么簡單。持續的培訓和心得交流是一個比較好的辦法,有助于讓團隊了解每一步的意義和目的。同時還要鼓勵大家多溝通交流,在Planning的時候提出自己的想法,多了解同伴的工作情況。不能再像原來一樣各家自掃門前雪。
團隊適應能力
談團隊素質是一個比較尷尬的問題,中國的游戲業畢竟還非常年輕。筆者的一個朋友曾經跟筆者抱怨過,原來嘗試過Scrum方法,但試行了半年之后就放棄了。理由是Scrum太講究團隊的自我管理能力,他的團隊并不能很好的適應這種自我管理的方式,而他的團隊中還不乏有多年經驗的開發人員。筆者的觀點則是團隊的適應能力跟團隊成員的態度有關。我們當然不能苛求所有的團隊成員都有多年的開放經驗,尤其是項目失敗經驗,以便于他們理解Scrum可以幫他們解決多少他們曾經遇到過的問題。同樣,就算有多年經驗,抱著原來的方式不放,覺得這些新東西只是花招式,還不如自己的老三套來得實在也要不得。
團隊是否能很好的適應Scrum方法,跟團隊是否抱著積極開明的學習的態度有關。這在一定程度上也是依賴于團隊內部的環境建設。而團隊成員中參差不齊的素質筆者認為并不是太大的問題,我們并不需要所有人都能夠對任務的規劃和分解深刻把握,團隊成員在這個高度強調溝通的環境中反而成長會更為迅速。
多次交付VS多次迭代
多次迭代并不等于多次交付,這是Scrum常有的一個誤區。在每個Sprint開始的時候,我們都必須要明確這個Sprint結束的時候我們需要Review的是哪些東西。很多時候,如果一個Scrum開展不是很順利,在Sprint Review的時候我們常常會聽到這樣的理由,“因為某些原因,這個功能我沒有辦法展示給你,但是這個功能是有了的,我只需要改動小小一點東西就可以了。”或者是“這個部分與另一個系統相關,我代碼已經寫好了,但我要一起改好了你才可以看到。”如果放任的話,這些理由到后期會泛濫成災。我們所能做的,除了拒絕通過這些相關的User Story之外,在每個Sprint開始的時候還應該幫助團隊了解到我們需要在Sprint Review上看到什么東西。強調我們重視的是可交付的版本,而不是一個口頭上的功能增加。
有些時候這也取決于我們的User Story是否范圍太大太空以至于無法實現。這也對要求我們提出更具體可實現的User Story,否則就需要及時拒絕它或者再細化。
結隊
是否結隊編程這個問題,筆者是持保留意見的。曾經有過一段不太愉快的結隊經歷,雖然不是隨時“面向顯示器編程”但相當時候兩個人坐在一起寫一段代碼是常有的事情。個人認為在兩人沒有達到足夠默契的程度的話,還是不要輕易嘗試結隊開發。而對于Scrum來說,除了結隊,也可以通過buddy check(在提交代碼前交由另一人檢查提交)來確保互相對工作情況的了解。同時前面提到的每天Merge同伴的代碼也是一個幫助團隊成員互相了解工作情況的好機會。
最后
Scrum畢竟是個新東東,大家還正從適應中慢慢了解和熟悉。但從筆者看來,它的確是目前最適合游戲開發的方法論之一。除了能夠從容應對需求的變化之外,他鼓勵溝通的方式也能一定程度上激發團隊的創造力,促進團隊內氣氛。在面對中國式MMO的開發上,靈活的把Scrum和傳統方式相結合,通過不同的工具進行控制,能很好的彌補原來Scrum對長期進度缺乏控制,以及文檔管理缺失的一些劣勢,從而發揮其在需求管理,針對性解決問題上的優勢,更好的解決我們在開發過程中可能會遇到的問題。
posted @
2009-09-09 10:33 暗夜教父 閱讀(322) |
評論 (0) |
編輯 收藏
2009-09-02今天為項目管理部的各個PM介紹了和培訓了Scrum,得到了一致的認可。并同意在接下來的項目中使用Scrum進行實踐。
但同時也提出了一些問題需要解決:
1、如果團隊中存在美工,只有一個美工的時候,美工的工作量如何估算才算合理。程序不知道美工要干什么、要干多少天。同樣美工也不知道程序怎么干。
如何保證美工的工作量估算的合適。
2、一個項目存在策劃、美工、程序三個不同技能的集合,是當做一個團隊、還是當做各自的團隊,還是出去策劃,把美工和程序作為一個團隊。
不過今天的目的是為了說服PM在接下來的工作中使用Scrum,今天得目標已經達到。接著等待項目實踐。
posted @
2009-09-09 10:32 暗夜教父 閱讀(273) |
評論 (0) |
編輯 收藏
版權聲明:轉載時請以超鏈接形式標明文章原始出處和作者信息及本聲明
http://dreamhead.blogbus.com/logs/14189175.html
作為一個有理想、有追求的程序員,你成天被各種名詞包圍著,你對其中一個叫做敏捷的東西特別感興趣,因為它特別強調人的作用,這聽著都讓做程序員的你感到舒服。為了讓自己早日敏捷起來,你從眾多的敏捷實踐中選擇了一個叫做測試驅動開發(Test Driven Development,TDD)的作為你的起始點。因為它對你周遭的環境要求是最低的:它不像結對那樣,要求其他人和你一起合作;也不像采用Story那樣改變你所在團隊的做事方式……你所需要做的,只是在你編寫業務代碼之前,把測試先寫好。這完全是一種潤物細無聲的做法,根本無需告訴你之外的任何人。就在別人忙碌的找bug時,你便開始享受敏捷帶給你的快樂了。順便帶來的好處是,下次在那里和別人爭論敏捷的時候,你可以以一個實踐者的姿態出現,而不是在那里信口開河。
你不會打無準備之仗,于是,你通讀了Kent Beck的那本薄冊子。通讀之下,你對TDD更是充滿了信心。因為“紅——綠——重構”的步驟實在是簡單得令人發指。好吧!總而言之,你已經信心十足的準備開始TDD,步入敏捷的康莊大道了。
理想很美好,現實很殘酷。
當你著手在實際項目中體驗TDD的時候,一切變得并不像最初看起來的那樣美好。雖然你努力的堅持著TDD的原則,但你經常就會發現某些東西不好測,比如你遇到了數據庫,比如你遇到了GUI,比如你遇到了計時器(Timer)。敏捷并非教條,當某些事不可為的時候,你完全可以不那么堅持。于是,你告訴自己,不好測的東西可以不測,這樣,至少從心理上來說,你覺得舒服多了。隨著工作的繼續,你發現,你不能測的東西越來越多,單元測試的覆蓋率隨著開發的進行正在逐漸降低,一絲恐懼涌上心頭。回過頭來,再去看Kent Beck的書,你突然覺得,你似乎被騙了,因為Kent Beck的例子貌似全都是邏輯,如果只是邏輯,當然好測了,但現實從來就不是這樣。
難道TDD只是看上去很美?
顯然,你不愿意就這樣放棄,放棄你苦心學來的軟件開發秘籍,那些傳說中的高手極力推崇的TDD必然有一定道理,TDD確實能夠讓你感覺很好:能測試的那部分代碼確實極大的增強了你對軟件質量的信心,而且出錯了也確實好找,每次修改代碼之后運行測試出現的綠條也確實讓你身心愉悅。
那問題到底出在哪呢?你陷入了沉思。
信馬由韁,你翻開了自己寫過的代碼。看著自己寫的這些代碼,你忽然意識到一個問題,自己遇到的問題并不屬于TDD,而是屬于單元測試。正如你之前所想到的那樣,TDD做法本身的結果是讓你感到快樂的。對,一定是單元測試本身出了問題。那單元測試出了什么問題,很顯然,一大堆不能測試的部分讓單元測試變得很難寫,降低了單元測試的覆蓋度。那是不是這會是一個無解的問題呢?你顯然不愿意就此放棄,所以,順著這個思路繼續向前。
TDD之所以讓你安心,主要是每次編寫代碼之后,運行測試會出現一個綠條,告訴你測試通過。這樣,你可以放心大膽的向前繼續,因為你的代碼并沒有破壞任何東西。究竟是什么讓你感到不安,顯然是那些測試沒有覆蓋到的代碼。你又仔細翻看了一下那些沒有測試覆蓋的代碼,你的思路一下子清晰起來。之所以這部分讓你不安,因為里面除了那些確實不好測試的部分之外,里面還有一些邏輯。如果只是那些真正不好測試的部分沒有被測試覆蓋到,你會覺得心里還有一些安慰。你確定了,真正使你不安的就是與不好測試的代碼共存亡的這些邏輯部分。
如果測試可以覆蓋到這些邏輯的部分,至少從感情上來說,就可以接受了。那怎么才能讓這些部分被測試覆蓋到呢?你仔細觀察著那些沒有測試的代碼,如果這樣做,這個部分就可以測試了,如果那樣做,那個部分也可以測試了,一來二去,這些貌似不可測試的代碼可以分解出許多可以測試的部分。
你的心情一下子好了許多,因為這么做終于可以讓測試的覆蓋度達到讓你心理上可以接受的范圍。不過,新的問題也隨之而來。我在做什么?拆來分去,這不就是設計嗎?怎么走到這里來了。我不是在分析單元測試的問題嗎?對了,我最初的問題是TDD,怎么一路跑到設計上來了?
TDD?設計?
你突然發覺自己對TDD的理解有一些偏差。TDD,并不代表不需要設計。讀過很多書的你突然想起了Robert Martin那本著名的《敏捷軟件開發》,上面有一個關于數據庫訪問的例子。那個例子里面,前后兩個版本的差異正好就是考慮設計的結果。通常,在設計中考慮測試,會很容易找到設計中僵硬的部分,讓程序更加靈活。再進一步,如果在開始動手之前,稍微進行一些設計,這些問題還是可能注意得到的。你突然覺得,正是因為TDD本身過于強調測試的價值所在,讓你忽略軟件開發中很重要的部分:設計。
思路一下子清楚起來,TDD其實不只是“紅——綠——重構”,它還是與設計相關的:在動手之前,還是要有一定的設計,而且,在設計中要考慮測試的問題。終于解開了心中的困惑,現在的你,對于TDD有了一個新的認識,雖然這個認識不見得是什么終極真理,但至少是通過自己的思考得來的,這讓你更加相信實踐出真知的道理。
理清思路后,你更加堅信TDD本身的價值所在,也堅定了在日后開發中繼續使用TDD的念頭,當然,目光遠大的你已經盯上了其它的敏捷實踐。
posted @
2009-09-09 10:32 暗夜教父 閱讀(218) |
評論 (0) |
編輯 收藏
第一步:
安裝DirectX SDK(June 2008)和Microsoft Visual Studio 2005
第二步:
設置DirectX和Visual Studio 2005關聯:
<1> 打開Visual Studio 2005,將D3D需要的Lib 文件目錄在鏈接器中指定路徑。具體步驟是:工具->選項->項目和解決方案->VC++目錄,在右邊“顯示以下內容的目錄”中選擇“包含文件”,加入directx中的Include目錄,我電腦上的該目錄為D:\program files\directx9\Include。添加完Include頭文件后,再
選擇庫文件,加入lib文件,我電腦上的該目錄為D:\program files\directx9\Lib\x86
<2> 打開sdk的sample里面的一個例子,打開時打開.sln文件,引用幾個相關的lib文件,具體步驟是:項目->屬性->配置屬性->鏈接器->輸入,在附加依賴項里面加入下面幾個lib文件:
d3dxof.lib
dxguid.lib
d3dx9d.lib
d3d9.lib
winmm.lib
第三步:
設置好后,就可以執行程序了,調試->開始執行(不調試)。
注: 若出現打不開預編譯頭文件的錯誤,就如下設置:項目->屬性->配置屬性->C/C++->預編譯頭,右邊第一項“創建/使用預編譯頭”選擇“不使用預編譯頭”。
本文來自CSDN博客,轉載請標明出處:http://blog.csdn.net/KEIGOliye/archive/2009/08/24/4479134.aspx
posted @
2009-09-09 10:31 暗夜教父 閱讀(380) |
評論 (0) |
編輯 收藏
[如果你在做游戲時已發現Scrum敏捷開發的價值,專家Clinto Keith向你概述精益和看板,使你在所有游戲開發階段變得敏捷的兩種方法.]
許多游戲團隊發現Scrum的價值后就迅速采用.引入的價值是提高了速度,游戲以一個經常反復的速度提示項目主題.并讓團隊和用戶頻繁地通過改善游戲來相互反應.然而當團隊進入制作階段,發現Scrum的價值減少了.
許多團隊在項目生命周期的晚期放棄了一些Scrum實踐又回到傳統的瀑布實踐方式.他們稱這種方法為”Scrum和瀑布的混合”.這篇文章將解釋背后的原因及引入一些精益制作及看板的概念作為采用瀑布實踐的替代方法.
精益和看板可以回答許多團隊使用Scrum面臨的問題,而且它們不需要團隊放棄敏捷的方法.這些實踐方法基于真實世界的產品制作經驗,它們改進了56%的關卡制作成本.
在游戲業以外的大部分敏捷項目中,沒有開發階段.沒有概念(concept)階段,沒有預制作(pre-production)階段或制作(production)階段.這些項目從發行(release)開始,每個發行發布一個新版本給客戶,比如Firefox這樣的應用程序每一個月左右發行一個新版本。而大部分游戲需要幾年后才拿到一個發行版本。
消除(Eliminating)階段是一個很大的敏捷好處;瀑布階段比如測試階段強迫測試關鍵活動被推遲到項目最后的話,這樣修復臭蟲(fixing bugs)的成本會很高。在項目開始的規劃(planning)階段嘗試創建關于什么功能是有趣的及創建關聯工作的詳細知識。不幸的是最好的知識來自于執行,這就是為什么非常詳細的預先規劃(pre-planning)會失敗。
對于許多游戲,在游戲制作過程中仍然需要分不同階段。有兩大原因:
被交付的無論什么質量的內容有個起碼的底線。 60美元的游戲必須提供8至12小時的游戲。這代表了大部分的開發成本和由游戲性產生的時間。這需要一個預制作階段(pre-production phase )用于發現游戲樂趣及一個制作階段(production phase)用于大規模制作內容,為了8到12個小時的游戲體驗。
發行商有一個投資組合驅動的市場模型。他們的投資制約了游戲的目標.為了獲得發行商的審批(其中包括市場及特許經營/知識產權所有權的審批),開發商在項目開始的概念階段(concept phase)需要創建一個詳細的概念論述。之后開發商不能太偏離整個項目的設想。
預制作可更自由地反復進行創意設計及探索各種可能性。制作期間,我們創建數以千計的資產依賴于我們在預制作階段所發現的經驗教訓。這些資產在制作階段變更會發生成本障礙。
例如,考慮一個團隊在制作一個平臺類型的游戲。平臺游戲(如任天堂的馬里奧系列)挑戰玩家用于開發在變化莫測的環境中的導航技能。制作團隊將創建數以百計的資產取決于角色移動指標,如“角色能跳多高”或“玩家能抓取的最低高度”。制作資產取決于這些指標。
如果這些指標在制作中期被變更,它可能會造成嚴重破壞。例如,如果設計人員變更了角色跳躍高度,數以百計的暗礁或障礙不得不被修改。這可能使在最昂貴的開發階段創建了大量的無用付出。
在預制作階段發現和鎖定這些指標是很關鍵的。這并不意味著我們不能在制作過程中使用敏捷。我們如何才能不改變敏捷。用更適用更漸進式的流程(如精益)代替使用迭代和漸進的流程(如Scrum)
沖刺和制作
資產創造的確定性和順序工作,也不符合沖刺迭代周期。如果我們把制作想象成工廠組裝生產線,那么2到4周迭代周期是沒有意義的。工廠不會每隔四周后空下來再決定將來構建什么東西。
組裝生產線更頻繁的復制產品需要即時逐步改進。完成資產復制的生產線時間成為制作團隊的新節拍.
Scrum任務公告板及制作團隊
沖刺開始時,Scrum團隊將提交一份由他們預估的完整任務集。這些任務集被放在任務公告板上,供每人每天復查。許多任務可以順序工作或并行工作。
如果一個任務在等另一個任務,就可以繼續做其他的任務。有組織的任務執行流程將促進團隊溝通并防止他們停滯。Scrum任務公告板正很好地表示了為了各個沖刺目標,大量在被順序執行的任務。
然而當我們有一長串序列的任務必須按順序完成那么我們失去一些并行執行任務的好處。任務必須按順序完成,工作必須經一個可預見方式的流動,用于確保制作團隊中的許多專家不在等待工作。Scrum任務公告板不能用于表示很長制作流水線的工作流。
Scrum任務公告板用3到4個任務狀態表示
- 還未開始(Not started yet)
- 進行中(In progress)
- 需要審批(Needs approval)
- 完成(Done)
這些在預制作階段足夠了。在任務進行中實際上在不同工種間有許多來回,這是正常的。然而當我們進入制作階段,在游戲中看到一些制作完成的資產之前可能有一個長的任務鏈。例如,出現在游戲中的一個單一關卡需要發生如下的步驟。
這是一個大量任務的簡化及發生在每個游戲關卡制作中的遞交(hand-offs)過程。這個流程中的每個任務在它遞交給下一個前必須發生。
如果在工作流中有一個步驟失敗或延誤,將影響到整個工作流中剩下的其他幾個步驟。讓我們套用一個任務公告板為一組任務:
以上任務公告板告訴我們劇本(script)完成后概念美術(concept art)要在關卡設計前完成審批。立即顯現出一個問題—整個工作流交叉依賴的可見性沒有在任務公告板上被表示出來。也許概念美術審批已被停滯了。
對其它任務這意味著什么?這意味著它們都被延遲了!誰來為延遲買單?正在做調整的人,或許甚至是音頻設計的人。任務公告板主要的好處是給團隊提供他們正在操刀的任務的可見度。在這個案例中工作流因為內部依賴性而失去了可見度。
Scrum任務公告板上表示工作流的另一個問題是:
當第一組任務正在被執行時,后續的工作是什么?音頻設計者在概念美術等待審批時在做什么?
他們可以創造環境的聲音或者一些填充者工作,但這沒有最有效地使用他們的時間。Scrum任務公告板在每個沖刺(Sprint)結束時被清空。制作中,我們不想清空制作線。我們希望能持續地填充,使工作流中的每個人每天有工作做。
那如何在制作階段使用敏捷?
我們需要刪除一些迭代開發特征并在制作期間變得更規范。但我們不想放棄對變更的反應能力,制作從來沒有100%的效率。
我們永遠不能預測每一個潛在的問題。我們有找到大量改善產品的權力直到游戲發賣。因此我們不想完全放棄敏捷。
如果我們設定了固定時間表(schedules)和最后期限(deadlines)。我們希望的最好結果是匹配時間表。無計劃的問題將繼續出現并威脅這些時間表。我們需要的仍然是敏捷實踐;實踐的期望不僅關注變更而且把注意力集中在不斷提高我們制作的資產品質。
精益制作及如何應用
精益開發與制作的根源可追溯到20世紀40年代的豐田(Toyota)。在20世紀90年代,許多汽車制作商和其他制造行業都采用了精益原則的思想。
過去十年中,在不被考慮的傳統制造行業領域,包括軟件開發的許多行業中都看到了它的運用。精益原則集中精力消除浪費,快速發布,增強團隊及全局控制(其他好處—見文章結尾的參考書籍)
我們也可以把這些原則應用到游戲開發。像汽車制造業一樣,在制作中我們有一個長長的工作鏈或工作流,需要一些專家按順序工作。
像汽車制作也一樣,勞動力成本及錯誤是迄今為止最大的成本。我們需要錄用覆蓋”制造線上”所需技能的每個人來提高我們制作及設計能力。汽車業幾十年前發現的,指派生產線上每個人以完成一套固定的任務并沒有達到最好的效果。
平整制作
平整制作是一種精益技術用于減少浪費及理順制作中的波動。這使我們以恒定可預見的節拍創建制作資產。
制作中我們花的大部分時間是無用工(或活動),這些成果不會添加到最終產品。通過我們的努力專注減少這些無用工,我們可以得到一個巨大的生產力的提高。
看板
凡使用Scrum的會使用一個簡單的看板系統。日語中單詞Kan意思是“信號”,ban意思是“卡片”。因此kanban是指“信號卡片”。看板是工作的“牽引系統”。
一張看板卡片是一個觸發行動的信號。看板隨處可見。當你下一次在星巴克喝咖啡時你可以看到一個適當的看板系統!
在Scrum中,每個團隊成員每天基于完成工作在板上“推拉”一張卡片。沒有人在按預定義的節拍推動工作。
我們可以選用一些看板實踐方法,這些用來可視化一個復雜制作流程并讓我們運用精益原則使制作流程盡可能有效率。
平準化(均衡化)公告板
一個平準化公告板是使用卡片來表示工作能力及整個工作流程的價值流的看板系統。
如上所述,當你使用Scrum任務公告板時,你正在使用一個非常簡化的平準化公告板來表示一個3到4個階段的價值流。我們可以通過增加步驟來擴大制作規模,以我們關卡制作的價值流為例:
現在我們有8個狀態用于每個關卡,它們代表了價值流的6個階段及在兩端關卡制作沒有開始和關卡制作完成的兩個狀態。在平準化公告板上旋轉典型的任務流程使之變為狀態。
該公告板在關卡制作中對于工作流程的溝通比Scrum任務公告板更清晰。
應用精益原則
現在我們已經展現了關卡制作的價值流,我們可以開始應用一些精益原則來逐步提高關卡制作。第一步我們需要審視價值流的周期時間。
周期時間是從左邊劇本(script)作業開始到調整階段(Tuning Pass)完成的總共時間。我們的例子,以上一個關卡需要16周的周期時間。通過減少周期時間使我們可以更有效率。
-更快的周期時間意味著更高的生產力。
-東西下線越頻繁,我們就越能解決制作生產線的問題。
-我們可以更容易地找出浪費(無用工)及解決這些問題。
有許多方法用來減少周期時間。第一個方法是通過縮小工作流中工作項規模。對于我們關卡制作的例子來說,我們可以通過把關卡分割成部分或區域。
每個區域大約花12天才能通過價值流—而不是每個關卡16周。因此,我們平準化公告板看上去像以下這樣:
一個平準化公告板顯示了一個區域通過價值流每個階段的過程。在上面的例子中,區域1通過了每個階段并被轉交到結束時最后調整階段。該公告板表現了完美地平衡跨越價值流每一步的工作流。
最初它不會以這種方式發生。在某些列中會出現斷層而在其它列中出現工作堆積,但這樣做:這些問題一旦發生能馬上可見,當我們發現了問題的本質后,就可以開始修復清楚地看到的問題。
如何改善流程
現在我們有一個看板并在運行中,我們必須努力使其盡可能有效。平準化公告板將每天告訴我們,在我們的工作流程中哪里有斷層哪里有工作堆積。我們不僅希望保持平衡而且希望工作流動盡可能迅速。
我們的例子中,如果每個區域需要12天才能通過整個價值流,我們要想方設法減少周期時間直到我們在不犧牲用戶可接受最低水平的品質。
我們有一些工具來改善流程:
- 時間盒
- 平整工作流
- 減少浪費
時間盒
時間盒是每個使用Scrum的開發者工具,一次沖刺是一個2到4周的時間盒。在一次沖刺中我們堅持并且只有我們能提供的功能。這樣的好處是創建一個價值能被加入游戲的可預見的節拍。
在制作中,我們借此又向前邁進了一步。我們在價值流每個階段啟動時間盒。例如,我們可能給音頻設計師10天給一個特定區域添加聲音。這和Scrum任務中不同之處在于音頻設計人員將預估自己的工作并告訴客戶他們愿意的承諾。
在制作中這種變化,因為我們在預制作中了解了給一個區域音頻設計應該需要多少時間。品質變成了你用時間盒資產控制的變量。我們不強迫美術在一個規定時間內滿足一套質量。
輸入是時間盒(我們愿意為這些資產支付的成本),輸出是品質,這是美術在一個限定時間內能提供的。
時間盒資產的關鍵是找到一個正確的時間盒大小。如果你選了一個太短的時間盒,那么品質會有問題。例如,如果高解像度關卡幾何的時間盒設定為一天,那美術將給我們一個用沒有貼圖的方塊填充的關卡!這肯定比用戶想要的品質低。
另一方面,如果給區域的時間盒是2個月,我們最終可能會是一個到處錯綜復雜的詳細幾何區域。這絕對是漂亮的,但對用戶來說帶來的成本太高了。這是用戶(Scrum中產品擁有者)的工作以創建的制作資產來對投資回報率(ROI)負責。
產品擁有者必須考慮玩家對游戲資產的期望。當我工作在一個開車游戲時,我會告訴我們的美術要把重點放在決策“90英里每小時的藝術”。質量條應基于玩家在全速駕駛看到的設置。如果我們陷入40小時創建一個完美的滅火器,這額外的成本將在玩家以90英里每小時穿過時被浪費!
產品擁有者必須始終在他腦子里保持成本/價值曲線。
以上表示用戶價值不是直接反映創建資產的成本.當你在資產(如方塊堆成的城市)上花太少投入,用戶價值就會太低.玩家可能會注意到路邊假裝消防栓的黃色方塊.
超過一定成本,投資回報也將會減少(如在一個開車游戲做一個1000面的消防栓).我們不是把品質關聯到成本.而是用戶價值關聯到我們付出的努力.我們不想”給想要巨無霸的用戶提供魚子醬”.
平整工作流
時間盒使我們錄用一個非常強大的看板.每列的卡片表示價值流每個階段的工作能力.正如我們以上所看到的,每個階段一次只能處理一個區域.這就是每個階段的工作能力,如果我們在每個階段只有一個人在工作.
時間盒是為價值流開始尋找平衡的工作流程的第一步.然而存在一個問題,在這個流程中每個階段的付出需要是不同長度的時間盒.這可能導致工作斷層和堆積.
例如,如果我們的關卡設計師一周內布局了一個關卡,但高解析度美術師需要兩周,那么對高解像度美術可能有許多工作堆積.反之,如果原畫設計師需要2周完成每個區域的原畫美術,那關卡設計師可能正在等工作,無事可做:
我們必須找到方法來平衡工作流,使每個人每天有事可做.一個方法是平衡每個階段的付出以實現整個系統同樣的工作流程.
例如,如果我們想使一個區域在10天內通過工作流程,我們開始尋找團隊每個成員工作每個階段的時間盒的付出
階段(Stage)
每區域人天(People days per zone)
劇本(Script)
5 days
概念(Concept)
10 days
關卡設計(Level design)
20 days
高解像度美術(Hi-res art)
30 days
音頻設計(Audio design)
10 days
調整階段(Tuning pass)
7 days
概念美術師和音頻設計師需要10天,每區域10天很符合我們的周期時間.然而其它幾個階段需要的時間是不同的.劇本和調整要低于每階段10天.劇本作家也許必須幫助兩個團隊.在調整階段的設計人員可以幫助關卡設計或甚至測試.
對那些超過每區域10天的階段,我們需要開始加人用并行來縮短時間.例如,我們可以增加第二個關卡設計師.兩個關卡設計師可能有效地在10天內完成一個區域.
由于高解像度美術師需要每區域30天,我們也許必須用3個高解像度來平衡我們的工作流.有三種不同方法用于加人來解決問題
1. 多個高解像度美術師可以同時工作在同一個區域.
2. 細分高解像度階段為更詳細的特定工作流程(如貼圖美術,道具美術,靜態幾何美術)
3. 多個高解像度美術師并行工作在不同區域.
所有這些方案工作在不同情況下的.方案1不是最好的因為我們的關卡編輯工具不支持同時在一個區域編輯.方案2不是最好的是因為這個特定的工作流也不是平衡的.
而且我們已經完成大部分貼圖和道具.我們選擇方案3.每個高解像度美術師仍然需要每區域30天,但工作被錯開使整個高解像度工作在每10天完成.
我們的平準化公告板看上去如下:
每個人有一個區域的制作能力.通過增加關卡設計師和高解像度美術師,我們可以在每個階段添加更多的卡片,因為我們需要加更多的制作能力.
我們現在設立了一個時鐘頻率,它是對關卡制作的每個階段是相同的.這個時鐘頻率(我們的例子中是10天)被稱為”節拍時間”.通過維護甚至改善整個價值流的節拍時間,我們平整制作及真正有效改善我們解決的浪費.
減少浪費
我們可能很高興地在這里止步了.我們已經有一個適度平衡及可預見的制作流水線.許多開發商將滿足現狀.然而精益制作的工具使我們可以走得更遠!
首先精益的原則是減少浪費.我們已解決許多在設立平準化公告板后標記出來的浪費,但我想強調一些其它特別針對游戲制作的方面.
許多這些浪費可以被團隊自己標記和糾正.這是理想的消除浪費方法.主要的工具是時間盒.時間盒在團隊找方法使其更有效時將產生微妙的壓力.在我們上述例子中,我們確定一個周期時間是10天及平衡整個工作流來改善效率.
當產品所有者要求團隊減少周期時間到9天會發生什么事?我們將失去10%的資產價值.令人驚訝的是我們不.第一反應是緊縮周期時間,如果對團隊來說消除效率低下的工作方法.
讓我們使用一個真實的例子.一個制作項目,在關卡制作中區域制作的周期時間是10天.當他們想減少20%的周期時間,他們面臨了一些瓶頸.
最大的瓶頸是概念設計階段.他們只有一個可用的原畫美樹師,并且該原畫美術師和其它原畫美術師坐在一起.該原畫美術師花10天來給每個區域創建十來個圖紙.沒有其它方法使更快地獲得這些原畫圖紙.
在小組討論中抖出關卡設計師和高解像度美術師并沒有真的需要所有這些圖紙.因為原畫設計師是個分離的團隊,許多概念設計是基于錯誤的假設.概念美術師不喜歡聽到他大部分工作被忽略.
方案是把這個概念美術師移到關卡設計師和高解像度美術師的旁邊.這樣讓他們討論設計圖及正在完成工作的質量條.因此,少得多的圖紙,這需要加以創造及實際改善最終產品.
這是一個工作遞交產生浪費的例子(由精益原則定義的7個浪費之一).文檔是一個移交浪費主要源頭.文檔的作用是記錄知識.但它不能代替面對面的交談.通過在工作流每個移交處使用這種方法,該團隊在跨越每個階段時同樣可以節省時間.團隊座位區應根據平準化公告板本身重新安排.
在上述例子中,團隊從16周制作一個關卡變為每周制作一個區域,每個關卡7個區域,最終的改善是關卡制作的成本改進了56%.
改善品質
注重品質是精益制作的原則.精益制作是最大限度地減少價值流中每個階段無需完成的工作.這使得變更被引入的更頻繁,因為這將無用組件的債務保持很低.
這是豐田等汽車公司提高汽車品質并主導市場的關鍵.如果你在汽車生產部分發現一個缺陷,它將很容易引入一個改進部分當沒有大量舊零件在庫存時.
這個理念也可以轉化到裝配線.在豐田工廠車間,如果任何一個裝配線工人看到有缺陷的車他就會按下附近的一個大按鈕.如果那個問題不能在隨后的20分鐘內修復的話,整個工廠裝配線馬上停止直到問題被修復.這對品質的貢獻是其它公司所不能比擬的,通過使用精益制作原則使之成為可能.
此外,我們通過整理完成制作的批次來減少周期時間.我們改進了迭代的周期.用我們的例子,我們可以每周玩到完成的區域像他們”復制出制作流水線”
我們不必等16周,整個關卡完成后才能玩.這一周的循環使我們更快地體驗關卡并在我們決定花許多時間來創建關卡區域的剩余工作前引入變更.
如果我們并行建造所有的關卡而且直到工作完成了90%后才發現問題(如渲染或內存預算或游戲性品質)我們將要面對不得不拋棄已完成的大量工作或者發賣低品質的工作以滿足最后期限.汽車企業當它們決定扔掉庫存中大量有缺陷的部件,也是同樣的問題.
外包
外包在資產制作中有其好處和地位.然而許多工作室已發現外包限制了迭代的次數,這些發生在創建大量資產如關鍵角色或關卡.有限迭代會影響到品質或引入昂貴的返工,這些限制了外包的成本收益.
精益制作方式演變成和外部供應商一起工作.這些對制造業如汽車制造都是必不可少的.供應商成為精益制作公司必須要自己變得精益.和精益供應商不同的關鍵是他們給主要制作線提供小批量零件.這樣做是為了以較低成本提高品質
如何轉化到游戲制作?我們的例子,我們不想外包整個價值流.關鍵是外包整個價值流中不需要高技能的部分,高技能部分就留給自己做.一般在關卡制作中,你想在工作室內能夠保持大的任務布局而且外包也是被用于布局中的幾個部分.
這個例子是一般整個關卡的環境集或資產集合.如果你在創建一個大城市的關卡,你將外包所有的小物如燈箱海報,油箱,車輛,建筑構件,背景音樂等等.這些環境集將被帶進設計圖階段(高解像度美術和音頻設計).這可以讓他們在自己的工作室繼續設計圖迭代.
我們外包的關卡制作價值流如下:
外包資產在早期關卡概念開發階段被確定給外包足夠的交貨期.許多設計工具支持異步引入外包組件.一個例子是Unreal Engine 3編輯器.數據包系統可以用代理資產,這些可以被一次自動替換整個游戲資產的所有實例.
如果其他團隊仍在使用Scrum?
制作期間,不是所有的迭代都沒有用.團隊仍然在不影響制作的領域進行游戲創新.對這些團隊沖刺仍然是有價值的.這些組如何和使用看板的組一起工作?
Scrum團隊仍然可以使用看板驅動制作.如果我們在一個4周沖刺內有一周的周期時間,制作團隊仍然可以顯示每沖刺4個周期的審查結果.制作團隊不必作沖刺計劃,但他們仍然需要定期回顧.另外每日Scrum對制作隊員仍然是個有用的實踐.仍然會出現障礙這需要由團隊解決.
結論
逐步地使用這些實踐方法來創建關卡資產.制作一個簡單游戲關卡的成本從16周變成了7周(7個區域*1周/區域).這表示改進了創建一個關卡成本的56%并且只需非常簡單的工具或技術就能達到.
這只是一個開始.精益制作表明改進可以用外包代替或擴充工作室可能想自己做的大量關鍵資產工作的外包需求。
像Scrum一樣,采用并精益實踐要根據你自己的環境進行調整.關鍵是獲取過程的可見度并創建有意義的指標.時間盒資產創建是有挑戰的.大部分美術人員在工作中沒有把品質作為一個變量考慮.產品所有者的關鍵作用將其遠景不僅是最終的產品也要有責任控制投資回報率.
本文來自CSDN博客,轉載請標明出處:http://blog.csdn.net/Guo_zanhua/archive/2008/11/17/3321368.aspx
posted @
2009-09-09 10:30 暗夜教父 閱讀(430) |
評論 (0) |
編輯 收藏