isobe_yakiのブログ

ニコ生ゲーム開発者向けの記事を書きます

任意のファイルを読み込めるようにする

AkashicEngineにはアセットをパッケージに含めるための仕組みとしてjsonフォーマットとコマンドラインツールが備わっている。

akashic-games.github.io

有効なファイルタイプとしてはscript,image,audio,textなどがある。エクスポートコマンドを実行するとgame.jsonに従って各アセットファイルが1つのzipにまとめられる。

この際、ファイルタイプによって次のような処理がされているっぽい。

  • scriptタイプのファイルは1ファイルにまとめられてかつminifyオプションが指定されていれば最小化もされる そのためjsとして解釈可能なテキストファイルでないとエラーとなる
  • imageタイプのファイルは専用のプロパティであるwidthやheightが正しいかどうかチェックされる そのためAkashicでサポートしているファイルフォーマットかつ、正しいサイズでないとエラーとなる
  • textタイプのファイルはエクスポート時にUTF-8エンコードされるのだがその条件はここにある通りだ
  • audioタイプのファイルは特に内容のチェックなどはされない
  • 全タイプ共通としてファイル名が謎のハッシュ値のような名前に置き換わる

これらを踏まえて、任意のファイルをパッケージに含めてそれを読み込む方法を考える。

game.json

まずファイルタイプであるが、scriptとimageに関してはエクスポート時に内容がチェックがされてしまい、適当なバイナリファイルなどだとエラーになるのでaudioかtextのどちらかを使うことになる。 よって1つの例として以下のようになる。

{
  ...,
  "assets": {
    "bin": {
      "type": "text",
      "path": "data.bin"
    }
  },
  ...
}

textタイプの場合前述の文字コード変換がかからないようにtextフォルダ以下に配置しない、拡張子としてtxt/jsonを避けるといった対策をする必要があることに注意。

これでエクスポートすることでdata.binというバイナリファイルをそのままパッケージ化できた。

読み込み

次に読み込み方法だが、ここはちょっとハック手法になる。通常アセットの読み込みにはScene | Akashic Engineクラスのコンストラクタに使いたいアセットのID配列を渡すか、アセットにglobalフラグを付けて読み込ませるが、これらの方法ではランタイムエラーが発生するので、ファイル読み込みはエンジンを介さず普通にfetch関数などブラウザで使えるデータ読み込み系のAPIを使う。以前の記事でも書いたが、パッケージに含まれるファイルというのは基本的にCDNサーバーに配置されており、ゲームから自由にアクセス可能なのだ。

APIに渡すアセットのURLをどうやって取得するか、結論から言うと以下のコードで取得できる。

g.game._assetManager.configuration[アセットID].path

アンダースコアが先頭についていることからもわかる通りエンジンのprivateメンバにアクセスしてしまっている(ここハックポイント)。そのため将来的にこの方法が使えなくなっても何も文句は言えない!

Base64

ちなみにだが、バイナリファイルをbase64エンコードしたものをtextタイプとして読み込んでゲーム実行時にデコードするという方法ももちろん可能である。base64エンコードをするとファイルサイズが1.33倍になるしデコード処理が要るし、何よりデータ作成した後いちいちbase64エンコードのプロセスが挟まってめんどいのでできればそのまま読めた方がいいよねということで上記のような読み込み方を採用した。


ここテストに出ます

というわけで、今回の記事はここまでですが今後の記事ではこのテク前提のテクも出てくることになるので、覚えておいてください✍