ティラノスクリプトと私④テキストの多言語対応の仕組みを配列変数で作る
※ノベルゲーム特化型ゲームエンジン「ティラノスクリプト」でそこそこ本格的なゲームを作るため、Javascriptなどの面倒くさいことを(嫌々)試行錯誤するおっさんの備忘録です。(※ティラノスクリプトVer 507bで動作確認)
昨今の市販ゲームで当然のようにできる表示テキストの言語変更。この機能をティラノスクリプト製ゲームに実装すれば母国語圏外のユーザーにも遊んでもらいやすくなるはずです! ドメスティックなネタの妙味が人種を超えて伝わる翻訳をできるかどうか、それ以前に翻訳をしてくれる人と巡り合えるかはまた別問題ですが!
多言語対応の大まかな仕組みと問題点
①表示する言語を指定する変数f.languageを用意。0なら日本語、1なら英語…みたいなやつ。
②以降、上記に対応した形式でテキストを表示。
③コンフィグ画面([sleepgame]~[awakegame]タグで割り込み移動できるシーン)で表示言語の各種設定を変更できるようにする。その際は、変更した項目を「scenario/make.ks」で適応させておく。
…合ってますかね?(エアリプ)
一番やっかいな工程は、段落番号書きだとさらっと流れている②です。
通常の記述に強引に対応させるとこんな感じでしょうか。
日本語、英語、中国語の3言語に対応に対応させると、シナリオテキストの1文節だけでもこのボリュームです。しかもここからさらに対応言語を増やすとなると、すべての箇所に[elsif]タグを追加する必要があります。加えてフォント表示にもこだわるとなると、各言語のテキスト表示ごとにフォント指定をし直す必要もでてきます。
短編シナリオなら怒濤のコピペ&手作業改変で乗り切れないこともないですが、スクリプトがいたずらに長くなることでのデメリットは計り知れません。点在する[if]系タグの羅列はただでさえ面倒なシナリオ・ラベル移動チェックの気力をアナタ(ワタシ)から確実に奪います。
そこで配列変数です!
…私程度の悩みなら、これで何でも解決しそうな気さえします。
テキストを配列変数に格納し読み出し方・表示のしかたを決めておけば、とてもスッキリしたシナリオファイルで、複数ある中から指定した言語をちゃんと表示できるはず。
試しに分岐なしで表示されるシナリオテキストのまとまりを2次元配列化してみます。
まずは素材を格納する2次元配列の変数f.serifを作成。
f.serifの最初の[]はテキストが表示される順番。並び方はメッセージウィンドウの改ページ順ではなく、[r]や[l]などのシナリオテキスト表示の制御系タグで区切られている順です。たとえば
なん……[l]だ…[l][r]と……[l]?[p]
という、何回もクリック(テキスト送り操作)しなきゃで面倒くさいけど、2行以上の表示に対応したメッセージウィンドウなら改ページすることなく表示されるこのテキスト。今回の仕組みでは
「 なん……[l]」
「だ…[l][r]」
「と……[l]」
「?[p]」
の4つのテキスト群を別々に順番で管理・表示します。[l][r](クリック待ち&改行)は使用タグがふたつですが、タグ間にテキストが入っていないので一連のアクション扱いとします。
2番目の[]は、実際に表示されるテキストとそれに付随するシナリオテキスト表示制御系タグ。
[0]に日本語(オリジナル)、[1]に英語版、[2]に中国語版が表示されるようにし、末尾([3])には、使用する制御系タグのカッコ内の文字を添えます。
配列変数内のテキストをマクロで表示する
次に、シナリオテキスト表示用マクロ(後述)内で使用する以下の4つの変数を用意します。
f.s_currentのパラメータを1ずつ増やすことでテキストの表示順を進め、実際に表示する言語はf.languageでそのつど確認…というわけです。
f.etとf.s_lengthは必須というわけではありませんが、対応させる言語の増減時やテストプレイの確認時に、あると便利かなーと思って作りました。
ちなみにいずれもゲーム変数(f.)にしているのは、データセーブ時に状態が保存されてほしいからです。プレイ内容どころかつねにゲーム全体に関わる…という機能上、f.languageとf.etはシステム変数(sf.)扱いでもよいかもしれません。
以上の材料を使って完成したマクロがこちら(料理のレシピみたい)。
メッセージの表示自体は2行目の[emb]タグで済んでいます。続く[if]~[endif]タグ内では、以前の記事であるといいなとぼやいた「セリフとして使用する文字列データの中にあるタグ表記を自動的に判別して、表示時に実行してくれるプラグイン」の機能を疑似的に実装しています。まあティラノビルダーのテキストコンポーネントを想定した車輪の再発明・劣化版なのですが、私の技量ではこれが限界です!
シナリオテキスト表示制御系タグの処理の直後で、テキストの表示順序をひとつ進めています(f.s_current+=1)。次にマクロ表記した時には、自動的に次のシナリオテキストが表示されるというわけです。最後の[if]~[endif]タグは、変数内のシナリオテキストを表示し終わったかどうかのチェック用です。とくにどう活用するか考えていませんが、あったら後々便利かなと思って仕組みだけ作っておきました。
というわけで最初に作ったf.serif内のシナリオテキストを表示させるためのシナリオファイルの上の表記は、こうです。
[serif]
[serif]
[serif]
超シンプルになりました。いえーい。
f.languageが0(jp)の場合の実行結果。
1(en)にした場合はこう。作り画像じゃないですよ。
2(cn)だとこうなります。
ニーハオのニーの字が表示されないのは、サンプルのプロジェクトに中国語用のフォントを入れていなかったからです。本格的に実装する際にはf.languageを変更するごとにフォント設定([deffont]タグとか)をし直す必要がありますね。
用法と注意点
今回作成したセリフの表示法はシンプルなわりに便利に機能してくれます。f.serifの2番目の[]の項目数を増やすことで果てしなく多言語対応できるのも魅力です(各言語の翻訳者がちゃんといればの話ですが)。
とはいえ使う際にはいくつか気をつけるべき点があります。
●各[serif]タグで表示されるシナリオテキストの確認は完全にアナログ作業
シナリオファイルに記述するマクロタグの総数や配置場所を間違えると、気持ちよくズレます。
●シナリオテキストの区切りの数(表示制御系タグが入る数、表示のタイミング)はすべての言語で共通
表示制御系タグの種類を各言語ごとに独自に持たせるくらいはできますが、言語ごとにことなるテンポ感でシナリオテキストを表示したい…というのは無理っぽいです。
●シナリオテキスト内に「’」「,」などを使うと正しく配列化されない
機械翻訳した英文をデータ部分にそのままコピペしたせいで、これ由来の「謎の不具合」に半日ほど足止めされました。これらをまったく使わない書き方をするか、別の何かで代用するかの必要があります。
いずれもメリットを台なしにするほど致命的ではありませんが、対応にまあまあ手間がかかります。このあたりを上手に解消する仕組みをどなたか作ってもいいんですよ…(もはや何目線かわからない発言)。
次回は多言語対応テキストの配列変数化およびその管理をスムーズにする方法をまとめます。
参考サイト
上にもちょっと書きましたが、今回のサンプルスクリプトを作る際、ちょっとした表記ミスになかなか気がつけず多くの時間を浪費してしまいました。
とくにやばかったのが演算子の書き間違い。つい最近MSX BASICをさわる機会が多かったこともあり(笑)、[if]タグ条件式内の等号表記を「==」ではなく「=」にしたまま、長いこと不具合に悩まされました。
不具合の原因に気づけたのは、何度もスクリプトをいじっては実行した結果、正しくないながらも反映されるシナリオテキスト表示制御系タグの表記場所を特定できたから。ティラノスクリプトやJavascriptが得意な人ならコンマ数秒でわかる答えを壮大な帰納法によって導き出す充実感も捨てがたいですが、判定系の挙動がおかしいと思ったら以下のようなサイトで表記を確認した方がはるかにいいです。
この記事が気に入ったらサポートをしてみませんか?