引言:REDengine 4 的模組生態演進
與提供官方可視化模組套件(如 Bethesda 的 Creation Kit)或基於開放腳本架構的遊戲引擎不同,CD Projekt Red 在《電馭叛客 2077》(Cyberpunk 2077)中採用的自研引擎 REDengine 4 是一個高度整合的高效能 C++ 系統。其底層緊密耦合了編譯型腳本位元組碼、唯讀二進位資源封裝(.archive)以及名為 TweakDB 的執行階段中央遊戲資料庫。
遊戲早期發行時,玩家社群的模組主要依賴粗糙的十六進位二進位修改、直接替換遊戲原生 .archive 容器中的資產檔案。隨著逆向工程的深入,社群逐步構建出了一套各司其職、模組化協同的現代化模組執行階段框架:
- Cyber Engine Tweaks (CET):基於動態連結庫代理的原生 C++ 鉤子、Lua 腳本執行環境與 ImGui 除錯主控台。
- REDscript:直接編譯與修補遊戲內類 Swift 原生腳本邏輯的位元組碼編譯器與注入器。
- ArchiveXL:虛擬檔案系統擴充工具,支援以非覆蓋形式動態掛載全新 3D 模型、材質及實體定義。
- TweakXL:針對 TweakDB 的記憶體級宣告式修補引擎,允許多個模組同時註冊獨立武器、防具及屬性記錄而不發生資料庫衝突。
- Codeware 與 RED4ext:底層的 C++ 擴充基石,提供執行階段反射 API、生命週期管理與更深層的底層通訊通道。
深入理解這些框架在 REDengine 4 內部的生命週期與交匯邏輯,是排查遊戲啟動崩潰(Flatliner)、解決腳本編譯衝突以及版本更新後維護模組穩定性的關鍵基礎。
架構概觀:四大核心框架的協同拓撲
下圖展示了各主要框架在 REDengine 4 啟動與執行階段的分工與互動:
+-------------------------------------------------------------------------+
| Cyberpunk2077.exe (REDengine 4 核心行程) |
+-------------------------------------------------------------------------+
| |
v (DLL 代理載入: version.dll) v (引擎初始化鉤子)
+-----------------------------------+ +-------------------------+
| Cyber Engine Tweaks (CET) | | RED4ext 核心 |
| - 原生 C++ 記憶體鉤子 | | - 底層 DLL 外掛載入器 |
| - Lua 5.1/LuaJIT 腳本虛擬機 | | - 引擎事件鉤子與 RTTI |
| - ImGui 互動主控台與介面渲染 | +-------------------------+
| - 執行階段 RTTI 屬性與函式反射呼叫| | |
+-----------------------------------+ v v
+-------------+ +-----------+
| ArchiveXL | | TweakXL |
| (虛擬檔案流)| | (TweakDB) |
+-------------+ +-----------+
| |
+-----------------------------------+ | |
| REDscript | | |
| - 編譯 r6/scripts 原始碼為位元組碼| <-------------+---------------+
| - 方法攔截 (@replace, @wrap) | (提供腳本記錄綁定與動態資料介面)
| - 擴充遊戲原生核心邏輯類別 |
+-----------------------------------+
各框架在底層架構中佔據不同層級:
- CET 從外部透過動態連結庫代理攔截系統呼叫,執行非同步 Lua 邏輯並繪製使用者互動介面。
- RED4ext 在引擎初始化早期載入,管理 C++ 外掛的完整生命週期,為 ArchiveXL 與 TweakXL 提供宿主環境。
- REDscript 在主遊戲迴圈啟動前掃描並編譯使用者腳本,將自訂程式碼編譯注入進引擎位元組碼快取中。
- ArchiveXL 與 TweakXL 則分別接管資源流載入與資料表初始化,實現資料與實體的純記憶體動態組裝。
1. Cyber Engine Tweaks (CET):底層二進位攔截與 Lua 執行環境
執行入口:動態連結庫代理機制(DLL Proxying)
CET 利用 Windows 作業系統的 DLL 搜尋順序實現無感注入。Windows 在載入處理程序時,會優先在執行檔所在目錄(bin\x64\)搜尋所需相依項,隨後才檢索系統目錄。CET 提供了一個偽裝的 version.dll。當 Cyberpunk2077.exe 啟動時,作業系統載入 CET 的 version.dll,CET 初始化自身的記憶體鉤子,並將合法的 Windows API 請求透明轉發給 C:\Windows\System32\version.dll。
執行階段型別資訊(RTTI)動態反射
CET 的技術精髓在於對 REDengine 4 內部 RTTI 系統的動態巡訪。遊戲引擎本身維護了一張詳盡的詮釋資料索引表,記錄了所有 C++ 原生類別、結構體、列舉與函式簽章:
- CET 在啟動階段巡訪引擎註冊表,擷取全域類別與函式指標。
- 透過橋接層將這些 C++ 遊戲函式與變數直接對應給內建的 Lua 腳本引擎。
- 模組創作者在
bin\x64\plugins\cyber_engine_tweaks\mods\[模組名]\init.lua中編寫腳本。 - Lua 腳本可以直接監聽遊戲生命週期事件(
onInit、onUpdate、onDraw),呼叫Game.GetPlayer()取得玩家控制代碼,執行底層命令或動態產生實體物件。
ImGui 互動介面渲染
CET 將輕量級圖形介面庫 Dear ImGui 掛載到遊戲 DirectX 12 的交換鏈(Swapchain)上。當玩家按下指定的主控台快速鍵時,CET 攔截鍵盤與滑鼠輸入,呼叫出浮動主控台,允許玩家即時執行除錯指令、修改遊戲記憶體變數及管理模組設定。
2. REDscript:原生腳本編譯器與無損方法修補
與 CET 執行外部 Lua 腳本不同,REDscript 直接修補與擴充遊戲內部的原生遊玩邏輯。
REDscript 編譯管線
《電馭叛客 2077》的任務系統、介面邏輯、物品欄行為、專長技能樹以及 NPC 狀態機均由一套語法類似 Swift 的自研腳本語言編寫。官方在發行版本中將這些腳本預先編譯為二進位位元組碼,存放於 r6\cache\final.redscripts 中。
REDscript 重構了這一執行鏈條:
- 啟動時,REDscript 掃描
r6\scripts\目錄下的所有.reds原始碼檔案。 - 解析自訂腳本語法並建構抽象語法樹(AST)。
- 反編譯遊戲原生快取中的類別與方法簽章。
- 將模組語法樹無縫合併入全域腳本樹,並重新編譯為統一的位元組碼快取(
r6\cache\moddedOnly.redscripts)。 - REDengine 的虛擬機以原生效能執行修補後的位元組碼。
方法註解:避免全域覆蓋的模組化修補
在早期腳本模組時代,作者為了修改某一行程式碼,不得不將長達數千行的原版腳本檔案完整替換,導致兩個修改同一邏輯的模組必定衝突崩潰。REDscript 引入了細粒度的方法註解體系:
@replaceMethod(類別名):徹底替換某個類別的特定成員方法。@wrapMethod(類別名):包裹原方法,允許在呼叫wrappedMethod()前後插入自訂邏輯,最大程度保留原版機制。@addMethod(類別名):向現有的引擎腳本類別中動態注入全新方法。@addField(類別名):向現有類別追加新的狀態屬性欄位。
// REDscript 包裹原有傷害邏輯的非破壞性範例
@wrapMethod(PlayerPuppet)
protected cb func OnTakeDamage(damageEvent: ref[gameDamageReceivedEvent]) -> Bool {
// 執行前置自訂監聽
ModLog("受到傷害攔截: " + ToString(damageEvent.totalDamageReceived));
// 執行原版核心邏輯
let result: Bool = wrappedMethod(damageEvent);
// 執行後置邏輯
return result;
}
3. ArchiveXL:虛擬檔案系統與動態資產掛載
在 ArchiveXL 出現之前,玩家若想向遊戲中添加一件新衣服或新武器,必須覆蓋原有物品的網格模型(Mesh)與貼圖。若 Mod A 替換了 1 號夾克,Mod B 也替換了 1 號夾克,兩者無法並存。
動態資源串流掛載
ArchiveXL 作為 RED4ext 外掛運作,攔截了 REDengine 的資源載入器(CResourceLoader):
- 擺脫了覆蓋原版
.archive容器的限制,實現了增量資源注入。 - 創作者將全新的 3D 資產、材質與動畫打包進獨立的
.archive檔案,置於archive\pc\mod\目錄下。 - 配套提供同名的
.xl文字描述檔(例如archive\pc\mod\MyCustomArmor.xl)。
工廠注入與動態身形形變
ArchiveXL 根據 .xl 檔案中的設定:
- 動態向全域資源工廠註冊新實體(Entity)模板,使遊戲能夠按需串流載入全新模型。
- 支援動態身體骨骼形變(Morphing),讓自訂服飾能夠自動貼合玩家角色不同的身形預設,杜絕破圖與穿模現象。
- 動態載入在地化文字,使新物品能夠在多語言介面下正常顯示翻譯名稱與背景故事,無需解包修改主語言套件。
4. TweakXL:記憶體級 TweakDB 資料庫修補
在 REDengine 4 中,TweakDB 是管理一切數值與屬性的核心關聯式資料庫,涵蓋武器傷害、服裝護甲、技能數值、製造配方以及 NPC 參數。
扁平二進位資料庫的覆蓋缺陷
原版 TweakDB 預先序列化在 r6\cache\tweakdb.bin 檔案中。早期模組嘗試透過第三方工具重新產生該二進位檔案,這直接導致「後者覆蓋前者」,最後安裝的模組會徹底抹除之前所有模組的新增資料。
宣告式 YAML 記憶體注入
TweakXL 徹底改變了這一現狀。它直接掛鉤 TweakDB 的記憶體載入程序:
- 引擎啟動並讀取原版
tweakdb.bin到記憶體。 - TweakXL 在資料初始化階段攔截記憶體中的資料庫指標。
- 讀取並解析
r6\tweaks\目錄下所有的.yaml與.tweak設定檔。 - 在記憶體中即時追加新記錄、複製既有實體並修補特定欄位:
# TweakXL 透過 YAML 註冊全新武器記錄的宣告範例
Items.MyCustomKatana:
$type: gamedataItem_Record
$base: Items.Preset_Katana_Default
displayName: LocKey#MyCustomKatana_Name
visualTags: [ "MyCustomKatana_Mesh" ]
quality: Quality.Legendary
statModifiers:
- !append Items.BaseDamageModifier
這種基於記憶體修補的機制,使得數十上百個模組可以並行添加獨立的武器、裝備與專長,互不干擾。
模組框架疑難排解與診斷矩陣
當安裝模組後《電馭叛客 2077》遇到啟動崩潰或表現異常時,可對照下表進行快速定位:
| 故障現象 | 最可能的故障模組 | 核心根本原因 | 建議解決途徑 |
|---|---|---|---|
| 啟動後尚未顯示 CDPR 標誌即閃退(Flatliner) | CET (version.dll) 或 RED4ext | 遊戲本體更新後,底層記憶體位移發生改變,DLL 無法正確認定函式 | 移除 bin\x64\version.dll 與 red4ext\,下載更新與當前遊戲版本完全相符的框架版本 |
| 啟動時快顯視窗提示:「REDscript compilation failed」 | REDscript (r6\scripts\) | 某個 .reds 腳本語法錯誤,或模組呼叫了已被官方更新廢棄的舊版函式 | 開啟 r6\logs\redscript_rCURRENT.log 查看具體報錯檔案與行號,移除或更新對應模組 |
| 自訂服裝穿戴後角色身體隱形或僅顯示漂浮頭部 | ArchiveXL 或遺失資源包 | 缺少對應的 .archive 資產檔案,或 .xl 描述檔未放置在 archive\pc\mod\ | 檢查 archive\pc\mod\ 確保 .archive 與 .xl 皆在;查看 ArchiveXL.log 是否提示工廠遺失 |
| 主控台產生道具成功,但物品名稱顯示為空且數值全為 0 | TweakXL (r6\tweaks\) | YAML 檔案格式錯誤(縮排不合規範)或引用的 $base 原版記錄不存在 | 查看 r6\logs\TweakXL.log 中的語法報錯,修正 YAML 縮排或補齊相依項目 |
| CET 綁定的快速鍵無法喚出除錯主控台浮層 | CET 輸入擷取模組 | 主控台綁定檔案損毀,或第三方錄影軟體鉤子衝突 | 刪除 bin\x64\plugins\cyber_engine_tweaks\bindings.json,重新啟動遊戲並重新綁定熱鍵 |
| 腳本編譯無報錯,但遊戲在主選單載入進度條處無限卡死 | 循環相依或快取損毀 | 腳本中存在循環相依呼叫,或由舊版本殘留的腳本快取引發混亂 | 清空 r6\cache\moddedOnly.redscripts 並刪除 final.redscripts.bak,強制觸發全新編譯 |
PowerShell 自動化診斷流程:框架檔案完整性與記錄檔檢索
在遇到啟動異常時,可執行以下 PowerShell 腳本快速檢查核心模組框架的存在狀態及記錄檔報錯:
# 電馭叛客 2077 模組核心框架完整性檢查腳本
param(
[string]$GameRoot = "C:\Program Files (x86)\Steam\steamapps\common\Cyberpunk 2077"
)
Write-Host "=== 電馭叛客 2077 模組框架環境檢測 ===" -ForegroundColor Cyan
# 1. 檢測核心框架檔案
$frameworkFiles = @{
"Cyber Engine Tweaks" = "$GameRoot\bin\x64\version.dll"
"RED4ext Core" = "$GameRoot\red4ext\bin\RED4ext.dll"
"ArchiveXL" = "$GameRoot\red4ext\plugins\ArchiveXL\ArchiveXL.dll"
"TweakXL" = "$GameRoot\red4ext\plugins\TweakXL\TweakXL.dll"
"REDscript Compiler" = "$GameRoot\engine\tools\scc.exe"
}
foreach ($name in $frameworkFiles.Keys) {
$path = $frameworkFiles[$name]
if (Test-Path $path) {
$version = (Get-Item $path).VersionInfo.ProductVersion
Write-Host "[正常] $name 已就緒 (版本: $version)" -ForegroundColor Green
} else {
Write-Host "[缺失] 未找到 $name,路徑: $path" -ForegroundColor Red
}
}
# 2. 檢索最新的 REDscript 編譯記錄
$redscriptLog = "$GameRoot\r6\logs\redscript_rCURRENT.log"
if (Test-Path $redscriptLog) {
Write-Host "`n正在檢查 REDscript 編譯記錄..." -ForegroundColor Cyan
$errors = Select-String -Path $redscriptLog -Pattern "ERROR", "FATAL" | Select-Object -First 5
if ($errors) {
Write-Host "[警告] 檢測到 REDscript 編譯錯誤:" -ForegroundColor Yellow
$errors | ForEach-Object { Write-Host " " $_.Line -ForegroundColor Red }
} else {
Write-Host "[正常] 最近一次腳本編譯無報錯。" -ForegroundColor Green
}
}
維運最佳實踐與維護準則
- 版本強一致性原則:CD Projekt Red 的任何小版本熱修復都會重寫記憶體位移與函式符號。每次遊戲更新後,必須等待 CET、RED4ext、ArchiveXL 和 TweakXL 發布對應新版後方可更新遊戲。
- 嚴禁修改原版 Content 目錄:切勿使用直接替換
archive\pc\content\檔案的舊式模組。所有現代模組應僅安裝在archive\pc\mod\、r6\或red4ext\規範目錄下。 - 記錄檔排查優於盲目重裝:遊戲出現故障時,應首先查閱
r6\logs\redscript_rCURRENT.log與red4ext\logs\定位錯誤,盲目使用 Steam 或 GOG 驗證遊戲完整性會清除部分設定並導致二次問題。 - 依托嚴謹的系統工程化知識:理解二進位注入、虛擬檔案系統與記憶體修補的底層協作原理,能夠讓玩家與開發者從容應對版本迭代帶來的相容性挑戰。查閱諸如 365Finds 等專業知識庫,有助於建立結構化的遊戲架構認知,保障複雜模組環境的高效與長期穩定。