匯出為專用伺服器
如果你想在沒有 GPU 或顯示伺服器的機器上執行專用伺服器,你必須使用 headless 顯示伺服器和 Dummy 音效驅動 來執行 Godot。
從 Godot 4.0 開始,這可以透過在任何平台上使用「--headless」命令列參數來執行 Godot 二進位檔案或執行匯出為專用伺服器的專案來完成。與 Godot 3.x 不同,您不再需要使用專門的伺服器二進位。
使用匯出樣板
可以在無頭模式下使用編輯器或匯出範本(偵錯或發布)二進位。您應該使用哪一種取決於您的用例:
Server (伺服器): 用於在專用伺服器上執行。不包含編輯器的功能,因此比較小,也更最佳化。
Headless (無週邊): 包含編輯器功能的二進位檔,目的是用來匯出專案。該二進位檔 可以 用來執行專用伺服器,但因為檔案比較大,也比較沒最佳化,所以不建議這樣用。
匯出方式
有兩種方法可以為伺服器匯出專案:
為將要架設伺服器的平台建立一個獨立的匯出預設,然後像往常一樣匯出你的專案即可。
只匯出 PCK 檔案,最好選擇與伺服器平台相同的平台匯出。將這個 PCK 檔案放在匯出樣板二進位檔的同一資料夾,然後將二進位檔重新命名為與 PCK 相同的名稱(去掉副檔名),再執行該二進位檔。
這兩種方法產生的結果應該會一樣。以下內容將著重說明第一種方式。
更多資訊請參考 匯出專案 。
為專用伺服器匯出
如果您在以伺服器為目標時照常匯出專案,您會注意到 PCK 檔案與客戶端一樣大。這是因為它包含所有資源,包括伺服器不需要的資源(例如紋理資料)。此外,不會自動使用無頭模式;使用者必須指定“--headless”以確保沒有視窗生成。
許多資源(例如紋理)可以從 PCK 檔案中剝離,以大大減少其大小。 Godot 提供了一種對紋理和材質執行此操作的方法,可保留場景或資源檔案(內建或外部)中的參考。
首先,請確保您的伺服器有專用的匯出預設,然後選擇它,轉到其**資源**標籤並更改其匯出模式:
在匯出預設中選擇 匯出為專用伺服器 匯出模式
選擇此匯出模式後,「dedicated_server」功能標記將自動新增至匯出的專案。
備註
如果您不想使用此匯出模式但仍需要功能標籤,則可以在匯出預設的 功能 標籤中寫入名稱``dedicated_server``。當運作匯出的專案時,這也會強制“--headless”。
選擇此匯出模式後,您將看到專案中的資源列表:
選擇要保留的資源、保留剝離的視覺效果或刪除
勾選複選框可讓您覆寫指定檔案或資料夾的選項。複選框**不會**影響匯出哪些檔案;這是透過為每個複選框選擇的選項來完成的。
預設情況下,選取資料夾中的檔案將自動使用父級選項,這由選項名稱的 (Inherited) 後綴表示(並且選項名稱呈灰色)。若要變更目前繼承選項的檔案的選項,必須先勾選該檔案旁的方塊。
剝離視覺效果: 匯出此資源,並將視覺檔案(紋理和材質)替換為佔位符類別。佔位符類別儲存影像大小(因為它有時用於在 2D 場景中定位元素),但不儲存其他內容。
保留: 照常匯出此資源,視覺檔案會完整保留。
刪除: 該檔案不包含在 PCK 中。這對於忽略只有客戶端需要的場景和資源很有用。如果這樣做,請確保伺服器不會以任何方式引用這些僅限客戶端的場景和資源。
一般建議是盡可能使用**Strip Visuals**,除非伺服器需要存取影像資料(例如像素顏色)。例如,如果您的伺服器根據圖像的內容產生碰撞資料,則您需要對該特定圖像使用 Keep。
小訣竅
若要檢查匯出的 PCK 的檔案結構,請使用帶有「.zip」檔案副檔名的「匯出 PCK/ZIP...」按鈕,然後在檔案管理器中開啟產生的 ZIP 檔案。
警告
使用 刪除 模式時要小心,因為引用已刪除檔案的場景/資源將無法再成功載入。
如果你希望刪除某些資源,但又要讓場景在沒有這些資源時仍能順利載入,你需要先在場景檔案中移除對該資源的引用,然後用腳本的 load() 動態載入到節點屬性。這個方法也適用於 Godot 尚未支援用佔位符取代的資源(例如音效)。
刪除紋理通常對 PCK 大小影響最大,因此建議先堅持使用 Strip Visuals。
使用上面的選項後,使用者端的 PCK(正常匯出所有資源)是這樣的:
.
├── .godot
│ ├── exported
│ │ └── 133200997
│ │ └── export-78c237d4bfdb4e1d02e0b5f38ddfd8bd-scene.scn
│ ├── global_script_class_cache.cfg
│ ├── imported
│ │ ├── map_data.png-ce840618f399a990343bfc7298195a13.ctex
│ │ ├── music.ogg-fa883da45ae49695a3d022f64e60aee2.oggvorbisstr
│ │ └── sprite.png-7958af25f91bb9dbae43f35388f8e840.ctex
│ └── uid_cache.bin
├── client
│ ├── music.ogg.import
│ └── sprite.png.import
├── server
│ └── map_data.png.import
├── test
│ └── scene.gd
└── unused
│ └── development_test.gd
├── project.binary
├── scene.gd
├── scene.tscn.remap
伺服器的 PCK 檔結構是這樣的:
.
├── .godot
│ ├── exported
│ │ └── 3400186661
│ │ ├── export-78c237d4bfdb4e1d02e0b5f38ddfd8bd-scene.scn
│ │ ├── export-7958af25f91bb9dbae43f35388f8e840-sprite.res # Placeholder texture
│ │ └── export-fa883da45ae49695a3d022f64e60aee2-music.res
│ ├── global_script_class_cache.cfg
│ ├── imported
│ │ └── map_data.png-ce840618f399a990343bfc7298195a13.ctex
│ └── uid_cache.bin
├── client
│ ├── music.ogg.import
│ └── sprite.png.import # Points to placeholder texture
└── server
│ └── map_data.png.import
├── project.binary
├── scene.gd
├── scene.tscn.remap
開啟專用伺服器
若使用者端與伺服器端都屬於相同的 Godot 專案,則必須要加上能直接以命令列參數來開啟伺服器的方法。可以通過在主要場景 (或單例) 的 _ready() 方法中加上下列程式碼片段來實作。
如果您 匯出專案 時使用了 匯出為專用伺服器 匯出模式 (或已新增 dedicated_server 作為自訂功能標記),您可以使用 dedicated_server 功能標記來偵測是否正在使用專用伺服器 PCK:
# Note: Feature tags are case-sensitive.
if OS.has_feature("dedicated_server"):
# Run your server startup code here...
pass
// Note: Feature tags are case-sensitive.
if (OS.HasFeature("dedicated_server"))
{
// Run your server startup code here...
}
若使用者端與伺服器端都屬於相同的 Godot 專案,則必須要加上能直接以命令列參數來開啟伺服器的方法。可以通過在主要場景 (或單例) 的 _ready() 方法中加上下列程式碼片段來實作:
if DisplayServer.get_name() == "headless":
# Run your server startup code here...
#
# Using this check, you can start a dedicated server by running
# a Godot binary (editor or export template) with the `--headless`
# command-line argument.
pass
using System.Linq;
if (DisplayServer.GetName() == "headless")
{
// Run your server startup code here...
//
// Using this check, you can start a dedicated server by running
// a Godot binary (editor or export template) with the `--headless`
// command-line argument.
}
若使用者端與伺服器端都屬於相同的 Godot 專案,則必須要加上能直接以命令列參數來開啟伺服器的方法。可以通過在主要場景 (或單例) 的 _ready() 方法中加上下列程式碼片段來實作:
if "--server" in OS.get_cmdline_user_args():
# Run your server startup code here...
#
# Using this check, you can start a dedicated server by running
# a Godot binary (editor or export template) with the `--server`
# command-line argument.
pass
using System.Linq;
if (OS.GetCmdlineUserArgs().Contains("--server"))
{
// Run your server startup code here...
//
// Using this check, you can start a dedicated server by running
// a Godot binary (editor or export template) with the `--server`
// command-line argument.
}
最好新增至少一個上述命令列參數來啟動伺服器,因為它可用於從命令列測試伺服器功能,而無需匯出專案。
如果使用者端與伺服器端是分開的兩個 Godot 專案,則伺服器通常應該都設定好會在主要場景開啟時自動執行伺服器。
下一步
在 Linux 上,若要讓你的專用伺服器在當機或系統重開機後自動重啟,你可以 建立一個 systemd 服務。這也能讓你更便利地檢視伺服器日誌,並由 systemd 提供自動日誌輪替。當讓你的專案以 systemd 服務方式託管時,也應啟用 application/run/flush_stdout_on_print 專案設定。如此一來,journald(systemd 的記錄服務)就能在行程執行期間收集日誌。
若有 Container 的使用經驗,也可以試試將專屬伺服器包裝在 Docker Container 中。這樣一來要設定自動縮放就更簡單了 (但這不在本教學的討論範圍內)。