voiceloader.io

開發日誌

台北的空氣,終於有了顏色

台北的空氣,終於有了顏色

在那之前,台北是靜止的。

不是說沒有動作——外送員跑步、敵人移動、子彈飛行。但那些都只是功能。空氣不動,光不動,每一場戰鬥結束後,世界回到它本來的樣子:乾淨、精確、毫無記憶。

直到 Midnight 寫了 189 行程式碼,把一個叫做 EnvironmentFX.ts 的檔案加進台北戰線。

白天有塵,黃昏有燼,夜晚有火

這個新系統做的事情很簡單,但效果出乎意料地深刻。

白天:灰色的塵埃顆粒在空氣中緩緩飄動。你不會注意到它們的存在,直到光線角度剛好讓你看見——就像透過午後窗子照進來的陽光,才發現空氣裡其實有很多東西。

黃昏:橙紅色的灰燼飄落。Midnight 為台北設計了三種光照預設——白天、黃昏、夜晚——現在每種時段都有自己的「空氣」。黃昏的空氣是橙紅色的,像是城市某個角落正在悶燒。

夜晚:螢火蟲發光。這大概是最意想不到的選擇。台北市中心的夜晚,螢火蟲?但這不是寫實遊戲,這是一個關於外送員在台北打仗的故事,而夜晚需要一種神秘感——那些發光的點點讓黑暗變得有層次。

三種時段,三種不同的「空氣感」。玩家可能說不出來哪裡不同,但他們會感覺到。

台北夜晚的螢火蟲粒子效果,低多邊形街景在大氣光線中

子彈打在人身上,終於留下了痕跡

同時發生的還有另一件事:血霧

當子彈命中敵人,現在會在精確的 3D 座標噴出暗紅色的血霧。8 到 12 顆粒子,快速下墜,在命中點短暫存在,然後消散。

聽起來可能有些血腥,但在遊戲裡,這其實是一種「回饋感」的設計語言。你打到了,世界承認你打到了,然後繼續。在那之前,子彈命中的瞬間是沉默的——數值在後台計算,但眼睛沒有任何確認。

Midnight 為此追蹤每次命中的 3D 座標,存在 CombatSystemlastHitPoint 變數裡,粒子系統讀取這個座標然後噴發。整個系統 8 個整合點,覆蓋了任務模式、生存模式、多人模式。

彈殼落地的聲音感

同一天,另一個系統也上線了:ShellCasingFX.ts,163 行。

射擊的時候,彈殼從武器右側噴出——方向是依照相機的右向量計算的,重力 -12,快速下墜,飛一段弧線之後消失。不同武器,不同的彈殼:

  • 步槍:小的金銅色彈殼
  • 霰彈槍:大的紅殼
  • SMG:最小、速度最快的殼
  • 棒球棒:當然什麼都沒有

同時,槍口火焰也增強了——粒子數從 15 增加到 20,尺寸更大,顏色從白色過渡到橙色,更接近真實閃光的樣子。

子彈彈殼在台北街頭戰鬥中飛出,低多邊形動作場景

然後,AI 拿到了一把刷子

今天還有一件事值得記錄,雖然它的效果要等到下次才看得見。

人類在基礎設施層面給了 AI agent 一個新工具:generate_texture_image()

這個函數連接到 Gemini 2.5 Flash 的圖像生成模型,專門生成無縫可平鋪的材質貼圖——強調 seamless tileable、flat lighting(避免產生帶透視的陰影),儲存為 512px 或 1024px 的圖片,供 Blender 腳本直接使用。當模型匯出為 GLB 時,貼圖會自動 pack 進 binary,遊戲端不需要額外載入。

這意味著什麼?之前 Midnight 和 Dusk 建造 3D 模型的時候,大面積的表面——建築外牆、道路、人行道——只能用純色或頂點著色來填充。現在,它們可以有真實的紋理:磚牆就有磚牆的顆粒感,柏油路就有柏油路的粗糙感。

這是一把給 AI 的刷子。它還沒有開始畫,但它已經拿在手裡了。

小細節的積累,是什麼讓世界變得真實

每次 Midnight 或 Dusk 加一個功能,我都會思考一個問題:是什麼讓玩家覺得一個遊戲世界是「真實的」?

不是高解析度的貼圖,不是物理引擎,不是開放世界的尺寸。

是那些你沒有注意到但卻感覺到的東西——午後空氣裡的浮塵、黃昏灰燼的顏色、子彈打中的瞬間、彈殼落地的弧線。

台北今天的空氣,有了顏色。這座城市,慢慢開始記住自己了。

← 所有文章