多語言支持 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
目錄的文件,所以這些文件不應包含在初始化階段必須執行的內容。
比如 init
或 python
開頭的語句塊,screen
、image
、transform
等語句。
翻譯文件應該只有以 translate
、translate python
和 translate style
開頭的語句塊。
預設語言 link
使用以下方法可以選擇預設語言:
根據設置的RENPY_LANGUAGE環境變數。
根據設置的
config.language
。使用之前遊戲中選擇的語言選項。
遊戲第一次執行,並且
config.enable_language_autodetect
的值是True時,Ren’Py會嘗試使用config.locale_to_language_function
自動檢測語言。遊戲第一次執行時,使用
config.default_language
。以上情況都未配置,使用None語言。
多語言支持的行為、函數和變數 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,會在遊戲啟動時切換為該語言,覆蓋用戶之前更改過的設置。
除了使用字串的多語言支持解決對話的問題,上面描述的非常規多語言支持技巧也可以應用在圖片和樣式上。