故事 › 一個檔案裡的地層
一個檔案裡的地層
本站測試機那份遊戲比賽畫面的介面檔有 2.5 MB。裡面只有 7.4% 是遊戲真正在用的。 另外 92.6% 沒有任何東西指向它 —— 但它就躺在那裡,而且還讀得出來。
先說這些資料哪來的
本頁前半的數字都來自把 data/frontend/ingame.big 直接打開量測。
方法很簡單:讀出目錄記載的 47 個項目各佔哪一段位元組,
剩下沒被任何項目蓋到的區間,就是這頁在講的東西。
後面「拿原版一比」那張表另外量了 models.big、portrait.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 是什麼
先看位元組本身怎麼分佈:
| 位元組 | 佔比 | 是什麼 |
|---|---|---|
| 0x00 | 36.2% | 零 |
| 0xFF | 22.4% | 全 1 |
| 0x2C | 8.1% | 逗號 |
| 0x30 / 0x31 | 8.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.fel | 2,698 | 667 | 667 |
| fes_hudleft.fel | 2,395 | 1,890 開頭被截掉 | 1,175 |
| fes_ingamepausemenu.fel | 1,044 | 667 | 667 |
| fes_ingameendofgamemenu.fel | 522 | 478 | 478 |
| fes_ingameoverlay.fel | 484 | 231 開頭被截掉 | 290 |
| fes_ingamepitcherinfo.fel | 434 | 394 | 394 |
| fes_ingamepitchersinbullpen.fel | 373 | 205 | 205 |
| fes_ingamerosterbatteroptions.fel | 303 | 151 | 151 |
訂正:不是「八個全部都比現在長」
本站原本在這裡寫「八個全部都比現在長,沒有一個例外」,還舉了 「暫停選單那個少了兩千行、左側 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:那片區域裡有 HUDLEFT1 到
HUDLEFT25 共 25 個,現行版本有這 25 個再加上一個基本的
HUDLEFT,總共 26 個。是多了一個,不是少了。
為什麼這些東西還在
因為刪掉它們沒有好處,而且有風險。
這種封裝檔的安全改法是:把新資料接到檔尾,只更新目錄裡那幾個位元組, 原本的資料一個位元組都不動。 舊資料就這樣一層一層留下來。
這也是本站一直強調那條鐵律的理由
如果你用「把所有項目讀出來、重新打包一次」的方式存檔, 這 2.5 MB 會在一瞬間變成 198 KB。47 個項目一個不少、檢查也全過、 沒有任何錯誤訊息 —— 你只會覺得檔案變小了、真好。
問題是你不知道那些被丟掉的東西裡有沒有還被誰用到。 詳見 BIGF 封裝格式的三條鐵律。
拿原版一比,發現這件事有三種狀態不是兩種
上面那 92.6% 是本站測試機的 ingame.big。
把剛安裝好的原版、以及同一台機器上的其他封裝檔一起量,圖像完全不一樣:
| 封裝檔 | 整份大小 | 目錄指不到的 | 佔比 | |
|---|---|---|---|---|
| 剛安裝好的原版 | models.big | 172,992,803 | 4,005 | 0.002% |
| portrait.big | 109,291,217 | 3,563 | 0.003% | |
| ingame.big | 167,682 | 71 | 0.04% | |
| 本站測試機 | models.big | 561,891,312 | 0 | 0% |
| portrait.big | 265,883,417 | 0 | 0% | |
| ingame.big | 2,665,562 | 2,468,068 | 92.6% |
「指不到的」= 整份大小 − 目錄指到的所有項目 − 目錄本身佔的位元組。
三種狀態,而且每一種都在講一件事
- EA 出貨的檔:碎片很小但不是零(幾 KB,佔比千分之幾)。 那大概是對齊或打包工具留下的填充,不是歷史地層。
- 被工具重新打包過的檔:剛好 0。
這台的
models.big與portrait.big一個位元組都不浪費 —— 那正是「全部讀出來、重新打包一次」的特徵。 - 被 append 模式改過的檔:越積越多。
這台的
ingame.big92.6%,就是一層一層接上去的結果。
所以那 92.6% 不是這個格式的性質,是「有人用 append 模式改過很多次」的痕跡。
那條鐵律的理由要換一個說法
本站一直說「存回 .big 一律用 append 模式」,
理由寫的是「不然 2.5 MB 會變成 198 KB」。
但這張表顯示:這台的 models.big 早就被重新打包過了(碎片剛好 0),
而它好好的 —— 894 張臉皮全部讀得出來,遊戲也在跑。
所以正確的理由不是「重新打包一定會壞」,而是:
你不知道手上這一份被誰疊過什麼。 重新打包會把「目錄沒指到、但可能還有人用」的東西一次丟掉, 而你沒有辦法事先知道有沒有。
append 模式的代價只是檔案變大;重新打包的代價是不可逆。 兩邊的風險不對稱,所以選 append。
同一款遊戲裡的三代名字
上面講的是「被目錄丟掉的舊版畫面」。還有一種更直接的地層 —— 畫面元素的名字本身。
這款遊戲叫 MVP Baseball 2005。但把所有版面檔 翻一遍,會找到這些元素名:
| 元素名 | 幾個 | 它載入的圖 | 顯示開關 |
|---|---|---|---|
| MVP2003 | 8 | mvp3 | 全部是 1 |
| MVP2003 | 3 | tp00/tp11/tp20 轉場用的圖 | 1 |
| MVP2003LOGO | 3 | tp10/tp20 | 1 |
| MVP2004 | 3 | mvp5 | 1 |
一共 17 個元素,散在 10 個版面檔裡, 而且十七個的顯示開關全部都是 1 —— 它們是活的,不是被關掉的殘骸。
最後一列是整段的重點
名字叫 MVP2004 的那三個元素,載入的圖是 mvp5。
圖換成 2005 的了,名字還停在 2004。
而叫 MVP2003 的那八個,圖也還是 mvp3 ——
那一批連圖都沒換過。
所以這不是「忘了刪」,是三次改版留下的三層: 2003 那層原封不動、2004 那層換了圖沒換名、2005 那層是新的。
這件事在球隊那邊也發生過:
球隊檔的欄位名還寫著 team_vs_mon(一支 2005 年就搬家的球隊),
但資料早就更新到 2023 年。
一條貫穿全站的規律
資料會被更新,名字不會。
因為名字是程式拿來對照的東西 —— 改了名字,程式就找不到了。 所以名字會一直停在它被建立的那一年, 變成檔案裡最誠實的一種時間戳。
順帶一提:遊戲資料夾裡那個工作人員名單檔,
第一行寫的是 # MVP2004 Credits。
📌 重點整理
- 一句話 本站測試機那份比賽介面檔
ingame.big有 2.5 MB,只有 7.4% 是遊戲真正在用的,另外 92.6% 沒有任何東西指向,但那不是垃圾,是同一批畫面的其他版本,而且沒有壓縮,記事本打開就能讀。 - 關鍵數字 檔案 2,665,562 個位元組、目錄 47 項合計 195,999、沒被指向的 2,468,068(92.59%)分成 24 段,最大一段 1,731,119,比整個有效內容還大八倍。那片區域的亂度是 3.85(滿分 8 代表隨機或已壓縮)、34.1% 是可列印字元,撈得出 13 個未壓縮的版面檔文字區塊、合計 690,059 個位元組。
- 八個對得起來的區塊 一塊常常不只裝一個版面檔(版面檔以行首
END:收尾)。切回單一檔之後八列裡有六列跟現行的一樣長:兩份暫停選單都是 667 行、結束選單 478、投手資訊 394、牛棚投手 205、打者選項 151,其中第 800,617 個位元組那份暫停選單跟現行檔案逐位元組完全相同;真的比較長的只有左側 HUD(讀得出來就有 1,890 行對 1,175 行)。(2026-09-05 訂正:本站原本寫「八個全部都比現在長」,那一欄量的是整塊區域不是單一版面檔。)同一個暫停選單在同一個封裝檔裡有三份,而「越後面越新」不成立:遊戲現在用的那份躺在第 233,987 個位元組,比另外兩份都前面,所以這個檔至少被整理過一次,不是單純一路往後追加。 - 訂正一:什麼都沒有消失。本站原本寫「那片區域撈得出 156 種舊版畫面代號」,錯的是「舊版」兩個字。讀得出整段文字的那 13 個區塊實測是 143 種(156 是把整片沒被指向的位元組一起掃的結果),其中現行版本沒有的是 0 種,現行版本反而額外多出 253 種。最明顯的是左側 HUD:那片區域有
HUDLEFT1到HUDLEFT25共 25 個,現行版本是這 25 個再加上一個基本的HUDLEFT,是多了一個,不是少了。 - 訂正二:那條鐵律的理由換過說法。本站原本說「不然 2.5 MB 會變成 198 KB」,但這台的
models.big早就被重新打包過(碎片剛好 0),而它好好的,894 張臉皮全部讀得出來、遊戲也在跑。正確的理由是:你不知道手上這一份被誰疊過什麼,重新打包會把「目錄沒指到、但可能還有人用」的東西一次丟掉,而你沒辦法事先知道有沒有。append 的代價只是檔案變大,重新打包的代價是不可逆,兩邊風險不對稱。 - 92.6% 不是這個格式的性質,是三種狀態裡的一種 EA 出貨的檔碎片很小但不是零(原版
models.big0.002%、portrait.big0.003%、ingame.big只有 71 個位元組 = 0.04%);被工具重新打包過的剛好 0;被 append 模式改過的才會越積越多。所以站上看到任何一個孤兒數字,都要先問量的是哪一份。 - 同一款遊戲裡的三代名字 版面檔裡找得到
MVP2003、MVP2003LOGO、MVP2004共 17 個元素,散在 10 個版面檔裡,顯示開關全部是 1,它們是活的不是被關掉的殘骸。重點在最後一列:叫MVP2004的那三個,載入的圖已經是mvp5,圖換成 2005 的了,名字還停在 2004。資料會被更新,名字不會,因為名字是程式拿來對照的東西,改了就找不到了。 - 本站沒驗的 暫停選單那三份誰先誰後、誰改的、什麼時候改的,本站沒有辦法從檔案本身判斷。那個孤零零跑到第 2,531,736 個位元組、跟其他 46 個隔著 1.7 MB 的
fes_ingamesettings.fel,「某次有人把大部分內容重寫進前段、之後又有人單獨改了設定畫面接到檔尾」這個解釋跟位置分佈一致,但本站沒有證據,不寫成定論。
接下來
- 平安夜凌晨的兩次建置 —— 另一批被留在檔案裡的時間痕跡
- BIGF 封裝格式 —— 為什麼不能整包重新打包
- FEL 版面語法 —— 那些讀得出來的文字在講什麼