個人開発Read this article in English

ゲームジャム作品を製品化する — テキスト周りを作り直す手順

ゲームジャムに出した作品の反応が予想より良く、ちゃんとした製品版を作ろうと決めた。この移行についての助言はたいてい規模の話です。何を削り、何を膨らませ、どうやって全部作り直す罠を避けるか。この記事が扱うのは、同じ仕事のいちばん地味な層、誰もロードマップに書かない部分 — 文章です。

ジャム作品のテキスト負債は、一般的な技術的負債とは少し性質が違います。深夜3時に、テーマを知っていて作品ページも読んでいる数百人の投票者に向けて書かれた文章が、これからは、何の前提知識もなくストアページから来る見知らぬ人に対して機能しなければなりません。配信で読み上げられても耐える必要があります。いつか翻訳されるかもしれません。そして量が、これから10倍から30倍に増えます。

最後の点が、これを最後ではなく早い段階でやるべき理由です。300行の文字列を整えるのは半日の作業です。同じ習慣のまま1年書き続けた6,000行を整えるのは、先延ばしされ続けるプロジェクトになり、やがて「だから言語追加はできない」という理由そのものになります。

48時間がテキストに何をするか

以下はジャムのコードへの批判ではありません。どれも、そもそもビルドを存在させるために必要だった近道で、あの時点では正しい判断でした。ただ、2年続くプロジェクトに持ち込みたい近道ではないというだけです。

  • プレイヤーに見える文が、必要になった関数の中に直接書かれ、全スクリプトに散っている
  • 仮テキストがそのまま出荷されている(「あとで説明を書く」「アイテム01」、仮の名前が定着したキャラクター)
  • ほぼ同じ文字列の重複。同じ警告が3か所で微妙に違う言い回しで書かれている
  • 実行時に断片を連結して文を作っている(書式指定より連結のほうが速かったため)
  • プレイヤーが到達できる場所にデバッグ用のテキストが残っている。たいてい誰も試さなかったエラー経路
  • 用語の揺れ。同じパラメータがチュートリアルでは「エナジー」、HUDでは「スタミナ」、アイテム説明では「SP」
  • 文体の揺れ。導入は冗談まじり、次の画面は素っ気ないシステム文、クレジットにはジャム内輪ネタ

手順1: プレイヤーに届く文字列を全部洗い出す

直し始めてはいけません。まず一覧にします。見つけていないテキストの作業計画は立てられませんし、記憶だけでは全部は出てきません。隠れるのはまさに、めったに通らない経路の文字列だからです。エラーダイアログ、空の状態、セーブに失敗したときのメッセージ、負けた周回の最後の画面。

3種類の探索を行ってください。それぞれ他の方法では見つからないものを拾います。まず、意図的にプレイする。発生させられる失敗経路をすべて通り、全画面をスクリーンショットに残します。次に、ソースツリーを引用符で検索し、結果をざっと読む。ログやデバッグ出力は無視します。最後に、ビルドの外にあるテキストを列挙する。ウィンドウタイトル、ストアやジャムの作品ページの紹介文、クレジット、実績があればその名前、スクリーンショットとトレーラーの中の文字。

この手順の成果物は修正ではなく一覧と、1つの数字です。総文字数。これが基準線になります。片付けの規模が分かりますし、翻訳の見積もりを取るときに最初に聞かれる数字でもあります。半年後に同じ数え方をすれば、自分のテキストが実際どれだけの速さで増えているかも分かります。

# プレイヤー向けの直書き文字列をざっと洗う。言語と構成に合わせて調整すること。
# パターンを信用するのではなく、出力に目を通すのが目的。
grep -rn '"' src/ --include='*.cs' | grep -viE 'log|debug|assert|print|path|http'

手順2: すべての文字列にキーと置き場所を与える

ここで移動します。プレイヤーが読む文字列は、安定したキーの下で1つのテーブルかリソースファイルに入れ、コードはキーで取り出す。この変更が、以降のすべてを可能にします。書き出せないテキストは、数えることも、見直すことも、誤字チェックも、校正も、翻訳もできません。

英雄的な一括リファクタではなく、画面単位で進めてください。1つのシーンを選び、その中の文字列を全部移し、シーンが正しく表示されることを確認し、コミットして次へ。こうすると作業をいつでも中断でき、その間ずっとゲームが動く状態を保てます。ほぼ確実に並行して新機能も作っているはずなので、これは重要です。

この作業のついでに直しておくべきことが2つあります。二度とこれほど都合のよい機会はありません。1つ目は、連結で組み立てている文をほどき、名前付きプレースホルダを含む1つの完結した文字列に置き換えること。あとで翻訳できるかどうかを最も左右する変更です。2つ目は、ほぼ同じ文字列を見つけたら、正しい言い回しを1つ決めて他を消すこと。1つのファイルに集まった瞬間、重複はスクリプトに散っていたときとは比べものにならないほど目立ちます。

// 変更前: どの書き出しにも現れず、語順がコードに固定されている
ShowMessage(itemName + "を買うには" + cost + "ゴールド必要だ。");

// 変更後: 1つの完結したメッセージ、名前付きプレースホルダ、置き場所は1つ
ShowMessage(T("shop.error.need_gold", cost, itemName));

// strings/ja.csv
// shop.error.need_gold,"{item}を買うには{cost}ゴールド必要だ。"

手順3: 投票者向けではなく、見知らぬ人向けに書き直す

抽出は機械的な作業ですが、この手順は違います。そしてジャム版と製品版の品質差の大部分は、実際にはここにあります。ジャムのプレイヤーは作品ページを読み、テーマを知り、しばしば作者本人も知った状態で来ていました。ストアページから来るプレイヤーには、そのどれもありません。共有された文脈があったから成立していた文章が、これからは文脈そのものを含んでいなければなりません。

抽出したファイルに対して、3回読み返す価値があります。1回目は分かりやすさ。ゲームを一度も見たことがない人に、各メッセージが通じるか。特にチュートリアルとエラーメッセージ。2回目は用語。1つの概念に呼び名が1つだけになっているか。UI、チュートリアル、アイテム説明のすべてで揃っているか。3回目は文体。ファイルを頭から通しで読み、ジャム時代の冗談と先週書いた別の気分の文が隣り合っている継ぎ目を聞き取ります。

用語の判断は、決めた端から書き出しておいてください。用語とその表記、そして何を指すかの一行メモ。いま作るコストはほぼゼロですが、翻訳者、絵を描く人、攻略情報をまとめる人、将来の共同開発者が、あとで必ず欲しがる資料です。同時に、システムを追加するたびに同じ命名論争を繰り返さずに済むようにもなります。

手順4: コンテンツが3倍になる前に、言語の方針を決める

翻訳するかどうかを決める必要はありません。決める必要があるのは「する可能性があるか」です。その答えによって、これから数か月の作り方が変わるからです。そして、その作り方を10倍のコンテンツを抱えてから適用しようとすることが、ローカライズを高く見せている正体です。

安上がりな保険は、手順2と3ですでに手に入れたものに加えて、小さな習慣を3つ守ることです。新しい文字列は必ずコードではなくテーブルに入れる。文は連結せず丸ごとで持つ。プレイヤーが読む必要のある文字を画像に描き込まない。1文字列あたりのコストはほぼゼロで、選択肢はすべて残ります。高くつくのは、18か月目に英語版を出したくなり、ルールに従っているのは最初の300行だけだったと気づくパターンです。

ジャム作品に、自分の分からない言語のコメントが付いていたなら、それは本物の需要データです。まだ見えているうちに記録しておく価値があります。どこから来た人か、何を求めていたか、何語だったか。ジャムのページ、配信、コメント欄は、個人開発者が「どの市場がすでに自分のゲームに気づいたか」という証拠を、頼まなくても得られる数少ない場所です。そしてページが動かなくなると、たいてい見えなくなります。

手順5: テキストが10倍になっても続く習慣にする

片付けは、製品版で同じ負債が再生産されれば無意味です。そしてルールを明文化しない限り、必ず再生産されます。個人開発でも例外ではありません。疲れて深夜にビルドを出している自分は、急かされた同僚とまったく同じ近道を選びます。

テキストを表示するもの全般について、短い完了条件を決めてください。文字列はキー付きでテーブルに入っている。連結していない。用語リストと表記が一致している。狭いUI枠に入るものには文字数の上限が記録されている。通常のプレイ経路からデバッグ表示に到達できない。5項目のチェックで、機能が新しいうちなら数秒で終わります。

そのうえで、1〜2か月に一度、テキストファイル全体を書き出して頭から通しで読んでください。ゲームのテキストに対して最も効果の高い品質習慣です。残った仮テキスト、重複した警告、文体の揺れ、3つ前のシステムで静かに変わった用語が、まとめて見つかります。進捗の目安としても悪くありません。ファイルが太っていく様子は、タスクボードよりも正直に、どれだけゲームが増えたかを教えてくれます。

関連記事