多語言支持 link

(譯者註:原文為“Translation”。將translation直譯為“翻譯”,容易引發歧義,所以文件中單獨出現時一律使用“多語言支持”,“translation file”則翻譯為“翻譯文件”。) Ren’Py包含了視覺系小說多語言支持的綜合框架。有4類要素支持多語言:

對話

腳本的主對話能夠支持多語言,包括各行文本內容的分割、合併、刪除和調整的一套規則。

菜單和介面字串

所有介面文本都支持多語言。

圖像和文件

選擇某種語言時,可以使用對應的一系列圖片和其他文件。

樣式

可以基於語言實現樣式訂製化,這樣遊戲會自動切換為對應某種語言的樣式。

目前Ren’Py的多語言支持主要聚焦在標準化的多語言支持。如果實現的話,創作者就可以使用將遊戲腳本直接扔給多語言解釋器,或者自己創建多語言模板。目前支持的非標準化多語言支持有諸多限制。

主語言和備選語言 link

Ren’Py需要每一個作品都使用一種主語言編寫。這種主語言無論具體是哪國的,都被稱作 None 語言。(如果使用英語編寫,英語就是 None 語言。)

備選語言在作品中出現時,推薦使用原來的Python標識符連寫兩次。(格式為,以字母或下劃線開頭,後面跟字母、數字或者下劃線。)

當選用None語言後,Ren’Py的大多數多語言支持功能都會關閉, 例如Ren’Py內建的異常提示字串和默認菜單項等。 在你項目代碼中找不到這些字串,也不會放入遊戲的最終分發版中。 你可以在 game/tl/None/common.rpym 文件中找到這些字串。 這些字串的用處有兩點: 1. 非英語做為None語言時提供多語言支持; 2. 允許創作者在遊戲中自訂翻譯。

啟動器的語言會作為項目創建時的預設語言。Ren’Py內部的字串初始化時也會使用同種語言。

生成翻譯文件 link

當項目腳本是正常可用的情況下,我們可以在Ren’Py啟動器中選擇“生成翻譯文件”。啟動器將提示你需要生成的語言名稱,然後創建或更新翻譯文件。

翻譯文件是在game文件夾中一個名為“tl”的子文件夾下的同名目錄中。例如,如果你為tutorial項目創建了piglatin的語言支持,對應的語言支持文件將會放在 tutorial/game/tl/piglatin 目錄下。

每一個遊戲腳本文件都會被創建對應的翻譯文件。common.rpy文件也會被創建,其內容包含所有Ren’Py製作遊戲使用的通用字串的多語言支持。

多語言對話 link

因為Ren’Py是一個視覺系小說引擎,我們最需要的自然就是對話的多語言支持。Ren’Py包含了一個具有可塑性的框架,允許對話內容的分割、合併、調整順序及整段刪除。

多語言支持的單元 link

一個由0個或多個可支持多語言的語句構成的語句塊(block)是多語言支持的基礎單元,後面可選加上一條say語句。可支持多語言的語句包括voice和nvl語句。例如下面腳本中的:

label start:
    e "Thank you for taking a look at the Ren'Py translation framework."

    show eileen happy

    e "We aim to provide a comprehensive framework for translating dialogue, strings, images, and styles."

    e "Pretty much everything your game needs!"

這段腳本可以分割為多個多語言支持單元。每個單元都有對應的一個標識符用於聲明該單元。標識符根據單元前的腳本標籤(label)和單元內的語句來生成。(如果多個單元被聲明為同一個多語言數字,從第二個單元開始會自動添加上一個自然數編號便於區分。)

在上面的樣例腳本中,第一個單元生成的標識號為start_636ae3f5,包含這條語句:

e "Thank you for taking a look at the Ren'Py translation framework."

第二個單元的標識號是start_bd1ad9e1m,包含這條語句:

e "We aim to provide a comprehensive framework for translating dialogue, strings, images, and styles."

第三個單元的標識號是start_9e949aac,包含這條語句:

e "Pretty much everything your game needs!"

當遊戲腳本載入時,這些多語言支持的單元會被Ren’Py自動創建。

translate語句 link

當你生成了對某種語言的支持時,Ren’Py會針對每一個多語言支持單元生成一條translate語句。我們再以剛才的那段腳本舉例,Ren’Py生成的語句如下:

# game/script.rpy:95
translate piglatin start_636ae3f5:

    # e "Thank you for taking a look at the Ren'Py translation framework."
    e ""

# game/script.rpy:99
translate piglatin start_bd1ad9e1:

    # e "We aim to provide a comprehensive framework for translating dialogue, strings, images, and styles."
    e ""

# game/script.rpy:101
translate piglatin start_9e949aac:

    # e "Pretty much everything your game needs!"
    e ""

編輯這個文件就可以實現對piglatin語言的支持了。完成編輯後的樣子如下:

# game/script.rpy:95
translate piglatin start_636ae3f5:
    # e "Thank you for taking a look at the Ren'Py translation framework."
    e "Ankthay ouyay orfay akingtay away ooklay atway ethay En'Pyray anslationtray ameworkfray."

# game/script.rpy:99
translate piglatin start_bd1ad9e1:

    # e "We aim to provide a comprehensive framework for translating dialogue, strings, images, and styles."
    e "Eway aimway otay ovidepray away omprehensivecay ameworkfray orfay anslatingtray ialogueday, ingsstray, imagesway, andway ylesstay."

# game/script.rpy:101
translate piglatin start_9e949aac:

    # e "Pretty much everything your game needs!"
    e "Ettypray uchmay everythingway ouryay amegay eedsnay!"

當引擎在主線腳本中遇到一個語句塊(block),Ren’Py就會檢查是否存在對應的translate語句存在。如果存在的話,Ren’Py將會執行translate語句,並向用戶顯示對應語言的內容。

更複雜的多語言支持 link

translate語句中數量並不要求與原語言語句數量保持1比1。例如,一行很長的語句可以分割:

# game/script.rpy:99
translate piglatin start_bd1ad9e1:
    # e "We aim to provide a comprehensive framework for translating dialogue, strings, images, and styles."
    e "Eway aimway otay ovidepray away omprehensivecay ameworkfray..."
    e "...orfay anslatingtray ialogueday, ingsstray, imagesway, andway ylesstay."

或者某條語句可以移除,並用 pass 語句代替。:

# game/script.rpy:101
translate piglatin start_9e949aac:

     # e "Pretty much everything your game needs!"
     pass

甚至可以運行非對話型的語句,比如條件語句或者Python語句。例如,我們可以把下面這句:

e "You scored [points] points!"

在其他語言中寫成:

# game/script.rpy:103
translate piglatin start_36562aba:

    # e "You scored [points] points!"
    $ latin_points = to_roman_numerals(points)
    e "Ouyay oredscay [latin_points] ointspay!"

小建議 link

在處理多語言支持的對話內容時必須非常小心,特別是某個腳本標籤(label)下某個對話內容重複多次的情況。在某些時候,有必要在主語言腳本中直接聲明多語言支持的標識符,像這條語句:

有時候,需要修改原語言對話內容中的某一行,但不想要修改所有翻譯文件的對應內容。 例如,英語中修復了個拼寫錯誤,但不想要修改俄語的翻譯文件。

此時可以在say語句中使用 id 從句,指定語言的翻譯ID。 例如:

label start:
    e "This used to have a typo." id start_61b861a2

增加文本標籤(label)也可能會導致多語言支持衝突。為了防止這種情況出現,腳本標籤(label)後加上一個 hide 分句就可以在翻譯文件生成時忽略這個標籤:

label ignored_by_translation hide:
    "..."

由於多語言語句塊(block)中可以包含Python語句,這些Python語句不應該在超過其所處語句塊(block)之外造成任何副作用。這是因為,切換語言會重啟多語言支持語句塊(block),語句塊內的Python語句的副作用會發生多次。

菜單和字串的多語言支持 link

除了對話,Ren’Py也可以提供菜單與其他字串內文本的多語言支持。介面的各種語言文本條數是嚴格1比1對應的。某個字串被對上的話,就能被另一種語言的字串替換。

當生成翻譯文件時,Ren’Py會掃描腳本文件中的菜單和 _()函數中定義的字串。然後它會將這些字串內容放入一個多語言字串語句塊(block)中。例如,如果我們有如下的腳本內容:

define e = Character(_("Eileen"))

# ...

menu:

    "Go West":
        # ...

    "Head East":
        # ...

Ren’Py會自動生成:

translate piglatin strings:

    old "Eileen"
    new ""

    old "Go West"
    new ""

    old "Head East"
    new ""

完成後的多語言支持內容為:

translate piglatin strings:

    old "Eileen"
    new "Eileenway"

    old "Go West"
    new "Ogay Estway"

    old "Head East"
    new "Eadhay Eastway"

字串的多語言支持用於在對話中內插的某些字串。那些字串不能以對話形式支持多語言。

如果某個字串同時用在多處,可以使用{#…}文本標籤(tag)加以區別。儘管這些字串使用同樣的名字,Ren’Py把這些稍有差別的字串看作需要多語言支持:

"New"
"New{#project}"
"New{#game}"
"New{#playlist}"

translate字串語句可以用來對None語言腳本的轉換。在使用非英語編寫的遊戲中,translate字串語句可以用來轉換Ren’Py的用戶介面。:

translate None strings:
    old "Start Game"
    new "Artstay Amegay"

多語言替換 link

!t標誌用於表示多語言的字串轉換。下面這段腳本使用了原對話和多語言字串的組合:

if mood_points > 5:
    $ mood = _("great")
else:
    $ mood = _("awful")

"I'm feeling [mood!t]."

提取和復用多語言字串 link

多語言字串可以從某個項目中提取,然後移植到另一個項目。完成這點需要以下步驟:

  • 選取來源項目,並選擇“生成翻譯文件”。

  • 輸入需要提取的語言,並點擊“導出字串翻譯”。

  • 回到主選單,選取目標項目,並選擇“生成翻譯文件”。

  • 輸入需要復用的語言(通常與之前提取的語言相通),並選擇“合併字串翻譯”。

這裡有兩個選項,控制語言的復用功能:

替換已存在的翻譯

如果選用這項,已經存在的重要翻譯文件會被覆蓋。默認情況下,復用過程會拒絕覆蓋已經存在的重要翻譯文件。

反轉語言

在復用之前反轉主備語言類型。例如,使用一個原本英語為主語言俄語為備選語言的項目,復用為“俄語為主語言英語為備選語言”的項目時,就需要勾選該項。

圖片和文件的多語言支持 link

當讓一個遊戲支持多語言時,最好替換文件時帶一個語言版本號。例如,某個圖片包含文本,最好的辦法是使用帶其他文字的圖片替換。而那個新的圖片帶一個語言版本號。

Ren’Py遇到這種情況時,會在translation文件夾裡尋找對應的圖片。例如,假如使用了“piglatin”語言,並載入了“library.png”圖片,Ren’Py就會使用 game/tl/piglatin/library.png 圖片代替 game/library.png

如果檔案位置直接在game目錄中,該目錄應該包含在對應的語言中。 例如,文件 game/gui/main_menu.png,可以使用 game/tl/piglatin/gui/main_menu.png 作為多語言替換圖。

樣式的多語言支持 link

當對某個遊戲實現多語言支持時,最好變更樣式(style)——特別是那些與字體相關的樣式。Ren’Py使用多語言樣式語句塊(block)和多語言python語句塊處理這類情況。這些語句塊(block)可以更改語言相關的變數和樣式。例如:

translate piglatin style default:
    font "stonecutter.ttf"

更常見的是,對話使用的字體由 gui.text_font 決定。 系統文本,比如異常界面、可達性菜單和GUI菜單,都由 gui.system_font 項決定。 系統使用的字體應能同時顯示ASCII碼和其他對應語言文字。 綜上,可以這樣訂製:

translate piglatin python:
    gui.text_font = "stonecutter.ttf"
    gui.system_font = "Noto Sans.ttf"

當某種語言被啟用——無論是遊戲開始時還是中途修改語言——Ren’Py都會重設初始化環節內所有樣式的內容。 Ren’Py會運行所有與當前啟用語言相關的 translate python 語句塊、style語句塊和translate style語句塊,保證文件中這些語句塊被優先執行。 最後,Ren’Py會重建所有樣式,並使語言修改生效。

樣式的多語言支持可以添加在任何.rpy文件中。

翻譯文件延遲載入 link

比較大的遊戲如果一口氣載入所有翻譯文件相當耗時。為了能提速,Ren’Py提供了翻譯文件延遲載入功能。 若要啟用該功能,需要在腳本中添加:

define config.defer_tl_scripts = True

通常這行會寫在 options.rpy 或其他載入優先度高於翻譯文件的腳本中。

當該項為True時,Ren’Py不會在初始化階段載入 tl/language 目錄下的腳本。 之後,只有首次啟用某種語言後,Ren’Py才會在遊戲啟動時載入對應翻譯文件。

由於在初始化階段不載入 tl/language 目錄的文件,所以這些文件不應包含在初始化階段必須執行的內容。 比如 initpython 開頭的語句塊,screenimagetransform 等語句。 翻譯文件應該只有以 translatetranslate pythontranslate style 開頭的語句塊。

預設語言 link

使用以下方法可以選擇預設語言:

多語言支持的行為、函數和變數 link

切換語言的主要辦法是使用語言的行為函數。

class Language(language) link

將遊戲語言改為 language

language

一個字串,表示切換的目標語言,若為None表示遊戲腳本預設語言。

語言行為函數可以用於在自訂配置界面添加一個語言自訂選項。

frame:
    style_prefix "pref"
    has vbox

    label _("Language")
    textbutton "English" action Language(None)
    textbutton "Igpay Atinlay" action Language("piglatin")

還有三個與多語言支持相關的函數:

renpy.change_language(language, force=False) link

一個字串,表示切換的目標語言命,若為None表示遊戲腳本預設語言。

renpy.get_translation_identifier() link

返回當前語句的翻譯文件標識符。

renpy.known_languages() link

返回已知語言的集。不包含預設語言None。

此外,還有四個與字串多語言支持相關的函數:

_(s) link

(單下劃線)返回字串 s 的原語言內容。Ren’Py會搜尋該函數傳入的字串,並把它們加入到多語言支持字串列表中。這些字串不會轉換為其他語言,直到他們被顯示過。

__(s) link

(雙下劃線)返回字串 s 轉換成當前語言後的內容。該函數返回的字串會被加入到多語言支持字串列表中。注意字串可以經歷過雙重轉換。如果其匹配到一個對應的多語言字串則顯示轉換後的結果。

_p(s) link

將一個字串重新格式化並標記其是支持多語言的。使用文本組件顯示的字串是轉換過語言的。該函數的用途是,使用表單格式(form)定義多行字串:

define config.about = _p("""
    These two lines will be combined together
    to form a long line.

    This line will be separate.
    """)

重新格式化會將整段文本斷行,移除每行開頭和結尾的空白。整段文本末尾的空白行會被刪除。段落中的空白行會被插入段落分割符。{p}文本標籤(tag)可以斷行,但不會增加新的空白行。

在字串多語言支持中的使用方式如下:

old "These two lines will be combined together to form a long line.\n\nThis line will be separate."
new _p("""
    These two lines will be combined together
    to form a long line. Bork bork bork.

    This line will be separate. Bork bork bork.
    """)
renpy.translate_string(s, language=<renpy.object.Sentinel object at 0x7f5afce071f0>) link

s 立刻翻譯為指定語言 language 並返回。 如果 language 的值是Default,使用設置(preferences)中的語言。 經過該函數翻譯後的字串 不會 被添加到可翻譯字串列表中。指定某個字串的語言可能會導致其發生兩次翻譯的情況。

這裡有兩個語言相關的變數。一個是 config.default_language ,用於改變遊戲預設語言。

_preferences.language link

當前語言名稱,如果使用的是預設語言則是None。需要改變語言的話,調用 renpy.change_language() 函數。

非常規多語言支持 link

Note

創建非常規多語言支持前,最好獲取原遊戲創作者的許可。

在沒有遊戲創作者原生支持的情況下,Ren’Py也有一點支持可以創建多語言支持。Ren’Py能根據遊戲內所有字串自動生成一個字串多語言支持的文件。因為多語言字串可以用在未轉換過的對話,這個小技巧可以讓遊戲直接支持多語言。

想要創建一個字串翻譯文件,需要執行以下步驟:

  • 設置環境變數RENPY_LANGUAGE為你想要添加的目標語言。

  • 設置環境變數RENPY_UPDATE_STRINGS為一個非空值。

  • 執行遊戲直到看見目標文本內容。

這些操作會更新 game/tl/language/strings.rpy 文件,其中包含所有多語言字串的一個模板。

如果某個遊戲內部不支持更改語言,可以在 config.language 中使用一個 init python 語句塊(block),強行切換到目標語言。

define config.language = None link

若不是None,會在遊戲啟動時切換為該語言,覆蓋用戶之前更改過的設置。

除了使用字串的多語言支持解決對話的問題,上面描述的非常規多語言支持技巧也可以應用在圖片和樣式上。