翻訳 link

Ren'Py には、ビジュアルノベルを翻訳するための包括的なフレームワークがあります。これによって主に4種類のものを翻訳できます:

台詞

スクリプトのメインの台詞は、分割、連結、省略、行の並べ替えを伴う翻訳ができます。

メニューとインターフェイスの文字列

すべてのインターフェイスのテキストが翻訳できます。

画像とファイル

ある言語が選択されたときに、通常とは異なる画像やその他のファイルを含めることができます。

スタイル

言語に合わせてスタイルをカスタマイズできるため、ある言語が選択された時にゲームで使用されるフォントを自動的に切り替えることができます。

Ren'Py の翻訳サポートは現在、正式に認可されている翻訳、つまりゲームの制作者が翻訳者に向けてリリースしている場合や、制作者自身が翻訳用の雛形を作成している場合に焦点を当てています。正式な認可を得ていない場合の翻訳では、これよりも制限があります。

主言語と副言語 link

Ren'Py は、それぞれのゲームが1つの主言語によって書かれていると想定します。このときの言語は None 言語と呼ばれますが、その言語が実際に何であっても構いません。(例えば、ゲームが英語で書かれている場合は、英語が None 言語となります。)

None 言語が選択されたときは、Ren'Py のほとんどの翻訳機能が無効化されます。

副言語は、Python の識別子としても振る舞える名前によって関連付けられます。(英字またはアンダースコアで始まり、英数字とアンダースコアが続きます。)

翻訳ファイルの生成 link

プロジェクトのスクリプトが利用できる場合、Ren'Py ランチャーでプロジェクトを開き「Generate Translations」を選ぶことで翻訳ファイルを生成できます。ランチャーは生成する言語の名前の入力を求めた後、翻訳ファイルの作成または更新を行います。

翻訳ファイルはゲームディレクトリーの中の「tl」サブディレクトリーの下に設置されます。例えばチュートリアルプロジェクトの piglatin の翻訳を作成した場合、翻訳ファイルは tutorial/game/tl/piglatin の下に設置されます。

ゲームのスクリプトファイル1つに対して翻訳ファイルが1つ作成されます。共通のコードで見つかった文字列の翻訳を含めるために、common.rpy ファイルも作成されます。

台詞の翻訳 link

Ren'Py ビジュアルノベルエンジンの開発者としては、ほとんどの翻訳が台詞と対応することを期待しています。Ren'Py には柔軟なフレームワークがあり、台詞の分割、結合、並べ替え、完全な省略を行えます。

翻訳ユニット link

翻訳の基本ユニットには、空のブロックから複数の翻訳可能なステートメントまであり、必要に応じて単一の 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!"

これは複数の翻訳ユニットに分割されます。それぞれのユニットには割り当てられた識別子があり、識別子はユニットに先行するラベルと、ユニット内のコードから生成されます。(複数のユニットに同一の翻訳番号が割り当てられた場合は、それらを区別するために2つ目以降のユニットに番号が振られます。)

上記の例において、生成される1つ目のユニットには start_636ae3f5 という識別子が割り当てられ、次のステートメントを含んでいます:

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

2つ目のユニットには start_bd1ad9e1m という識別子が与えられ、次を含みます:

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

3つ目のユニットには 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 ""

生成されたコードを編集することで翻訳できます。翻訳が完了すると次のようになります

# 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!"

メインスクリプトの中にブロックが見つかると、Ren'Py はそのブロックに対応する translate ステートメントが存在するかどうかを確認します。存在する場合は翻訳前のブロックの代わりに 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!"
    e $ latin_points = to_roman_numerals(points)
    e "Ouyay oredscay [latin_points] ointspay!"

ヒント link

ラベルの中の複数の場所で同じ台詞が繰り返される場合は、翻訳された台詞の変更には特に注意して下さい。いくつかの例では、次のように翻訳用の識別子をステートメントを使って直接割り当てる必要があるでしょう:

translate None mylable_03ac197e_1:
    "..."

ラベルの追加によっても翻訳の過程で混乱が発生します。これを防ぐには、ラベルに hide 節を与えて翻訳コードから無視されるようにします。:

label ignored_by_translation hide:
    "..."

翻訳ブロックが Python のコードを含む場合、コードはブロックの外側に影響を及ぼすべきではありません。何故ならば、言語を変更するときに翻訳ブロックは再度開始されますが、これによって副作用が何度も発生してしまうからです。

画像とファイルの翻訳 link

ゲームを翻訳するとき、ファイルを翻訳版に置き換える必要があるかもしれません。例えば画像にテキストが含まれている場合、意味が分かるようにテキスト部分が別の言語で書かれた画像に置き換えるでしょう。

このような場合に Ren'Py は画像を翻訳ディレクトリーの中から探します。例えば「piglatin」言語において「library.png」を読み込むとき、Ren'Py は「game/tl/piglatin/library.png」を「game/library.png」よりも優先して使います。

スタイルの翻訳 link

ゲームの翻訳時に、スタイルの変更 (特にフォント関係のスタイル) が必要になるでしょう。Ren'Py ではこれに対し translate style ブロックと translate python ブロックで対応しています。これらのブロックには、言語関係の変数やスタイルを変更するためのコードを含めることができます。例えば

translate piglatin style default:
    font "stonecutter.ttf"

または等価なもので:

translate piglatin python:
    style.default.font = "stonecutter.ttf"

言語が利用可能になった時 (ゲームの開始時、もしくは言語が変更された後)、Ren'Py は init フェーズの後でスタイルをこの内容にリセットします。

スタイルの翻訳はどのような .rpy ファイルにも追加できます。

既定の言語 link

既定の言語は以下の方法によって選択します:

  • RENPY_LANGUAGE 環境変数が設定されていれば、その言語が使用されます。

  • config.language が設定されていれば、その言語が使用されます。

  • 過去にゲームで言語を選択したことがあれば、その言語が使用されます。

  • ゲームが最初に開始された時は、 config.default_language が使用されます。 ( このデフォルト値は None 言語です。 )

  • これら以外の場合は、None 言語が使用されます。

翻訳に関連したアクション、関数、変数 link

言語を切り替える主な方法は、Language アクションを使うことです。

Language(language) link

ゲームの言語を language に変更します。

language

翻訳先の言語の文字列、または None のときはゲームスクリプトの既定の言語を使います。

Language アクションを使うと、以下のようなコードを使って設定画面に言語設定を追加できます

frame:
    style_prefix "pref"
    has vbox

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

翻訳関連の関数は2つあります:

renpy.change_language(language) link

現在の言語を language に変更します。この値は文字列、または既定の言語の場合は None にできます。

renpy.known_languages() link

既知の言語のセットを返します。これには既定の言語 None は含まれません。

さらに、文字列の翻訳に関連した 3 つの関数があります:

_(s) link

(単一のアンダースコア) s を変更せずに返します。Ren'Py はこの関数で囲まれた文字列をスキャンし、翻訳可能な文字列のリストにそれを追加します。文字列は表示されるまで翻訳されません。

__(s) link

(2重アンダースコア) s を現在の言語に直ちに翻訳して返します。この関数で囲まれた文字列は、翻訳可能な文字列のリストに追加されます。翻訳後の文字列が表示される時に、文字列翻訳にマッチすると文字列が2重に翻訳されてしまうことに注意してください。

_p(s) link

Reformats a string and flags it as translatable. The string will be translated when displayed by the text displayable. This is intended to define multi-line for use in strings, of the form:

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

    This line will be separate.
    """)

The reformatting is done by breaking the text up into lines, removing whitespace from the start and end of each line. Blank lines are removed at the end. When there is a blank line, a blank line is inserted to separate paragraphs. The {p} tag breaks a line, but doesn't add a blank one.

This can be used in a string translation, using the construct:

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.
    """)

言語関連の変数は2つあります。1つは config.language で、これはゲームの既定の言語を変更するために使用されます。

_preferences.language link

現在の言語の名前、または既定の言語が使われている場合は None。これは読み込み専用の変数として扱わなければなりません。言語を変更するには renpy.change_language() を使用して下さい。

正式な認可を受けていない場合の翻訳 link

注釈

正式に認可されていない翻訳を作成する前に、ゲーム制作者の許諾を得ることが最善です。

Ren'Py には、ゲーム制作者からの十分な支援が無い場合の翻訳の作成に、少しだけ対応しています。これは、ゲームのすべての文字列から自動的に文字列翻訳ファイルを作成する機能です。未翻訳の台詞に対して文字列翻訳を行うことで、この方法によるゲームの翻訳が可能となります。

文字列翻訳ファイルを作成は、以下の手順で行います:

  • RENPY_LANGUAGE 環境変数を翻訳先にしたい言語に設定します。

  • RENPY_UPDATE_STRINGS 環境変数を空でない値に設定します。

  • すべてのテキストが表示されるまでゲームを動かします。

これにより "game/tl/language/strings.rpy" ファイルが更新され、すべてのテキストが含まれた翻訳の雛形となります。

ゲームに言語切り替え機能が含まれていない場合は、init python ブロックで config.language に翻訳先の言語を設定するのが適切でしょう。

台詞の文字列翻訳を使った場合、認可を受けていない翻訳者は画像やスタイルの翻訳に対して上記で説明した方法を使うことができません。