速查 › FEL 版面語法

FEL 版面語法速查

遊戲的選單、HUD、轉場全部寫在 .fel 版面檔裡。它外面包一層壓縮, 解開後是純文字腳本,每行一個元件。看懂這頁,就能改遊戲裡幾乎所有介面。

先看規模

以比賽中的介面檔 ingame.big 為例,把裡面 47 個 .fel 全部解開後:

項目數字備註
版面檔47 個比賽中的每一塊畫面各一個檔
總行數22,516 行全部是人看得懂的純文字
畫面(SC:410 個一個檔可以裝很多個畫面
指令種類22 種下面有完整對照表(不含每個檔結尾的 END:,也不含下面那兩個錯字)
群組(GR: 等)4,272 個巢狀結構,包最多的那個群組底下直接掛了 111 個元件
壓縮前後1,560,268 → 195,999壓到 13%,所以打開前要先解壓

上面每個數字都是把 ingame.big 現場解開數出來的,不是引用他人資料。

一個檔案的骨架

每行都是「指令:名稱,一串參數」,縮排代表層級(縮越深包越裡面)。 檔案開頭是版本行,結尾一定是 END:

VR:78                                 版本行,每個頂層區塊前面都有一行
SC:PITCHERINFO,1,0,0,0,640,480,...    畫面定義,畫布 640×480
 LF:twn14_en.ffn                      載入字型
 LS:ingameov                          載入圖集
 GR:PITCHER,1,0,371,68,254,356,...    群組:投手資訊區
  GR:BACKARTH,1,0,371,68,220,356,...  群組:底圖
   TX:POSITION,1,0,291,276,51,16,...  ← 文字元件,開關在第 1 個參數
END:                                  檔案結束(47 個檔全部如此)

參數怎麼看(以 TX 為例)

TX:RATING,1,0,618,391,20,12,1,1,1,1,0,0,hrdbg_en.ffn,3501,0,255,255,255,...
   │      │ │  │   │  │  │                  │        │   │  └ 顏色 RGB(白)
   │      │ │  │   │  │  └ 高 12            │        │   └ 對齊方式
   │      │ │  │   │  └── 寬 20             │        └ 字串編號 3501
   │      │ │  │   └───── Y 座標 391        └ 字型檔
   │      │ │  └───────── X 座標 618
   │      │ └──────────── 保留(此檔一律 0)
   │      └────────────── 顯示開關:1 顯示 / 0 隱藏 ← 最常改的就是它
   └───────────────────── 元件名稱

22 個指令完整對照

行數是 ingame.big 全 47 檔的實際統計。「證據」欄說明我們憑什麼這樣解釋:

指令行數用途證據
VR504版本行,出現在每個頂層區塊前 實測 值有 78 / 71 / 69 三種
SC410畫面定義,畫布 640×480 實測 只出現在頂層,參數含 640,480
LF142載入字型 實測 值就是 .ffn 檔名,142/142 掛在 SC
LS851載入圖集 實測 值是圖集名,貼圖指令都引用它
SF78引用另一個 .fel 實測 參數第二欄就是檔名(fes_popup.fel
GR3,933群組,可巢狀 實測 縮排層級
GG267會閃動的群組 命名佐證 名稱含 FLASH 或 BLINK 者 150/267(FLASH 87、BLINK 63、兩者皆含 0;例:TEAMSCOREFLASHSCOREBLINKSTAMINABLINK
SG72某種群組 未確認 名稱只有 SG1/SG2 這種代號,看不出用途
TX1,796文字。最常改的就是它 實測 帶字型檔、字串編號、RGB
TL282多段文字的容器 實測 底下 100% 只掛 TE
TE563TL 的項目 實測 563/563 掛在 TL 下,值是字串編號
TB706文字區塊,帶多組顏色 實測 40 欄含字型 + 六組 RGB;底下永遠沒有子元素
SH4,063貼圖,從圖集取一張來畫 實測 參數含圖集名(blsr
RT1,629色塊矩形,常做半透明底 實測 兩組 RGB,無字型無貼圖
SL532影格序列容器 實測 底下 100% 只掛 SE
SE1,684SL 的影格 實測 1684/1684 掛在 SL 下,值形如 a000
BU544可操作的元件(按鈕) 命名佐證 名稱如 NEXTPREVZOOMINROTATECAMERA
FC721影格容器 實測 底下 100% 只掛 FR
FR3,605FC 的影格 實測 3605/3605 掛在 FC 下,欄位結構同 GR
KA57關鍵影格動畫資料 推測 403 欄浮點數的長串,未逐欄解讀
VS9直向捲軸 實測下面那一節。 貼圖名字就是證據:sup0sdn0sldvsldb
TS17用途未知 未確認 17 行內容完全一樣都是 TS:CROPLOGOS,

我們改過這張表

這頁上線時,表上寫「VR 固定 78」和「TS 是編譯時間」。 重新量測後兩條都不對:VR 實際有 78、71、69 三種值; TS 的 17 行內容一模一樣,不可能是時間戳。已修正。

寫成「未確認」不好看,但比寫錯有用。

巢狀規則(這幾條是硬的)

把 22,516 行的每一行跟它的上層對照一遍,有五組是 100% 成立的:

規則符合
SE 一定掛在 SL 底下1684 / 1684
TE 一定掛在 TL 底下563 / 563
FR 一定掛在 FC 底下3605 / 3605
LF 一定掛在 SC 底下142 / 142
SC 一定在頂層410 / 410

這對你有什麼用:看到 SE: 就往上找 SL:,看到 TE: 就往上找 TL:, 不用猜。反過來說,如果你動了縮排讓這個關係斷掉,那一行大概就失效了。

同一個東西會出現很多次(最容易踩的坑)

你在檔案裡找到要改的那一行,改了、存回去、進遊戲一看 —— 沒變。 十次有八次是這個原因:那個元件在同一個檔案裡有好幾份,你只改到其中一份。

原因是一個 .fel 通常裝了同一塊畫面的許多版本,每個版本各自把元件重畫一次。以左側 HUD 為例:

檔案行數畫面數畫面代號
fes_hudleft.fel1,17526 HUDLEFT, HUDLEFT1 … HUDLEFT25
fes_ingameinfobar.fel9515 PITCHERINFO, JUMBOBIO, PLAYERGRP, TEAMSMATCHUP, IGPAUSEINFO

fes_hudleft.fel 裡,好球壞球數那個 TX:BALLS 出現 6 次, 分屬 HUDLEFTHUDLEFT22HUDLEFT23 三個畫面。 只改第一個,另外兩個畫面照舊。

兩個方向都要記得

想全面生效:把該檔裡所有同名的那個元件全部改一遍。 本站跑壘者速度那一課的腳本就是這樣做的, 它不寫死數量,掃到幾個就改幾個;在本站測試機那一份上是 6 行:四個壘包各一份,而GR:FIRSTBASE 這個群組 在這份檔案裡被宣告了兩次(第 782 行與第 791 行,座標略有不同), 第二次那份底下又有兩行。只改前四行,一壘的數字還是會冒出來。

想只在某個情境隱藏:那就反過來利用它,只改那個畫面裡的那一行。

別拿「名稱」當識別

元件名稱完全不唯一。實測最誇張的是 fes_ingamesettings.fel 裡的 SH:F5,同一個檔出現 191 次。 要定位一行,請用「檔名 + 行號」「畫面代號 + 上層群組路徑」,不要只記名字。

群組不記錄「我底下有幾個」

改版面時很容易冒出一個念頭:「我可以直接把整行刪掉嗎?還是父群組會發現少了一個?」

這是可以直接量的。把 4,272 個群組全部按「它自己那行有幾欄」分類,再看每一類的直接子元素數 —— 這裡的「直接子元素」指縮排剛好比它深一層的那些行,不含更深層的孫元素:

群組行的欄位數這類群組有幾個它們的直接子元素數範圍
16530 ~ 10
1711
183,9510 ~ 32
25142
272660 ~ 111

3,951 個群組欄位數一模一樣都是 18,可是直接子元素從 0 個到 32 個都有。 欄位數取決於群組的種類,跟它裝了幾個東西完全無關。 另外有 792 個群組底下一個元件都沒有 —— 空群組是合法的。

結論:刪行不會讓父群組「數量對不上」

但本站還是建議改開關而不是刪行,理由不是怕數量對不上,而是: 改開關可以一秒改回來,刪掉就要從備份撈。這是操作上的保險,不是格式上的限制。

三條鐵律(踩到會壞檔)

1 · 存回 .big 一律用「接到檔尾」,絕不整包重新打包

本站測試機那份 ingame.big 為例:全檔 2,665,562 bytes,但目錄指到的資料合計只有 195,999 bytes, 只佔 7.4%。其餘 92.6% 是目錄已經不指向、但確實還躺在檔案裡的資料。 重新打包會把它們整批丟掉(實測 2.5 MB 變 198 KB),而且不會有任何錯誤訊息

這三個數字是本站測試機那一份量到的,不是這個格式的性質: 剛安裝好的原版 ingame.big 只有 167,682 bytes、44 個版面檔,孤兒資料 71 bytes = 0.04%, 兩份差兩千倍以上。鐵律照舊 —— 理由是你不知道手上這份被疊過什麼,不是「這種檔天生有孤兒」。 兩份的對照與算法定義見這裡

正確做法:新資料接檔尾,只改目錄 8 bytes + 檔頭 4 bytes。本站腳本都是這樣寫的。 詳見 BIGF 的 append 鐵律

2 · 要關單一元素,改它自己那行,不要關父群組

群組(GR:)的開關會被遊戲程式在執行時覆寫 —— 例如本壘群組寫 0,有跑者時照樣被打開。 改元素自己那一行的開關才穩定有效。

3 · .fel 全部使用 CRLF 換行,編輯器不能自作主張

實測 47 個檔全部是純 CRLF,沒有一個混入 LF (全檔共 22,515 個 CRLF,單獨的 LF 與單獨的 CR 都是 0 個)。 若編輯器把 CRLF 統一成 LF,檔案長度會少掉一個行數的位元組數,直接壞檔。

還有一個更容易被「順手修好」的地方:檔尾有沒有換行,每一份檔案不一樣, 改之前一定要先看。很多編輯器存檔時會自動補上檔尾換行,那會讓檔案多出 2 bytes。

2026-08-28 補:把這條規則推到全遊戲,而且量到一個相反的例子

上面那個「47 個檔」只量了 ingame.big。 把剛安裝好的原版全部 329 個版面檔解壓後重量:

檔案個數換行符號
.fel 版面檔(六個封裝檔全部)329 CRLF 329 個,LF 0 個
data/datafile/ 底下的 .txt466 LF 460 個,CRLF 0 個(另外 6 個是 0 bytes 的空檔,一個換行位元組都沒有)
anims.big 裡面.axt244 CRLF 200 個、LF 44 個(同一批裡混的

同樣是純文字,兩個封裝檔用相反的慣例。 所以規則是看檔案家族,不是看副檔名 —— 寫工具的人如果照副檔名決定換行符號,一定會寫壞其中一邊。

⚠️ 動作庫那 244 個的副檔名是 .axt 不是 .txt, 而且 data/anims/ 這個資料夾裡只有 anims.big 一個檔 —— 244 個 .axt 全在它裡面,要先解開封裝檔才看得到。 逐項說明見動作庫 anims那頁。

⚠️ 這個數字第一次量的時候是錯的。 datafile.big 裡那 460 個 .txt 全部是 QFS 壓縮的, 直接在壓縮位元組裡數 \r\n 會得到一堆假的「混合」。 要先解壓再數。本站是印出一個實例、看到內容是亂碼才發現的 —— 量之前先問「我的量法本身可信嗎」。

實測:EA 原版那 44 個版面檔全部以 CRLF 結尾,一個例外都沒有; 但本站這份 ingame.big 裡,fes_hudleft.felEND: 後面沒有換行符。所以規矩是 改完確認檔案長度跟改前一模一樣,不要去背哪個檔有、哪個檔沒有。

用 Notepad++ / VS Code 這類會保留原始換行的編輯器, 關掉「存檔時自動補檔尾換行」,改完確認檔案長度跟改前一模一樣

順帶一提:這台機器的檔案裡有兩個錯字 —— 但原版沒有

我們改過這一段

這一節上線時的標題是「原廠檔案裡有兩個錯字」。拿剛安裝好、從未改動的原版一驗,那句話不成立:

原版全遊戲 329 個版面檔,三字母指令一個都沒有END: 除外)。同一支掃描在原版讀出 9,556 行 TX:,證明它確實有讀到內容。原版的 fes_hudleft.fel 對應那一行,是拼寫正確的 TX:BALLS

另一個錯字所在的 fes_ingameinfobar.fel在原版的 ingame.big 裡根本不存在(原版只有 44 個版面檔)。

所以這兩個錯字不是 EA 留下的,是這份檔案被改過的過程中產生的。本站無法判定是哪一個工具或哪一次改動造成的。未解

本站這份 ingame.big 的 22,516 行裡,有兩行的指令是三個字母:

fes_ingameinfobar.fel 第 900 行
     GR:X2Y1,0,0,229,330,64,8,...
      SSH:BARBACK,1,0,77,448,66,16,...      ← 多了一個 S
      SH:POWERBAR,1,0,79,450,62,6,...

fes_hudleft.fel 第 615 行
    GR:COUNT,1,0,10,61,35,13,...
     TTX:BALLS,1,0,53,61,17,25,...        ← 多了一個 T
     TX:STRIKES,1,0,72,61,17,11,...

兩行都緊挨著一個拼寫正確的同類指令,參數結構也完全相同。 TTX:BALLS 甚至就在 TX:STRIKES 上面 —— 那是好球壞球數的顯示。

這裡要誠實

我們沒有驗證遊戲拿這兩行怎麼辦。合理的猜想是直接跳過, 但那是猜的,本站不寫成定論。能確定的只有:全部 47 個檔、22,516 行裡, 只有這兩行用了三字母指令。

VS 是直向捲軸(2026-08-29 從「用途未知」升級)

這一頁上線時把 VS 標成「用途未知」,理由是 「只有 9 行,名稱全是 VS1」。 那是樣本太小 —— 上表只算 ingame.big 的 47 個版面檔。 把六個封裝檔的 332 個版面檔全部算進來,VS128 個

一個 VS 打開來長這樣(fes_savesys.fel,存檔畫面):

GR:VSCROLL,1,0,560,156,20,194,…
  VS:VS1,1,0,560,156,20,194,…
    BU:SU,…                 ← 上捲按鈕
      SH:BN … sup0          ← 平常
      SH:BP … sup1          ← 按下去
      SH:BH … sup1          ← 滑鼠移上去
    SH:SBsldv          ← 軌道
    BU:SD,…                 ← 下捲按鈕
      SH:BN … sdn0
      SH:BP … sdn1
      SH:BH … sdn1
    SH:SSsldb          ← 滑塊

真正的證據是貼圖的名字,不是數量。

貼圖名出現次數拆開來讀
sup0 / sup1151 / 229 scroll up 的兩個狀態
sdn0 / sdn1151 / 229 scroll down
sldv128 slider vertical,軌道
sldb126 slider button,滑塊

結構本身也一致到不像巧合:

⚠️ 一併推翻一個順手寫下的說法:「X 貼著畫面左右邊」

本站的內部筆記曾經寫過「VS 的 X 座標貼著畫面左右邊」,當成佐證之一。 實測不成立。128 個的 X 座標落在 19 到 600 之間, 貼畫面左緣(<10)0 個、貼右緣(>630)0 個

正確的說法是貼在它服務的那個清單面板側邊。 上面那個例子裡,GG:FILETABLE 從 X=50 佔到 590, 捲軸就在 X=560 —— 貼的是面板不是畫面。

上表 VS 那一列的「9」維持不變 —— 那一欄算的是 ingame.big。本節的 128 是把六個封裝檔全部算進來的。 口徑說明見這裡

(2026-09-05 訂正:本節原本寫 VS228 個。 那個數字是掃了本站測試機資料夾裡的每一個 .big 算出來的, 而那台機器上除了 frontend.big,還躺著一份逐位元組相同的副本 (兩者 SHA-256 完全一樣),於是同一份東西被數了兩次。 照本站一貫的「六個封裝檔、332 個版面檔」口徑重量是 128 個, 上面的貼圖次數、子元素組合、父群組與 X 座標範圍都已跟著重量。 結論不變:VS 是直向捲軸。

📌 重點整理

接下來