遊戲:玩命起司
先談談寫這篇文章的原因?
--
在 JCConf 結束後,被一篇 FB 上的貼文 所吸引。其中的要旨就是由於遊戲的複雜度,恰好足夠用來作為練習軟體工程技術與品味對象:
在這個遊戲微服務計劃的介紹,將軟體開發描繪成打獵活動的有趣想法特別吸引人!近期跟著線上讀書會一起練習了 Practice Stack 的內容,花了二三週的時間,稍稍理解了過去未曾接觸的事件風爆(Event Storming)、Example Mapping 與應該要知道,但其實不太會的物件導向分析 (Object-Oriented Analysis)之後,想著要再多花點時間練習,於是挑了一套小遊戲來實踐前幾週學到的內容。
遊戲參考資料
說明書
- 中文 http://www.gokids.com.tw/tsaiss/gokids/rules/AllesKaese_CNRules.pdf
- 英文 http://www.gokids.com.tw/tsaiss/gokids/rules/AllesKaese_Rules.pdf
Event Storming
敘事歷程:
- 遊戲會在開始前設置好,設定完成的遊戲有洗混的 36 張牌在牌堆上,並由牌堆的上方抽出 6 張放入展示區。接著,指定一位起始玩家後開始遊戲。
- 遊戲開始玩家回合,會自動地替玩家擲骰,通知玩家目前獲得的點數,玩家得依點數行動 (Policy)。
此 Policy 依點數決定不同的情況:
- 當所得的點數有與展示區卡片相符時,玩家可選擇保留卡片或棄牌。遊戲會在玩成動作時,自動由牌堆抽一張替補展示區的空缺。
- 當所得的點數未有與展示區卡片相符時,玩家只能偷看展示區中的一張牌。
- 在玩家選擇保留卡片的情況,並累積至 3 張陷阱卡時,此玩家淘汰。
- 玩家只要做完動成,即結束他的回合。這時若場上只剩下一位玩家,他就是遊戲的勝利者。若已將牌堆與展示區的卡片都用盡,則進行算分得出最後的勝利者。
計分的細節是:
- 陷阱卡不算分
- 加總牌背的點數
- 點數同分時,張數多者獲勝
Example Mapping
遊戲的概念不算複雜,單純舉個例子練習 Example Mapping 😃
OOA
利用遊戲規則進行語意分析,抓出重點的名詞列出如下:
找出適合作為類別者,標上橘色。其餘的得思考,它們能被一般化為類別或是應為某類別的屬性:
- 骰的數字,應為骰子被骰後的「正面」的數字。
- 卡片有正面與背面,正面會放洞數,背面可以是起司或陷阱
- 供應牌堆與棄版堆,雖然都是一些有序的卡片。但供應牌堆只能被抽牌,棄牌堆只能被放牌。也許,先一般化為牌堆?
稍作整理後,主要的「點」已經明確,再來是連上「線」的部分:
替每個類別拉了線之後,發現回合也許不是那麼重要的概念。回合是指輪到一個新的玩家,等待他完成動作的歷程,那麼有幾種可能的設計:
- 回合改名為:行動中玩家。成為遊戲的屬性。
- 直接移除回合,保留其他的類別。
拿掉了回合,接著替玩家與骰子補上「一瞬」的關係。最後,我們可以替類別補上主要的行為。在玩家獲得了行為後,發現他其實應該與展示區、棄牌堆還有卡片(透過玩家牌堆)相依:
目前畫起來多了不少線,看起來稍亂了點。但想了想,遊戲可以作為 Aggregate Root 去委派玩家想要「偷看」或「棄牌」的動作,不用直接讓玩家相依「展示區」與「棄牌堆」。這些可以到 DDD 戰術設計時進行規劃。
讀書會的體驗
經過了這幾週的參與,學到了一些 DDD 相關的概念,特別喜歡目前 Practice Stack 的設計,在上一次的讀書會,有個值得提起的變化。在最開始水球潘介紹遊戲的複雜度有二個面向。一是流程上複不複雜,再來是概念好不好理解。
經過了幾回的討論後,遊戲的複雜度成為了三維。我們可以用不同的策略來應對:
- 以 Event Storming 梳理複雜的流程
- 以 Example Mapping 梳理複雜的 (遊戲/Spec) 規則
- 以 OOA 梳理複雜的概念
你可以觀察到這一切都很有機 (organic),不是互動較少像是為了一起集資點個套餐,想要別人幫忙分攤一點食量與分母的讀書會型式。組織與參與者都是在不斷變化中的。