RPGツクールMV/MZのゲームを多言語対応する — テキストの在り処と進め方
ツクールで作ったゲームを、英語をはじめとする別の言語でも出したい。まず良い知らせとして、MVとMZはプロジェクトのデータをそのままJSONで保存しています。書いたテキストは、開けないバイナリの中ではなく、スクリプトで処理できる読めるファイルの中にあります。悪い知らせは、ツクールがテキストを一か所にまとめることを一度も求めてこなかったことです。結果としてテキストは十数個のファイル、数種類の入れ物、そして一見テキストに見えない場所に散らばっています。
この「散らばり」こそが本当の難所です。翻訳そのものは見通しの立つ作業で、ツクールのプロジェクトが崩れるのは、すべての文字列を見つけ、翻訳者が作業できる形で取り出し、プロジェクトを壊さずに戻す部分です。自分が思っている行数より実際の行数のほうが多いのも、たいていこれが理由です。
この記事では、テキストの在り処を地図にし、繰り返し実行しても安全な往復のやり方を示し、最も壊れやすいもの — 制御文字、メッセージウィンドウ、フォント — を扱います。特定のプラグインを名指しで勧めることは意図的にしていません。その領域は変わっていくもので、選ぶべき方法はチェックリストによる評価だからです(記事の後半に置いています)。
テキストが実際にある場所
プロジェクトの data フォルダを開くと、データベースがそのままJSONで並んでいます。ファイルごとに1種類のレコードが入っており、プレイヤーに見えるテキストは、数値やフラグと混ざった状態で保存されています。下の一覧が作業対象の棚卸しです。ここに載っていないものは、公開日に原語のまま残る文字列だと思ってください。
- データベースの各レコード — アイテム・スキル・ステート・アクター・職業・敵キャラの名前、説明、メッセージ
- System.json — ゲームタイトル、通貨単位、そしてUIの用語(コマンド名、能力値の表記、定型のシステムメッセージ)
- マップファイル — そのマップ上のすべてのイベント。会話も選択肢も、イベントのコマンドリストの中に入っている
- CommonEvents.json と Troops.json — コモンイベントとバトルイベントのテキスト。普段あまり見返さないぶん忘れやすい
- js/plugins.js — プラグインのパラメータ。プラグイン管理画面で入力した、プレイヤーに見える文言を含む
- img/ — タイトル、ロゴ、看板、文字を描き込んだピクチャ。ツールから見ればこれはテキストではない
data/ Actors.json Classes.json Skills.json Items.json Weapons.json Armors.json Enemies.json States.json System.json CommonEvents.json Troops.json Map001.json Map002.json ...
イベントのテキストはコマンドの並び — 往復はそこを通り抜ける
マップファイルの中では、イベントページがコマンドの並びを持っています。各コマンドは数値のコードとパラメータの配列を持ちます。メッセージは一つのまとまったテキストではなく、開始のコマンドに続いて表示行ごとに一つずつコマンドが並ぶ構造で、選択肢はさらに別のコマンドが自前の配列を持ちます。抽出スクリプトが歩き回るのは、この構造です。
コマンドコードを記事の一覧から信じ込むより、実測してください。イベントに特徴的なテスト用の一行を入れて保存し、マップファイルをその文字列で検索します。その行が入っていたコマンドが、あなたが対象にすべきコマンドです。この方法なら、いま使っているバージョンでの理解も同時に確認できます。選択肢と文章のスクロール表示についても、格納のされ方が違うので同じように確かめてください。
半日を失いがちな注意点を一つ。エディタはプロジェクトをメモリ上に持っていて、保存時にデータファイルを書き出します。プロジェクトをエディタで開いたままJSONを手やスクリプトで編集すると、次の保存が確認なしにあなたの変更を上書きします。取り込み処理を走らせる前にエディタを閉じ、プロジェクトはバージョン管理に入れて、スクリプトが何を変えたのか差分で見えるようにしておいてください。
書き出しのほうでやりがちなのは、一度書き出して、翻訳して、全部貼り戻すやり方です。これはちょうど一回だけうまくいきます。ゲームはこの先も変わるので、本当に必要なのは繰り返し実行できる書き出しと取り込みです。データファイルを歩いて、翻訳対象の文字列を安定した識別子つきの表に書き出すスクリプトと、翻訳済みの表を読んで戻すスクリプトの組です。
設計する価値があるのは識別子です。原文そのものをキーにしてはいけません。原文の誤字を直した日に、それに紐づいた訳文がすべて迷子になります。キーは場所から組み立ててください。どのファイルの、どのレコードまたはイベントの、どの項目の、何行目か。この形なら文言が変わってもキーは生き残り、再書き出ししたときの差分が「まったく別のファイル」ではなく「新規と変更の数行」として見えるようになります。
key,ja,en system.terms.command.attack,攻撃,Attack item.0007.name,ポーション,Potion item.0007.desc,HPを 500 回復する。,Restores 500 HP. map001.ev003.p1.text.01,\N[1]は 宝箱を 開けた!,\N[1] opens the chest! common.0012.choice.02,やめておく,Not right now
制御文字はテキストではない
ツクールのメッセージには、表示時にエンジンが解釈する制御文字が含まれます。それを知らない翻訳者は、親切心からそれを訳したり、消したり、間隔を整えたりします。結果は、画面に円記号がそのまま出るか、そのシーンが再生されるまで誰も気づかない不具合になります。
とくに注意が要るのは、名前や数値を差し込む制御文字です。これらは文の中に空いた穴であり、穴の周りに何を組み立てられるかは言語によって違います。日本語は差し込まれた名前のあとに助詞を付けられるので、穴がどこにあっても自然に読めます。英語は文法が許す位置に名前が来る必要があり、しかも後続を単数にすべきか複数にすべきかを知っている必要があります。ある言語で穴の周りを流れるように書かれた行は、別の言語では文を書き直さない限り成立しないことがよくあります。
ですから翻訳者には、行の中で制御文字を動かしてよいと明示的に許可を出し、それぞれに実際何が入るのかを伝えてください。パーティメンバーの名前なのか、アイテム名なのか、1にも複数にもなりうる数値なのか。書き出しの表に「変数12はプレイヤーが持っている鍵の数」と書かれた文脈列が一つあるだけで、推測が翻訳に変わります。
同じくらいはっきり、制御文字そのものは変えずに残す必要があることも伝えてください。同じつづり、同じ番号、同じ個数です。位置を動かすのは問題ありません。名前を変える・消す・複製するのは不可です。エンジンは完全一致で照合しているからです。これは翻訳されたツクール作品で最も多い不具合の型であり、完全に機械的な性質を持っています。つまり、目視ではなく機械的に検査できます。
表記についてもう一点。JSONファイルの中ではこれらはバックスラッシュがエスケープされた形で入っているため、データファイル上の見え方とエンジンが解釈する表記は一致しません。翻訳者に渡す表には、翻訳者が打ち戻す形で載せ、変換はスクリプト側の責任にしてください。全体の一覧はエンジンのヘルプにあります。以下は、必ず出会うものです。
\V[n] ゲーム内変数の値を差し込む \N[n] アクターの名前を差し込む \C[n] 以降の文字色を変える \I[n] アイコンを描画する \. \| \! ウェイト(短い/長い)と入力待ち
画面で壊れるもの — ウィンドウの大きさとフォント
既定のメッセージウィンドウは決まった行数(プロジェクト側で変えていなければ4行)と決まった幅で表示されます。これは一つのメッセージコマンドで表示できる量の上限であり、日本語で書かれたゲームの翻訳が最初に詰まる場所でもあります。同じ意味を表すのに、ヨーロッパ系の言語では日本語より文字数が必要になることが多く、ウィンドウにぴったり収まっていたメッセージがあふれます。
解決は多くの場合「一つのメッセージを二つに分ける」ことですが、これは計画上の重要な違いを含みます。メッセージの分割は文字列の編集ではなく、イベントのコマンドリストの編集だからです。表計算ソフト上で作業している翻訳者にはできません。誰かがプロジェクトを開くか、取り込みスクリプトが分割に対応しているか、あるいは手作業のイベント編集が工程に含まれることを受け入れるか。翻訳が始まる前に、どれなのかを決めてください。選択肢、名前欄、独自のウィンドウにもそれぞれ幅の制限があり、こちらは会話文より静かにあふれます。切り詰められた選択肢も、選択肢には見えてしまうからです。
文字を小さくする、自動で折り返す、ウィンドウを広げる、といった定番の緩和策があり、それぞれにプラグインも存在します。何を使うにせよ、設定したパラメータを読んで確認するのではなく、実際にそのシーンを再生して確認してください。これらの設定同士、そして文字を描画する他のプラグインと干渉します。
画面で壊れるもののもう半分がフォントです。MVとMZは、プロジェクトの fonts フォルダに置いたフォントで文字を描画し、フォントは自分が収録している文字しか描けません。これは両方向に効きます。ラテン文字しか収録していないフォントのプロジェクトに日本語・韓国語・中国語を足せば、豆腐(空の四角)が出ます。見落としやすいのは逆方向で、日本語用に選んだフォントがフランス語・スペイン語・ドイツ語・ポーランド語などに必要なアクセント付きラテン文字を持っていないことがあり、英語だけで確認していると気づけません。
対象言語ごとに、実際のフォントで、動いているゲームの、文字が出る画面で確認してください。フォント単体のプレビューでは分かりません。商用作品に同梱する前にライセンスの確認も必要です。埋め込みは個別の許諾事項であり、すべてのフォントが認めているわけではありません。
データファイル自体は UTF-8 のJSONです。これは、工程のどこかのツールが別の文字コードで書き戻したり、BOMを付けたりするまでは問題になりません。表計算ソフトに書き出して保存し直すのが、その典型的な発生場所です。往復は自分で管理できるスクリプトの中に置き、すべてをバージョン管理下に置いてください。文字が化けたときに見るべきは、翻訳ではなく、そのファイルを最後に書いたツールです。
実行時の言語切り替えか、言語ごとのビルドか
ツクール作品を多言語で出すとき、現実的な形は二つあります。一つは、翻訳を外部ファイルに持ち、表示のタイミングでテキストを差し替えるプラグインを使う方法で、一本のビルドに言語設定が付きます。もう一つは言語ごとに別のビルドを作る方法で、プロジェクトを複製し、テキストを入れ替え、それぞれを配布します。
最初のリリースなら、言語ごとのビルドにも実際の利点があります。信頼すべきプラグインがなく、切り分けるべき不具合もありません。ただしその費用は最初のコンテンツ更新で顔を出します。あらゆる変更をすべての複製に対して行う必要があり、複製同士は必ずずれていきます。更新を続ける予定があるか、三言語以上を出すなら、この費用は急速に積み上がります。なお、配布されたゲームの data フォルダは誰でも読めます。ツクール作品の有志翻訳が成立しているのはそのためで、別ビルドにしたところで、一本のビルドで見えるもの以上に隠せるわけではありません。
プラグインを使う道を選ぶなら、説明文ではなくチェックリストで選び、翻訳が存在する前に自分のプロジェクトで試してください。下の質問が、そのプラグインが自分のゲームに合うかどうかを決めます。
- データベースのレコードと System の用語まで対象か、それともメッセージ本文だけか
- 選択肢、文章のスクロール表示、戦闘中のメッセージに対応しているか
- 制御文字はどう扱われるか。完全に保持されるか、そしてそれが明記されているか
- すでに使っている他のプラグイン、特に文字を描画するものと共存できるか
- 翻訳データはバージョン管理で差分が読めるプレーンテキスト形式で保存されるか
- 行が欠けているときの挙動はどうなるか。原文にフォールバックするか、空白になるか
- 現在も更新されているか。対応するエンジンのバージョンが明示されているか
公開前の確認
翻訳されたツクール作品で起きる問題の多くは機械的なもので、つまり、読めない言語でゲームを最後まで遊ばなくても見つけられます。まずファイルに対して機械的な検査を通し、人にしか判断できないことにプレイ時間を使ってください。
- 原文の表にあるキーが全言語で値を持っており、うっかり原文のままになっている値がない
- 制御文字が原文と訳文で、つづり・番号・個数まで一致している(全行)
- 表計算ソフト由来の全角スペース、閉じ忘れた括弧、余計な改行が混入していない
- 各言語で使われるすべての文字が、動いているゲーム上でフォントによって描画されている
- メッセージ・選択肢・名前欄を、最も長くなる言語で画面上で読む(表の上でだけ見ない)
- 文字を描き込んだ画像に言語ごとの版があるか、不要だという判断が記録されている
- プラグインのパラメータと System.json のゲームタイトルが書き出しに含まれており、原文のまま残っていない