
最近在B站刷到不少FNFFriday Night Funkin的二次創作視頻尤其是那些基于QT引擎的模組Mod視覺效果和玩法都讓人眼前一亮。很多開發者包括一些剛接觸游戲開發的朋友都很好奇一個完整的FNF QT模組從零到一到底是怎么做出來的為什么網上有些演示視頻看起來絲滑流暢而自己動手時卻總是遇到各種奇怪的Bug比如角色動畫錯位、音符判定不準甚至游戲直接崩潰本文將從一個完整的實戰項目出發為你拆解FNF QT模組的開發全流程。我們將制作一個包含兩個版本的模組一個是“失誤版本”模擬開發中常見的錯誤和問題另一個是“完美版本”展示修復后的正確實現。通過這種對比你不僅能掌握QT引擎如Psych Engine模組開發的核心技術棧更能深刻理解那些“坑”在哪里以及如何系統性地規避和解決。無論你是想為FNF制作自己的原創角色和歌曲還是想深入學習Haxe語言和游戲Mod開發這篇文章都能提供一條清晰的路徑。1. 背景與核心概念什么是FNF與QT模組在開始敲代碼之前我們有必要厘清幾個核心概念這能幫助你更好地理解整個開發框架。Friday Night Funkin‘ (FNF)是一款使用Haxe語言和HaxeFlixel框架開發的開源節奏游戲。玩家需要根據屏幕上落下的音符在正確的時機按下對應方向鍵讓游戲角色“說唱”并擊敗對手。其開源特性和強大的社區支持催生了海量的玩家自制模組。“QT模組”通常指的是基于Psych Engine的模組。Psych Engine是一個為FNF社區開發的高級、優化過的游戲引擎分支俗稱“QT引擎”它提供了比原版更強大的功能例如更靈活的動畫系統、內置的關卡編輯器、復雜的腳本事件支持等。因此現在社區提到“做QT模組”大多是指基于Psych Engine進行二次開發。一個完整的模組Mod通常包含以下幾個部分資產Assets圖像角色精靈圖、背景、聲音音樂、音效、字體等。數據Data定義每周Week、歌曲Song、角色Character的JSON配置文件。代碼Code用Haxe編寫的游戲邏輯可能包括新的游戲機制、UI、特殊效果等。腳本ScriptsPsych Engine支持使用Haxe腳本.hx文件或類Lua腳本.lua文件在運行時動態修改游戲行為這是實現復雜效果的關鍵。本次實戰我們將創建一個名為“TutorialMod”的模組包含一首原創歌曲和一個自定義角色并分別實現“失誤”與“完美”兩個版本。2. 環境準備與版本說明工欲善其事必先利其器。搭建一個穩定、版本匹配的開發環境是成功的第一步。核心環境要求操作系統Windows 10/11 macOS 或 Linux。本文以Windows為例。編程語言Haxe 4.2.5。這是Psych Engine使用的穩定版本不推薦使用最新的Haxe 4.3可能存在兼容性問題。游戲引擎Psych Engine 0.7.1h。這是社區廣泛使用且文檔相對齊全的一個穩定版本。集成開發環境IDEVisual Studio Code “Haxe Extension Pack”插件。這是最主流的Haxe開發環境。版本控制Git可選但強烈推薦用于管理你的模組項目。詳細安裝與配置步驟2.1 安裝Haxe與Haxelib下載Haxe訪問Haxe官網下載Haxe 4.2.5的Windows安裝程序。安裝運行安裝程序記得勾選“將Haxe添加到系統環境變量”選項。驗證安裝打開命令提示符CMD或PowerShell輸入以下命令haxe -version haxelib version如果正確顯示版本號如4.2.5說明安裝成功。2.2 安裝Psych Engine依賴Psych Engine通過HaxelibHaxe的包管理器管理依賴。打開命令行依次安裝以下關鍵庫。請嚴格按照順序和指定版本安裝這是避免后續編譯錯誤的關鍵。haxelib install lime 8.0.1 haxelib install openfl 9.2.1 haxelib install flixel 5.4.1 haxelib install flixel-tools 1.5.2 haxelib install flixel-ui 2.7.1 haxelib install hscript 2.5.0 haxelib install polymod 1.6.0 haxelib install discord_rpc 2.0.0運行haxelib list檢查所有庫是否已正確安裝。2.3 獲取Psych Engine源代碼使用Git克隆Psych Engine倉庫到本地如果沒有Git可以直接下載ZIP包解壓git clone https://github.com/ShadowMario/FNF-PsychEngine cd FNF-PsychEngine建議切換到0.7.1h標簽以確保版本一致git checkout 0.7.1h2.4 配置VSCode與項目用VSCode打開FNF-PsychEngine文件夾。安裝擴展搜索并安裝 “Haxe Extension Pack”。首次打開項目VSCode可能會提示你選擇Haxe版本。選擇你安裝的4.2.5。在項目根目錄下你應該能看到project.xml、export、source等關鍵文件夾。至此基礎環境搭建完成。接下來我們將在mods目錄下創建我們的模組。3. 模組項目結構與核心文件解析一個標準的Psych Engine模組其文件結構是高度規范化的。理解這個結構是組織代碼和資源的基礎。在我們的FNF-PsychEngine/mods/目錄下創建名為TutorialMod的文件夾。結構如下TutorialMod/ ├── _append/ # (可選) 用于向游戲原有列表追加內容 ├── _core/ # (可選) 核心代碼覆蓋 ├── characters/ # 角色定義文件 │ └── tutorial-bf.json # 我們的自定義角色定義 ├── data/ # 歌曲和每周數據 │ ├── tutorial-song/ # 歌曲專屬文件夾 │ │ ├── tutorial-song.json # 歌曲配置文件 │ │ └── tutorial-song.mp3 # 歌曲音頻文件 │ └── weeks.json # 每周列表定義 ├── images/ # 圖像資源 │ ├── characters/ # 角色精靈圖 │ │ └── tutorial-bf.png │ ├── stages/ # 舞臺背景 │ │ └── tutorial-stage.png │ └── icons/ # 角色圖標用于選歌界面 │ └── tutorial-bf-icon.png ├── sounds/ # 音效如打擊音效 ├── videos/ # 過場視頻 ├── scripts/ # Haxe或Lua腳本 ├── mods-list.txt # 模組列表文件需手動添加 └── pack.json # 模組元數據描述文件核心配置文件詳解pack.json模組的“身份證”。{ name: Tutorial Mod, description: A mod to demonstrate common mistakes and fixes., version: 1.0.0, releasestate: stable, tags: [tutorial], characters: [ { name: tutorial-bf, icon: icons/tutorial-bf-icon.png, color: 0x31b0d5 } ], songs: [ { name: Tutorial Song, character: tutorial-bf, color: 0x31b0d5, difficulties: [easy, normal, hard], week: 1 } ] }characters和songs數組定義了本模組引入的內容游戲會根據這個列表加載。角色JSON文件 (characters/tutorial-bf.json)定義角色的所有屬性。{ animations: [ { anim: idle, name: BF IDLE, fps: 24, loop: true, indices: [], offsets: [0, 0] }, { anim: singLEFT, name: BF LEFT NOTE, fps: 24, loop: false, indices: [], offsets: [0, 0] } // ... 其他動畫定義 ], image: characters/tutorial-bf, scale: 1.0, sing_duration: 4, healthicon: tutorial-bf, position: [770, 450], camera_position: [0, 0], flip_x: false, healthbar_colors: [0x31b0d5, 0x31b0d5] }animations每個動畫對應一個精靈圖幀序列。indices為空表示使用所有幀。offsets動畫的偏移量用于微調角色在舞臺上的位置。這里是“失誤版本”的常見雷區。歌曲JSON文件 (data/tutorial-song/tutorial-song.json)定義歌曲的元數據和譜面。{ song: { song: Tutorial Song, notes: [ { sectionNotes: [ [0, 0, 0], [500, 2, 0], [1000, 1, 0] ], sectionBeats: 4, typeOfSection: 0, mustHitSection: true, bpm: 150, changeBPM: false, altAnim: false } // ... 更多小節 ], events: [], bpm: 150, needsVoices: true, player1: tutorial-bf, player2: dad, speed: 2.5, stage: tutorial-stage } }sectionNotes譜面數據。[時間戳(ms), 軌道(0-3), 音符類型(0普通, 1長按開始, 2長按結束)]。時間戳錯誤是“失誤版本”的另一個重災區。speed音符滾動速度。stage對應的舞臺背景名稱。4. 實戰案例從“失誤版本”到“完美版本”現在我們開始實際創建模組內容。我們將故意在“失誤版本”中埋下幾個典型錯誤然后在“完美版本”中修復。4.1 創建基礎模組結構按照第3節的目錄結構在mods/TutorialMod/下創建所有必要的文件夾和文件。確保你的圖像和音頻文件已放入正確位置。精靈圖如tutorial-bf.png需要是包含所有動畫幀的橫向或縱向圖集Psych Engine支持XML或TXT格式的圖集描述文件但最簡單的方式是使用等間距幀并在JSON中通過indices或留空來定義。4.2 “失誤版本”實現與問題復現在這個版本中我們故意制造三個常見問題。問題一角色動畫偏移錯誤在tutorial-bf.json中我們為singLEFT動畫設置一個離譜的偏移量{ anim: singLEFT, name: BF LEFT NOTE, fps: 24, loop: false, indices: [], offsets: [150, -100] // 錯誤示范偏移過大 }后果當角色向左唱歌時精靈圖會嚴重偏離其基準位置可能飛到屏幕外或與音符位置不匹配。問題二譜面時間戳計算錯誤在tutorial-song.json中我們錯誤地計算了時間戳。假設BPM是150那么每拍的時間是60000 / 150 400ms。如果我們想在第2拍索引為1因為從0開始的“右”軌道軌道2放置一個音符正確時間戳是400 * 1 400ms。但我們錯誤地寫成了sectionNotes: [ [400, 2, 0], // 意圖第2拍右箭頭 [800, 0, 0], // 意圖第3拍左箭頭 錯誤 [1200, 1, 0] ],實際上如果BPM是150第3拍的時間戳應該是400 * 2 800ms但這里[800, 0, 0]從數值上看是800ms如果這是第3拍左箭頭那它是對的。但常見的錯誤是忘記將音樂編輯軟件中的節拍數從1開始轉換為以0開始的時間索引或者在變速BPM Change段落計算錯誤。更典型的錯誤是直接使用秒數而不是毫秒。問題三資源路徑或名稱拼寫錯誤在pack.json中我們將角色圖標路徑寫錯icon: icons/tutorial-bf-ico.png // 錯誤實際文件是 tutorial-bf-icon.png后果在游戲自由模式Freeplay中該角色的圖標無法加載顯示為默認的“”圖標或導致游戲崩潰。4.3 編譯、測試與問題現象添加模組到列表在mods/mod-list.txt文件中添加一行TutorialMod確保游戲能識別它。編譯游戲在VSCode中按F5或根據你的配置選擇“Debug”模式編譯并運行Psych Engine。你也可以在命令行執行lime test windows或其他目標平臺。進入游戲測試在主菜單進入“自由模式Freeplay”。你應該能看到“Tutorial Song”但角色圖標可能顯示錯誤問題三。選擇歌曲并開始游戲。觀察問題一當按下左方向鍵時tutorial-bf角色的動畫會“跳”到一個奇怪的位置。觀察問題二音符的下落節奏與音樂節拍對不上感覺要么太快要么太慢或者根本不在拍子上。玩家會感覺游戲“手感”極差。4.4 “完美版本”修復方案現在我們逐一修復上述問題。修復一校正動畫偏移動畫偏移offsets的[x, y]用于微調該動畫幀在角色position基礎上的最終顯示位置。通常需要通過反復測試來調整。對于對稱的角色很多動畫的偏移可能是[0, 0]。我們可以先設為[0, 0]然后在游戲中觀察如果向左唱歌時手臂位置不對再慢慢調整例如[10, 5]。{ anim: singLEFT, name: BF LEFT NOTE, fps: 24, loop: false, indices: [], offsets: [0, 0] // 修正先歸零再根據視覺微調 }最佳實踐使用Psych Engine內置的“角色編輯器”Character Editor或第三方工具如“Friday Night Funkin‘ Character Editor”來可視化地調整偏移和位置這比手動修改JSON高效準確得多。修復二精確計算譜面時間戳確保你理解時間戳單位是毫秒ms。計算時間戳的公式是時間戳 (節拍數 * (60000 / BPM))。節拍數從0開始計數。第1小節第1拍是0第1小節第2拍是1以此類推。如果歌曲中有BPM變化計算會復雜很多。強烈建議使用專業的譜面編輯器如Psych Engine 內置的關卡編輯器在游戲調試菜單按7中開啟這是最原生、最準確的方式。第三方工具如“FNF Chart Editor”可以導入音頻可視化地放置音符并導出為Psych Engine兼容的JSON。使用編輯器生成的sectionNotes會是絕對正確的例如sectionNotes: [ [0, 0, 0], // 第0拍左箭頭 [400, 1, 0], // 第1拍下箭頭 [800, 2, 0], // 第2拍上箭頭 [1200, 3, 0] // 第3拍右箭頭 ],修復三嚴格核對資源路徑與名稱養成嚴格一致的文件命名習慣并使用編輯器的“復制路徑”功能來避免手動輸入錯誤。icon: icons/tutorial-bf-icon.png // 修正與文件名完全一致同時檢查所有JSON文件中引用的圖像、聲音鍵名是否與文件名不含擴展名匹配。例如image: characters/tutorial-bf對應images/characters/tutorial-bf.png。4.5 最終測試與效果對比修復所有問題后重新編譯并運行游戲。自由模式現在可以看到正確的角色圖標和歌曲信息。游戲過程角色動畫流暢唱歌時動作與音符方向匹配位置穩定。音符精準地落在音樂節拍上游戲體驗絲滑。沒有崩潰或資源缺失錯誤。至此你已經成功將一個充滿Bug的“失誤版本”模組修復成了一個可正常游玩的“完美版本”。這個對比過程深刻揭示了模組開發中細節的重要性。5. 常見問題與排查思路在模組開發中你肯定會遇到各種報錯和異常。下面是一個快速排查清單。問題現象可能原因排查步驟與解決方案編譯失敗Haxe報錯1. Haxe或Haxelib版本不對。2. 依賴庫缺失或版本沖突。3. 源代碼語法錯誤。1. 確認Haxe為4.2.5用haxelib list檢查核心庫版本是否與上文一致。2. 運行haxelib upgrade更新所有庫或刪除~/.haxelib緩存重新安裝。3. 檢查VSCode的錯誤提示定位到具體文件行。游戲能編譯但啟動后黑屏/閃退1. 模組JSON格式錯誤。2. 資源文件路徑錯誤或格式不支持。3. 腳本.hx/.lua語法錯誤。1. 使用JSON驗證工具檢查所有JSON文件。2. 檢查控制臺輸出如果可用看是否有“Failed to load image/sound”錯誤。3. 暫時移除scripts/文件夾內的腳本看是否正常。角色/背景不顯示1. JSON中image路徑錯誤。2. 圖片文件損壞或格式不對。3. 圖片尺寸過大非2的冪次方。1. 確認路徑是相對于images/文件夾的且不帶擴展名。2. 嘗試用其他圖片替換測試。3. 將圖片尺寸調整為如1024x1024、512x512等。音符與音樂不同步1. 歌曲JSON中的bpm值錯誤。2.sectionNotes時間戳計算錯誤。3. 音頻文件本身有空白開頭。1. 用音頻軟件如Audacity準確測量歌曲BPM。2.務必使用內置關卡編輯器制作譜面。3. 修剪音頻文件確保第一個節拍從文件開頭開始。動畫播放錯亂或偏移1. JSON中animations的indices定義錯誤。2.offsets值不合理。3. 精靈圖幀順序或尺寸不統一。1. 確認indices數組與精靈圖幀數匹配。留空[]表示使用所有幀。2. 使用角色編輯器進行可視化調整。3. 確保精靈圖每一幀的尺寸相同。在自由模式中看不到模組歌曲1.pack.json中songs未定義或格式錯誤。2.mods-list.txt中沒有添加模組名。3. 歌曲JSON文件不在正確的data/子文件夾內。1. 仔細檢查pack.json語法特別是引號和逗號。2. 確認mods-list.txt中有TutorialMod區分大小寫。3. 確保歌曲文件夾和JSON文件命名符合規范。6. 最佳實踐與工程建議掌握了基礎之后遵循一些好的實踐能讓你的模組開發更高效、更專業也更容易被社區接受。版本控制與備份務必使用Git管理你的模組項目。為每個新功能或修復創建分支。定期提交Commit并寫好清晰的提交信息。將代碼倉庫托管到GitHub或GitLab便于協作和版本回溯。資源管理命名規范使用小寫、短橫線分隔的命名方式如my-cool-character.png。圖像優化使用工具如TinyPNG壓縮PNG圖片減少游戲加載時間和內存占用。確保尺寸為2的冪次方。音頻格式音樂使用OGG Vorbis格式.ogg音效使用WAV格式。OGG格式體積小且支持流式播放。代碼與腳本模塊化如果你的模組有復雜邏輯不要把所有代碼塞進一個腳本。按功能拆分成不同的.hx或.lua文件。注釋與文檔在JSON配置和腳本中添加注釋說明關鍵參數的作用。為你的模組編寫一個簡單的README.md說明安裝方法、功能特性。錯誤處理在Haxe腳本中使用try-catch處理可能出錯的操作避免游戲崩潰。測試流程分階段測試每完成一個角色、一首歌或一個功能就立即進行測試。多難度測試確保“簡單”、“普通”、“困難”三個難度的譜面都經過測試。性能測試在低配電腦上測試模組確保動畫和特效不會導致嚴重卡頓。發布與分享清理無用文件發布前刪除開發過程中的臨時文件、備份文件。創建發布包將TutorialMod文件夾打包成ZIP文件。遵守社區規范如果使用了他人的資產音樂、圖像務必取得授權并在發布說明中注明出處。7. 總結與學習路線通過這個“失誤vs完美”雙版本模組的實戰我們系統性地走完了FNF Psych Engine模組開發的核心流程從環境搭建、結構解析、資源創建、配置編寫到問題排查與修復。關鍵在于理解JSON配置與游戲資源的對應關系以及利用好引擎提供的工具如關卡編輯器來保證基礎數據的準確性。你的下一步學習路線可以這樣規劃鞏固基礎嘗試為你的模組添加第二個角色、第二首歌曲或者創建一個全新的舞臺背景。學習腳本深入研究Psych Engine的腳本系統。從修改UI顏色、添加簡單的鏡頭晃動事件開始逐步學習如何使用Haxe腳本創建全新的游戲機制如“健康值流失”、“彈幕音符”。研究源碼閱讀Psych Engine的源代碼source/目錄這是理解其工作原理和實現高級修改的最強途徑。重點關注PlayState.hx游戲主邏輯和Character.hx角色邏輯。參與社區加入FNF模組開發社區如Discord服務器、相關論壇閱讀其他人的模組源碼向有經驗的開發者提問這是快速提升的最佳方式。模組開發是創意與技術的結合。一開始的“失誤”并不可怕它正是通往“完美”的必經之路。希望這篇教程能為你打下扎實的基礎助你創造出屬于自己的精彩模組。如果在實踐中遇到新的問題不妨回頭看看“常見問題”部分或者帶著具體的錯誤信息去社區尋找答案。祝你開發順利