速查 › 字型檔 .ffn
字型檔 .ffn
遊戲畫面上的每一個字都來自 data/fonts/fonts.big 裡的 12 個點陣字型。
這頁除了講格式,還會用這個檔把「孤兒資料到底怎麼產生的」完整證明一次 ——
它剛好留下了一組算得清清楚楚的證據。
這一份被改過
本站測試機的 fonts.big 檔案日期是 2022 年 11 月,
不是 2005 年的原廠狀態(判斷方法見模型那頁)。
所以這頁描述的是「這個檔案現在長什麼樣」。 這反而讓它成為很好的教材 —— 因為改動的痕跡都還在裡面。
先看規模
| 項目 | 數字 | 備註 |
|---|---|---|
| 檔案大小 | 397,327 bytes | 388 KB。以封裝檔來說算小的,但不是最小 |
| 字型數 | 12 個 | 全部是 .ffn |
| 目錄涵蓋率 | 37.0% | 剩下 250,411 bytes 沒被指向 —— 這頁後半會解釋那是什麼 |
| 解壓後合計 | 777,520 bytes | 759 KB |
| 不重複的內容 | 9 種 | 12 個檔只有 9 種內容 |
上面每個數字都是把 fonts.big 現場解開數出來的,不是引用他人資料。
兩種檔頭代號,大小寫不一樣
把 12 個字型解開後看開頭四個位元組,只有兩種:
46 4E 54 46 = FNTF
46 6E 74 46 = FntF ← 中間兩個字母是小寫
大小寫跟「有沒有壓縮」完全對應
| 代號 | 檔數 | 外層是否 QFS 壓縮 |
|---|---|---|
| FNTF | 5 | 全部沒壓縮 |
| FntF | 7 | 全部有壓縮 |
12 個檔零例外。
所以看到 FntF 就知道它外面包了一層 QFS,看到 FNTF 就是直接讀。
檔頭第 9-10 個位元組也跟著分群:FntF 那七個全部是 414,
FNTF 那五個是 317 到 366 之間。
推測 看起來像是格式版本號,但本站沒有證實。
檔頭自己寫著檔案多大
第 5 到 8 個位元組是一個數字,跟解開後的實際長度比對:
| 字型 | 代號 | 解壓後大小 | 檔頭宣告 | 結果 |
|---|---|---|---|---|
| Tw24_en.ffn | FNTF | 4,048 | 4,048 | 相符 |
| frk12_en.ffn | FNTF | 17,104 | 17,104 | 相符 |
| au20b_en.ffn | FNTF | 18,000 | 18,000 | 相符 |
| twcnb_en.ffn | FNTF | 14,928 | 14,928 | 相符 |
| hrdbg_en.ffn | FntF | 72,544 | 72,544 | 相符 |
| mini1_en.ffn | FntF | 133,216 | 133,216 | 相符 |
| mini2_en.ffn | FntF | 264,288 | 264,288 | 相符 |
| twc14 / 16 / 18 | FntF | 各 72,544 | 各 72,544 | 相符 |
| dflt_en.ffn | FNTF | 14,608 | 13,520 | 差 1,088 |
| twn14_en.ffn | FntF | 21,152 | 20,064 | 差 1,088 |
12 個裡有 10 個完全相符。剩下兩個各多出 1,088 個位元組 —— 部分已解 兩個差距一模一樣,不像隨機出錯。本站後來把那 1,088 個位元組打開看,得到三件事:
| 它不是填充 | 開頭是 ff ff ff 04、ff ff ff 05、ff ff ff 06…
這種規律遞增的結構,不是一片 0 |
| 其中一個帶著標記 | EAGL64 EAGL 是 EA 的圖形函式庫, 動畫那頁也出現過 |
| 兩個尾巴不一樣 | 逐位元組比對 90.8% 不同 —— 所以不是同一塊資料被複製兩份 |
還是不知道它是什麼,但至少知道它不是垃圾: 是兩塊各自不同、有結構的資料,接在宣告的長度後面。 仍未解
跟 FSH 圖片與音訊索引一樣, 這是又一個「格式自己帶著驗算方法」的例子。
12 個檔,只有 9 種內容
四個檔的內容完全相同
hrdbg_en.ffn
twc14_en.ffn ← 這四個解開後
twc16_en.ffn 位元組完全一樣
twc18_en.ffn
都是 72,544 bytes,內容一個位元組不差。 名字看起來是 14、16、18 三種不同字級,實際上裝的是同一份東西。
推測 這是替換字型時常見的做法: 為了讓所有地方都顯示同一套字,把同一個字型檔複製到好幾個名字上。 但本站無法確認是誰、什麼時候做的。
孤兒資料是怎麼產生的:一個算得清楚的例子
前面說這個檔有 250,411 bytes 沒被目錄指向。 其中有三段大小完全相同:
[189,700 → 252,239) 62,539 bytes
[262,244 → 324,783) 62,539 bytes
[334,788 → 397,327) 62,539 bytes
三段一模一樣大,這不會是巧合。看看它們前面各接著什麼:
| 目錄指向的項目 | 佔用 | 後面接著的空隙 | 兩者相加 |
|---|---|---|---|
| twc14_en.ffn | 10,005 | 62,539 | 72,544 |
| twc16_en.ffn | 10,005 | 62,539 | 72,544 |
| twc18_en.ffn | 10,005 | 62,539 | 72,544 |
72,544 正好是這三個字型解壓後的大小。
決定性的一步
如果推論成立 ——「原本這裡放的是未壓縮的 72,544 bytes, 後來被壓縮成 10,005 bytes 蓋在前面」—— 那麼那段空隙應該恰好等於 解壓後資料的第 10,005 個位元組之後的部分。
本站直接比對:三段全部逐位元組相同,62,539 bytes 一個不差。
所以整件事的經過是這樣:
原本 [────────── 未壓縮字型 72,544 bytes ──────────]
改過之後 [壓縮版 10,005][──── 原本資料的後半段 62,539 bytes ────]
↑
目錄現在只指到這裡,後面那段沒人認領
這就是「孤兒資料」的真面目
不是垃圾,也不是損壞。是舊資料沒被覆蓋掉的那一部分。
改檔的人把新版本寫進原本的位置、更新目錄的長度, 但沒有(也不需要)把後面清乾淨。 檔案於是一層一層留下痕跡。
比賽介面檔 ingame.big 也有同樣的現象,規模更大 ——
本站測試機那一份有 92.6% 是這種資料(剛安裝好的原版只有 0.04%),故事見
一個檔案裡的地層。
中文字型走的是「日文」那個槽位
原版 12 個字型的檔名全部以 _en 結尾。
本站另外打開一份 2023 年的中文懶人包,同一個封裝檔長這樣:
⚠️ 這張表跟上面那張不要直接對數字,兩件事都不一樣:
上面那張量的是本站測試機那份 2022 年被改過的 fonts.big,欄位是解壓後大小;
這張量的是剛安裝好的原版與中文包,欄位是封裝檔內佔用。
所以同一個檔名在兩張表會出現兩個數字(Tw24_en.ffn 上面 4,048、這裡 5,751;
au20b_en.ffn 上面 18,000、這裡 57,617)——
差的不只是口徑,連檔案本身都被換過了,那正是本頁開頭「這一份被改過」在講的事。
同理,〈先看規模〉那個「解壓後合計 777,520」也是測試機那份,跟這一節的 204,523 不同口徑。
| 原版 | 封裝檔內佔用 | 中文包 | 封裝檔內佔用 | 倍數 |
|---|---|---|---|---|
| twcnb_en.ffn | 14,525 | twcnb_jp.ffn | 180,079 | 12× |
| au20b_en.ffn | 57,617 | au20b_jp.ffn | 304,485 | 5× |
| Tw24_en.ffn | 5,751 | Tw24_jp.ffn | 140,882 | 24× |
| frk12_en.ffn | 27,618 | frk12_jp.ffn | 140,882 | 5× |
| dflt_en.ffn | 5,815 | dflt_en.ffn(沒改,而且另外多一個 dflt_jp.ffn) |
5,815 | 1× |
| 原版 | 12 個字型 | 204,523 bytes | 全部 _en |
| 中文包 | 13 個 | 1,683,191 bytes | 12 個 _jp + 留著原本的 dflt_en |
這跟另一頁的發現是同一招
EA 官方繁體中文版那一頁量到:
官方的中文不是覆蓋英文,而是放進日文的槽位
(IGJPN.LOC/FEJPN.LOC)。
字型這裡是一模一樣的做法:中文字型檔名結尾是 jp。
兩件事互相印證 —— 這個遊戲要顯示中文,走的是它原本給日文的那條路。
為什麼是日文槽位?合理的猜想是「日文本來就要顯示漢字, 那條路上的字型與編碼處理現成可用」。 但這是推想,檔案裡沒有寫。推測
2026-08-28 補上實測
「只能借現成語系的位子」這件事,現在有執行檔層的證據了。
組字型檔名的那段程式(0x004FE860)是
「名字表[編號] + 語系後綴 + .ffn」,
而語系後綴來自 0x004FE9BC 的一張跳表,只有四種:
case 0、1 → "_en" case 2 → "_sp" case 3、4 → "_jp" case 5 → "_es"
裡面沒有中文。所以不管是官方版走 _jp、
還是社群包蓋掉 _en,都不是偏好,是只有這幾個位子可以借。
這一頁原本是從檔名推出這件事的,兩邊互相印證。
⚠️ 另外要注意社群的中文包不只一份,動的槽位也不一樣, 所以不同頁的字型總量對不起來是正常的:
| 哪一份 | 檔名結尾 | 幾個 |
|---|---|---|
| EA 官方繁體中文版(本節這張表量的就是它)
⚠️ 2026-08-30 訂正:這一列原本被拆成兩列 (「2023 年的中文懶人包」與「EA 官方繁體中文版」各一列,一列寫組成、 一列只寫 13)。那是同一個檔 —— 本機那份 2023 中文懶人包裡的 fonts.big 跟剛安裝好的官方繁中版逐位元組相同:
兩份都是 1,683,513 個位元組、13 個項目,SHA-256 前 12 碼同為
a5c92f50616f。也就是說那個懶人包直接沿用 EA 出貨的字型檔,
一個位元組都沒改。 |
_jp | 12 個 _jp + 留著 dflt_en = 13 |
走 _jp 的社群合包(另一份,不是上面那個) |
_jp | 13(其中 12 項
跟 EA 出貨那份逐位元組相同,只有 hrdbg_jp.ffn 不一樣) |
| 中文版配大球場就跳出那一課量的那份社群包 | _en | 12(直接蓋掉英文字型) |
上表第二列那份合包,官方繁中版那一頁
量到它 13 個項目裡有 12 個跟 EA 出貨那份逐位元組相同
—— 它是拿官方的字型來用,不是自己做的。
本機能拿到的 fonts.big 全部量過一輪,去掉內容重複的一共七種。
走 _jp 的有兩種:上表第一列那份(1,683,513)與上表第二列
那份合包(1,686,625),兩者只差一個 hrdbg_jp.ffn。
其餘五種都是 12 個 _en 的路線(英文原版 204,820/
2009 台灣模組 1,279,340/測試機現況 397,327/Taiwan_English_1X 420,650/
另一份 2007 年的轉播畫面模組 351,434)。
所以你的遊戲能不能顯示中文,看檔名跟大小就知道
打開 data\fonts\fonts.big,看裡面的檔名結尾與合計大小:
全部是 _en,合計約 200 KB | 沒裝中文字型 |
出現 _jp,合計超過 1 MB | 裝過中文字型了 |
全部是 _en,但合計遠超過 200 KB(例如 1.2 MB) |
也裝過中文字型了 —— 那是直接蓋掉英文槽位的社群包 (中文版配大球場就跳出那一課量的那份就是), 檔名分不出來,要看大小 |
python mvp_fel_toolkit.py "你的遊戲資料夾" --big data\fonts\fonts.big --entries
工具在介面萬用工具那一課。 更完整的說明在 怎麼看出哪些檔還沒被動過。
能改到什麼程度
| 你可能想做的事 | 現況 |
|---|---|
| 知道遊戲用了哪些字型、多大 | 完全可改 檔頭讀得懂,本頁的表就是這樣來的 |
| 把某個字型換成另一個現有的 | 可以替換 四個檔內容相同就是這樣做出來的 |
| 自己做一個新字型 | 未解 字圖集與字元表讀得出來(見下面的訂正), 但本站沒有從零產生一份、再寫回去的辦法 |
| 加入原本沒有的字(例如中文字) | 未解 同上,而且字圖集與字元表要一起改 |
誠實邊界
本站解出的是容器層:有幾個字型、各多大、壓縮與否、檔頭前 10 個位元組怎麼讀。
⚠️ 2026-09-05 訂正:字符本身後來解開了。
這裡原本寫「字符本身長什麼樣、怎麼對應到文字編碼,本站沒有解讀」,那句已經不成立:
圖片的像素怎麼排那頁量到 au20b_en.ffn 裡有一張
格式 0x79、256×128、每個像素半個位元組的字圖集,後面接著一張 16 筆的
0x2A 調色盤;中文版配大球場就跳出
那一課把中文字型的字圖集(0x79、1024×512)與整張字元表讀了出來,
數到字型提供 1,529 個字,拿去跟中文語系檔用到的 1,536 個字對帳。
仍然沒解的是「從零產生一張新的字圖集與一張新的字元表、再寫回去」 —— 所以這頁能幫你判斷與替換,不能幫你造字。
📌 重點整理
- 一句話 遊戲畫面上每個字都來自
data/fonts/fonts.big裡的 12 個點陣字型,本站把容器層全部解開(幾個、多大、壓縮與否、檔頭前 10 個位元組怎麼讀);字圖集與字元表在另外兩頁也讀出來了,但沒有從零產生一份再寫回去的辦法,所以這頁能幫你判斷與替換,不能幫你造字。 - 大小寫代號就是壓縮開關 解開後開頭四個位元組只有兩種,
FNTF5 個全部沒壓縮、FntF7 個全部有 QFS 壓縮,12 個檔零例外。檔頭第 5 到 8 個位元組自己宣告長度,12 個裡 10 個完全相符。 - 決定性的那一步 這個檔 397,327 個位元組裡有 250,411 沒被目錄指向,其中三段大小完全相同都是 62,539,而它們前面各接著
twc14/twc16/twc18佔用的 10,005,10,005 + 62,539 = 72,544正好是解壓後的大小。本站直接比對:三段逐位元組相同,62,539 個位元組一個不差。孤兒資料不是垃圾也不是損壞,是舊資料沒被覆蓋掉的那一部分。 - 12 個檔只有 9 種內容
hrdbg_en、twc14_en、twc16_en、twc18_en四個都是 72,544 個位元組、內容一個位元組不差。名字看起來是 14/16/18 三種字級,裝的其實是同一份東西。 - 那兩個「多 1,088 個位元組」的檔,打開看過了
dflt_en與twn14_en各比檔頭宣告多 1,088。那段不是填充(開頭是ff ff ff 04、ff ff ff 05這種規律遞增),其中一個帶著EAGL64標記,而兩個尾巴逐位元組比對 90.8% 不同,所以也不是同一塊資料複製兩份。從「沒解讀」進步到「知道它不是垃圾」。 - 中文走的是日文那個槽位 原版 12 個字型檔名全部以
_en結尾,2023 年的中文包是 12 個_jp+ 留著原本的dflt_en,總量從 204,523 個位元組變成 1,683,191。2026-08-28 補上執行檔層證據:組檔名的那段程式(0x004FE860)取的語系後綴來自0x004FE9BC的跳表,只有_en/_sp/_jp/_es四種,裡面沒有中文,所以不是偏好,是只有這幾個位子可以借。 - 看檔名跟大小就知道你的遊戲能不能顯示中文 打開
data\fonts\fonts.big,全部是_en、合計約 200 KB = 沒裝中文字型;出現_jp、合計超過 1 MB = 裝過了;全部是_en卻遠超過 200 KB(例如 1.2 MB)也是裝過了 —— 那種包直接蓋掉英文槽位,檔名分不出來,要看大小。另外社群的中文包不只一份、動的槽位也不一樣(本頁表裡這份是 12 個_jp+ 留著dflt_en,〈中文版配大球場就跳出〉那一課量的那份是 12 個_en直接蓋掉英文),所以不同頁的字型總量對不起來是正常的。 - 本站沒驗的 字圖集與字元表讀得出來(見本頁「誠實邊界」的 2026-09-05 訂正),但本站沒有從零產生一份、再寫回去的辦法,所以做不出新字型、也加不了原本沒有的字;那 1,088 個位元組到底是什麼仍未解;檔頭第 9 到 10 個位元組「看起來像版本號」是推測;四個檔內容相同是誰、什麼時候做的無法確認;「為什麼借日文槽位」是推想,檔案裡沒有寫。還有一件事要記得:這份
fonts.big檔案日期是 2022 年 11 月,不是 2005 年的原廠狀態,本頁描述的是它現在長什麼樣。