ドット絵ゲームのフォント — 日本語と英語を同じ画面で成立させる
ドット絵のゲームには、高解像度のゲームにはないローカライズ上の問題があります。フォントが普通の意味でのフォントではなく、絵だからです。決まったグリッドの中で決まったサイズに置くために選ばれていて、ゲーム内のあらゆるレイアウトは「そのフォントで何文字入るか」を前提に組まれています。そこに英語やロシア語を足すと、前提のほうが崩れます。
崩れ方も分かりやすい。欧文が和文フォント付属の英数字だと安っぽく見える、専用の欧文フォントを足したらベースラインが揃わず一行の中で文字が跳ねて見える、ドイツ語の単語が枠から出る、そもそも収録されていない文字が豆腐になる。どれも翻訳の側では直せません。
この記事では、ドット絵のゲームが2つ目の文字体系を背負えるかどうかを決めてしまう判断を扱います。漢字が読める下限サイズ、フォントを混ぜるかどうか、ドットを潰さない描画ルール、枠に何文字入るかの計算、そしてこの種のフォント特有の収録文字とライセンスの話です。
漢字には下限サイズがあり、ラテン文字にはない
ピクセルフォントの大文字アルファベットは数本の線でできていて、5×7ピクセルの領域でも問題なく読めます。ゲームの歴史を通じて8ピクセルのセルで英語が成立してきたのはそのためです。漢字は部首の組み合わせで、部首自体が複数の画を持つものもあり、あるグリッドサイズを下回ると画が分離できなくなります。デフォルメされるのではなく、消えます。
この違いは、逆方向のローカライズを考えるときに効いてきます。日本語を前提に12×12や16×16で組んだ画面に英語を入れると、今度は文字が余ります。同じ12ピクセルの高さで、和文は全角12ピクセル幅、欧文は半角6ピクセル幅。同じピクセル数の枠に、欧文は倍の文字数が入り、しかも1単語が長いので折り返し位置は和文よりシビアになります。「和文で組んだ枠なら欧文は余裕」という直感は、単語の長い言語では成立しません。
実務でよく落ち着く段階は3つです。8×8の日本語ピクセルフォントは実在し、技術としては見事ですが、可読性の代償がある様式的な選択です。長い会話文よりは短い文字列向きです。10×10から12×12が、ほとんどの漢字が判別できる一般的な作業範囲。16×16は余裕があり、テキスト量の多い日本語ゲームで広く使われてきたサイズです。
そして、8ビット期の日本のゲームに全文かなの作品が多いのは、8×8のタイルに漢字が入らなかったからです。当時のチームが受け入れた実在の制約で、その結果として当時のプレイヤーには漢字かな交じり文より読みにくいテキストになりました。漢字は、英語におけるスペースの仕事をかなりの部分担っているからです。
フォントを1つにするか、2つにするか
日本語のピクセルフォントは、たいてい半角幅の英数字を自前で持っています。12ピクセルのフォントなら和文は幅12ピクセル、英数字は幅6ピクセル。日本語のテキストは英数字だらけなので — 所持数、レベル、ダメージ値、キー名、訳さない固有名詞 — この付属分の出来はそのまま画面の印象になります。
付属の英数字をそのまま使うと、メトリクスが1系統で済みます。ベースラインも行の高さも文字送りの規則も1つで、行の中のすべてが揃います。代償は、CJKフォントの付属品として設計された欧文が、欧文専用のピクセルフォントほどの個性を持っていることはまれだという点です。ゲームの見た目のアイデンティティをフォントが一部担っているなら、この差は目に見えます。
2つのフォントを使うと、望んだ欧文が手に入り、代わりに継ぎ目を抱えます。同じ公称サイズで描いた2つのピクセルフォントは、ベースラインの位置、大文字の高さ、上下のセンタリングでたいてい食い違います。CJKのグリフは仮想ボディいっぱいに設計され、欧文のグリフはディセンダの余地を残してベースラインに乗るからです。症状は、1行の中で文字種が切り替わるたびに文字が跳ねて見えることです。
2つでいくなら、位置合わせは一度目視で調整するものではなくデータとして持ってください。フォントごとの縦方向オフセットと行の高さをフォントの隣に持たせ、描画コードがそれを適用する。そのうえで最悪ケースでテストします。和文と欧文と数字が1行に同居する箇所 — HUDの表示や、数量付きのアイテム名です。そこが落ち着いて見えれば、残りは大丈夫です。
ドットを潰さないための描画ルール
ピクセルフォントは、1ピクセルでも補間された瞬間にピクセルフォントではなくなります。地味なルールばかりですが、どれも実際に出荷されたゲームで起きている不具合です。
- 拡大は整数倍のみ。1.5倍のピクセルフォントは半分のピクセルに正解が存在せず、描画側が勝手に作り出す
- フォントテクスチャのサンプリングはニアレストネイバー。バイリニアフィルタは使わず、アトラスのミップマップも無効にする
- テキストの描画座標を整数ピクセルに丸める。滑らかに動くカメラや補間で動くパネルに追従するテキストは小数座標に着地し、動くたびにちらつく
- ビットマップのアトラスではなくピクセル風のTTFを使う場合は、設計サイズちょうど、または整数倍で描画し、ヒンティングとアンチエイリアスを切る。この種のフォントは特定のピクセルグリッドに合うよう描かれているため、他のサイズではぼやける
- UIは低い固定解像度で描画し、フレーム全体を整数倍で拡大する。テキスト要素ごとに正しさを担保するのではなく、正しさが既定になる
枠に何文字入るかは計算できる
ここはドット絵のゲームが高解像度のゲームより有利な点です。文字が収まるかどうかは見積もりではなく算数になります。あるピクセルフォントの全角グリフはほぼすべて同じ幅で送られ、同じフォントの半角文字はきっかりその半分です。つまり、翻訳が1文字も存在しない段階で、すべてのテキスト枠の容量を文字数として言い切れます。
テキストの入る枠ごとに一度計算して、書き留めておいてください。横320ピクセルのキャンバスに左右8ピクセルずつの余白を取ったメッセージウィンドウなら、使える幅は304ピクセル。12ピクセルのフォントなら1行あたり全角25文字、半角なら50文字で、英語では8〜9語程度です。3行なら全角75文字、あるいは半角150文字。
この数字は、翻訳者に渡せるものの中で最も役に立ちます。そして誰も開かない仕様書ではなく、翻訳ファイルの中の該当行の隣に置くべきものです。「この枠は1行25文字まで、3行まで」は翻訳者が実際に守れる指示です。「短めでお願いします」は守りようがありません。
計算は両方向でやってください。伸び縮みの向きは一定ではないからです。日本語は同じ内容を英語より少ない文字数で書けることが多い一方、1文字あたりの幅は倍なので、英語向けに余裕を取った枠でもあふれます。逆に、日本語がちょうど収まるように作った枠は、単語が長く半角幅で描かれるドイツ語やロシア語であふれます。3言語以上を出すなら、原語ではなく実際に出荷する中で最悪のケースに合わせて枠を作ってください。
キャンバス幅 320 px 枠の余白 8 px(左右それぞれ) 使える幅 304 px フォント 12 px 全角(12 px) 304 / 12 = 1行 25文字 半角( 6 px) 304 / 6 = 1行 50文字 3行の枠 -> 全角75文字、または半角150文字程度 翻訳者に渡すのは「短めに」ではなく、この数字。
収録文字・サブセット化・そして読まなければならないライセンス
収録文字とは、そのフォントが実際にどの文字を持っているかという話で、日本語については目安がはっきりしています。一般の文章で使う漢字として定められた常用漢字は2,136字。より広く、旧来のJIS規格の第1水準は2,965字で、一般的な文章を想定するフォントが目標にする実用的な線がこのあたりです。これを下回ると、普通の単語が持っていない文字にぶつかり始めます。
安心できるのは、ドット絵サイズのビットマップ漢字が容量的に安いことです。12×12ピクセルの3,000字はアトラス上で50万ピクセルに届かず、1,024×1,024のテクスチャ1枚に余裕で収まります。フォントサイズが本当にメモリの問題になるのは高解像度かベクターフォントの場合で、それはこの記事が対象にしているゲームとは別のカテゴリです。
それでも文字数が多い場合、サブセット化 — 翻訳済みテキストが実際に使う文字だけのアトラスを生成する — には意味があります。ただし自動化必須の依存関係を1つ増やします。テキストを変更するたび、アトラスに無い文字が混入しうるからです。出荷後の症状は、チームの誰も読めない言語の文章の途中に空の四角が出る、という形になります。アトラス生成はローカライズファイルを読むビルド工程にして、フォントに無い文字が現れたら実行時の驚きではなくビルド失敗にしてください。
ライセンスの確認は、通常のフォント以上に必要です。使い方が特殊だからです。フォントをゲームのバイナリに埋め込み、多くの場合はテクスチャアトラスに変換したうえで配布します。ライセンスによっては、この変換が改変にあたり、同梱が再配布にあたります。開発者がよく検討対象にする、自由に入手できる日本語ピクセルフォントには、10ピクセルと12ピクセルのPixelMplus、8×8の美咲フォント、k8x12などがあります。条件はフォントごとに異なり、時期によって変わることもあるので、配布元のライセンスは必ず自分で読み、埋め込みと商用利用が許諾されているか、表記義務があるかを確認し、ライセンス本文の写しをプロジェクト内に保存しておいてください。2年後に同じ答えを出せるようにするためです。
出したい言語がフォントの収録範囲から外れている場合、それは技術的な細部ではなくプロダクトの判断です。ドットでないフォントで代替すれば見た目は不統一になりますが読めます。文字が欠けたまま出せば、そもそも出荷できる状態ではありません。意識的に決めてください。豆腐だらけの言語を出すくらいなら、その言語を落とすほうがましです。
言語を追加したときに確認すること
以下はどれも表計算ソフト上では見えず、ゲームを30秒眺めれば分かるものです。だからこそ、運任せにせず手順の中に組み込む価値があります。
- 翻訳文に出てくる全文字を並べたテスト画面を作り、プレイヤーが見るサイズで読む。エディタ上で拡大して見ると何でも読めてしまう
- 収録されてはいるが、そのグリッドサイズでは読めない文字を重点的に探す。フォントが対応していることと、判別できることは別
- 文字種と数字が混ざる行を確認する。2フォント構成の継ぎ目が出るのはそこ
- 行間を言語ごとに確認する。CJKのグリフは仮想ボディいっぱいに描かれるため、欧文で適切に見えた行間だと日本語では行が接触する
- スペースのない言語で折り返しを確認し、行頭に句点や閉じ括弧が来ていないかを見る
- テキストが通るすべての経路で整数倍拡大が保たれているか確認する。フルスクリーン、ウィンドウ、リサイズ、カメラのズームや画面の揺れ
- テキストを更新するたびにアトラス生成と未収録文字チェックを回す。緊急修正も例外にしない。想定外の文字が入ってくるのはまさにそのとき