Whisper Isle 遊戲連結(PC Only):whisperisle.app(註:專案每日持續高速演進,撰文當下線上已推進至 v0.2.1)
昨天在 Day 2 聊完了 monorepo、Pixi.js v8、Colyseus 0.17 以及無 DB 開局的技術選型。按照傳統的軟體開發思維,接下來大家通常會埋頭苦幹:先把地圖畫出來、把人物移動做順、把怪物的戰鬥迴圈寫完,等到整個遊戲有一點模樣了,在專案收尾的最後一週再來研究怎麼買網域、租主機、寫 Dockerfile 部署上線。
但在 Whisper Isle 開工的第一天(2026-07-09),做完基礎骨架後的下一件事,不是讓人物在地圖上走動,而是直接把這個空的黑色畫布專案推上了雲端 PaaS 服務。為什麼一個連怪都還沒做,角色都還不能動的空畫布,儘速推上去線上環境?
跟 AI 協作開發時,最大的陷阱之一就是「本機幻覺(Localhost Illusion)」。AI 寫程式時對真實的執行環境是沒有物理體感的,只要在它的沙盒環境裡能編譯過,在本地端開得起來,它就會認為這項任務已經完成。但真實的公網環境完全是另一回事:跨網域 CORS 阻擋、反向代理的 WebSocket 升級逾時、TLS 證書握手、容器環境的路徑解析、動態連接埠注入。
如果放任 AI 在本地開發了一個月,累積了幾百個檔案和複雜的依賴,才在最後一天準備部署,你很可能會迎來一場長達數天的 Infra 地獄,這時候只要一個設定報錯,你根本分不清楚到底是哪一天的哪次改動踩了坑。
對獨立開發者加上 AI 的組合來說,持續可玩(Continuously Playable)是一條必須恪守的紀律:每天工作結束時,線上環境都必須是一個能夠正常運行,可以被真實點擊的版本。可運行的公網狀態,是我們排除 AI 幻覺與進度欺騙的唯一真相。
做多人連線網頁遊戲,最省事的作法通常是用同一個 Node.js 伺服器:Server 既要負責處理即時 WebSocket 通訊,又順便當 Express 靜態檔案伺服器把 HTML 和 JS 包丟給瀏覽器。
但我們將它們拆成兩個獨立服務:
在常理認知中,一個連玩家都沒有的空專案,通常不太會需要埋 Analytics 或寫 SEO 設定。
但我們在第一天就把 robots.txt、sitemap.xml 和 Google Analytics (GA4) 埋進了 client/index.html。這不是為了宣傳,而是為了把「生產環境」與「開發環境」的資料邊界劃清楚。
AI 在寫 code 的過程中,每幾分鐘就會重新觸發一次 hot reload;我們在本地測試或跑自動化腳本時,一天可能就會產生上千次虛假頁面瀏覽。如果不做防護,正式上線後你的分析儀表板就會被自己和 AI 刷成垃圾數據。
因此在第一天接上 GA4 時,我們就刻意寫了環境隔離防線:
<!-- client/index.html -->
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
// 防線:只有在正式網域名稱下才載入真實上報 script
if (window.location.hostname === 'whisperisle.app') {
var s = document.createElement('script');
s.async = true;
s.src = 'https://www.googletagmanager.com/gtag/js?id=xxxxxx';
document.head.appendChild(s);
gtag('config', 'xxxxxx');
}
</script>
在本地 localhost 開發時,gtag 始終只是一個空的 stub 函式,隨便呼叫都不會發送真實封包,徹底杜絕了測試流量對營運數據的污染。
明天我們將正式進入遊戲世界,把怪物、戰鬥與升級的核心迴圈做出來,要讓數值全部由表格驅動。