Now in REALITY Tech #75 多言語の複数形対応のプロジェクト紹介
Hey guys! こんにちは!タイ出身のiOSエンジニア、時々ローカライズ大使と名乗る @chuymaster です!
REALITYは世界中63地域にサービスを展開していて、アプリでは12言語の表示に対応しています。日本以外のユーザー数が約8割で、ローカライゼーションの重要性が非常に高いサービスです。
今回はローカライゼーションの取り組みの一環として、多言語の複数形対応(Pluralization)プロジェクトを企画から担当しましたので、この記事で説明していきたいと思います。
背景
12言語対応に当たって、REALITYではLokaliseというLMP(Localization Management Platform)を導入しました。クライアント・サーバーを含め、アプリケーション上の言語リソースを一箇所で管理できるようになっています。Lokalise導入の詳しい経緯や翻訳のワークフローについては、下記記事からご覧ください。
Lokalise導入によって12言語の翻訳の適用は簡単にできるようにはなりましたが、翻訳の質という面ではいくつか課題があります。そのうち、名詞の「複数形」に対応できていなかったので、例えば英語では下記のような翻訳がなされています。
日本語:ガチャをn回まわす
英語:Pull Gacha n time(s)
time(s) はネイティブスピーカーからすると不自然な文章で、間違った文法の翻訳といえます。この現象が、英語、フランス語、ドイツ語、ポルトガル語(ブラジル)、ロシア語、スペイン語の6か国語で長年起こっていました。
幸い、Lokaliseの言語リソース管理の標準機能として、Plurals機能があるので、アプリ側が複数形フォーマットの言語リソースを読み込むことさえできれば直すことができます。ということで、正しい文法で、過不足なく翻訳を適用できるように、複数形対応プロジェクトを発足しました。
複数形のルールの奥深さ
ところで、複数形(Plural Form)とはどういう意味でしょうか?多くの方は、英語の名詞に「s」をつけることを思い浮かぶと思います。しかし、世の中の言語には実に様々な複数形があります。このルールはUnicodeが定義した「Language Plural Rules」から確認できます。ここでは日本語・英語・ロシア語のルールを解説します。
日本語のような、名詞の複数形がない言語の場合、ルールは存在せず、カテゴリが「other」のみであり、単位を表す名詞が数に関わらず同じです。「日」は「1日」「10日」「100日」だろうと同じですね。
英語の場合、複数形のカテゴリが「one」「other」になります。数が1の場合は「one」、それ以外は「other」になります。「day」だと、1 day、2 daysのように、2種類まで変化しますね。
ロシア語の場合、複数形のカテゴリが「one」「few」「many」「other」になります。ロシア語の文法では、名詞の形が数によって最大4種類まで変化します。結構難しいですね。
このように、複数形のルールは言語によって違っています。数が1だったらa、それ以外だったらbといった単純なプログラムで分類することはできません。
実装の紹介
複数形のルールについて理解したところで、実装について説明します。現時点リリース済のiOS, Android, Unityの実装方法について紹介します。
言語リソースの出力フォーマット
Lokaliseは様々なファイルフォーマットへの出力に対応しています。REALITYが使うフォーマットに複数形の言語リソースキーを出力すると、それぞれこのようになります。
iOS
stringsdict で言語リソースが出力されます。
<dict>
<key>resource_key</key>
<dict>
<key>NSStringLocalizedFormatKey</key>
<string>%#@format@</string>
<key>format</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>li</string>
<key>one</key>
<string>%1$li item</string>
<key>other</key>
<string>%1$li itemss</string>
</dict>
</dict>
</dict>
このフォーマットはそのままLocalizedStringのフォーマットとして利用できます。特に実装なしで、数字を代入すれば、iOSがアプリの言語に従って複数形のカテゴリを判定して、正しい文字列を返してくれます。
Android
xml で言語リソースが出力されます。キーの種別が plurals になります。
<plurals name="resource_key">
<item quantity="one">%1$d item</item>
<item quantity="other">%1$d items</item>
</plurals>
getQuantityString (Kotlin) および pluralStringResource (Compose) 関数を使えば、Androidがアプリの言語に従って複数形のカテゴリを判定して、正しい文字列を返してくれます。
Unity
REALITYのUnityアプリ(UaaL)は独自でjsonのdictionaryを読み込んでローカライゼーションを行っています。複数形のキーはこのようなdictionaryが出力されます。
"resource_key": {
"one": "%1$d item",
"other": "%1$d items"
}
Unityは残念ながら複数形のカテゴリを判定するAPIがないため、様々な可能性を検討した結果、NativePluginを書くことにしました。詳細は割愛しますが、iOSとAndroid側に数字を渡して、複数形のカテゴリを判定してもらい、 one か other (またはそれ以外)かを返してもらいます。Unity側ではその種別をjsonのdictionaryから探して、文字列を取得します。
全プラットフォームの共通点として、開発者が複数形のカテゴリを判別するコードを書かないで、OS任せで実現できました。これにより、表示言語が増えても、複数形の判別に悩まずに済みました。
複数形が複数ある場合
複数形の単位が一つの文章に2つ以上ある場合、それぞれ正しく複数形を適用するのはかなり難しいです。例えば、2つある場合、最大4パターンの組み合わせになります。
単数形x単数形 - 1 day 1 item
単数形x複数形 - 1 day 2 items
複数形x単数形 - 2 days 1 item
複数形x複数形 - 2 days 2 items
プログラムでこれらのケースを出し分けるのは難しいことと、現在の言語リソースではこのパターンの文章は極めて少ないため、「対応できなくても良い」と決めました。
結果、AndroidとUnityは1つ目の数字で複数形を決める仕様にしていますが、iOSは組み合わせのパターンでも出し分けられるので対応しました。ただし、特殊なフォーマットが必要です。それについては、WWDC2023のDiscover String Catalogsの動画の15:47のComplex plural stringsの解説より参照できます。
運用の紹介
アプリ側が複数形の表示に対応できましたので、次に複数形の運用について紹介します。
できれば複数形化しない
Lokaliseでは、言語リソースキーの複数形化は簡単で、ワンクリックですべての言語に適用できます。しかし、複数形化すると、英語の文章修正はもちろん、他の5ヶ国語も修正しないといけないため、運用コストが上がります。そのため、複数形化しなくても自然な文章が作れる場合、複数形化をしない方針としています。
よく使っている回避方法は3つあります。
短縮形を使う:5時間前 → 5h ago
単位をなくす:ガチャチケット5枚 → Gacha Ticket x 5
必ず複数形だと見なす:500アバターポイント → 500 Avatar Points
アバターポイントは500単位での交換のため、1になることはない
このように整理すると、複数形化しなくても済む文章がかなり多かったので、翻訳コスト・管理コストを抑えることができました。
英語以外の言語はベストエフォートで翻訳
REALITYでは12言語表示に対応していますが、社内にすべての言語の翻訳者がいるわけではなく、基本的に英語のみプロの翻訳者に翻訳を依頼しています。その他の言語は、最初は外部に翻訳を依頼しましたが、最近追加した文章は機械翻訳を使っています。(ちなみにタイ語は私がチェックしています。)
上記のスクショのように、言語リソースキーを複数形化すると、当然ながら、英語のみならず他の言語も単数形・複数形で翻訳しなければなりません。ここで活用しているのがChatGPTです。
上記では、ドイツ語の複数形が正しいかどうかを聞きました。単数形が Zeihung で複数形が Ziehungenですね。ネイティブスピーカーがいない場合、Google翻訳やDeepLの翻訳が特定のコンテキストにおいて正しいかどうかを聞くにはChatGPTが非常に精度高いです。これにより、タイムラグなく複数形対応が必要な言語の翻訳ができました。
まとめ
以上、複数形対応についてご紹介しました。
冒頭で書いたように、REALITYは海外ユーザーが実に約8割です。日本発のコミュニケーションプラットフォームとして、日本ユーザーの方が少ないプラットフォームは非常に珍しいと思います。「言語」はすべてのユーザーが目に触れる基礎要素であり、そのユーザーの母国語に対応しているか否かでサービスの印象が大きく変わります。
複数形対応によって、ローカライゼーションの質をシステム面から向上させることができましたが、REALITYプラットフォーム全体のローカライゼーションにはまだまだ課題があり、試行錯誤しながら改善に努めています。アバターを通して日本の魅力を見せつつ、グローバルユーザーにより一層受け入れられるサービスを目指します!