1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Rust製の自作ゲームエンジンを日中韓対応した話:3万9千行を書き換えずに翻訳する

1
Posted at

自作ゲーム「O'BLOCK」(スニーカー転売で10億ドルを目指すローグライト)を日本語・中国語・韓国語に対応させました。問題は、ゲームが自作の Rust エンジン(Proof Engine)で動いていて、フォントアトラスに ASCII と記号しか入っていなかったこと。そしてゲーム本体には英語の文字列が約3万9千行のあちこちに散らばっていました。

やったことを短くまとめます。

日本語化した交渉画面

1. 全角文字を2マス扱いにする

等幅グリッドでは CJK の文字は半角2つ分の幅です。エンジンに is_wide(char) と text_cols(&str)(全角を2列として数える)を足して、文字送り・幅計測・右寄せ・折り返しをすべて「文字数」ではなく「列数」で計算するようにしました。英語の描画位置が1ピクセルも変わらないことはテストで確認しています。

折り返しも変えています。日本語と中国語はどの文字の間でも改行できますが、「。」「」」の前では改行しない(禁則処理)。韓国語は分かち書きがあるので英語と同じくスペースで折り返します。

2. 実行中に作り直せるフォントアトラス

アトラスは起動時に TTF から作る SDF(符号付き距離場)です。CJK は Windows に最初から入っているフォント(中国語: Microsoft YaHei、日本語: 游ゴシック、韓国語: Malgun Gothic)から、その言語の翻訳ファイルで実際に使う文字だけを2マス幅のセルに焼きます。日本語は約1,150文字で、生成は約150ms。設定画面で言語を切り替えると、再起動なしで次のフレームまでにアトラスを作り直します。

3. 3万9千行を書き換えずに翻訳する

すべての文字列を tr!() で包むと数千か所の修正になります。でもこのゲームは、画面上の文字のほとんどを render.rs の数個のヘルパー関数経由で描いていました(箱に収めるための関数)。なのでそこで翻訳します。

  1. スクリプトでソースを走査し、format!("SOLD {} PAIRS FOR {}", n, cash) を SOLD {0} PAIRS FOR {1} というテンプレートに変換(合計3,323個)
  2. 描画時に tr() がテンプレートと照合して値を取り出し、翻訳側のテンプレートに好きな順番で戻す
  3. 結果はキャッシュするので、1フレームあたりのコストはハッシュ1回
  4. 合わなかったものは英語のまま。表示が壊れることはありません

人名(パロディのラッパーたち)、スニーカーのモデル名、カラーウェイ、ゲーム内のメカニクス名はあえて英語のままです。

4. ハマったところ

英語の複数形の "s" をプレースホルダーで渡しているテンプレートが十数個あって、「3日s」と表示されました。英語以外では複数形の部分だけを捨てるようにして解決。

おわりに

O'BLOCK は Steam で無料、10月20日リリースです。相手の「言い値」を読む交渉ゲームが好きな人は、ウィッシュリストに入れてもらえるとすごく助かります。

エンジンは MIT ライセンスで公開しています: https://github.com/Mattbusel/proof-engine

1
0
5

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?