Windward

一名茶馬幫工背負九十公斤磚茶翻越喜馬拉雅山口,山口上的強風以肉眼可見的陣風形式襲來。按住以拄杖穩住身形;放開則繼續前行。頂風雖然安全,卻並非無代價——燈油會隨你的選擇而燃盡,而背上的負重擺動又比你的步伐慢了半拍,因此若強風正好在你邁步途中襲來,就會將你吹落懸崖。九段過山旅程,由 AI 智慧代理在 Linux 無畫面環境下使用 Cocos Creator 從頭到尾打造完成——幫工的行走、頂風與跌落動作皆以僅 2,275 位元組承載的真實動作捕捉資料呈現。

立即遊玩

按住畫面任意處以頂風‧放開以行走——滑鼠、觸控或空白鍵 · R 重新開始 · P 暫停 · M 減少動態效果 · N 靜音
資料量 2,379,340 位元組(原始)/965,836 位元組(gzip)· 數秒內即可載入並開始遊玩 · 支援直向、桌面與手機

▶ 開始遊玩

概念即契約

概念稿在任何程式碼寫成之前先行產出,最終成品則會逐區域比對稽核——提示板上的十項道具,各自對應到一列庫存清單,以及最終上線的檔案。十項中有九項相符,第十項則被記錄為偏差並附上原因,這正是唯一有意義的一致性檢查方式。

概念稿 C1:一名茶馬幫工在積雪懸崖邊頂著側風前行
C1——主視覺畫格。身體的傾斜並非畫進美術稿中,而是源自動作捕捉資料本身:行走時約為 2°,頂風時則接近 25°。
實際運行中的 Cocos 版本,正處於過山途中
實際運行版本。同一處懸崖、同樣的負重、同樣的墜落——而畫面中的人物其實是由烘焙關節角度驅動的十片剪影精靈圖。

動作捕捉資料是承載內容,而非動畫本身

這件作品的存在是為了回答一個問題:在主套件僅 4 MB 的等級限制下,真實的人體動作要付出多少成本?每個動畫使用一張精靈表是負擔不起的,骨架運行時系統更是想都別想,因此行走、頂風與傾倒動作皆從 CMU 動作捕捉資料中萃取,簡化為每格每肢一個角度,最終以 2,275 位元組的 JSON 呈現。三段動畫、共四十格畫格。人物本體是一個十肢剪影階層結構;同一套正向運動學同時驅動灰盒階段的桿狀人偶與最終製作完成的精靈圖,這也是為何替換美術資源時,沒有動到任何一個玩法數值的原因。

灰盒階段:以扁平幾何形狀繪製的相同過山場景
灰盒階段。整個九段過山循環以扁平幾何形狀完整跑過一遍,盲測可讀性檢查也在此階段進行——共進行了兩次,因為第一次未通過。
幫工頂著強風、拄杖穩住身形
頂風姿勢。截取自 CMU 15_04 的一段動作片段,三格畫格、維持不動——由於步伐停止,負重的擺動也隨之停止。

在 Blender 中以程式建模,並以最終尺寸製作

十四列庫存清單、十七張已渲染精靈圖、一張搭配對應攝影機空間法線圖的 512×512 圖集。幫工各部位以每公尺 249.6 像素渲染——也就是實驗室共用的 96 PPU 乘上此人物的比例——因為那正是它們在螢幕上的實際大小,所以每個部位皆以 1 倍比例繪製,不需重新取樣。若以 96 PPU 渲染後再於引擎中放大,那是前一輪循環已在另一套服裝上付出代價學到的教訓。

已渲染完成的幫工部位精靈圖
剪影組件。每個部位皆以其關節位於原點方式建模,圖集則記錄該關節裁切後落在何處。
概念稿 C2,十項道具提示板
C2,用來稽核比對的提示板。
道具圖集,反照率貼圖
一張 512×512 的圖集收納了幫工本人、其負重與整段山口場景。
對應的攝影機空間法線圖集
對應的法線圖——版面完全一致,因此一組 UV 座標即可同時對應兩者。

看不見來襲的強風,稱不上是一種遊戲機制

祈禱旗會在風吹到之前先繃直,而提示訊號是 形狀 形狀的改變而非色調的改變,因為在你盯著自己腳步時,形狀更容易用餘光辨識。每個關卡在被遊玩之前都會先經過驗證:警示時間窗、陣風之間的最小間隔,以及燈籠是否真的能涵蓋整段穿越,並負擔所有這些的成本。若某個關卡未通過驗證,就會印出 FAIR=false 而稽核失敗會導致建置失敗。這項驗證曾抓出一個無法支撐自身穿越所需的燈光預算。

強風襲來,旗幟被吹得筆直,畫面中劃過陣陣風痕
強風襲擊瞬間。顏色標示危險、動態標示風勢——兩個獨立通道、各司其職;風痕絕不使用紅色。
同一段過山場景於手機畫面上的呈現
同一段過山場景於 390×844 解析度下的呈現。每個檢查點皆同時於桌面與手機上稽核;曾有一次直向設計解析度掩蓋了一個只有在桌面版才能發現的渲染錯誤。

誠實的實測數據

每一項數字皆於最終上線版本上實測而得。此實驗室的招牌問題,便是某項能力相對於 4 MB 限制要付出多少成本,而本輪循環則為這張表新增了動作捕捉這一項。

量測方式條件
微信主套件2,462,582 位元組(2.35 MiB)佔 4,194,304 位元組上限的 58.7%
剩餘可用空間1,731,722 Bunused
真實動作捕捉的成本2,275 B3 個片段、40 幀、10 個肢段——僅佔上限的 0.06%
——相較之下,真實 Box2D415,693 B9.9%,在第 2 輪以相同方式測得
——以及真實的圖塊地圖143,558 B3.4%,在第 4 輪以相同方式測得
道具圖集234,728 B反照率+攝影機空間法線貼圖,512×512,17 個精靈圖
音訊248,024 B7 個取樣樂器的單聲道 MP3
每次建置都會修剪未使用的字型868,140 B佔建構器預設隨附上限的 20.7%,而本作品並未使用到
網頁建置原始 2,379,340 B/gzip 965,836 Bweb-mobile 目標平台
實測通關9/9 次穿越成功,桌面與手機皆是,0 錯誤桌面 1280×720 與手機 390×844,使用 Playwright
圖形背景的成本隱藏後從 4.3 fps → 9.9 fps透過在執行時逐一停用場景圖層來獨立測量;軟體 GL,共用主機
——同一箱、同一分鐘、姊妹作品13.9 fpsKarez,已上線且乾淨——作為對照組,用來說明這個數字有多少來自機器
裝置驗證待驗證WeChat 開發者工具僅支援 Windows/macOS;詳見下方說明

尚未證實的部分。本作品從未在手機上實際執行過。WeChat 封裝在結構上有效,且相同程式碼在無頭 GL 環境下能順利運作,但這僅能證明程式碼的一致性與渲染能力,並不能證明它能在 WeChat 中啟動。這需要營運方憑證與實體裝置才能驗證,在此之前不會做出這項聲明。

真實的引擎功能,靠實測換來

第 1 輪靠自製光照著色器贏得引擎的信任,第 2 輪靠真實的 Box2D 物理實體,第 3 輪靠自行生成材質,第 4 輪則讓圖塊地圖本身成為狀態。而這一輪,是靠在無法負擔其他做法的層級上,將真實人類動作當作資料來承載,贏得引擎的信任。

作為資料的動作捕捉

三段 CMU 片段被簡化為每幀每肢一個角度——整段步態僅需 2,275 B。

剪影階層結構

十個肢段,遠側先繪製並調暗,以正向運動學擺出姿勢。

擁有自身物理特性的負重物

堆疊物是由髖部擺動驅動的阻尼彈簧;它會落後於步伐,而這個延遲正是危險所在。

經過驗證的公平性

每個關卡在被遊玩之前,都會先驗證其警示時間窗、陣風間距與燈光預算。

一個能用餘光讀取的提示訊號

旗幟改變的是形狀而非顏色——是兩種經過設計的狀態,而非單純的色調變化。

一個動作,兩種輸入方式

透過一組共用的處理程序按住以穩住身形;滑鼠與觸控輸入分別偵測。

9 次穿越,36→52 公尺 行走速度 1.5 m/s 燈籠持續 50 秒 每次穿越 4→8 陣風 警示時間 2.3→0.9 秒 最小間隔 2.0 秒 擺動超過 26° 即倒塌 40 幀動作捕捉資料 96 PPU,美術資源為 249.6