翻訳したらゲームが起動しない?原因の行を探す
翻訳したゲームがウィンドウを開いてすぐ閉じる、あるいはロード画面で永遠に止まる。翻訳した行のどれかが、もともとテキストではなかったのです。ID、パス、ゲームが比較するフラグ。まず原因が翻訳かどうかを確かめ、そのうえで半分に割りながら行を突き止めます。書き出し十三回ほどで、五千行が一行まで絞れます。
ウィンドウが開く。ウィンドウが閉じる。昨日まで動いていたゲームを一晩かけて翻訳したら、いまはもう死んでいる。
その行のどこかに、もともとテキストではなかったものが一行あります。シーン名、ファイルパス、ゲームが比較しているフラグ。エンジンはそれに突き当たり、何も描画しないまま諦めたのです。
それを見つけるために五千行を読む必要はありません。「はい/いいえ」の質問を、十三回ほど繰り返すだけです。
短い答え。 まず原因が本当に翻訳かどうかを確かめ、それから半分に割る。容疑のある行の半分を翻訳し、書き出し、起動する。失敗したほうの半分に目的の行があります。その半分に対して、一行になるまで繰り返します。
探す前に:そもそも原因は翻訳か
- オリジナルのゲームを起動する。 書き出したものではなく、手を付けていないコピーを。それも失敗するなら、原因はPCかフォルダーかゲーム自体です。
- 短くて無害な一行だけを翻訳し、書き出して起動する。 画面で見えるメニューの単語で十分です。
- そのあとで初めて、行を探し始めます。
手順2があえて「一行も翻訳しない」ではなく一行と言っているのには理由があります。書くものが何もないと途中で打ち切るアダプターがいくつかあり、空の書き出しは配置処理ではなくファイルコピーを試すだけになるため、本番が壊れていても通ってしまうことがあるのです。
一行だけのビルドも失敗するなら、特定の行が悪いのではなく、半分に割っても何も見つかりません。まっさらな空フォルダーへ書き出し直し、起動しているのがオリジナルではなく書き出したコピーであることを確認し、書き出しの警告を読んでください。それでも失敗するなら、配置の問題として報告してください。
この切り分けにかかるのは起動二回と書き出し一回。小さなRPGツクールのプロジェクトなら数分、大きなUnityのゲームならもう少し。存在しない行を探して一晩を溶かさずに済みます。
似ているけれど別物が二つ。ゲームは動いていて、文字が□や疑問符、崩れたラテン文字になるのはフォントかエンコードの問題です。プラグインやオーバーレイを入れた直後に落ちるのは道具側の問題で、あなたの行ではありません。
半分に割って行を見つける
たいていのプロジェクトはファイルが多く、二つに割るのがいちばん簡単なのはファイル一覧です。
- ツールバーのすべての翻訳をリセット。
- 翻訳するファイルを選択を開きます。説明はそのまま書いてあります。「翻訳するファイルを選んでください。チェックを外したファイルはそのまま残ります。」ファイルの半分のチェックを外し、残りを翻訳します。
- 空のまっさらなフォルダーへ書き出し、ゲームを起動します。
- 起動したなら、目的の行は手を付けなかった側の半分にあります。起動しないなら、いま翻訳した側です。どちらにしてもリストは半分になり、もう片方は忘れて構いません。
- もう一度すべての翻訳をリセットし、残ったリストを半分に割り、書き出して起動します。
- ファイルが一つになるまで繰り返し、そのファイルの中で一行になるまでさらに割ります。
ファイル単位で割るのは行単位より粗いので、回数はファイル数に従います。四十ファイルならファイルにたどり着くまで約六回、そこから中でやり直しです。
ファイルが一つしかないプロジェクト——NScripterのスクリプト、シナリオが一本だけのKirikiriやWolfのゲーム——には割るためのファイル一覧がありません。その場合は行の上をドラッグして枠で囲みます。チェックボックスと一括操作バーが自動的に現れ、あとは選択行を再翻訳が引き受けます。もっと広く一気にやるなら、まずフィルターと検索で行を絞ってから表示中をすべて選択を使います。これには注意が必要で、フィルターが表示しているものだけをそのまま取るため、消し忘れたフィルターは以降のすべての回を静かに汚します。使ったフィルターは書き留めておいてください。
百行の壊れた一束を、最後まで進めた例:
- 1回目 — 容疑100行、最初の50行を翻訳:起動する。つまり残り50行の側。
- 2回目 — 容疑50行、最初の25行を翻訳:壊れる。つまりこの25行の中。
- 3回目 — 容疑25行、最初の13行を翻訳:起動する。つまり残り12行の側。
- 4回目 — 容疑12行、最初の6行を翻訳:壊れる。つまりこの6行の中。
- 5回目 — 容疑6行、最初の3行を翻訳:壊れる。つまりこの3行の中。
- 6回目 — 容疑3行、最初の2行を翻訳:起動する。残り一行。
百行からなら最悪でも書き出し七回、五千行からなら最悪で十三回ほどです。
一回にかかる時間
書き出し一回、起動一回、そしてゲームが最初の台詞にたどり着くまでの時間。小さなRPGツクールのプロジェクトなら二、三分。書き出しがゲーム丸ごとをコピーし、タイトル画面ものんびりしている大きなUnityのゲームなら十分近く。
つまり十三回はほぼ一晩です。それでも安いほうの選択肢です。もう一方の道は、五千行を自分で読んで当てることなのですから。
手作業で失敗しやすいのは二つ。毎回まっさらな空フォルダーへ書き出すこと。 パッチを積み重ねて読み込むエンジンがあり、3回目が1回目と2回目の上に乗ると三つまとめて試すことになります。リセットは本当のリセットで。 手で書き戻すのではなくすべての翻訳をリセットを使ってください。こちらはプロジェクト作成時に取り込んだテキストを復元するので、あとで元フォルダーを上書きしていても正しく戻ります。
その行を戻してもまだ起動しないとき
壊れた行が複数あったということです。解析に敏感なエンジンで最初に「全部翻訳」をやったときの、ごく普通の結果です。見つけた行は元の言語のままにして、まだ翻訳されている範囲に対してもう一度同じ手順を回します。二つ目の犯人は、たいてい一つ目と同じ種類の文字列で、同じファイルの中にいます。
次からは小分けにして翻訳する
小分けにしても書き出し回数は減りません。どのみち行う書き出しであり、失敗が最初から狭い範囲で届くという点が違うのです。壊れたのは最後の一束なので、絞り込みは五千行ではなく百行から始まります。まずは100行、いくつかの束が問題なく通ったら500行や一ファイル丸ごとへ広げてください。
間違った行を翻訳すると壊れるエンジンは?
エンジンが厳しいとか寛容だとか言われますが、実際に決めているのは、翻訳がどこへ落ちるかです。
データとして読むエンジンがあります。Ren'Pyは別ファイルと実行時フック、RPGツクールはエスケープ済みJSON、Unrealはキーのハッシュをそのまま保った.locresの値。ゲームの構造があなたのテキストを見ることはないので、間違った行の代償は間違った行だけです。もう一方は、ゲームが解析するファイルの中へ差し込みます。スクリプト、マークアップ、バイト列として読まれるファイルであり、あなたの文がそのファイルの構造の一部になります。そうなるとコロン一つ、括弧一つ、余分な1バイト、あるいは検索キーも兼ねていた文字列だけで、ゲームは止まります。
ルールはそれだけです。自分のエンジンを探し、その行を読んで、先へ進んでください。
- RPGツクールMV/MZ — 構造的な危険はありません。JSONもCSVもエスケープされ、提示されるのは決まった種類のイベントコマンドだけです。唯一の実際的な危険は話者名を完全一致で照合するプラグインですが、書き出しはそのプラグイン側のキーも書き換えます。
- Ren'Py — ほとんどありません。ソースを書き換えないので、論理キーを兼ねた文字列も安全です。
- Unreal Engine — 行単位の失敗例は確認していません。
.locresの文字列は仕組みからして表示テキストです。ここでの危険は起動しないことではなく、テキストが出ないことです。 - Unity — 重く、しかも静かです。シーン名も変数キーもコールバックも、台詞とまったく同じ形で保存されています。無限ロード、反応しないボタン、真っ暗な画面を覚悟してください。
- Godot — 重い。ノードパス、StringName、
res://参照はエンジンが引く住所そのもので、書き戻しはこれらを拒否します。 - Wolf RPG — ここで最も壊れやすい形式です。1バイトのずれが列全体を崩し、ウィンドウが出る前にプロセスが落ちます。
- Kirikiri / KAG — 重い。角括弧は構文であり、ストレージ名はファイル名です。タグ名の翻訳、括弧の変換、画像ファイル名の翻訳は、それぞれ単体でゲームを止めます。
- Electron VN — 重い。
app.asarの中の生きたJavaScriptにテンプレートの差し込み記号が書き込まれれば、それは訳の善し悪しではなく構文エラーです。 - TyranoBuilder / TyranoScript — Kirikiriと同じ系統です。KAGタグはマークアップなので、タグを翻訳することは構文をいじることです。行中のキャラクター参照は書き換えません。
- NScripter — 重く、しかも独特です。
?、%、$は変数の記号なので、迷い込んだ一文字が構文エラーになります。 - YU-RIS — 重い。この形式が文字列と呼ぶもののかなりの部分が、実際にはオペランドだからです。両者を分けたことで、あるゲームは有効行40,678から8,914になり、台詞は一つも失われませんでした。
ほかのエンジンにもそれぞれのページとガイドがエンジンにあります。
ゲームを殺した三行
RuneTranslateの除外ルールは、どれも起動しなくなったゲームと引き換えに手に入れたものです。この三つはすでに修正済みです。いずれも、壊れた行は見た目にはまったく妥当で、書き出しは緑で終わっていました。
Godot:ゲームが登場人物をでっち上げる。 ある行にはこう書かれていました。Warning: the door is locked。完璧な英語です。Dialogicは保存テキスト中のコロンをすべてエスケープします。エスケープされていないコロンこそが話者名を切り出す目印だからです。そのまま書き戻された結果、この文はWarningという人物がthe door is lockedと話しているものとして読み直され、アドオンはその人物をきちんと作成しました。
Kirikiri:ゲームが`End`という名前のファイルを探す。 あるボタンのタグは画像ファイル名とジャンプ先ラベルを持っていましたが、マスク処理が自前の括弧を含むタグをまたげず、両方が露出して翻訳されてしまいました。いまのスキャナーは括弧を理解し、対応する括弧で閉じます。入れ子の式はタグの内側に留まり、普通のタグは最初の]で終わります。
RPGツクール:立ち絵が黙って消える。 立ち絵プラグインは、話者名を自前の設定にある表と一文字ずつ突き合わせてキャラクターの画像を選びます。名前を翻訳するのは正しい。その設定に手を付けないのも、素材キーだらけなのだから正しい。二つが重なった結果、一致が崩れ、そのキャラクターの立ち絵はログに何も残さず消えました。
三つとも書き出しは成功と報告しています。きれいな書き出しは、どのエンジンでも、ゲームが動く証拠にはなりません。 証拠は起動することだけです。
そもそもあなたの行のせいではないとき
半分に割ってもこれは見つかりません。どちらの半分も起動しないからです。問題は書き出しがどこへ着地したかにあります。Wolf RPGのゲームは隣に置かれたファイルより先に.wolfアーカイブを読むため、翻訳データがディスク上で読まれないまま、あるゲームはタイトル画面を出していました。UnityのAddressablesはバイト列がチェックサムと合わなくなったバンドルを拒否し、どのログにも何も残さず真っ暗な画面を返します。パックされたRPGツクールのゲームは、実行ファイルの隣に置いたデータファイルを無視します。三つとも現在は対処済みで、だからこそ配置の失敗は追いかけるより報告する価値があります。
どの行が台詞かを示す目印はある?
ありません。あると言う人は疑ってください。
あるユーザーから、台詞の文字列をすべて||で囲んでいるGodotのゲームを見つけ、それだけを翻訳したらゲームが動いた、と聞いたことがあります。そのゲームには本当に有効でした。ただしそれは開発者一人の癖であってGodotの決まりではなく、次のゲームは別のことをします。
反例はYU-RISから。あるゲームではバッククォートの系統がインターフェースの文字列表を丸ごと抱えており、692行のうち687行が表示テキストでした——それでもバッククォートにそこでの意味はありません。三種類の引用符はどれも同じものにコンパイルされるので、区切り記号に頼ったルールは本物の文章まで赤くします。値がどこにあったかはすべてを語り、どう囲まれていたかは何も語りませんでした。
頼るべきは位置と形であり、その両方はゲーム自身が教えてくれます。起動して、画面に出た最初の台詞を読み、その同じ行をエディターで探してください。そのファイル、そのグループ、その前後の行が、このゲームにおける台詞の姿です。それ以外の場所にあるものは、台詞でない候補です。
アプリが印を付けられること、付けられないこと
RuneTranslateは、コード・素材パス・IDだと判断した行を除外として印を付けます。隠すのではなく表示したまま、除外を表示の切り替えの奥でオレンジに色づけされるので、何が判断されたかを確認でき、それでも翻訳するでどの行でも押し通せます。独自のパターンを追加することもできます。
除外された行を選んで実行を始めると、こう尋ねて止まります。「選択した340行のうち12行は除外されています——フィルターによって、またはRuneTranslateがコード・素材パス・IDと判断したためです。これらを翻訳するとゲームが壊れることがあります。スキップすれば除外のままです。翻訳すると、以後の実行でも対象に含まれます。」
押し通すこと自体は構いません。ただ、押し通したことは覚えておいてください。書き出しが起動しなくなったとき、最初に見るべき場所だからです。
正直な限界もあります。除外は文字列についての推測なので、あなたのゲームのある一文が、同梱プラグインの中で検索キーも兼ねていることまでは分かりません。元の言語がすでに英語のゲームはさらに保護が薄くなります。最も強いフィルターは、その文字列に元の言語のテキストが含まれているかどうかを尋ねるものだからです。
よくある質問
翻訳したらゲームが起動しなくなったのはなぜ?
ほぼ必ず、翻訳した行のどれかが識別子、パス、シーン名、あるいはゲームが完全一致で比較するフラグだったからです。それを変えると解析か検索が壊れます。
どの翻訳行がゲームを壊したのか、どうやって見つける?
半分に割ります。すべての翻訳をリセットし、半分を翻訳し、空のフォルダーへ書き出して起動する。失敗した半分に目的の行があるので、それをまた半分に割って繰り返します。百行なら六、七回、五千行なら十三回ほどです。
翻訳したゲームがすぐ閉じます。どういう意味?
起動時の致命的なエラーです。Kirikiri、ElectronのビジュアルノベルやNScripterでは、たいてい構文エラー——括弧、引用符、差し込み記号が翻訳されたか失われたか。Wolf RPGやYU-RISでは、列のずれです。
翻訳したゲームが真っ暗な画面で始まるのはなぜ?
多くは、例外を握りつぶすコードの中で読み込みが失敗しています。Unityなら、チェックサムがカタログの記載と合わなくなったバンドルです。無害な一行だけを翻訳したビルドを試してください。それも真っ暗なら、原因はどの行でもなく配置のほうです。
翻訳したゲームがロード画面で止まります。翻訳のせい?
Unityならその可能性が高いです。無限ロードは、シーン名や変数キーを翻訳したときの典型的な症状です。ゲームはもう一致しない名前を待ち続け、エラーは一つも出ません。
絶対に翻訳してはいけないのはどんな行?
ゲームが文字列の完全一致で解決するものすべてです。パス、シーン名やノード名、変数名やイベント名、言語コード、snake_caseやres://の形をしたもの。プレイヤーが画面でそれを読む姿を想像できないなら、そのままにしてください。
ゲームは動くのに文字が□や疑問符です。これも同じ問題?
違います。一様な□はフォントにその文字の字形がないということ、そのままの疑問符はファイルを書いた時点で文字が失われたということです。どちらもフォントかエンコードの問題で、直し方は別です。
次に読むもの
直すのではなく、これから翻訳を始めるところですか?翻訳パッチの作り方が全体の流れを扱っています。
行が見つかったら、その行は元の言語のままにして、周りをすべて翻訳し、空のまっさらなフォルダーへ書き出して起動してください。識別子が一つ訳されていなくても、プレイヤーは何も失いません。
RuneTranslate を試してみませんか?
無料プランですべてのエンジンとすべての翻訳プロバイダーが使えます。Supporter(月額 $3)ならフルスピードで翻訳できます。
Windows 版をダウンロード
