In English — I don't write code. After shipping a retro tank defense game, I reused its engine to build something with a point: a top-down game about hospital infection control, where antibiotics do nothing to viruses and only UV clears the spores — so the strategy is the public-health lesson. Reusing the engine made it fast and 45 automated checks passed. But the most unsettling bug of the whole project wasn't in the game: another background process was serving my old tank game on the same address, so for a while my verification was reading the wrong file. A green check pointed at the wrong target is scarier than a red one.
The scariest bug wasn't in the game
我的測試在替「另一個遊戲」改考卷 | My tests were grading a different game
先講最毛骨悚然的一段。
做這個防疫遊戲時,我照慣例讓 AI 開一個本機伺服器、用機器人瀏覽器打開遊戲跑自動化驗收。跑一跑,我請它去確認一個檔案內容,結果它抓回來的程式碼——是我上一個坦克遊戲的。
當下很錯亂:明明改的是防疫遊戲,怎麼驗證讀到坦克的檔案?追下去才發現:我電腦上另一個工作視窗,早就在同一個網路埠上開著坦克遊戲的伺服器。兩個伺服器搶同一個門牌,連線時有時候被導去坦克那台。也就是說——那一小段時間,我的自動化測試是對著錯的對象打分數。
這比測試失敗可怕多了。測試變紅,你會停下來查;測試變綠,你會放心往前走。但如果它綠得很開心、卻是在幫別的遊戲改考卷,你會帶著假的安全感一路蓋房子。
修法其實是紀律:每次跑測試前,先確認伺服器是不是「你這一台」——換一個沒人用的冷門埠、開跑前先驗一下網頁標題與檔案內容對不對,是自己的遊戲才開始信任後面的結果。這一條後來被我寫進了跨專案的踩坑筆記。

Why an infection-control game?
把街機公式變成衛教 | Turning an arcade formula into public health
坦克遊戲很純粹:守基地、擋敵人。做完之後我想試試——同樣一套「守住底線、擋下一波波敵人」的街機骨架,能不能拿來講一件有意義的事?
於是有了這個題目:你是一名感染管制醫師,病原體從醫院上方湧入,要攻擊底部的 ICU 重症病人。你手上有三種工具:酒精噴霧、抗生素、紫外線消毒器。
關鍵設計是——用錯工具不是「比較弱」,而是「這就是衛教本身」:
- 抗生素打病毒,傷害是歸零的(畫面直接跳「無效」)——因為抗生素本來就治不了病毒感染。
- 芽孢對酒精幾乎免疫,得靠紫外線或環境消毒。
- 抗藥性細菌血厚、優先撲向病人,逼你組合手段。
玩家為了贏,會自然學會「什麼病原體該用什麼」。這不是在遊戲裡塞一段衛教文字,而是把知識寫進勝負規則裡。
Standing on my own shoulders
不是從零開始,是拿自己的引擎改 | Reusing a proven engine
這次我沒有從白紙開始——我把上一個坦克遊戲的引擎骨架整包拿來改。四方向移動、格子地圖碰撞、砲彈子步掃掠、波次狀態機、粒子系統、Web Audio 即時合成音效……這些「怎麼讓一個 2D 俯視角遊戲順順跑」的底層,坦克版已經驗證過了。
所以大部分工作變成換皮與擴充:把坦克換成醫師、磚牆換成污染隔板、基地換成 ICU 病人;再疊上坦克版沒有的新系統——三種工具的抗性矩陣、污染區、洗手台、隔離門、三階段 Boss。
這件事本身就是一課:好的架構是可以重複用的資產。第一個專案我把數值、繪製、邏輯拆得夠乾淨,第二個專案才有辦法「站在自己的肩膀上」快速長出來。如果第一版寫成一坨,這次就得整個重來。
The AI grades its own homework — again
45 條驗收,全綠才上線 | 45 checks, green before ship
一樣的分工:我出題(這次是一份 30 節、附 45 條驗收條件的需求書),AI 寫程式、寫自動化考卷、自己修到全綠。機器人瀏覽器會實際開遊戲、移動醫師、切換工具、發射,再檢查遊戲內部數值:病人生命有沒有正確扣、抗生素打病毒是不是真的 0 傷害、Boss 是不是真的有三個階段、重新開始有沒有殘留上一局的敵人。
45/45 全綠,我才按下部署。但——你大概已經猜到了——真正好玩的部分,還是在「全綠之後」。

Ten minutes of real play, three things no test caught
全綠之後,真人一玩就露餡 | Playing finds what tests don't
跟坦克版一模一樣的劇本又上演了一次:45 項自動檢查全過,我自己坐下來玩十分鐘,抓到三個它們都沒抓到的問題——而且全是「機器不會在意、但真人一定會卡住」的體感問題:
- 右邊的數字鍵盤沒反應。 切換工具我寫的是主鍵盤上排的 1/2/3,測試也是用那三顆按鍵驗的、全綠。但我習慣用右側的數字鍵盤,那是另一組完全不同的按鍵代碼——結果我狂按都沒反應,還以為切換壞了。(修法:兩組按鍵都收。)
- 上方的敵人被狀態列蓋住。 敵人的出生點太靠上,剛好躲在畫面頂端的資訊列後面,看起來像從牆裡冒出來。測試只檢查「敵人有生成」,不在意「玩家看不看得到」。(修法:把出生點下移,並幫遊戲場加一道上緣邊界。)
- 按了鍵卻沒有回饋,就像壞了。 切工具時畫面沒動靜、按「關隔離門」時門還好好的沒反應——功能其實都對,但沒有回饋 = 感覺故障。(修法:切工具時在角色頭上跳出工具名+「按 Space 使用」;關門時依情況回「門完好/整備中/已關閉」。)
這三個沒有一個是「程式錯誤」,全是體感落差。測試驗的是「我想到要驗的事」,真人玩會撞到「我根本沒想到的事」——尤其是身體記憶(我的手就是習慣右邊數字鍵)、視覺遮擋、操作回饋這種東西,機器不會替你在意。
Extensions in an afternoon
地基好,加功能就便宜 | Good foundations make features cheap
跟坦克版第二天加寶物一樣,這次上線後一個下午又疊了四樣東西:
- 難度選擇(簡單/普通/困難):一次調整敵人血量速度、病人受傷、玩家無敵時間。
- 無盡模式:波次程序化持續變強、每五波一隻菌王,比存活與分數。
- 疫苗接種站:走過去替病人開一段「疫苗防護」大幅減傷——又是一個把衛教寫進機制的設計。
- 行動裝置觸控:左下虛擬搖桿+右下動作鈕,手機也能玩。
快的原因還是老話:數值集中管理、系統彼此不打架。加一個難度只是乘上幾個倍率,加疫苗站只是複製洗手台的模式再換效果。

Ship it
上線 | Deploy
跟坦克版同一條路:AI 把遊戲推上 GitHub Pages,綁上我在 Cloudflare 設好的網域,遊戲就住在 game-pandemic.tingyudeco.com。純靜態、零伺服器成本,之後改完 git push 就自動更新。
Takeaways
- 綠燈指錯對象,比紅燈更危險——跑測試前先確認「你驗的是不是自己這一台」,別讓假的安全感帶你蓋錯房子
- 好架構是會複利的——第一個專案拆乾淨,第二個才能站在自己肩膀上快速長出來
- 自動化驗你想到的,真人玩發現你沒想到的——尤其是按鍵習慣、視覺遮擋、操作回饋這類體感問題,機器不會替你在意
- 把知識寫進勝負規則,比在遊戲裡塞衛教文字更有效——玩家為了贏,自然就學會了
Links | 所有連結
- 🎮 線上遊玩:game-pandemic.tingyudeco.com
- 📖 完整攻略與說明書:操作、工具、敵人與新手攻略
- 💻 原始碼:github.com/Ttingyu1123/hospital-infection-defense
- 🛠️ 更多工具:tingyudeco.com/portfolio/tools
Appendix: the spec, condensed | 附錄:需求書重點
以下是餵給 Claude Code 的需求重點(30 節、45 條驗收,這裡整理成可直接取用的骨架),按右上角按鈕可整份複製,自由改造成你自己的專案。
你是一位資深 HTML5 遊戲工程師、遊戲系統設計師、醫療教育遊戲設計師與軟體測試工程師。
請直接建立一款可在瀏覽器執行的 2D 俯視角動作防守遊戲《醫院防疫大作戰 / Hospital Infection Defense》。玩法可參考經典俯視角迷宮防守與波次生存遊戲的結構,但不可使用任何受版權保護的名稱、圖像、地圖、角色、音效或素材。請實際建立完整專案、執行、測試並修正錯誤,直到遊戲可正常遊玩。
一、核心概念
玩家扮演感染管制醫師,在醫院內阻止病原體擴散,保護位於地圖底部中央的「ICU 重症病人」。需在走廊移動、使用不同感染控制工具攻擊病原體、清除污染區、擊退一波波細菌與病毒,並在最後一關擊敗抗藥性 Boss。兼具明確動作性、感染控制教育元素與清楚易懂的繁體中文介面。
二、技術規格
HTML5 + CSS + JavaScript + Canvas。不使用任何前端框架或遊戲引擎、不依賴 CDN、不使用外部圖片或音效檔;所有角色、場景、道具、UI 以 Canvas 幾何繪製,音效以 Web Audio API 即時合成,可離線執行。邏輯解析度固定 960×720,CSS 等比縮放不影響碰撞。模組化檔案結構(constants / audio / particles / map / entity / projectile / tools / items / player / pathogen / boss / game / main)。
三、玩家與操作
感染管制醫師:白袍、口罩、聽診器、藍綠識別色,含待機/移動/攻擊/受傷閃爍/無敵護盾狀態。WASD 或方向鍵四向移動(移動同時決定攻擊方向);Space 使用工具;1/2/3 或 Q/E 切換工具;C 重新關閉隔離門;P 暫停;M/B 音效/音樂;R 重新開始;Enter 開始/關閉提示。不可穿牆、病床、設備、其他角色與地圖邊界;受傷後短暫無敵並閃爍。
四、三種感染控制工具(含抗性矩陣)
- 酒精噴霧:近距扇形 AoE、清污染,對一般細菌佳、病毒普通、芽孢極差。
- 抗生素發射器:直線投射物、射程長,對一般細菌佳,對病毒無效(顯示提示),對抗藥性低。
- 紫外線消毒器:慢速直線光束、可貫穿多個敵人並清污染,剋病毒/芽孢/污染/Boss 護盾;冷卻長、耗能高。 每種工具有獨立能量池與冷卻;不同敵人對不同工具有不同傷害倍率。
五、四種病原體 + Boss
一般細菌(綠、朝病人)、快速病毒(紫、不規則、成群、抗生素無效)、芽孢細菌(黃褐、厚血、留污染、酒精極差)、抗藥性細菌(深紅、優先攻病人、快速腐蝕隔板)。第五波 Boss「超級抗藥菌王」三階段:緩進生成小兵→血量 60% 加速並污染地面→血量 30% 狂暴,週期生成護盾(紫外線可快速破除)。敵人 AI 用有限狀態機+方向權重+卡住偵測+視線判斷,不逐幀改向、不長時間卡牆。
六、場景與保護目標
醫院走廊、護理站、病房、ICU、設備、洗手台、隔離區、警示標誌,可愛卡通幾何風、不寫實不血腥。ICU 病人有生命條與心電監視器,接觸/被投射物命中會扣血,歸零即失敗;周圍有可破壞隔板與可重新關閉的隔離門。加入污染區(減速玩家、增益病原體、可被酒精/紫外線清除)、洗手台增益、疫苗接種站、PPE、消毒補給、急救包、隔離警示卡。
七、波次與教育提示
至少五波(基礎清潔→病毒入侵→環境污染→抗藥性危機→Boss),每波開始提示、清光才進下一波、完成給分並回復病人少量生命。首次觸發特定事件顯示一次性衛教卡(抗生素對病毒無效、芽孢耐酒精、手部衛生、環境污染、抗藥性、PPE、疫苗)。明確標示「本遊戲為教育與娛樂用途,不取代正式醫療建議或感染管制指引」。
八、狀態機、碰撞與效能
狀態:START / TUTORIAL / PLAYING / PAUSED / WAVE_TRANSITION / PLAYER_RESPAWNING / BOSS_INTRO / GAME_OVER / VICTORY。穩定 AABB/圓形碰撞涵蓋玩家、敵人、投射物、地形、病人、道具、邊界。requestAnimationFrame + delta time(含上限)、安全陣列刪除、粒子與敵人數量上限、物件池;重新開始零殘留、不重複註冊事件、不產生雙重迴圈。
九、驗收條件(45 項,節錄)
頁面開啟、四向移動、無法穿牆/穿病床、切換三工具、酒精近距命中、抗生素直線且對病毒無效、紫外線命中多敵、四種病原體可生成、敵人朝病人前進且遇障礙改向、玩家與病人可受傷、受傷無敵、病人/玩家歸零失敗、污染可傷可清、洗手台與 PPE 生效、道具拾取、波次切換、Boss 三階段且擊敗顯示勝利、暫停與音效開關、教育提示只顯示一次、R 重新開始不殘留、Console 無持續錯誤、縮放不影響碰撞、切分頁不瞬移、長時間無記憶體累積、所有主要文字為正確繁體中文。
十、工作流程與回報
檢查目錄 → 建檔 → 最小可玩版 → 執行 → 查 Console → 加敵人與病人保護 → 加三工具 → 加其他敵人與波次 → 加污染/洗手台/PPE → 加 Boss、教育提示、UI、音效、粒子 → 完整驗收 → 主動修錯 → 更新 README → 最終回報。不要每個小步驟停下詢問,自行做合理決策並持續完成;進階功能若嚴重影響穩定性,先採較簡單但可運作的實作。




