[開發日誌 #4] 原型時期的程式開發方式
在開發遊戲原型時,最重要的是盡快實現遊戲玩法,但一開始自己走了許多歪路,反而花更多心力在不重要的地方。在 TDGF 上聽到分享與請教朋友之後,學到不少在原型階段的開發方式,就透過這篇文章來分享減少走錯路的方法。
能動就先用,不急著重構
開發時總是會想要重構程式碼,可能是因為覺得有更好的作法,或是覺得現在的架構不適合新的功能。但是在開始重構之前最好先評估要花多久,以及牽涉到的範圍有多廣。因為在原型時期的遊戲規格變動很快,如果花了大把時間重構的功能要再修改,甚至被打掉的話,花的時間就白費了(上一篇的悲慘經驗)。所以當需要增加或是修改功能時,先順著繼有的架構去作,等功能確定之後才來重構,此時的規格也比較完整,重構才有效益。
嘗試不同作法的好時機
在原型階段,程式結構還沒有很複雜,是可以嘗試用不同作法或是新套件來開發功能的好時機。可能是在之前的開發中遇到的問題有更好的作法,或是知道有不錯的套件可以使用。在這個階段多多嘗試與實驗,知道使用的作法或套件的極限到哪裡,如果不合適的話,替換掉的成本也相對低。
這次開發的遊戲為了能更方便管理與播放角色動畫,就嘗試使用 Animancer 套件來製作相關的功能。一開始我先列出想要這個套件實現的功能,然後花兩三天的時間「玩」這個套件,看看有哪些功能可以實現,哪些要自己實作,而且要花多久時間實作。評估這個套件合適後,才導入到專案中。
新內容用新功能
那如果是開發到一半,發現有更好的作法時要怎麼辦?那最好的作法是只在新的內容用新的功能,一來可以不用先花時間重構既有的功能,二來也可以驗證新的作法是不是真的比較好。如果不合適,那也只有新的內容會受到影響。如果合適的話,則在舊內容需要修改時,或是時機成熟時,像是用新作法的內容製作流程確立,再改成使用新作法,慢慢取代掉舊功能。
這次開發的遊戲中有不同的敵人,在戰鬥邏輯上就使用這樣的開發方式。原本的戰鬥邏輯是使用 ScriptableObject 來設定數值與時機,但後來為了配合角色動畫,這些資訊得改成由播放的動畫提供。所以我只有先在新的敵人上使用動畫來控制戰鬥邏輯,而既有的敵人就先不動,等到需要的時候,就直接用新功能來做擁有同樣能力的敵人,直接取代舊的敵人。
功能要有隨時被改掉的覺悟
我要修改… 部份規格!!! ー《大東京玩具箱》
在原型階段最常發生的事情就是規格改變。所以不要過度設計功能,不要想著這功能要囊括所有可能性,或是未來的需求。否則花了大把時間精心設計的功能,因為測試後覺得在遊戲中不好玩,而要被拿掉的話,只有滿滿的失落感,勞神又傷心。因此功能能解決現階段的需求就可以了,製作時間也不用花太多,先拿出來被驗證才是首要目標。
永遠考慮時間是否夠用
寫程式沒辦法兼顧「快」與「好」,在原型階段只能做取捨,就是以快速實現遊戲玩法為主要目標。所以在製作功能或是重構前,先評估要花多久時間才能完成。如果時間可以接受,就能開始動工。如果不行,就看瓶頸在哪邊,有沒有方法可以先繞過那部份,又可以掌握在可以控制的程度。再真的沒辦法,就是跟團隊討論,看能否縮減規格,或是能接受花時間下去製作。
在程式的架構設計上我以功能為單位來切割元件,一個元件(不一定只有一個程式碼檔)專門負責一個功能(一個功能下面也可能有子功能),呼叫功能的角色不用在意其中做了什麼事,只要控制什麼時候呼叫就可以了。這樣程式碼混雜的地方就只會集中在各自的元件內,無論是要替換或是修改,受影響的範圍就不大。