iT邦幫忙

2026 iThome 鐵人賽

DAY 29
0
Claude AI

奇幻塔防開發實錄:用 Claude 打造一款有靈魂的塔防遊戲系列 第 29 篇

Day 29:塔防遊戲正式上線:demo 展示、架構全貌圖與開發數據總結

  • 分享至 

  • xImage
  •  

claude_29

系列:奇幻塔防開發實錄:用 Claude 打造一款有靈魂的塔防遊戲
今日工具:Claude Cowork(彙整 30 份 day-log)/ Claude Code(最後一次部署)
今日進度:《薪火要塞》正式版上線;Day 1 的六個承諾逐項驗收;30 天數據攤開

前言

Day 28 把部署雷排成表、算完那張 US$1.35 的月費單,剩下的事只有一件:把最後一版推上去,然後誠實地對帳。今天不寫新功能——deploy-api 第 21 次、deploy-web 第 24 次跑完,Day 28 補的部署後煙霧測試第一次在 CI 裡用真實 token 打了 /api/v1/saves/{id}/story,綠了。理由很簡單:API Gateway 的 payload 1.0、CloudFront 的 /api/*,這兩件事在我這台筆電上一件都驗不到。

這篇要做三件事:帶你走一遍 demo、把 30 天蓋出來的東西畫成一張圖、然後回到 Day 1 那六個「做不到我會誠實列出」的承諾。數據全部來自 Day 1 用 Cowork 建的 day-log。

一、Demo:從點燃初火到三個結局

網址是 CloudFront 的網域(連結在 README),手機橫向開啟即可。流程:

  1. 首頁輸入名字、按「點燃初火」→ POST /api/v1/saves 拿到存檔與 token(Day 27)。
  2. 序章:艾瑟琳的對白(Day 18 的打字機效果)→ 第一個抉擇「糧倉」,三個選項各代表守望/燃盡/餘燼(Day 4)。
  3. 灰原邊境:五波、四個塔位、v0.2 數值(Day 23),mixed 配置通關率 100%。
  4. 霧河渡口、斷橋古道:兩條路徑匯流、飛行單位登場——火砲在這裡打不到霧翼,是設計不是 bug(Day 23)。
  5. 抉擇累積到 n_final_gate,route 節點依 flags 分流(Day 10、21 坑 #4)→ 薪火王城 boss 依路線變化 → 三個結局之一。

坦白交代第 4–6 關的狀態:關卡資料、波次、boss 變體全部就位、可玩、通關率跑過(棄守修道院 79.5%、黑岩隘口 91.0%、薪火王城 73.5%);但劇情圖 60 個節點只定稿 52 個,第 4–6 關還有 8 個節點是 Day 7 就承認的草稿。

從 Day 16 上線至今 13 天,戰鬥稽核 item 累計 58 場、7 位玩家(含我;Day 23 時是 23 場、3 人),三個結局各至少有一筆真人存檔——這是承諾二的證據。

二、架構全貌

claude_29_diagram_01

圖上只有 S3 帶尾巴:bucket = "${var.name}-web-${var.aws_account_id}"。bucket 名稱全球唯一,不像其他資源「同帳號同區不撞就好」,那截帳號 ID 不是裝飾。

每個箭頭都對應一篇文章:靜態站與 /api/* 同源(Day 22)、API Gateway REST API、ECR 容器映像與 Lambda(Day 16)、DynamoDB 單表(Day 13)、告警(Day 24)、WAF 與 Authorization 轉發(Day 27、28 雷 #1)、OIDC 免金鑰部署(Day 16)。整張圖 Terraform 六個 module、51 個資源可 plan,46 個真的 apply 上去過,月費 US$1.35(Day 28)。

值得說一次的是這張圖裡沒有的東西:沒有 VPC、沒有子網、沒有 NAT、沒有安全群組、沒有一個按小時計費的資源。Day 9 那條分界線(「會留下資料的東西 → 隨時可重建的東西 → 會叫的東西」)到今天還撐得住——六個 module 的邊界一次都沒重畫。

三、Day 1 的六個承諾,逐項驗收

claude_29_diagram_02

# Day 1 的承諾 結果 證據
1 瀏覽器(含手機)可玩,至少 3 關完整 ✅ 前三關對白定稿、Redmi Note 8 第 5 波 58.9 FPS(Day 26)
2 三條路線、三種結局,可從存檔查證 ✅ routes_test.go 三路線全綠(Day 25);GSI1 三個結局節點各有真人存檔
3 Go API 在 AWS,Terraform 全程可重建 ⚠️ 從零 apply 46 個、玩到結局、再 destroy 掃到淨空;沒做的是 destroy 後再 apply 的回程
4 CI/CD 一鍵部署、告警實際觸發過 ✅ api 21 次、web 24 次自動部署;告警 2 次演練 + 1 次真實(Day 24、26)
5 worktree 對照數據 ✅ 四筆:−38%、−44%、+13%、−41%(Day 12、14、26)
6 可複製的 /ultracode(我自訂的 slash command,不是官方功能) ✅ 兩次實戰 41 與 24 分鐘(Day 20、26),指令與 subagent 全文公開

第 2 項的「可查證」是字面意義的——三個結局各下一次 GSI1 查詢,數字對得上劇情稽核 item 裡的選項序列:

# dawn 換成 ash / kindling 再跑兩次
aws dynamodb query --table-name emberhold-prod --index-name GSI1 \
  --key-condition-expression 'GSI1PK = :n' \
  --expression-attribute-values '{":n":{"S":"NODE#n_ending_dawn"}}' \
  --select COUNT

從一句 SQL 變成三次 Query,是單表設計的代價:關聯式資料庫可以事後想出新的 GROUP BY,DynamoDB 得先想好存取模式再建 GSI(Day 13)。

第 3 項打 ⚠️ 是因為「可重建」我只證明了單程:51 個資源 plan 乾淨,46 個從零 apply 起來(cicd 那五個排除),跑完一輪真實存檔,最後 terraform destroy 全數拆掉、掃描確認區域淨空。缺的是回程——destroy 之後再 apply 一次、確認它長得回來。表上 deletion_protection_enabled = true 要先手動關掉,這趟往返我沒有在最後三天再跑,所以它留在下面的未完成清單裡。

四、30 天數據、Cowork 收尾,以及沒做完的事

量測方式沿用 Day 7:專注分鐘來自 day-log 的時間表;session 數含 subagent 與 Day 7 的 6 個實驗 session;token 是每個 session 結束時 /cost 的輸出 token。下表每一週都含當週的週記日,所以會比週記當天的數字大一些。

週 專注分鐘 Claude session commit 部署(api / web / infra)
1(Day 1–7) 950 18 31 0
2(Day 8–14) 870 16 58 0
3(Day 15–21) 1,210 16 67 9 / 14 / 1
4(Day 22–28) 1,105 14 49 11 / 9 / 6
終章(Day 29–30) 230 2 9 1 / 1 / 0
合計 4,365(≈ 72.8 小時) 66 214 21 / 24 / 7

表格有兩個形狀值得看。第一,專注分鐘與 commit 數不成正比:第二週 870 分鐘產出 58 個 commit,第四週 1,105 分鐘只有 49 個——第四週多出來的時間花在排雷(260 分鐘)與演練,那些工作不產生 commit,但產生 runbook。第二,session 數逐週遞減而產出沒減少:第一週 18 個裡有 5 個是「反問型」長對話,第四週 14 個裡一半是十分鐘的短問答。session 變短,是 CLAUDE.md 累積四週規則的結果——Claude 需要被解釋的事越來越少。

其他總數:輸出 token 約 162 萬;worktree 4 次(序列估 365 分鐘 → 實測 240 分鐘,−34%);/ultracode 2 次;測試 Go 62、vitest 20、Playwright 9;記錄在案的 bug 與雷 31 個(整合坑 6、部署雷 12、/ultracode 處理 2、其他 11);平均每天 145 分鐘。

哪裡加速、哪裡沒有,用數據說:

Claude 明顯加速 數據 沒加速、甚至變慢 數據
設計稿→元件(附意圖說明) 91% 可直接用、8.5 分鐘(Day 7) 實機測試 210 分鐘,無工具可省(Day 19)
worktree 平行獨立任務 −38%~−44%(Day 12–14、26) worktree 平行糾纏任務 +13%、3 次語意衝突(Day 14)
骨架生成(Plan mode) 事前改 2 個決定 vs 事後改 14 檔(Day 8) 契約決策 六個整合坑有四個是契約(Day 21)
排雷:把查文件壓成一個問題 平均 29 分鐘/雷(Day 28) 數值與設計決策 /sim(同樣是我自訂的指令)只給三條建議,決定權在人(Day 23)

最後一份工作交給 Cowork:

Prompt(給 Claude Cowork,指定 ~/emberhold-notes/)
「讀 daylog/day01.md 到 day30.md。彙整成同一層的 retrospective.md:一、每週專注分鐘、session、commit 的表;二、所有『踩雷』欄位依『契約/預設值/程式邏輯/其他』分類計數;三、每天『明日計畫』與隔天『實際做了什麼』不一致的日子列出來。只要事實,不要評論。」

報告刻意留在 ~/emberhold-notes/、不進 repo:docs/ 只放讀 code 的人需要的東西,寫作素材混進去,第一個受害的是 CLAUDE.md 的 context 預算。產出 4 分鐘。第二項的分類結果:契約 11、預設值 9、程式邏輯 7、其他 4——程式邏輯錯誤只占兩成,今天才看到全貌。第三項抓出 6 天計畫與實際不符,其中 4 天在第三週,跟 Day 1 標的高風險區完全吻合。

repo 最終長這樣(比 Day 6 的骨架只多了每天在長的 PITFALLS.md 與 docs/ 兩個子目錄):

project/
├── CLAUDE.md  Makefile  README.md  PITFALLS.md
├── .claude/            settings.json、commands/{ultracode,review,sim}.md、agents/、hooks/
├── frontend/           Vue 3 + Canvas,vitest 20、Playwright 9
├── backend/            Go Clean Architecture,go test 62,cmd/{api,sim,storylint}
├── infra/terraform/    envs/prod + modules/{foundation,compute,cdn,cicd,monitoring,waf}
├── data/               towers / enemies / levels×6 / story(v0.2)
├── docs/               gdd、api、architecture、balance、qa-matrix、adr/×6、runbook/
├── scripts/            contract-test、lambda-image、tf-plan-offline、e2e-fixture(.sh)
└── .github/workflows/  ci / deploy-api / deploy-web / infra

docs/ 底下只有 adr/ 與 runbook/ 兩個目錄,其餘都是單檔:sim-*.csv 該進 artifact,不是進 git。

未完成清單,明天不會再提第二次:兵營塔與士兵阻擋(Day 3 就割捨)、第 4–6 關 8 個節點對白定稿、destroy 之後再 apply 的回程演練、重播式反作弊(Day 12 留的門)、lambda-duration-p99 的 800 ms 閾值要等真實流量校正(Day 24)、合成探測(Day 24 那個盲點:「完全沒有被呼叫」是沒有指標的,六個告警都不會叫)、排行榜、SNS 加 Slack 訂閱。

小結

上線這天最大的感受不是「做完了」,是「對得起 Day 1 的清單」:六項裡五項有證據、一項誠實打折。30 天 72.8 小時、66 個 session、214 個 commit 蓋出一個能玩、能查、能監控、每月一塊多美金的東西——但 Cowork 那份報告提醒我,31 個雷裡只有 7 個是程式寫錯,其餘都是「兩邊各自正確」與「預設值」。Claude 寫程式的部分幾乎沒讓我失望,讓我失望的都是我沒問的問題。這句話明天展開。

今日產出

  • [x] 正式版部署(api #21、web #24)、部署後煙霧測試進 deploy-api.yml
  • [x] ~/emberhold-notes/retrospective.md(Cowork 彙整 30 份 day-log,不進 repo)、docs/architecture.md(本篇兩張圖)
  • [x] Day 1 六項承諾驗收表、30 天數據表、未完成清單

明日預告

Day 30:【終章】30 天後的我——Claude 全流程開發心得,與這場鐵人賽留給我的東西。


上一篇
Day 28:【週記】Day 22-27 回顧:從本機到 AWS,那些部署當下才會踩到的雷
系列文
奇幻塔防開發實錄:用 Claude 打造一款有靈魂的塔防遊戲 共 29 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言