作者NDark (溺於黑暗)
看板GameDesign
標題[程式] 資料驅動設計的比較
時間Wed Sep 5 20:40:11 2012
今天工作不爽.
就來談一下資料驅動設計(Data-driven Design)好了.
我現在的專案的介面模組就是DDD.
有優點.這點我不會故意忽視.
透過資料檔的更動.程式的結果就不同了.我想這是當初設計者使用DDD的原因.
然而,一直看不順眼的原因我卻一直到今天才明瞭.就是程式寫太爛嘛.
設計概念好,實作爛
-就如同洋房的磚塊是用沙堆黏起來般-又脆弱又難改,
一戳就破,一改就一連扯下一堆爛木版.
為了避免有人不知道Data-driven是什麼,
我還是要稍微說明一下,順便連帶帶出我要比較的各種軟體架構模型.
# Data-driven design 資料驅動設計.
系統本身不負責運作,系統本身只負責執行各項由資料端定義而來的反應.
資料端可能是一個xml的檔案.定義配置,屬性,以及各項事件.
比如說一個按鈕按下的時候播放一個聲音.
資料端就會這樣定義這個按鈕的位置,顏色,然後搭配按下的時候要執行的內容.
<Button id...>
<Press>
<PlaySound file=.../>
</Press>
</Button>
程式碼可能像這樣
ButtonPressed()
{
// trigger_button
switch( trigger_button->Action[j] )
...
case ePlaySound :
PlaySound( ... ) ;
}
當然有好處的不然不會這麼多人推這個做法.
第一個好處就是當我想改變這個按鈕的行為的時候我就改xml.
改完再去執行程式,結果當然就不一樣了.
要拿掉,新增,改變屬性,改變行為都可以由編寫xml的人員去獨立進行.
這樣的設計方式通常會有一小撮精英把底層架好(Engine).
然後由Artist來部署大量的xml.
第二個好處就是xml的可讀性不錯,編寫xml的工人不難教育.
缺點我們等下在一起講
# hard coded 透過程式碼實現邏輯
相反地,把邏輯用程式碼實現就叫硬摳.它正好就是DDD所解決的問題.
因為硬寫.所以要改的時候要重新編譯,再測試,再改再編譯.也難怪會有人發明DDD.
程式碼可能就像這樣
ButtonPressed()
{
// trigger_button
{
PlaySound( ... ) ;
}
}
# script 透過腳本
第三種變形,會使用腳本的原因在DDD我們沒有提及.
也就是xml不相容於我們的程式語言(以這裡的例子就是c++),當然嘛它就是個"資料".
但是正因為不相容,我們必須寫中繼的程式,
以xml來說就是 xml parser ,把資料存入執行中的程式裡面調用.
xml的規則越複雜, parser就越複雜,廢工. 而同時複雜等於容易出錯.
所以才有透過腳本的方式來替代(或是部份替代)xml.
腳本語言裡面一樣可以撰寫配置,屬性,事件.
相對於寫parser,腳本語言的作法依然要寫橋接的"介面".
但好處是因為腳本是程式語言,多半可與執行的程式語言有共通之處.
(譬如說可以使用同一組資料結構來傳遞資訊)
這樣就可以少寫了parse的部份.
腳本語言就會變這樣
Script_Button_i_Pressed()
Script_PlaySound(...)
End
專案程式這裡就是
ButtonPressed()
{
// trigger_button
{
run_script( "Script_Button_i_Pressed" )
}
}
# 其他組合型
譬如說flash + c++
由flash負責介面,然後c++負責觸發與hard code其他的功能
ButtonPressed()
{
// trigger_button
{
flash_component->run( "ButtonPressed" ) ;
PlaySound( ... )
}
}
這種組合跟hard coded很像,但是又有橋接的部份,
以flash來說他也有action script,但是又不像一般腳本語言這樣能夠橋接到多功能,
所以說這樣的寫法跟腳本的作法又有雷同之處.
這邊的flash模組就是一筆可活動封裝良好的"資料",由flash engineer來製作.
若以象限圖來看可以把這四種作法切成這樣
Combine | DDD
----------|--------
Hard-Coded| Script
右方是修改的彈性良好
上方是資料端封裝良好
最後要說明比較的部份,可能比較多人會跟我看法不同
. DDD:
就如同我開場所述,如果底層"功能"明確,製作完成後就不大改變,那麼就容易大量配置.
但是若底層撰寫不良,或是功能陸續增加,就會慢慢發生混亂.
因為在陸續增加功能的情形下,
有可能是xml寫錯,有可能是parser寫錯,也有可能是新增的功能項寫錯.
增加的部份很廣泛導致如果不嚴格控管,容易變成blob般肥大,
模組內部的運作全部混在一起,邏輯混亂.
而DDD的缺點也就會浮現出來,
運作的邏輯不顯而易見,
新人(不是最初架構引擎的人)難以維護.
而xml的parse也都為人所詬病,若只parse一次,
改了資料後程式還是要重開,但又不能每個畫格都去parse,會浪費很多效能.
這更考驗xml的安排切割與最佳化.
. hard coded
其實我對hard coded的看法沒有這麼糟糕.
在技術強度不高的團隊中,它也並非是一個不可行的辦法.
若在 "大架構上有良好的區隔" 的前提下
hard coded顯而易見的第一優點就是模組清楚.哪裡出錯就是哪裡的問題.責任相對清楚.
當我們要重構的時候最怕有一半正確,一半錯誤的模組,
hard coded的優點正來自他的缺點,整個模組抽掉就對了.
. script
script是不錯的進階選擇,
可以與程式共用一些模組,可以少寫一些程式,
缺點就是腳本語言管理,除錯不方便,
要橋接的良好還是需要一點技術能量,
若要自己創script就需要更高一層的技術力.
. 組合型
越是封裝越好的模組就就是除錯不易.
但是封裝的好,也代表污染不會蔓延.
優劣並立.
--
"May the Balance be with U"(願平衡與你同在)
視窗介面遊戲設計教學,討論,分享。歡迎來信。
視窗程式設計(Windows CLR Form)遊戲架構設計(Game Application Framework)
遊戲工具設計(Game App. Tool Design )
電腦圖學架構及研究(Computer Graphics)
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 1.164.51.135
※ 編輯: NDark 來自: 1.164.51.135 (09/05 20:40)
※ 編輯: NDark 來自: 1.164.51.135 (09/05 20:40)
推 osanaosana:推...原來我曾經實作過DDD 09/05 21:40
→ VVll:剛寫完這東西 在ios上吃json的client 09/05 21:44
推 GALINE:對*玩家*來說 Data Driven 還有 moddable 的好處 09/05 21:45
→ GALINE:寫死的話玩家只能改改貼圖讓女角裸體,完全 data driven 09/05 21:47
→ GALINE:奇怪的遊戲了 09/05 21:47
→ NDark:然而,moddable的前提在於第一版的好玩. 09/05 23:16
→ NDark:至少要吸引到第一批志願者,才有後續的mod出現. 09/05 23:16
→ NDark:如果在還沒確定第一版就好玩的情形下就執著擴充性, 09/05 23:17
→ NDark:風險是很大的. 09/05 23:17
推 damody:快來寫 lua 可惜不原生支援 unicode 09/05 23:18
推 asoedarren:js漸漸變成script的主流 09/05 23:26
推 lf21201:感覺很酷! 請問有沒有關於DDD的實作範例@_@ 09/06 00:23
推 Bencrie:Data Driven 的話想推 1997 的 Total Annihilation 09/06 09:20
→ Bencrie:到現在還有人在做 mod,花樣比原作還豐富 XD 09/06 09:21