故事 › 一個檔案裡的地層

一個檔案裡的地層

本站測試機那份遊戲比賽畫面的介面檔有 2.5 MB。裡面只有 7.4% 是遊戲真正在用的。 另外 92.6% 沒有任何東西指向它 —— 但它就躺在那裡,而且還讀得出來

先說這些資料哪來的

本頁前半的數字都來自把 data/frontend/ingame.big 直接打開量測。 方法很簡單:讀出目錄記載的 47 個項目各佔哪一段位元組, 剩下沒被任何項目蓋到的區間,就是這頁在講的東西。

後面「拿原版一比」那張表另外量了 models.bigportrait.big 與剛安裝好的原版;「三代名字」那一節掃的是全部 332 個版面檔與 credits.tsv

目錄只指到十三分之一

項目數字
檔案大小2,665,562 bytes
目錄裡的項目數47 個
這 47 項合計佔用195,999 bytes
沒被指向的部分2,468,068 bytes(92.59%)
分成幾段24 段
最大的一段1,731,119 bytes

最大那一段有 1.7 MB,一個檔案裡有一塊比整個有效內容大八倍的區域, 沒有任何東西指向它

那 2.5 MB 是什麼

先看位元組本身怎麼分佈:

位元組佔比是什麼
0x0036.2%
0xFF22.4%全 1
0x2C8.1%逗號
0x30 / 0x318.3%數字 0 與 1

逗號跟數字這麼多,代表裡面有純文字

整段區域的亂度是 3.85(滿分 8 代表完全隨機或已壓縮), 34.1% 是可以直接列印的字元

壓縮過的資料不會長這樣。這裡面有沒有壓縮的東西

讀得出來的那 690 KB

把連續超過 400 個可讀字元的片段全部抓出來,篩掉不像版面檔的:

結果數字
未壓縮的版面檔文字區塊13 個
合計690,059 bytes
佔那片區域27.9%
裡面的畫面代號143 種

這是關鍵差異:遊戲現在真正在用的 47 個項目是壓縮過的, 而躺在那裡的這些是沒壓縮的純文字。不需要任何工具,記事本打開就能讀。

八個區塊,對得上現在的八個檔

用「畫面代號重疊」把每個未壓縮區塊對到現行的檔案,八個對得起來。

一個區塊常常不只裝一個版面檔。版面檔以行首的 END: 收尾, 照這條界線切回去,第 354,045 個位元組那一塊其實是四個完整的版面檔接在一起 (fes_ingametuning.fel 764 行、fes_ingameroster.fel 993 行、 fes_ingamepausemenu.fel 667 行、 fes_ingamerosterpitcheroptions.fel 207 行)再加一段尾巴。 所以下表把「整塊」與「切出來那個檔」分開列:

對應的現行檔案那一塊的行數切出來那個檔的行數現行的行數
fes_ingamepausemenu.fel2,698667667
fes_hudleft.fel2,3951,890
開頭被截掉
1,175
fes_ingamepausemenu.fel1,044667667
fes_ingameendofgamemenu.fel522478478
fes_ingameoverlay.fel484231
開頭被截掉
290
fes_ingamepitcherinfo.fel434394394
fes_ingamepitchersinbullpen.fel373205205
fes_ingamerosterbatteroptions.fel303151151

訂正:不是「八個全部都比現在長」

本站原本在這裡寫「八個全部都比現在長,沒有一個例外」,還舉了 「暫停選單那個少了兩千行、左側 HUD 少了一千兩百行」當例子。 (2026-09-05 訂正:那一欄量的是整塊區域,不是單一版面檔。)

切回單一版面檔之後,八列裡有六列跟現行的一樣長: 兩份暫停選單都是 667 行、結束選單 478 對 478、投手資訊 394 對 394、 牛棚投手 205 對 205、打者選項 151 對 151。其中第 800,617 個位元組那份暫停選單 跟現行檔案逐位元組完全相同(45,025 個位元組)。

真的比較長的只有左側 HUD —— 它讀得出來的部分就有 1,890 行,對現行的 1,175 行。 而比賽畫面疊層那一份讀得出來的反而比現行短,因為那一塊的開頭被截掉了; 未確認本站沒有辦法從這個檔判斷它原本多長。

同一個畫面,三份複本

注意上表出現了兩次的 fes_ingamepausemenu.fel。 這個檔案在同一個封裝檔裡有三份

667 行  ← 躺在檔案第 354,045 個位元組(有 63 行跟現行的不一樣)
667 行  ← 躺在檔案第 800,617 個位元組(跟現行的逐位元組完全相同)
667 行  ← 目錄指向的,遊戲現在用的這份

三份都完整、都讀得出來、都是同一個暫停選單,連行數都一樣。 (2026-09-05 訂正:本站原本在這裡寫「三份不同版本」,行數寫成 2,698/1,044/667。 前兩個是整塊區域的行數;第二份既然跟現行的逐位元組相同, 實際上是三份複本、兩個版本。)

但哪一份最早?看不出來

直覺會說「越後面越新」,因為這種封裝檔的更新方式就是把新資料接到檔尾。 照這個邏輯,遊戲現在用的那份應該排在最後面。

但實測不支持這個推論。遊戲現在用的那份在第 233,987 個位元組 —— 比另外兩份都前面。 如果純粹是往後追加,它不可能排在最前面。

所以這個檔案被整理過至少一次,不是單純的一路追加。 至於誰改的、什麼時候改的、三份的先後順序, 未確認本站沒有辦法從檔案本身判斷。

一個佐證:資料的位置很不平均

現行的 47 個項目數量
位於檔案前 800 KB 之內46 個
位於第 2,531,736 個位元組(幾乎在檔尾)1 個

那個孤零零跑到檔尾的是 fes_ingamesettings.fel。 它跟其他 46 個之間隔著 1.7 MB 沒人指向的資料。

推測 看起來像是:某次有人把絕大部分內容重新寫進檔案前段, 之後又有人單獨改了設定畫面、把它接到檔尾。 這個解釋跟位置分佈一致,但本站沒有證據,不寫成定論。

什麼都沒有消失

本站上線時曾在封裝格式那頁寫過 「那片區域撈得出 156 種舊版畫面代號」。重新量測後:

檢查實測
那 13 個讀得出來的區塊裡的畫面代號143 種
其中現行版本沒有0 種
現行版本額外多出253 種

換句話說:那片區域裡的每一個畫面,現在都還在。 而現行版本比它多了 253 個。沒有任何畫面在改版過程中消失 —— 真正不對的是「舊版」這兩個字。

156 這個數字本身量得出來,它是把整片沒被指向的位元組一起掃的結果: 多出來的 13 個只出現在讀不成整段文字的地方,其中 3 個還是被壓縮資料切壞的名字。 只看讀得出整段文字的那 13 個區塊是 143 種。 (2026-09-05 訂正:本站原本在這裡寫 134 種與「多出 262 種」, 重新量測是 143 種與 253 種。)

最明顯的例子是左側 HUD:那片區域裡有 HUDLEFT1HUDLEFT25 共 25 個,現行版本有這 25 個再加上一個基本的 HUDLEFT,總共 26 個。是多了一個,不是少了。

為什麼這些東西還在

因為刪掉它們沒有好處,而且有風險

這種封裝檔的安全改法是:把新資料接到檔尾,只更新目錄裡那幾個位元組, 原本的資料一個位元組都不動。 舊資料就這樣一層一層留下來。

這也是本站一直強調那條鐵律的理由

如果你用「把所有項目讀出來、重新打包一次」的方式存檔, 這 2.5 MB 會在一瞬間變成 198 KB。47 個項目一個不少、檢查也全過、 沒有任何錯誤訊息 —— 你只會覺得檔案變小了、真好。

問題是你不知道那些被丟掉的東西裡有沒有還被誰用到。 詳見 BIGF 封裝格式的三條鐵律。

拿原版一比,發現這件事有三種狀態不是兩種

上面那 92.6% 是本站測試機ingame.big。 把剛安裝好的原版、以及同一台機器上的其他封裝檔一起量,圖像完全不一樣:

封裝檔整份大小目錄指不到的佔比
剛安裝好的原版models.big 172,992,8034,0050.002%
portrait.big109,291,2173,5630.003%
ingame.big167,682710.04%
本站測試機models.big 561,891,31200%
portrait.big265,883,41700%
ingame.big2,665,562 2,468,06892.6%

「指不到的」= 整份大小 − 目錄指到的所有項目 − 目錄本身佔的位元組。

三種狀態,而且每一種都在講一件事

所以那 92.6% 不是這個格式的性質,是「有人用 append 模式改過很多次」的痕跡。

那條鐵律的理由要換一個說法

本站一直說「存回 .big 一律用 append 模式」, 理由寫的是「不然 2.5 MB 會變成 198 KB」。

但這張表顯示:這台的 models.big 早就被重新打包過了(碎片剛好 0), 而它好好的 —— 894 張臉皮全部讀得出來,遊戲也在跑。

所以正確的理由不是「重新打包一定會壞」,而是:

你不知道手上這一份被誰疊過什麼。 重新打包會把「目錄沒指到、但可能還有人用」的東西一次丟掉, 而你沒有辦法事先知道有沒有。

append 模式的代價只是檔案變大;重新打包的代價是不可逆。 兩邊的風險不對稱,所以選 append。

同一款遊戲裡的三代名字

上面講的是「被目錄丟掉的舊版畫面」。還有一種更直接的地層 —— 畫面元素的名字本身。

這款遊戲叫 MVP Baseball 2005。但把所有版面檔 翻一遍,會找到這些元素名:

元素名幾個 它載入的圖顯示開關
MVP20038 mvp3全部是 1
MVP20033 tp00/tp11/tp20
轉場用的圖
1
MVP2003LOGO3tp10/tp201
MVP20043 mvp51

一共 17 個元素,散在 10 個版面檔裡, 而且十七個的顯示開關全部都是 1 —— 它們是活的,不是被關掉的殘骸。

最後一列是整段的重點

名字叫 MVP2004 的那三個元素,載入的圖是 mvp5

圖換成 2005 的了,名字還停在 2004。

而叫 MVP2003 的那八個,圖也還是 mvp3 —— 那一批連圖都沒換過。

所以這不是「忘了刪」,是三次改版留下的三層: 2003 那層原封不動、2004 那層換了圖沒換名、2005 那層是新的。

這件事在球隊那邊也發生過: 球隊檔的欄位名還寫著 team_vs_mon(一支 2005 年就搬家的球隊), 但資料早就更新到 2023 年。

一條貫穿全站的規律

資料會被更新,名字不會。

因為名字是程式拿來對照的東西 —— 改了名字,程式就找不到了。 所以名字會一直停在它被建立的那一年, 變成檔案裡最誠實的一種時間戳。

順帶一提:遊戲資料夾裡那個工作人員名單檔, 第一行寫的是 # MVP2004 Credits

📌 重點整理

接下來