用 Claude Fable 5 一次提示就完成《浣熊大劫案》遊戲
原文由 Simon Willison 于 發布,訂閱此部落格
早在 2022 年,我曾發文分享了用 GPT-3 生成的遊戲概念截圖,以及用 DALL-E 製作的概念「美術圖」。今天,正好是那則貼文的四週年,我決定試試看,能不能讓 Claude Fable 5(在Claude Code for web 上執行)直接根據那則貼文的內容,把整個遊戲做出來。結果它表現得還不錯!
你可以在這裡試玩遊戲。這裡是GitHub 儲存庫,還有一段簡短的示範影片:
我是怎麼做出來的

我當時給 GPT-3 的提示詞是:
Write a detailed product description of a computer game where a team of raccoons go on heists.
那時還是文字接續的時代,你給 GPT-3 一段文字,讓它把剩下的部分補完。它的續寫是:
在《Raccoon Heist》中,你和你的浣熊竊盜小隊將執行一連串大膽的劫案。從搶銀行到竊取無價藝術品,再大再小的案子都難不倒你這群毛茸茸的夥伴。你得靠智慧與技巧躲過警察,帶著戰利品全身而退。憑藉刺激的遊戲玩法與討喜的角色陣容,《Raccoon Heist》是任何想來場輕鬆劫案冒險的玩家的完美選擇。
我給 DALL-E 的提示詞很短:
Screenshot from a video game where a team of raccoons go on a heist
今天的實驗是:能不能把那些截圖直接丟給 Fable 5,再加上一段要它寫遊戲的提示詞,然後就放手讓它自己發揮,最後得到一個可玩的遊戲?
設定 Claude Code for web 搭配 GitHub Pages 使用
Claude Code for web 令人困擾的一點是,在它還在運作時,很難測試它正在做的東西。
我一直用 GitHub Pages 來繞過這個限制,發現效果非常好。
我的流程是這樣的:
- 在 https://github.com/new 為專案建立一個新的儲存庫——公開或私人都可以,這個技巧兩種都適用。
- 在 Claude iPhone 或桌面應用程式,或是在瀏覽器中透過 https://claude.ai/code 啟動一個 Claude Code for web 工作階段
- 告訴 Claude 要做什麼,並請它盡快提交一個
index.html頁面。這會建立一個名稱類似claude/3d-raccoon-heist-game-50n293的分支 - 前往儲存庫的 Settings -> Pages 區域(以我為例是
github.com/simonw/raccoon-heist/settings/pages),選擇「Deploy from a branch」,選好分支名稱後按下 Save。
這樣就完成了!每次推送後大約 30 秒內,最新內容就會出現在 yourname.github.io/your-repo/。
如果你用私人儲存庫這麼做,任何猜得到儲存庫名稱的人都能看到已發布的內容。我自己是不太擔心這點。
給 Fable 5 的提示詞
以下是我給 Fable 5 的提示詞(在手機的備忘錄 App 裡寫的——整個專案都是在手機上完成的)。我同時附上了原始貼文中的兩張圖片。
Build this 3D game, for the browser.
This repo is configured to serve static files so make sure there is an index.html that loads everything else.
Make sure it is mobile-friendly (touch controls, works well on small screens).
You have an OpenAI API key and access to their image generation model APIs, use that for textures to use with your 3D models. Docs here: https://developers.openai.com/api/docs/guides/image-generation - use gpt-image-2
Work independently - do not ask me to make any further design decisions. Make sure the game is fun, a little surprising, has good raccoon heist vibes, and is visually pleasing.
Commit and push as often as possible so I can preview your work - start with an index.html that presents a title screen, then build from there.
Append to a notes.md file as you work, including your changes to that as part of every commit.
我沒有指定任何技術選型。我假設(結果也猜對了)它大概會用 Three.js,這是根據先前的實驗判斷的。
讓 Claude 存取 OpenAI 金鑰,結果發現對於補足它能力的缺口非常有效——在這個案例中,我們需要某種方式來產生圖片作為材質貼圖。Fable 在撰寫生圖提示詞方面非常厲害!
我會寫「獨立作業——不要再請我做任何進一步的設計決策」,是因為我想看看它能不能在沒有我進一步介入的情況下,做出一個完整、可玩的遊戲。
我也寫了「盡可能頻繁地提交並推送,這樣我才能預覽你的成果」。當你在 Claude iPhone App 中使用 Claude Code 時,你會給它一個 GitHub 儲存庫,它會在一個分支上工作。告訴它「盡可能頻繁地推送」,就代表提交會馬上陸續出現在那個分支上。
我喜歡請它維護一個 notes.md 來增加一點額外的紀錄——這是完成後的檔案,以及它加入狗狗時寫下的那筆紀錄:
新增難度:從第 3 晚開始,院子裡會出現一隻巡邏的看門狗——一隻低面數的棕色獵犬,戴著紅色尖刺項圈,尾巴會搖擺。牠會在隨機地點之間遊走,在 12 單位距離內會聞到你的氣味並循味追蹤(視線是否阻擋無關——全靠鼻子,頭頂會顯示 👃 並伴隨吠叫)。如果你拉開 17 單位的距離,牠就會放棄追蹤。被抓到的提示訊息現在會依來源區分:警衛/車頭燈/獵犬。已透過自動化測試驗證遊走 → 追蹤 → 被抓的流程。
回顧對話紀錄
你可以查看Claude Code 共享工作階段,我也用了自己的 claude-code-transcripts 工具,匯出了自己的 HTML 版本,你可以在這裡找到。
Fable 先從一個索引頁面開始,內嵌了一份 Three.js 的本地副本,接著自己寫了一個 gen_textures.py 腳本(副本在此)。
它產生了這些材質貼圖,並抽樣檢查確認看起來沒問題。它為垃圾桶產生的 metal.jpg 檔案長這樣,不過我覺得在遊戲裡似乎沒有完全正確地套用:

接著它建構出遊戲的第一個基本版本,然後決定用 Playwright 「在預先安裝的 Chromium 中進行冒煙測試」。這代表它可以對自己的成果截圖並用肉眼檢查。它分別在桌機和手機寬度下都做了這件事,然後發現浣熊在手機寬度下會看不見,於是修掉了這個問題:
浣熊、垃圾桶藏身處和另外兩隻小隊浣熊現在在手機上都能完美顯示了。正在提交這個關鍵修正。
它決定產生一個標題畫面,並透過這個 gen_title.py 腳本來完成。以下是它為此使用的 gpt-image-2 提示詞:
Video game key art, low-poly 3D render style, moody nighttime scene: a cute low-poly raccoon wearing a tiny black burglar mask sneaking on its hind legs carrying a glowing gold coin, next to a tipped-over metal trash can, suburban house with warm glowing windows in the background, deep blue night, full moon, fireflies, cinematic rim lighting, charming heist caper mood. No text, no words, no logos.
而產生的圖片(Claude 覺得「超漂亮」)——不過我注意到,在桌機上顯示時,畫面會被裁切到只剩上半部的三分之一,浣熊就不見了!

接著是我最喜歡的改動:它加入了那隻狗:
export function makeDog() {
const g = new THREE.Group();
const BROWN = 0x8a6440, DARK = 0x5e4128;
const body = new THREE.Mesh(new THREE.SphereGeometry(0.42, 10, 8), M(BROWN));
body.scale.set(0.9, 0.8, 1.5);
body.position.y = 0.55;
body.castShadow = true;
g.add(body);
const head = new THREE.Mesh(new THREE.SphereGeometry(0.3, 10, 8), M(BROWN));
head.position.set(0, 0.85, 0.62);
g.add(head);
const snout = new THREE.Mesh(new THREE.SphereGeometry(0.16, 8, 6), M(DARK));
snout.scale.set(0.9, 0.7, 1.3);
snout.position.set(0, 0.76, 0.9);
g.add(snout);
const nose = new THREE.Mesh(new THREE.SphereGeometry(0.06, 6, 6), M(BLACK));
nose.position.set(0, 0.78, 1.08);
g.add(nose);
for (const s of [-1, 1]) {
const ear = new THREE.Mesh(new THREE.SphereGeometry(0.12, 6, 6), M(DARK));
ear.scale.set(0.7, 1.3, 0.5);
ear.position.set(0.2 * s, 1.08, 0.55);
g.add(ear);
const eye = new THREE.Mesh(new THREE.SphereGeometry(0.05, 6, 6), M(0x1a1a1a, { emissive: 0x331111 }));
eye.position.set(0.13 * s, 0.92, 0.86);
g.add(eye);
}
const tail = new THREE.Mesh(new THREE.CylinderGeometry(0.05, 0.09, 0.5, 6), M(DARK));
tail.position.set(0, 0.8, -0.62);
tail.rotation.x = 0.8;
g.add(tail);
// spiked collar
const collar = new THREE.Mesh(new THREE.TorusGeometry(0.22, 0.05, 6, 12), M(0xc0392b));
collar.position.set(0, 0.78, 0.5);
collar.rotation.x = Math.PI / 2.4;
g.add(collar);
const legGeo = new THREE.CylinderGeometry(0.07, 0.09, 0.34, 6);
const legs = [];
for (const [x, z] of [[-0.22, 0.35], [0.22, 0.35], [-0.22, -0.35], [0.22, -0.35]]) {
const leg = new THREE.Mesh(legGeo, M(DARK));
leg.position.set(x, 0.17, z);
g.add(leg);
legs.push(leg);
}
let phase = Math.random() * 10;
return {
group: g,
animate(dt, speed) {
phase += dt * (3 + speed * 10);
const amp = Math.min(0.6, 0.1 + speed * 0.6);
legs[0].rotation.x = Math.sin(phase) * amp;
legs[3].rotation.x = Math.sin(phase) * amp;
legs[1].rotation.x = -Math.sin(phase) * amp;
legs[2].rotation.x = -Math.sin(phase) * amp;
tail.rotation.z = Math.sin(phase * 1.5) * 0.4;
body.position.y = 0.55 + Math.abs(Math.sin(phase)) * 0.04 * (0.3 + speed);
},
};
}接著它用 Playwright 對此做了一輪測試,還截了另一張圖,其中包含:
// walk near the dog
await page.evaluate(() => { const d = window.__rh.dog; window.__rh.teleport(d.x + 6, d.z); });
await page.waitForTimeout(2000);
info = await page.evaluate(() => JSON.stringify({ dog: window.__rh.dog, state: window.__rh.state, player: window.__rh.debug().player }));
console.log('after approach:', info);
await page.waitForTimeout(3000);
info = await page.evaluate(() => JSON.stringify({ dog: window.__rh.dog, state: window.__rh.state }));
console.log('after chase:', info);
await page.screenshot({ path: __dirname + '/shot-dog.png' });
它又做了一些微調,然後宣告完成了:
Raccoon Heist 已建構、測試並推送 — 在
claude/3d-raccoon-heist-game-50n293上共有 7 次提交,全部透過自動化的 Playwright 遊玩測試驗證,涵蓋桌機、直式手機和橫式手機的顯示範圍。遊戲內容:你是一隻戴著面罩的浣熊,從小隊的垃圾桶藏身處溜進月光下的死巷。收集硬幣、寶石、戒指、甜甜圈和魚(牠們會可見地疊在你背上並讓你變慢),然後搖搖晃晃地走回家、在天亮前存起來。每一晚目標和難度都會提升:第 1 晚有 1 名拿手電筒巡邏的警衛,第 2 晚有 2 名,第 3 晚會加入一隻靠嗅覺追蹤、完全無視視線的獵犬。一輛警車會用車頭燈掃過街道,屋主會隨機從窗戶探頭,一隻海鷗會不時俯衝搶走你還沒收好的戰利品,披薩片會觸發 6 秒的極速 FRENZY,稀有的金色電視則價值 120 分,如果你能扛著它的重量回家就能拿到。勝利階級:TRASH PANDA ⭐ → CAT BURGLAR ⭐⭐ → MASTER OF DISGUISE ⭐⭐⭐,最佳紀錄會儲存到 localStorage。
建構方式:內嵌 Three.js(不用 CDN)、程序化生成的低面數角色,以及程序化生成的 WebAudio 音軌(帶有潛行感的 walking-bass 爵士樂加上所有音效——零音訊檔)。全部七張地面/牆面材質和標題畫面的主視覺都是用 gpt-image-2 產生,並作為靜態資源提交,因此部署後的遊戲不會發出任何 API 呼叫。手機版有動態觸控搖桿(點哪裡就出現在哪裡)加上 DASH 按鈕;桌機則使用 WASD/方向鍵和空白鍵。
測試抓到了兩個值得一提的真實錯誤:畫布在任何實體手機上都以 2 倍大小渲染(一個
cssText賦值清掉了 Three.js 的行內尺寸設定——桌機 DPR-1 的測試完全沒發現),以及勝利畫面的星級評分 div 繼承了標題畫面全螢幕的.starsCSS,默默吃掉了「下一晚」按鈕上的每一次點擊。兩者都已修復並完成回歸測試,同時也測試了拾取、存入、追逐/被抓、天亮、夜晚推進以及失敗/重試等流程。
notes.md裡有完整的建構紀錄。遊戲已經在分支上上線——只要提供儲存庫根目錄的服務並開啟index.html即可。
這遊戲好玩嗎?
作為起點來說令人印象深刻,但它稱不上是一款好遊戲。
你要操作浣熊在院子裡四處移動、收集物品——甜甜圈、魚、金幣、寶石——同時躲避拿著手電筒的警衛,到後面的關卡還要躲狗。你的負重有上限,裝滿後就得回到垃圾桶卸貨。如果你撿到披薩片,就會獲得短暫的加速效果。
完全沒有團隊機制——垃圾桶旁邊雖然有另外兩隻浣熊,但牠們只是裝飾,完全靜止不動。
隨著關卡推進,難度會稍微提升——第 3 關加入的狗是最有趣的新機制——但整體還是非常、非常容易過關。而且也相當無聊——每一晚都有固定的持續時間,你可以把所有物品都收完,然後在等天亮的期間無事可做。
我對它的實作感到印象深刻。它是完全 3D 的,有垃圾桶,手電筒的光錐效果很有趣,整體也有還算一致的視覺風格。它在手機上也能玩。音樂(根據 Claude 的說法是「程序化生成的 WebAudio 音軌(帶有潛行感的 walking-bass 爵士樂加上所有音效——零音訊檔)」)很簡單,但感覺還算到位。
作為一個已完成的遊戲專案,它很平庸。但作為單一提示詞產生的起點,我覺得已經非常厲害了。
我現在已經用 vibe coding 做了不少遊戲。從遊戲性的角度來看,它們都讓人相當失望——事實證明,設計出真正好玩的遊戲,依然是人類獨有的能力,而且需要遠比我或 Claude 所能提供的更多技巧與經驗。
話雖如此,我還是非常推薦把遊戲開發專案當作用來探索代理能力的方式。這是一種有趣、低風險的嘗試新事物的方法。如果你堅持做得夠久,甚至可能會做出值得一玩的東西!
更新於 2026 年 8 月 7 日:我用同樣的提示詞在運行 GPT-5.6 Sol Ultra 的 OpenAI Codex Desktop 上試了一次,得到明顯更好的結果——GPT-5.6 Sol 抓住了「一群浣熊去行竊」中小隊的重要性,並做出一款你必須在博物館中救出兩名隊友,然後疊在牠們身上去偷走 Golden Sardine 的遊戲。
隨機一篇部落格
留言
登入後參與討論