Updated at: 2014-07-03

ゲームの運用フローについて考える

アセットのキャッシング

Client Side

  • アプリとかだと Server からアセット DL してローカルにキャッシュとかするよね
  • Version が変わってたら DL し直す
    • 事前に何らかの方法で Version を知る必要がある

Version を知る方法のパターン

  • 起動時とかに Version 一覧(manifest ファイル)のようなものを取得する
  • 一定時間ごとに取り直す
  • マスタ情報だけは必要なぶんだけ都度 Server から取得する
    • マスタ情報だけなら軽いという前提
    • Version 一覧がめっちゃ肥大化するような案件では都度とらないとスケールしない

CDN (Contents Delivery Network)

  • Akamai とかのキャッシュサーバのレイヤ
  • ソースを取り直すには URL を変えてやる必要があったりするよね
    • URL の後ろに GET パラメータでバージョンをつけてやるとか
  • Client は知っている Version 情報を URL にくっつけてリクエストすればいい

運用時の更新

  • 「このリソースのバージョンはこれだよ」っていうのをデプロイしなきゃいけない
  • ファイルを更新する人が一緒にバージョンも書き換える、みたいなのは面倒なのでナシ
  • デプロイ前にスクリプトで全対象ファイルなめてハッシュを生成して DB に保持、とかが無難か
  • Server は Client にマスタ情報を渡す際、このハッシュをくっつけてやるとかする

  • Server が都度ファイルのタイムスタンプ調べてその情報くっつけて返す、とかでもまあよい

更新タイミングに起こりそうな問題

  • ファイルをデプロイするタイミングで、Server にファイルが浸透する前に 返るバージョン情報が上がっちゃったりすると、ちょっと厄介
  • Akamai がキャッシュ更新されたな、と思って新しいファイルを取りにいったけど、 まだファイルが一部の Server に届いてなくて、古いものキャッシュしちゃうとかあり得る
  • 【解決策】
    • バージョン情報はファイルが浸透してから更新
    • ファイルのタイムスタンプで管理している場合、実際のタイムスタンプと違ったら 404 を返すような仕組みを入れてエラーハンドリング
    • デプロイ後、ファイル浸透したらバージョンを上げて同じものをもう一度デプロイ

動的アセットのダウンロード

ダウンロードの粒度

ゲーム開始後に追加でダウンロードする画像やレベルデータなどのファイル群。 要件として 2 つある:

  • (1) ゲームの進捗に合わせて、ステージ単位で DL すればよいもの
    • 例:アクションゲームのワールドごとのテクスチャやレベルデータ
    • 最初にガッと全部 DL しておいて、そこから先は DL 無しで快適に遊ばせたい

  • (2) その場その場で、必要なものだけ DL しないとスケールしないもの
    • 例:種類が豊富なキャラクターのアバターのテクスチャやデータ
    • (他のユーザが絡んだり、ランダム性があったり、いつ何が必要になるかわからないようなもの)
    • 必要なものだけ個別にオンデマンドで DL する。Web ページの画像とかの感覚

ダウンロードのさせ方とバージョン管理

共通の考え方

  • Server が Client にファイルを配信
  • Server はファイルを特定するバージョンを知り、それを Client に伝える必要がある
  • バージョンの生成は自動化したい
  • 開発者はファイルを配置するだけやって、ビルドスクリプトを回すとバージョン情報を生成してどこかに保存、とかが無難
  • バージョンは更新時刻とかでもよいけど、ファイルの MD5 ハッシュとかが確実

(1) バンドル系

前項の (1) を便宜上、バンドル系と呼ぶ。

  • ファイルはたくさんある(一度にたくさん落とす)
  • ファイルリクエストかさむの嫌なので、一定の単位にまとめたい
  • 昔っぽくやるなら packfile とか、楽をするなら zip とか

  • 僕が過去に作ってみたのは、ファイルをディレクトリ切って配置しておくと、 スクリプトが「ディレクトリ名_1.zip」みたいな感じで適当なサイズ(1 MB くらい)ごとに まとめてくれるような仕組み
  • 同時に、「zip ごとの MD5 ハッシュ」とかをまとめた manifest ファイルも生成する
  • Client は manifest ファイルを取得して、「今自分が知っている hash」と「Server 上での最新の hash」を zip 単位で保存
  • 必要な zip に対して、hash が違っていたら DL → 展開 → 保存、hash も更新する

(2) オンデマンド系

  • 手軽にやるなら、Web ページの画像のように単純にオンデマンドで DL しちゃう
    • 一定時間キャッシュする、とかで済ますならバージョンを管理する必要もない
    • その代わり、きめ細やかなアップデートはできない

  • きちんとバージョン管理するなら?
  • Server はデプロイタイミングで、ビルドスクリプト回して各アセットの hash を計算して保存しておく
  • Client は事前に(もしくは直前に)Server から version 情報を取得する必要がある
    • 必要なものの情報が都度 Server から降る、とかが楽ではある
  • Client はローカルに version を保存して、それと比較する
  • version に差分があれば DL してローカルにキャッシュ、ローカルの version も更新

独自ファイルシステム / パッチシステム

こまかい Tips

  • ユーザからの問い合わせに対応しやすいように、エラー時にエラーコード出しとくとか
    • さらにユーザの覚え間違い防止のためにそのコードの末尾の桁にもチェックディジットつけとくとか