模組一|立案與選型(Day 1–4)
先給結果,再講過程。
遊戲在這裡,開了就能玩,不用註冊:https://save-the-dog-web.vercel.app/
原始碼在這裡,全部公開:https://github.com/HarryFan/save-the-dog-web
玩法一句話講得完:畫一條線,擋住從蜂巢飛出來的蜜蜂,讓狗狗撐過十秒。
結論先講:這 30 天不是「我用 AI 三天做完一款遊戲」的故事。真正撐得住 30 天的主張只有一句——AI 產出的品質,取決於你設得出幾道它過不去的自動檢查。設不出檢查的環節,就是你必須親自出席的環節。這個系列會用一款小遊戲的每一個決策,把這句話驗證三十次。
兩條線,同時跑,不切成兩半。
技術那條線:一款畫線物理小遊戲,怎麼從零長到公開可玩。Vite 建置、PixiJS 8 負責畫、Matter.js 0.20 負責算、三十幾張原創 SVG 當素材、GitHub Actions 部署。從「手指按在螢幕上」到「一個擋得住蜜蜂的剛體」,中間有八件事會發生,每一件都可能出錯。
AI 那條線:這個專案有大量實作是我指揮 AI 完成的,尤其是素材。但值得寫的不是「AI 很好用」,而是相反的東西——我在哪裡設了閘門、閘門長什麼樣、AI 在哪裡試圖繞過去。
這兩條線不是輪流講。每一篇都同時交付:這一步技術上怎麼做,以及這一步我怎麼交給 AI(或者為什麼刻意不交)。
MVP 的規則三句話講完:
沒有帳號、沒有排行榜、沒有商店、沒有多人。第一關的教學提示只有兩行:「畫出一道防線,保護狗狗撐過 10 秒。」「把洞口封起來就好。」
小到這種程度有理由:題目越小,越能把每個決策攤開講。
一款複雜遊戲的文章只能寫「我大概是這樣做的」。一款只有一條線的遊戲,可以把「這條線從手指到剛體之間發生了幾件事」逐步拆給你看——原始的 pointermove 可能觸發數百次,那幾百個點怎麼被抽稀成四十個節點,那四十個節點又為什麼被合併成單一複合剛體而不是一條鏈。這些都是具體的、可以攤開的東西。
小也不代表沒有工程約束。舉幾個已經寫死在 src/config/game.js 裡的數字:邏輯座標固定 750 × 1334、物理步長固定 1000/60 毫秒、單幀時間上限 100 毫秒、蜜蜂同時最多 16 隻硬上限 24 隻。這幾個數字每一個背後都有一篇文章,後面會逐一講。
我是前端工程師。這是我第一次認真寫遊戲迴圈、第一次用物理引擎、第一次處理「同一個操作在不同幀率的裝置上會跑出不同結果」這種問題。
這件事對你反而是好事:
相對的,這系列不是最佳實踐指南。 它是一份「一個沒做過遊戲的人,怎麼把一款遊戲做到可以公開玩」的完整紀錄。有些決定後來證明是錯的,我會寫出來。
| 模組 | 天數 | 這個模組要回答的問題 |
|---|---|---|
| 一 | Day 1–4 | 為什麼做這個?為什麼是這套技術?範圍怎麼畫? |
| 二 | Day 5–9 | 怎麼讓 AI 產出的東西是「可以驗收」的? |
| 三 | Day 10–15 | 玩家滑一下,中間到底發生了幾件事? |
| 四 | Day 16–20 | 怎麼讓敵人有壓迫感,又不會失控? |
| 五 | Day 21–25 | 怎麼把一個關卡變成資料,而不是程式碼? |
| 六 | Day 26–30 | 怎麼證明它真的能跑?在別人的手機上也能? |
模組二是 AI 密度最高的一段,模組三是技術密度最高的一段。
先把你不該期待的東西講掉,省得你追到第十天才發現。
不是 PixiJS / Matter.js 的 API 教學。 官方文件寫得比我好。我只寫「為什麼這樣用」,不寫「這個函式有哪些參數」。
不是一份可以照抄的最佳實踐。 我做的很多選擇是學習取向而非工程取向——例如選 PixiJS 而不是 Phaser,理由是我想看清楚每一層在做什麼。如果你的目標是最快做出一款遊戲,Phaser 大概是更好的選擇。
有些證據我沒有留下來。 這是這個系列最尷尬的部分,但必須在第一天講:我的留存機制建立得太晚。驗證器實際擋下過哪些 AI 產出,沒有紀錄;素材審查過程的中間版本截圖,沒有留存。所以那幾篇我改寫成「這道閘門在防什麼」而不是「它擋下過什麼」——誠實的缺席,比補寫的敘述可信。 遇到這種段落我會明講。
專案還在動。 我寫這篇的時候,這個 repo 今天還在被提交。所以文章裡出現的量體數字都會標明快照時間,你在別的天數看到不一樣的數字,那不是筆誤。
先講一個具體的、可以查證的事實,因為它就是這條線的起點。
這個專案開工前有一份 2,419 行的 PRD,涵蓋技術選型、素材清單、物理參數、測試計畫、部署流程。單人小專案寫這麼長的規格,第一反應通常是「幹嘛」。我原本也這樣想。
改變我想法的是這件事:當實作的執行者是 AI,規格就不只是給人看的文件,而是驗收的依據。
viewBox 固定、允許色碼十五個、必須有這九個語意分組 → 可以自動檢查
於是這個專案裡有一支 scripts/validate-svg.js,516 行、20 條規則加一條警告,不合格的 SVG 直接讓 CI 失敗。這一條就是整條線的核心:一支會讓 CI 失敗的腳本,比一百句提示詞有效。
閘門有四種形式,後面會各自展開:
| 形式 | 管什麼 | 在哪篇 |
|---|---|---|
合約(AGENTS.md / CLAUDE.md) |
AI 知道該做什麼 | Day 6 |
| 驗證器 | AI 做錯了會被擋下 | Day 8 |
| 母版制 | 後續變體只能依照一個被人工核准的樣本 | Day 7 |
| 人工閘門 | 機器判斷不了的事 | Day 9 |
而這條線最有意思的發現不在「AI 很聽話」,在於哪些規則做得到自動檢查、哪些做不到。把合約逐條對映到檢查腳本之後,結果是:SVG 那一層 18 條規則裡有 17 條有對應的自動檢查;工程規則那一層 8 條裡只有 1 條有。
差別不在重不重要,在於規則有沒有一個可以被程式解析的目標。這件事 Day 8 開頭,Day 29 收尾。
如果你今天只能記一句話,記這句:
你希望 AI 遵守的規則,如果沒有對應的自動檢查,就等於沒有規則。差別只在於你什麼時候發現。
如果還能記第二句,記這個:選函式庫之前,先問它「刻意不做什麼」。它不做的那些事,全部會變成你的工作。 PixiJS 不做物理、不做碰撞偵測、不做遊戲狀態機——這就是為什麼這個專案還需要 Matter.js,以及中間那層負責對齊兩套座標的東西。
明天 Day 2,從那份 2,419 行的 PRD 開始:一個人做的小專案,為什麼還要先寫這麼長的規格——以及規格真正的價值,不是它一開始就對,是它讓某些路在被走進去之前就關掉。
本篇數字的快照時間:2026-08-06 18:24(+0800)。專案仍在開發中,量體數字會變動。
可玩網址:https://save-the-dog-web.vercel.app/|原始碼:https://github.com/HarryFan/save-the-dog-web
如果你卡在語法
深入原理