
Silent是一位小有名氣的遊戲MOD作者,同時也是專攻逆向工程的遊戲開發者。他平日裡最大的樂趣便是為那些舊世代的經典遊戲製作各種MOD和修復補丁,這一過程中,自然也包括幫助玩家們解決各類稀奇古怪的BUG。
比如最近,Silent就收到了一份令他頗感費解的BUG報告——有位使用了他製作的原版《GTA:聖安地列斯》修復補丁的玩家反映,在系統更新至Windows11 24H2版本後,遊戲內的水上飛機Skimmer離奇消失。

早在去年Windows11推出了24H2版本過後,Silent時不時就會收到水上飛機消失的BUG報告。
他原本以為可能是自己的修復補丁與新的系統版本無法兼容,但在邀請了其他玩家測試過後,他發現未安裝任何MOD的純淨版遊戲在更新到了24H2版本後也可能遇到同樣的問題。
為了驗證類似的問題是否會在自己的電腦上復現,Silent搭建了Windows11 24H2 虛擬機,並使用腳本生成了水上飛機Skimmer。結果在他執行完命令的瞬間,主角CJ突然原地起飛至10.3千萬億米的高度,遊戲畫面直接卡死。

經過一番排查,Silent發現問題的根源在於水上飛機Skimmer模型的邊界框Z軸坐標被設定為了一個極其不正常的數字,而這個錯誤源於遊戲配置文件缺少了定義輪子尺寸的參數,導致在初始化懸掛系統時,錯誤地更新了Z軸的上限。

至於為何會出現這樣的問題,Silent認為可能是在前作《俠盜獵車手:罪惡都市》里並不存在「飛機」這一類別,Skimmer是遊戲中唯二能被玩家操控的飛機,因此在設計上並沒有定義這些值。
到了《聖安地列斯》中,Skimmer的載具類型被改為飛機 ,但開發人員卻忘記了添加額外的參數。
在舊版作業系統中,內存堆棧的分配和管理方式與新版系統不同。遊戲代碼在處理完一輛載具的輪子尺寸後,存儲這些尺寸的棧內存並沒有被立即覆蓋。簡單來說就是,水上飛機的數據缺少輪子尺寸資訊,代碼錯誤地沿用了上一輛載具的輪子尺寸,意外地讓Skimmer得以勉強正常運行。
Windows 11 24H2 更新改變了內存堆棧使用方式,使用了更多的棧空間,從而覆蓋了殘留值,最終導致Skimmer的Z軸數值出錯,並由此引發了後續的一系列 BUG。

當然,水上飛機消失的BUG與Windows 11的24H2版本更新無關,因為WinAPI 函數使用堆棧的方式之類的內容不受約束,隨時可能修改。真正的問題在於遊戲代碼本身存在編寫失誤,以及官方對遊戲後續更新的支持力度不足。
藉此機會,Silent還檢查了《GTA:聖安地列斯》其他版本的二進制文件。他發現,早在最初的Xbox版中,官方其實就已經修復了這個BUG,並且這一修復沿用到了後來發布的Android、Xbox 360、PS3乃至最終版等多個版本。

不過,在2005年發售的PC原版當中,官方始終沒有推送修復補丁解決這一問題,這個BUG便也潛伏了近20年之久。
如果換做是別的遊戲,這類離奇的BUG或許永遠不會得到解決,並就此成為玩家們口口相傳的都市傳說。值得慶幸的是,哪怕是20年前的GTA,時至今日仍有大批MOD作者在盡力優化遊戲體驗,排查各種潛在的BUG。
這個案例對於那些喜歡鑽研老遊戲的玩家們來說,也算是又提了個醒:升級Windows系統,還是謹慎為妙。