見出し画像

ゲーム内での自作のローカライズの実装

Steamで出そうとしているゲームは日本語以外に、英語、中国語などの言語でも配信しようとしているので、今のうちにローカライズについても考慮しておいた方がスムーズかと思い、少なくともゲーム内の部分で既に日本語で表示させている部分を各言語で切り替えられるよう実装してみました。

Phaser.js自体にはそういった機能はないので、自作ライブラリとしてPhaser.jsを内部で扱うmeowser.cljsの中にその機能を入れてみました。

今回は、ライブラリ側で実装したコードをサクッと紹介したいと思います。
まず言語ごとの設定ファイルを読み込むため、ClojureScriptのatomでその設定情報を保持するconfigを用意します。

(def config (atom {}))

このconfigに言語ごとの設定ファイルを読み込む実装はこちら。

(defn load-dictionary [scene lang-opts]
  (doseq [[lang path] lang-opts]
    (.text (.-load scene) (name lang) path))
  (swap! config assoc
         :cache-manager (-> scene .-cache .-text)
         :langs (map first lang-opts)))

言語ごとの設定ファイルをPhaser.jsのCacheManagerを使い読み込みを任せてせています。
CacheManagerで読み込みが終わったタイミングで、以下の関数にて、読み込まれた結果を最初に用意したconfigの中にセットしています。

(defn setup-dictionary! []
  (when-not (:dictionary @config)
    (swap! config assoc :dictionary
           (into {}
                 (map (fn [lang]
                        [lang (reader/read-string (.get (:cache-manager @config) (name lang)))])
                      (:langs @config))))))

具体的にどういった言語ごとの設定ファイルを読み込むかというと、

;; 日本語の場合
{:blocks
 {:logic {:if-touching "もしプレイヤーに触れたら"}
  :move {:right "右に移動する"
         :down "下に移動する"
         :left "左に移動する"
         :up "上に移動する"}}}

;; 英語の場合
{:blocks
 {:logic {:if-touching "if touching player"}
  :move {:right "move right"
         :down "move down"
         :left "move left"
         :up "move up"}}}

という形で、blocksや、logicは今回作っているのがビジュアルプログラミングのブロックごとのタイトル部分のローカライズなのでこうしているだけで、ゲームごとに自由に設定でき縛りはありません。

読み込まれた内容をもとに、ローカライズされたテキストを取り出す関数は、

(defn t [key & [args]]
  (let [keys (map keyword (str/split key #"\."))]
    (cond-> (get-in ((lang) (:dictionary @config)) keys)
      args (replace-by-args args))))

という形で実装していて、以下のように t 関数を設定ファイルに記述したキーをドットで繋げることで、用意した言語に応じたテキストが返ります。

あとは実際にライブラリを使ってブロックのタイトルが変わる様子です。

また t関数は引数を渡すことでテキストを動的に置換できる仕組みも用意し、一旦今の時点で必要そうなローカライズの実装ができ、以下のコードが全てとなっていて、わりかしシンプルで済みました。
https://github.com/Meotaverse-Games/meowser.cljs/blob/main/src/main/meowser/i18n.cljs

ただ、Steamで動いた時のデフォルトの言語を取得する方法はまだわかっていないので、ゲームとしての進捗が進めば改めて調査が必要だなと思いつつ筆を置きます。

いいなと思ったら応援しよう!