Attention: Here be dragons

This is the latest (unstable) version of this documentation, which may document features not available in or compatible with released stable versions of Godot.

使用 gettext(PO 檔)進行在地化

In addition to importing translations in CSV format, Godot also supports loading translation files written in the GNU gettext format (text-based .po and compiled .mo).

備註

如需 gettext 的基礎介紹,請參考 A Quick Gettext Tutorial。雖然該教學以 C 專案為例,但大多數內容同樣適用於 Godot(除了 xgettext 相關部分)。

完整文件請參閱 GNU Gettext

優點

  • gettext is a standard format, which can be edited using any text editor or GUI editors such as Poedit. This can be significant as it provides a lot of tools for translators, such as marking outdated strings, finding strings that haven't been translated, etc.

  • TransifexWeblate 等翻譯平台也支援 gettext,讓多人協作在地化更加便利。

  • 與 CSV 相比,gettext 檔更適合搭配 Git 等版本控制系統使用,因為每個語系都有獨立的訊息檔。

  • 在 gettext PO 檔中編輯多行字串比在 CSV 檔中更為便利。

缺點

  • gettext PO 的格式比 CSV 複雜,對在地化新手來說較不易上手。

  • 維護在地化檔案的人員需要在系統上安裝 gettext 工具。不過,由於 Godot 支援以文字為基礎的 .po 檔案,譯者無需安裝 gettext 工具也可直接測試翻譯成果。

  • gettext PO 檔通常以英文作為基底語言,譯者會以此作為來源翻譯至其他語言。你也可以使用其他語言作為基底語言,但並不常見。

安裝 gettext 工具

部分維護操作(如更新訊息檔案)需使用命令列 gettext 工具,因此強烈建議安裝。

  • Windows: 請從 此頁面 下載安裝程式。各種架構與二進位型式(動態或靜態)皆可使用;若不確定,建議選擇 64 位元靜態安裝程式。

  • macOS: 可透過 Homebrew 使用 brew install gettext 指令安裝,或使用 MacPortssudo port install gettext 指令。

  • Linux: 在大多數發行版上,請透過套件管理器安裝 gettext 套件。

若需圖形介面工具,可自其 官方網站 取得 Poedit。基本版本為開源並以 MIT 授權提供。

建立 PO 範本

用編輯器自動產生

The editor can generate a PO template automatically from specified scene and GDScript files. This POT generation also supports translation contexts and pluralization if used in a script, with the optional second argument of tr() and the tr_n() method.

Open Project > Project Settings > Localization > Template Generation, then use the Add… button to specify the path to your project's scenes and scripts that contain localizable strings:

Creating a PO template in the Localization > Template Generation tab of the Project Settings

Creating a PO template in the Localization > Template Generation tab of the Project Settings

After adding at least one scene or script, click Generate in the top-right corner, then specify the path to the output file with a pot file extension. This file can be placed anywhere in the project directory, but it's recommended to keep it in a subdirectory such as locale, as each locale will be defined in its own file.

關於在 GDScript 檔案中加入譯者註解或排除特定字串不加入 PO 範本,請參閱下方 從 GDScript 檔案擷取可在地化字串

接著,請參考 如何從 PO 範本建立訊息檔

備註

每當你變更可在地化字串、或新增場景、腳本後,請記得重新產生 PO 範本。否則,新字串將無法在地化,且舊有字串的翻譯也無法及時更新。

手動建立

如果自動產生無法滿足需求,你也可以用文字編輯器手動建立 PO 範本。檔案可放在專案目錄任意位置,但建議集中於子目錄,以利各語言版本管理。

Create a directory named locale in the project directory. In this directory, save a file named messages.pot with the following content:

# Don't remove the two lines below, they're required for gettext to work correctly.
msgid ""
msgstr ""

# Example of a regular string.
msgid "Hello world!"
msgstr ""

# Example of a string with pluralization.
msgid "There is %d apple."
msgid_plural "There are %d apples."
msgstr[0] ""
msgstr[1] ""

# Example of a string with a translation context.
msgctxt "Actions"
msgid "Close"
msgstr ""

gettext 的訊息由 msgidmsgstr 配對組成。msgid 是原文(通常為英文),msgstr 則是對應的譯文。

警告

PO 範本檔(.pot)裡的 msgstr 值應 一律 保持空白。在地化內容則會填寫於產生的 .po 檔案中。

從 PO 範本建立訊息檔案

msginit 指令可將 PO 範本轉換為訊息檔案。例如,若要建立法文翻譯檔,請在 locale 目錄下執行以下指令:

msginit --no-translator --input=messages.pot --locale=fr

上述指令會在同目錄下產生名為 fr.po 的檔案。

你也可以用 Poedit 圖形介面操作,或將 POT 檔上傳至你選用的協作平台來建立。

在 Godot 載入訊息檔案

To register a messages file as a translation in a project, open the Project Settings, then go to Localization > Translations, click Add… then choose the .po or .mo file in the file dialog. The locale will be inferred from the "Language: <code>\n" property in the messages file.

備註

更多關於在 Godot 匯入與測試翻譯的資訊,請參閱 將遊戲國際化

依照 PO 範本更新訊息檔案

更新 PO 範本後,也要同步更新各語言訊息檔,以包含新字串並移除已不存在的字串。此操作可用 msgmerge 工具自動完成:

# The order matters: specify the message file *then* the PO template!
msgmerge --update --backup=none fr.po messages.pot

若需保留原始訊息檔備份(如本例將備份為 fr.po~),請移除 --backup=none 參數。

備註

執行 msgmerge 後,若原文有改動,則對應譯文前會自動添加 "fuzzy" 註解。這表示翻譯需檢查修正,否則可能已不精確。

帶有「fuzzy」註解的字串將**不會**被 Godot 讀取,直到翻譯被更新且「fuzzy」註解被移除。

檢查 PO 檔案或範本有效性

可以檢查 gettext 檔案的語法是否有效。

若用 Poedit 開啟,若有語法錯誤會顯示相應警告。你也可以藉由執行下列 gettext 指令來驗證:

msgfmt fr.po --check

如有語法錯誤或警告,將顯示於終端機,否則 msgfmt 不會有任何輸出。

使用二進位 MO 檔案(僅適用於大型專案)

若你的專案有成千上萬條需翻譯字串,建議使用二進位(編譯後)MO 檔案取代文字型 PO 檔案。MO 檔案體積更小、讀取速度更快。

可用下列指令產生 MO 檔案:

msgfmt fr.po --no-hash -o fr.mo

若 PO 檔有效,此指令會在同目錄下產生 fr.mo。之後即可如上所述在 Godot 中載入該 MO 檔。

建議將原始 PO 檔案納入版本控制,便於日後維護翻譯。若遺失原始 PO 檔需將 MO 檔反編譯回文字 PO 檔,可用下列指令:

msgunfmt fr.mo > fr.po

反編譯回來的檔案不會包含註解或 fuzzy 標記,因為這些資訊原本就不會被編入 MO 檔案中。

從 GDScript 檔案擷取可在地化字串

內建的 編輯器外掛 可識別多種原始碼模式,從 GDScript 檔案中擷取可在地化字串,包含但不限於下列類型:

  • tr()tr_n()atr()atr_n() 呼叫;

  • 設定 textplaceholder_texttooltip_text 屬性時;

  • 呼叫 add_tab()add_item()set_tab_title() 等方法;

  • FileDialog 篩選字串,如 "*.png ; PNG Images"

備註

參數或右側運算元必須是常數字串,否則編輯器外掛將無法解析並會忽略該表達式。

若外掛擷取了不需翻譯的字串,可在其前方加上 NO_TRANSLATE 註解來忽略。你也可以用 TRANSLATORS: 註解提供補充說明給譯者。這些註解必須與被識別的程式碼在同一行或直接前一行。

$CharacterName.text = "???" # NO_TRANSLATE

# NO_TRANSLATE: Language name.
$TabContainer.set_tab_title(0, "Python")

item.text = "Tool" # TRANSLATORS: Up to 10 characters.

# TRANSLATORS: This is a reference to Lewis Carroll's poem "Jabberwocky",
# make sure to keep this as it is important to the plot.
say(tr("He took his vorpal sword in hand. The end?"))

使用語境(context)

可以使用 context 參數來區分譯文使用的情境,或區分同形異義詞(多重意義的詞)。

例如:

tr("Start", "Main Menu")
tr("End", "Main Menu")
tr("Shop", "Main Menu")
tr("Shop", "In Game")

In a gettext PO file, a string with a context can be defined as follows:

# Example of a string with a translation context.
msgctxt "Main Menu"
msgid "Shop"
msgstr ""

# A different source string that is identical, but with a different context.
msgctxt "In Game"
msgid "Shop"
msgstr ""

更新 PO 檔

隨著時間推進,你會替遊戲加入新內容,也就會出現需要翻譯的新字串。此時需要更新現有的 PO 檔以包含這些新字串。

首先,產生一個包含所有既有字串與新加入字串的 POT 檔。接著,將現有的 PO 檔與新的 POT 檔合併。有兩種作法:

  • 使用 gettext 編輯器,它通常會提供從 POT 檔更新 PO 檔的選項。

  • 使用 gettext 的 msgmerge 工具:

# The order matters: specify the message file *then* the PO template!
msgmerge --update --backup=none fr.po messages.pot

若需保留原始訊息檔備份(如本例將備份為 fr.po~),請移除 --backup=none 參數。

自訂 POT 產生外掛

如果你需要處理額外的檔案格式,可以撰寫自訂外掛來剖析並擷取自訂檔案中的字串。當你按下 Generate POT 時,這個自訂外掛會擷取字串並寫入 POT 檔。要了解如何建立翻譯剖析器外掛,請參考 EditorTranslationParserPlugin