[心得] 容易被遺忘的遊戲設計模組(3)
作者:NDark
時間﹔201001
http://wp.me/pBAPd-a4
"容易被遺忘的遊戲設計模組"之三:Resource/Stage Paragraphing
http://blog.zhieng.com/wp-content/uploads/2009/10/warcfrat_loading.jpg

我想大家都看過進遊戲之前,或是從遊戲大廳進入戰鬥時的讀取狀態跟讀取條。
不知道有沒有人想過,為什麼不在程式開始的時候就把所有東西讀進來。
這樣遊戲過程不就不用等待了嗎?
也許這個問題太笨了。
OK,
以關卡制為例,我們不用在第一關開始的時候就把第二關的場景讀進來。
(這樣做造成了第一關開始要讀入的資料變少了。只是把資料讀取延後到第二關。)
以MMORPG為例,還沒有跨到下一區的時候也沒必要讀入那一區的場景。
因為那對於主記憶體都是一個浪費,
不如把資源省下來給目前正在使用的場景讓他有更多的多樣性。
一定有人想過MMORPG在快接近第二區的時候就開始偷偷預先讀資料的設計。
避免遊戲中的停頓是非常重要的設計,
有時候差那個幾秒,對使用者來說就會累積不耐煩。
因此有些人在讀取資料的時候用動畫,用讀取條來"安慰"使用者。
或是先讀入小部分的資料,用預先設計好的即時動畫,或飛覽來讓使用者再多等一下。
這邊不是要討論如何製造這些安慰劑。
而是用幾個事實說明分段的重要性。
.如果把資料全部在一開始讀入,那麼程式開始可能要讀10分鐘。這恐怕是個災難。
但是如果分成3分3分4分讀入,使用者也許就能接受。
.只讓主記憶體塞滿目前要用的資料為目標,那麼這空間就很可觀,
可以讓你的場景豐富起來。意思是同一時間能呈現的多變性夠多。
.資源是有限的,讓盡量多的使用者的電腦都能玩是一件重要的事情。
無論使用者的主記憶體與顯示卡有多low。
確認了分段的重要性
那麼,確實來說要怎麼分段?
大部分的遊戲都包含這樣的結構
主選單模式:還沒進入遊戲,大部分是讓你選擇要繼續上次的進度還是新遊戲。
資源與遊戲模式是幾乎豪無相關。
遊戲模式:主要的場景,大部分的遊戲時間在的模式。
戰場模式:或是次遊戲模式,從主遊戲切換至的遊戲模式,
場景與主遊戲不相關,但是資料是相關的。
註:有時會只分兩段,也就是主選單-遊戲
因此我們的遊戲應該怎麼執行?
1)-讀取主選單的資源-主選單模式-釋放主選單的資源-進入2
2)-讀取遊戲模式的資源-遊戲模式-釋放遊戲模式的資源-進入1/3
3)-讀取戰場模式的資源-戰場模式-釋放戰場模式的資源-回到2
延伸思考
如果考量到"安慰劑"的話上面的狀況會變成怎樣?
意思是在真的開始大量讀取資源之前一定有一些事情要作吧。
註:這邊我定義的資源與資料有點不太一樣。應該不用我多作說明了吧。
到此所討論的東西我把他稱之為Resource Paragraphing,
主要是為了資源分配最大化(後述)為考量的。
我在沙漠商旅C的時候用的stage稍微細一點,分別是:
system initalization:程式開始,將遊戲系統初始化中,把主選單的資源讀進來。
system pre-main menu:遊戲系統已經讀入了基本的元件,或是已經初始化完畢。
在主選單前會有一些必要的東西。
請思考一下這段使用者看到什麼。
main menu:主選單,舉凡列出讀檔清單與新遊戲挑選角色。
load level:讀取關卡資源,開始進入遊戲模式了。
game starting:遊戲開始中。
game playing:遊戲進行中,請思考一下跟starting有什麼不一樣。
load battle:讀取戰場資源,進入戰場模式
game battling:遊戲戰鬥中。
back to play:自戰場回到遊戲模式。這是第二種進入遊戲模式的方法。
back to main:自遊戲模式回到主選單。大量的資源被釋放了,
這是第二種進入主選單模式的方法。
pausing:暫停狀態。
exiting:從主選單或是從任何狀態離開程式的時候,連遊戲系統的物件都被釋放了。
延伸思考
暫停狀態是什麼暫停了?什麼沒暫停?
如果主選單太久沒動作會自動播放動畫,那麼要怎麼修改?
戰鬥之後的結算畫面應該是哪個stage?或是額外的stage?
註:沙漠商旅C的結構是
平台程式承載遊戲系統物件 遊戲系統物件再承載遊戲資料如圖:
http://ndark.files.wordpress.com/2010/01/caravaneerclone-system-graph.jpg

但平台程式負責將遊戲資料繪出
且平台程式負責互動處理。恩...大概很像是MVC的架構。
(沒聽過這個的後述)
註:這些分段如果大部分的遊戲都存在這樣的設計,
是否我們可以在每個遊戲設計專案開始之初建立一個架構?
這也是我寫這幾篇文章的起始動機。
曾經有位非遊戲界的軟體工程師問我,multi-thread在遊戲程式設計中有沒有用。
我回答他:"有用,但不是最重要的。因為遊戲設計開始之初,都是單執行緒的。"
當然隨著時代進步,開始有多工軟硬體環境(如Sony PS3就是多工硬體),
但是那都是加強運算的能力,而非加強遊戲程式設計的本質。
我們接下來都先假設我們只有單執行緒。
再進一步討論之前,
我要先介紹codeproject.com的一篇文章。
SK Genius 的 "Game Programming - One"
http://www.codeproject.com/KB/game/skgameone.aspx
他介紹了一個十分簡單卻重要的遊戲流程。
請翻到"It's All About Timing"下方的程式碼。
我們可以看到,在一個單執行緒的流程中,遊戲是一直反覆著在作相同的幾個步驟。
GetInput()
PerformLogic()
DrawGraphics()
這三步驟基本上涵蓋了遊戲程式設計的主要工作:控制,資料/流程,繪圖
也就是Control,Model,View。
(與一般視窗軟體不同的是,
遊戲進行中即使不輸入,流程本身也是一直在進行控制=改變的。)
當然複雜一點的遊戲流程會作比較多的步驟。以沙漠商旅C為例,依序為
1.FPS計算,
2.網路處理(未完成預留),
3.3D動畫(未完成預留),
4.更新位置,
5.2D動畫(未完成預留),
6.輸入事件,
7.碰撞偵測,
8.環境變化(讀檔,遊戲事件處理,更新3D視野,更新2D選單),
9.人工智能,
10.繪圖前處理(未完成預留),
11.繪圖(設定3D視野,畫3D物件,設定平面視野,畫2D選單)
註:這些流程的順序當然並非一定得這樣排,而且一定可以找到更好的排法。
很希望未來有機會可以跟各位討論這個問題。
因此,我們有主要流程,每個畫格都作一樣的事情-執行了1,2,3...的步驟流程。
再加上還有一開始討論的stage,就是不同的階段下我們的流程應該作不同的事情。
那麼這兩個該怎麼組合在一起?
最Naive的做法當然就是把各個階段當作不同的遊戲,甚至是不同的程式。
畢竟它們的流程是真的不一樣。因此這樣的主流程會像這樣:
-以Stage(階段)為經,以Process(流程)為緯
MainLoop
{
switch( StageNow )
{
case system initalization :
GameLoopSysInit() ;
case game playing :
GameLoopGamePlaying() ;
...
}
}
但是,
我們會發現其實每個階段中都會有相同的工作要作,
這一種方式簡直就是把同樣的事情重複作好幾次。完全不符合程式設計偷懶的本質。
因此接下來我們就要跟各位討論本篇主題的第二個部分Stage Paragraphing。
-以Process(流程)為經,以Stage(階段)為緯
我們的流程變成這樣
MainLoop
{
InputHandling() ;
...
EnvironmentChanging() ;
...
DisplayMain()
}
MainLoop裡面的各子函式就都可以變成這種形式
(*)SubFunc()
{
switch( stage )
{
case game playing :
...
break ;
case game battling :
...
break ;
}
}
這樣作的好處是有時候 相同的流程可以用在不同的階段。
譬如說
主選單模式的stage,遊戲模式的stage,與戰場模式的stage都有畫選單的流程
而且這些流程基本上是做相同的事情-畫出目前需要的選單。
因此在畫選單函式就可以合併成這樣。
RenderMenu
{
switch( stage )
{
case main menu :
case game playing :
case game battling :
DrawAllValidMenu() ;
break ;
}
}
壞處是,結構改變的時候,
a) 當原本合併的兩個stage要分開,或是
b) 原先沒有必要進行因此忽略的stage突然需要,卻忘記修正這個分段結構。
就會造成除錯的風險。(A)
簡單來講,如果開發團隊沒辦法完全掌控好這結構就容易造成維護上的困擾。
分段結構造成的影響是
a) 極大化同樣的程式-若是相近的流程運作,卻因為小處的不同而刻了兩段類似的程式
,反而會造成未來維護上的更大危機。
b) 強迫遊戲開發者去開發通用(robust)的元件,來符合這個分段結構。
註:這邊的"更大"指得是相較於上述(A) "忘記修正這個分段結構"
講了這麼多,最後作總結。
雖然有點抽象,但請試著想像一下
一個好的分段就像一個"壓縮率"的比例,同時壓縮資源/程式碼/風險
這個分段的做法保持了一個原則:
"將相同的事情變成同一件事,將不同的事情盡量分開"。
(剛好符合程式設計模式的大概念。)
假設優秀的分段可以讓效能發揮到0.3的壓縮率。
而沒有分段時壓縮率為1.0。
當硬體進步時100分的硬體等於塞進了100個未壓縮的物體
有分段的結構就是塞進了100/0.3=333個物體。
當硬體效能1000的時候,比值就是 1000比3333
高壓縮率的設計方式可以讓在同等硬體平台同樣的人力工時運作"開發"這件事情的時候,
獲得超越對手的(虛擬)硬體/遊戲內容。
這聽起來既模糊又顯而易見。
事實上就是一個永無止盡的軍備競賽-遊戲開發工廠的輸入與輸出。
輸入的是code或是PG的工時,輸出的是遊戲效能。
質的改變最終造成量的改變。
--
"May the Balance be with U"(願平衡與你同在)
視窗介面遊戲設計教學( http://0rz.tw/V28It ),討論,分享。歡迎來信。
視窗程式設計(Windows CLR Form)遊戲架構設計(Game Application Framework)
遊戲工具設計(Game App. Tool Design )
電腦圖學架構及研究(Computer Graphics)論文代讀(含投影片製作)
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 140.96.77.176
※ 編輯: NDark 來自: 140.96.77.176 (02/05 18:20)
※ 編輯: NDark 來自: 140.96.77.176 (02/05 18:20)
推
02/05 18:34, , 1F
02/05 18:34, 1F
推
02/05 18:56, , 2F
02/05 18:56, 2F
推
02/05 19:08, , 3F
02/05 19:08, 3F
推
02/05 20:23, , 4F
02/05 20:23, 4F
推
02/05 21:01, , 5F
02/05 21:01, 5F
推
02/05 21:02, , 6F
02/05 21:02, 6F
推
02/05 21:11, , 7F
02/05 21:11, 7F
→
02/05 22:20, , 8F
02/05 22:20, 8F
推
02/06 12:34, , 9F
02/06 12:34, 9F
→
02/08 02:27, , 10F
02/08 02:27, 10F
推
03/11 19:47, , 11F
03/11 19:47, 11F
GameDesign 近期熱門文章
PTT遊戲區 即時熱門文章
10
39