<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>猴子靈藥 [Monkey Potion] &#187; 開發日誌</title>
	<atom:link href="http://blog.monkeypotion.net/category/gamedev/journal/feed" rel="self" type="application/rss+xml" />
	<link>http://blog.monkeypotion.net</link>
	<description>遊戲開發‧遊戲程式‧遊戲設計</description>
	<lastBuildDate>Mon, 06 Sep 2010 01:52:21 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>遊戲開發日誌：水晶守護者</title>
		<link>http://blog.monkeypotion.net/gamedev/journal/dev-journal-of-crystal-guardian</link>
		<comments>http://blog.monkeypotion.net/gamedev/journal/dev-journal-of-crystal-guardian#comments</comments>
		<pubDate>Wed, 21 Jan 2009 16:25:58 +0000</pubDate>
		<dc:creator>半路</dc:creator>
				<category><![CDATA[開發日誌]]></category>

		<guid isPermaLink="false">http://blog.monkeypotion.net/?p=173</guid>
		<description><![CDATA[這是《Crystal Guardian》的遊戲設計草稿。 其實大約在四個月前，我就已經完成了遊戲的基礎設計，本來想要在 NDS 平台上嘗試製作這款小小的遊戲原型，不過後來因為被其他有趣的事情吸引，再加上我一直找不到能夠在 Homebrew 套件上執行 Lua 的方法，所以也就沒有往 NDS 的方向繼續發展下去了。直到兩個月前，在玩過「咕世界」並且讀了「How to Prototype a Game in Under 7 Days」一文之後，內心深處那股「無論如何都想要做遊戲」的雄雄烈火，又再度燃燒了起來！ 一開始在做遊戲設計的靈感發想時，對於目前網路上各種動作過關類型的小遊戲，可以看到大多數作品都是以「攻擊」、「毀滅」或者「破壞」當作遊戲的主要題材與樂趣元素。而我想要嘗試的，則是完全相反的方向。我反問自己：「有沒有可能以『保護』或者『防衛』的概念，做為遊戲的主要機制？」 當然，現在有許許多多 Tower Defence 類型的遊戲，但是我想做的並不是這種玩法的遊戲。我想做的遊戲，設計概念與核心機制的出發點在於「防護」(Defence)，或許是保護金銀財寶、捍衛重要的東西或者心愛的人，無論那是什麼，我認為世界上總有些值得我們守護的人、事、物以及價值。而至於遊戲的操作方式，我想嘗試的方向，是一個不用動腦思考，只需要不停移動並且點擊滑鼠就能夠進行的遊戲。 按照遊戲原型開發文章裡的做法，我原先預估的開發時程為 10 天整。直到正式開始動工之後，馬上就發現每天的開發時間，實在是超級無敵不夠用，才剛做出了點東西就花費掉一整個晚上，依照這樣的進度，10 天左右肯定無法完成遊戲，於是決定將開發時程延長為 14 天。結果，最終在燃燒小宇宙與睡眠時間的狂暴化狀態下，還是延遲了 2 天，整整用了 16 天才完成這款小遊戲。 雖然遊戲的核心機制很早就已經建立完畢，但是 Game Theme（遊戲題材）卻一直處於懸而未決的狀態。原因是「遊戲題材」與「遊戲素材」具有非常高的相依性，在找不到美術設計者合作，我自己也不會畫圖的情形下，想要對遊戲題材拍板定案，實在是一項相當困難而又不切實際的想法。 以後見之明來看，如果當初能夠使用 Flash 做為製作工具的話，應該可以節省不少開發基礎遊戲元件所花費的時間。但是我對 Flash 的熟悉度，差不多停留在讓矩形移動與變大變小的程度而已，所以最終還是毫無懸念地決定使用我最熟悉的 C++ 與 Lua 製作遊戲。 而這次開發的成果，並不是完全從零到有產生出來的。我原先已經有一個小小的遊戲程式框架 (Framework)，曾用來製作過一個 2D 遊戲的半成品，其中的功能只有非常基本的 Graphics、Audio、Input、Script 與 Debug 功能。於是我就以這個 Framework [...]]]></description>
			<content:encoded><![CDATA[<div id="attachment_1154" class="wp-caption aligncenter" style="width: 500px"><img src="http://blog.monkeypotion.net/wp-content/uploads/2009/01/crystal-guardian-draft.jpg" alt="crystal-guardian-draft" title="crystal-guardian-draft" width="490" height="367" class="size-full wp-image-1154" /><p class="wp-caption-text">《Crystal Guardian》Design Draft</p></div>
<p>這是<a href="http://blog.monkeypotion.net/game/crystal-guardian">《Crystal Guardian》</a>的遊戲設計草稿。</p>
<p>其實大約在四個月前，我就已經完成了遊戲的基礎設計，本來想要在 NDS 平台上嘗試製作這款小小的遊戲原型，不過後來因為被其他有趣的事情吸引，再加上我一直找不到能夠在 Homebrew 套件上執行 Lua 的方法，所以也就沒有往 NDS 的方向繼續發展下去了。直到兩個月前，在玩過<a href="http://blog.monkeypotion.net/gamedesign/case/world-of-goo">「咕世界」</a>並且讀了<a href="http://www.gamasutra.com/features/20051026/gabler_01.shtml">「How to Prototype a Game in Under 7 Days」</a>一文之後，<strong>內心深處那股「無論如何都想要做遊戲」的雄雄烈火，又再度燃燒了起來！</strong></p>
<p>一開始在做遊戲設計的靈感發想時，對於目前網路上各種動作過關類型的小遊戲，可以看到大多數作品都是以「攻擊」、「毀滅」或者「破壞」當作遊戲的主要題材與樂趣元素。而我想要嘗試的，則是完全相反的方向。我反問自己：<strong>「有沒有可能以『保護』或者『防衛』的概念，做為遊戲的主要機制？」</strong></p>
<p>當然，現在有許許多多 Tower Defence 類型的遊戲，但是我想做的並不是這種玩法的遊戲。我想做的遊戲，設計概念與核心機制的出發點在於「防護」(Defence)，或許是保護金銀財寶、捍衛重要的東西或者心愛的人，無論那是什麼，<strong>我認為世界上總有些值得我們守護的人、事、物以及價值</strong>。而至於遊戲的操作方式，我想嘗試的方向，是一個不用動腦思考，只需要不停移動並且點擊滑鼠就能夠進行的遊戲。</p>
<p><span id="more-173"></span></p>
<p>按照遊戲原型開發文章裡的做法，我原先預估的開發時程為 10 天整。直到正式開始動工之後，馬上就發現每天的開發時間，實在是超級無敵不夠用，才剛做出了點東西就花費掉一整個晚上，依照這樣的進度，10 天左右肯定無法完成遊戲，於是決定將開發時程延長為 14 天。結果，最終在燃燒小宇宙與睡眠時間的狂暴化狀態下，還是延遲了 2 天，<strong>整整用了 16 天才完成這款小遊戲</strong>。</p>
<p>雖然遊戲的核心機制很早就已經建立完畢，但是 Game Theme（遊戲題材）卻一直處於懸而未決的狀態。原因是「遊戲題材」與「遊戲素材」具有非常高的相依性，在找不到美術設計者合作，我自己也不會畫圖的情形下，想要對遊戲題材拍板定案，實在是一項相當困難而又不切實際的想法。</p>
<p>以後見之明來看，如果當初能夠使用 Flash 做為製作工具的話，應該可以節省不少開發基礎遊戲元件所花費的時間。但是我對 Flash 的熟悉度，差不多停留在讓矩形移動與變大變小的程度而已，所以最終還是毫無懸念地決定使用我最熟悉的 C++ 與 Lua 製作遊戲。</p>
<p>而這次開發的成果，並不是完全從零到有產生出來的。我原先已經有一個小小的遊戲程式框架 (Framework)，曾用來製作過一個 2D 遊戲的半成品，其中的功能只有非常基本的 Graphics、Audio、Input、Script 與 Debug 功能。<strong>於是我就以這個 Framework 做為出發點，義無反顧地展開了這趟遊戲開發的奇妙旅程</strong>。</p>
<p>過程中，我將每一天的進度都大致記錄了下來。以下就是這段時間裡，每天所做的開發日誌筆記：</p>
<p><u><strong>Day 1</strong></u></p>
<ul>
<li>簡單扼要地在 Lua 端確立了程式的主流程。當程式啟動初始化完畢後，程式的控制權，包含 Update、Render 以及偵測視窗訊息與鍵盤滑鼠狀態在內，<strong>全權交由 Lua 端掌控</strong>。只要控制權一回到 C++ 端，就要清理資源然後準備結束程式了。</li>
<li>在既有的程式碼中，只能夠顯示單一的 Sprite 物件，這樣可不行哪。以 Sprite 為基礎，開始打造 CompositeSprite，可以組合任意多個 Sprite 做為一個完整的物件個體。（結果最後並沒有使用到這個功能）</li>
<li>原先在 Framework 中的 Input 系統只有二元狀態 On 或 Off 的 Polling 模式，對於開發除錯來說實在很不方便，所以決定先在 Lua 裡弄個簡易的 Event-based 模式，讓我在每次按下鍵盤或滑鼠按鈕時，只會送出一次事件訊息。</li>
<li>在網路上亂逛，意外找到《太空戰士》系列作品的 Sprite Sheet，品質看起來很不錯，是不是可以考慮拿來做為遊戲的素材？</li>
</ul>
<p><u><strong>Day 2</strong></u></p>
<ul>
<li>製作 Animation 系統。以前有使用 Lua 寫過相同的東西，所以翻出舊作的 Source 來看。「寫得真糟，當初怎麼會這樣想又這樣寫呢？」費了些功夫，翻修製作出新的 AnimatedSprite 元件。當然動畫資料的定義，也全部都使用 Lua 完成。</li>
<li>現在可以載入多張獨立的圖片播放動畫，但是網路上找到的 Sprite Sheet 通常都是一整張圖片的連續畫格，如果還得自己動手裁切，未免也太費力了點。所以只好再製作 AnimatedSprite 的第二種模式，讓它能夠讀入單張圖片來播放動畫。</li>
<li>套用《太空戰士》的 Sprite Sheet，測試 AnimatedSprite 元件的功能無誤。<strong>好，就決定偷這些圖來用！</strong></li>
<li>重新組織 Lua 端的檔案結構。</li>
</ul>
<p><u><strong>Day 3</strong></u></p>
<ul>
<li>給點回應吧！實現簡單的矩形與圓形碰撞檢測。有了 Pick 元件後，才能夠知道滑鼠到底有沒有點選到 Sprite。</li>
<li>創造簡易的 State Machine 元件來搭配角色的 Animation 系統，目前只有 idle 與 move 兩種狀態。</li>
<li>放上數個不同圖片的角色，於遊戲視窗中隨機遊走。顯示結果怎麼全部的角色圖片都相同？</li>
<li>第一次臭蟲大魔頭來襲：是之前的 AnimatedSprite 功能有誤嗎？還是哪個部分的功能有所疏忽？經過了一番奮戰並且用掉好幾罐「補血瓶（小）」之後，<strong>才發現原來我誤用了</strong> <a href="http://www.lua.org/pil/16.html"><strong>Lua 物件導向設計</strong></a><strong>的觀念！</strong></li>
</ul>
<p>    下列程式碼是錯誤的用法：</p>
<pre name="code" class="lua">
    local o = self:Instance();
    o.m_Transform = transform;
    o.m_Texture = texture;
    o.m_Sprite = sprite;
    </pre>
<p>    下列程式碼才是正確的版本：</p>
<pre name="code" class="lua">
    local o = self:Instance
    {
        o.m_Transform = transform,
        o.m_Texture = texture,
        o.m_Sprite = sprite,
    };
    </pre>
<p>    修改完成後，終於還給每個角色他們原來的真面目了！</p>
<p><u><strong>Day 4</strong></u></p>
<ul>
<li>開始加入先前已設計完成的 Game Level 結構，可使用 Lua 檔案很便利地定義每一個關卡敵人的出現時間、類型、數量與方位。</li>
<li>簡便地使用 function 與 if-else 切換不同的 Game Stage。目前初步規劃，共有 Initialize、In Game、Between Level 與 Game Set 四個 Stage。（決策錯誤）</li>
</ul>
<p><u><strong>Day 5</strong></u></p>
<ul>
<li>建立玩家角色的各種狀態：idle、move、attack、powerup 以及 dead。滑鼠點擊後，玩家角色會移動至滑鼠位置，如果角色正在進行攻擊動作則無法移動。過程很順利。</li>
<li>創建敵人的 dead 與 dig（偷取水晶）狀態，包含先前的 idle 與 move 在內，終於完成了第一個完整的 AI 流程。不過敵人還是只會在場景上到處亂逛。</li>
</ul>
<p><u><strong>Day 6</strong></u></p>
<ul>
<li>開始著手製作原先規劃的數種 AI 型態：預設的一路走到底 AI、亂亂走 AI，還有走一走會停下來的 AI。</li>
</ul>
<p><u><strong>Day 7</strong></u></p>
<ul>
<li>為了讓 Release Build 的建置程序更加自動化與直覺化（簡單說就是我懶得做一大堆複製貼上的動作），所以用 Lua 弄了個 Prebuild 程序。將指定的純文字格式 Lua 檔案，全部寫入一個新的檔案中，完畢之後執行 luac 編譯成 binary 格式。最後，把執行命令加在 Project 的 Post-Build Event 中，搞定！</li>
</ul>
<p><u><strong>Day 8</strong></u></p>
<ul>
<li>開始寫 Gameplay 流程的部分，包括 Stage 與 Stage 之間的銜接，Game Over 與全破關的條件判斷。程式碼逐漸有越來越混亂的感覺……</li>
</ul>
<p><u><strong>Day 9</strong></u></p>
<ul>
<li>到目前為止，遊戲中還沒有出現任何文字。所幸 Framework 中已有繪製 TrueType Font 的功能，直接拉進 Lua 使用。測試無誤。</li>
</ul>
<p><u><strong>Day 10</strong></u></p>
<ul>
<li>到 <a href="http://www.popcade.com/">POPcade</a> 的音樂音效素材區搜尋資料，找到一個日本的網站 <a href="http://propanmode.net/">Propan_Mode</a>，裡頭滿滿的都是 MP3 格式的高品質音效與音樂，真是太棒太讚太感動啦！（不過一直沒有找到合適的攻擊音效，囧）</li>
<li>加入播放音樂與音效的功能。製作一個 Radio 元件，用來做為遊戲中的 BGM Player，可把使用者提供的播放清單，依序、隨機或者循環播放。</li>
</ul>
<p><u><strong>Day 11</strong></u></p>
<ul>
<li>在 Google 打上「Free Font」，從成千上萬個 Font 裡找到幾個還算合用的字型。</li>
<li>用網路上搜尋到的免費軟體，將 MP3 轉換為檔案容量較小的 OGG 格式，將播放音效的程序加入遊戲。</li>
</ul>
<p><u><strong>Day 12</strong></u></p>
<ul>
<li>用 Photoshop 幫角色圖片進行去背程序。讚！終於不用帶著白色的框框在場景上行走啦。</li>
<li>再度修改 Animation 系統與 AnimatedSprite 元件，現在可以指定動畫中每個畫格的起始位置了。</li>
<li>產出遊戲角色以及水晶的動畫定義檔，對每一個動作的每一個畫格（還好數量很少），Pixel by Pixel 逐一進行微調。</li>
</ul>
<p><u><strong>Day 13</strong></u></p>
<ul>
<li>測試 AI 系統裡最複雜的「閃避」程序。果然有不少問題，經過整修後得出一個還算可接受的成果。</li>
<li>修改 Framework 的 Debug 功能，可將 Lua 的錯誤訊息以 MessageBox 秀出來並且記錄在 Log 檔中。（為什麼這麼晚才想到可以這樣做？ =_=）</li>
</ul>
<p><u><strong>Day 14</strong></u></p>
<ul>
<li>實作 AI 的 Perk 程序，敵人「格檔」時會無視玩家的攻擊，「反制」時會使玩家在三秒內無法動作。掛上一個額外的盾牌與雙劍小圖示。</li>
<li>加入分數計算以及 Combo 連擊加成的程序。</li>
<li>從以前的作品素材中，拉來幾張背景圖。場景畫面終於脫離了單調無趣的背景色！</li>
</ul>
<p><u><strong>Day 15</strong></u></p>
<ul>
<li>開始正式製作遊戲關卡。<strong>試玩，微調，微調，微調。</strong></li>
<li>找了台沒有安裝 MSVC 的電腦測試，確認遊戲執行檔沒有 DLL 相依性的問題。</li>
<li>第二次臭蟲大魔頭來襲：正當我以為遊戲已經逼近完成之時，突然發現了嚴重的邏輯與流程問題。當敵人奪取水晶之後再被玩家擊倒，敵人的 AI 會產生異常狀態。然後過關條件的判斷也不正確，水晶都被幹光了竟然沒有切換到 Game Over 的 Stage，到底是怎麼回事？</li>
</ul>
<p><u><strong>Day 16</strong></u></p>
<ul>
<li>重新大整修：首先是敵人連結水晶的部分，寫的方式含糊不清又太多假設條件，造成不正確的執行結果。接著再重新思考敵人的 State 轉換，將原先散落在各個 State 中的邏輯判斷，提煉出來做為獨立的 function。最後，加入一個新的「準備階段」Stage，大幅簡化 Stage 與 Stage 之間的切換流程。</li>
<li>重新調整關卡難度。調整。測試。調整。測試。<strong>完成！</strong></li>
<li>打包壓縮，撰寫文章，發佈。（靈魂飄走）</li>
</ul>
<p>以上就是 16 天以來的開發流程。</p>
<p>雖然我使用 Lua 已經有一段不算短的時間了，但這還是<strong>我第一次以 Lua 完成所有的 Gameplay 程式碼</strong>。在遊戲的開發流程中，相關於程式設計的部分，只有使用了 5% 左右的時間在修改及新增 C++ 端 Framework 的功能上，<strong>其餘 95% 的時間全投注於 Lua 的環境下撰寫程式碼</strong>。再者，為了使這些以 Lua 撰寫的遊戲元件能夠繼續在未來的遊戲作品中使用，所以也耗費了不少時間在考量 Reusability（可復用性）的議題。最終，順利地把 Lua 端的程式碼，分成了「遊戲元件」（可復用）以及「Gameplay 相關」（不可復用）兩種不同的用途。</p>
<p><strong>使用 Lua 編寫 Gameplay 程式邏輯的主要優勢在於「速度」。</strong>修改，存檔，然後執行，一氣呵成！再也不必因為一點小小的修改，而必須等待漫長的程式碼編譯與函式庫連結時間。但是使用 Lua 也並非全無缺點；在程式碼編輯工具的選擇上，我使用的是 <a href="http://luaforwindows.luaforge.net/">Lua for Windows</a> 套件中的 SciTE 編輯器，雖然 SciTE 具備有基本的編譯與除錯功能，但無法與 C++ 端的程式碼相互連結，所以在 Gameplay 的除錯程序上比較麻煩，還是必須執行 C++ 端的程式執行檔，才能夠找出 Lua 端的錯誤與問題點。</p>
<p>另外在撰寫程式的過程中，我有點太過於小看 Stage 切換邏輯判斷的複雜度。一開始在撰寫 Stage 相關的部分時，並沒有設想太多，只使用了最簡單的 function 與 if-else 敘述句來切換不同的 Stage，結果到了最後反而造成不少問題。還是應該打從一開始就把 Stage 的架構與流程控制，寫成一個獨立可重複利用的元件才正確。</p>
<p>而在所有的程式系統與遊戲邏輯中，最複雜的部分應該就是敵人的 AI 程序了。我想達到的目標，是多變且具有擴充性的 AI 模組。為了達成多樣化的 AI 行為，如果只是單純地將 AI 程序分成「直線型」、「隨機型」與「格檔型」等等，其實無法發揮良好的綜效。所以後來我想到了一個做法，就是<strong>將 AI 處理程序拆解成三種獨立的邏輯程序</strong>，分別是 Path Planner、Tactic Thinker 以及 Perk（特技）：</p>
<blockquote><p>
<u><strong>Path Planner</strong></u></p>
<ul>
<li>直線</li>
<li>隨機</li>
</ul>
<p><u><strong>Tactic Thinker</strong></u></p>
<ul>
<li>無</li>
<li>暫停</li>
<li>閃避</li>
</ul>
<p><u><strong>Perk</strong></u></p>
<ul>
<li>無</li>
<li>格檔</li>
<li>反制</li>
</ul>
</blockquote>
<p>分成三種獨立程序之後，我就可以在設計各關卡的敵人類型時，任意組合上述三種 AI 邏輯程序，然後再加上敵人外觀與生命數值的設定，製作出豐富而多樣化的敵人軍團。</p>
<p>在這 16 天的遊戲開發過程中，排除之前預先完成的遊戲設計層面，以程式設計、素材生產與關卡設計三個面向進行評估，<strong>程式設計約略佔了 80% 左右的開發時間，而素材生產與關卡設計加起來卻只佔用了 20% 左右的時間。</strong>用在關卡設計與素材製作面向上的心力，實在太少太少啦！</p>
<p>總結來說，下一款遊戲作品的改善目標為：</p>
<ol>
<li>先搞定 Stage 架構與流程控制元件。</li>
<li><strong>美術！</strong>我需要找到能夠共同合作的美術成員，或者是可以見人的 <a href="http://www.gamedev.net/reference/articles/article2594.asp">Better Programmer Art</a>。</li>
<li>花費更少的時間寫程式碼，把更多時間心力投注在<strong>關卡設計與素材製作</strong>上。</li>
<li><strong>遊戲必須要更有趣，更具有可玩性。</strong></li>
</ol>
<p>在遊戲設計的層面上，我還是個十足的嫩咖，<strong>但是只要過程好玩，我就會一直一直玩下去！</strong> ：D</p>
<blockquote><p>
<u><strong>你可能不知道的小秘辛</strong></u>：遊戲本來想取名為 <strong>Crystal Defender</strong>，後來發現 Square Enix 在 iPhone 上有發佈一款同名作品，所以只好更換名稱為 <strong>Crystal Guardian</strong>。 XD</p>
<p><u><strong>你不可不知道的小秘技</strong></u>：如果覺得遊戲太刁難或是滑鼠不夠滑而過不了關，請打開遊戲資料夾中的 GameEnemy.lua 與 GameLevel.lua 檔案，相信各位一定能夠發現戰勝遊戲的<strong>很黑暗的招</strong>。 ：P
</p></blockquote>
<img src="http://blog.monkeypotion.net/?ak_action=api_record_view&id=173&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://blog.monkeypotion.net/gamedev/journal/dev-journal-of-crystal-guardian/feed</wfw:commentRss>
		<slash:comments>23</slash:comments>
		</item>
	</channel>
</rss>
