見出し画像

モバイルゲームでの追加コンテンツの実装について

前置き

最近ではゲーム開発においてネットワークの要素は欠かせない要素になってきています。

一言にネットワークの要素といっても様々な要素があります。
・DLCや配信による追加コンテンツ対応
・ユーザーのセーブデータ管理
・ガチャやログインボーナス等の処理
・プラットフォームサービスやSNS等外部サービスとの連携
・サービス運営でお客様サポート等を行うために必要な諸々の話
・ネットワークを通じたマルチプレイ
等々…

今回は「DLCや配信による追加コンテンツの対応」にフォーカスしてお話を進めていきたいと思います。

ここでは、ガチャ等でマネタイズしているスマートフォン向けの基本無料ゲーム(いわゆるソシャゲ)を前提にして話を進めていきたいと思います。
(筆者が2012年頃~2014年頃に、モバイルゲームのサーバーサイド実装をしていて、その頃の事をメインにしています)

コンテンツ追加について

基本無料のスマートフォンゲームでは、ユーザーに遊び続けてもらうために常にコンテンツを追加し続けていく運営をしていきます。

例えば、下記のような事を実現しようとした場合にはコンテンツ追加する必要が出てきます。
・メインストーリー、ステージの追加
・ガチャで排出されるキャラクター/アイテム等の更新や追加
・ガチャそのものの変更
・期間限定のイベント追加

プログラム更新ではなくデータによるコンテンツ追加

これらのコンテンツ追加をするためには、プログラム更新ではなく、データ配信のみで駆動する必要があります。

と言うのも…C#やC++で書かれたプログラム部分を更新する際にはアプリケーション自体をアップデートする必要があります。
しかし、アプリケーション自体をアップデートする際にはプラットフォーマー(Apple/Google等)による審査を待つ必要があり、アプリケーションがアップデートされる日時がずれてしまう可能性があるからです。

そのため、タイムリーなコンテンツ追加を行っていくためには、プログラム更新によるコンテンツ追加ではなく、データ配信のみで行う必要があります。
※新しい種類のイベントや、プログラム自体を弄らないといけないような新キャラクターの追加などを行うときは、それよりも前にアプリケーションをアップデートして備えています。

データ配信によるコンテンツ追加のために…

データを追加取得するためにはアプリケーション側にも仕込みが必要です。

インターネットを通じてサーバー上に置いてあるデータを取得してきて端末側にファイルとして保存する等が行うような実装が必要になります。

サーバーとの通信で最も多い通信はHTTP/HTTPSという方式でWebを閲覧するときと同じプロトコルで通信を行い、データを取得してきます。

データについて

データも大きく二種類に分けます。リソースデータとマスターデータです。

リソースデータはキャラクターのモデルやテクスチャ、モーション、ボイスデータなどと言ったものです。

対してマスターデータは、「どのようなキャラクターがいるか?」「ステージはどういうステージがあるか?」などと言った設定データになります。

データを二つに分けたのは、データの特性・持ち方が異なるので大きく二つに分けました。

リソースデータ

リソースデータは手元のアプリで表示するときには欠かせないデータですが、サーバー側にはあまり重要ではないデータです。
そのため、UnityであればAssetBundleという形でまとめてサーバー上にファイルをそのまま配置したりすると言った形です。

ファイルをそのまま落としてくるだけに近いので、ファイル配信に特化したAkamaiなどのCDN(Content Delivery Network)を利用して配るケースが多いと思います。

マスターデータ

ゲームの設定データと言われもピンとこないという方のためにも、もう少し具体例を挙げていきます。

例えばステージであれば、下記のようなデータを1ステージごとに持つ形になります。
・ステージ固有のID
・どのステージIDをクリア後に解禁されるのか?
・出てくる敵の配置情報や、敵自体の設定情報など…

画像1

例えばキャラクターデータであれば下記のようなデータを1キャラ毎ずつ持つ形になります。
・キャラクターを示すID
・キャラクターのHP、攻撃力などのパラメーター
・キャラクターの成長曲線
・表示するときのモデルファイル名等
・レア度
・強化の素材にしたときの経験値

画像2

他にもガチャの抽選テーブルであったり、イベントに関する設定項目で合ったり、ログインボーナスの設定だったりといったものもマスターデータになります。

ここで取得してきたステージリストを元にステージ一覧のUIを構築するようになっています。
ここで取得するステージリストにデータが追加されていればUI上で表示も増え、ステージが追加されるというわけです。

そして、マスターデータはサーバー側にとっても必要な情報になってくることが多いです。
例えばステージに入ってプレイを開始する前に行われる通信で、「そのプレイヤーは本当にそのステージをプレイできる状況にあるか?」などをチェックしたりする際には、その情報が必要だからです。
他にもキャラクターを強化する際に、「指定されたキャラクターを素材にすると経験値がいくつ入るはずなのか?」と言ったことをサーバー側でも把握しておく必要があるからです。

そのため、マスターデータはDBサーバー(データベースサーバー)上に配置して、サーバーサイドのプログラムからアクセスできる形で置く事が多くなってきます。
そして、クライアント側のアプリケーションは、APIサーバーと呼ばれるサーバープログラムとの通信を通じて、データを取得していくという流れになってきます。

データの取得タイミングについて

データの取得についてはタイトルによっても異なってきますが、私の観測範囲で一番多そうな実装について話していきたいと思います。

リソースデータは、クライアントアプリ起動直後にすべてのリソースデータを取得させるものが多いです。
ずっと起動しっぱなしの場合に対策して、APIサーバーとのやり取りでリソースデータ更新があったかを検知できるようにして、発覚したら起動直後の状態にアプリが遷移するようにつくると言った作りになっている事が多いように見えます。
タイトルによっては、必要最低限のリソースデータのみダウンロードするという形を取っているタイトルもあります。たとえば、自分が保持しているキャラクターに関するリソースデータのみ取得する、新たにキャラクターを獲得した時に合わせてリソースデータも取得して端末側に保存すると言った作りです。

マスターデータは、ログイン通信時に合わせて諸々送ってくるケースが多いと思います。リソースデータと違い、すべてを一括で送る形ではないことが多いです。

例えばステージデータについてです。
ステージに入ってプレイする時にはどんな敵がどういう配置で出現するのかが必要です。
しかし、ステージセレクト画面にはその情報が必要ないので、その時点では取得しないと言った形です。
ステージに入るときにスタミナを消費するので、APIサーバーと通信をするのですが、その時にステージの詳細の設定データを貰うと言った形です。

逆にキャラクターデータは、様々な所で参照されることが多いので、ログイン通信ですべてを事前に送ってしまうみたいな形になります。

一昔前のゲームだと、画面が遷移するごとにサーバープログラムと通信していて、その遷移先の画面に必要な情報をサーバーから取得するという実装をしていたものもありました。ですが、最近では画面遷移するごとに通信するとテンポが悪くなるので、通信頻度を下げてテンポよく進行するためにもログイン時に色々な情報を取得してしまおうという実装が多く見受けられます。

※実装は通信が行われているかどうかをみて想像しながら語っています。実際の実装を見ているわけではないのでご注意を…

期間限定のイベントや時限式配信について

期間限定のイベントや「○○日の〇時から解放されるステージ」みたいな実装について、少しここで話をしておきたいと思います。
ここでは実装の一例ですので、他にも実装方式はあると思います。

例えばイベントステージの場合、通常のステージ情報に加えて、下記のような情報を付与して実現していました。
・イベント開始日時
・イベント情報解禁日

イベント開始日時より前にクライアントアプリ側でサーバーからデータは取得しておきます。
アプリ内の時計を見て、イベント開始時刻を過ぎていたらUI上に表示すると言った形で利用します。
端末の時計を弄るとUI上で表示されてしまいますが、実際にプレイできなければ大した問題にはなりません。
実際にプレイするにはサーバーとの通信が必要になります。そこでサーバー側ではイベント開始時刻とサーバー時間で比較して、開始時間前であればエラーを返すようにすれば、不正なスタートダッシュを防げるという事になるわけです。

イベント情報解禁日はサーバー側でデータをクライアントに渡すかどうかを制御するために利用します。サーバー側の時計で判断して、この日時以降であれば、ステージに関する情報をクライアントに渡すという事をしています。これは、お知らせするよりも前にクライアントの時計をずらしたり、データを引っこ抜いて、イベント情報がリークされないための対策でこのようにしていました。

期間限定でのイベントチェックのTIPS

クライアント側の時刻だけでなく、サーバー側の時刻でチェックする事で、端末の時計をずらす事での不正を防ぐ話をしました。
ただ「イベントが実際に行われる前に設定が正しく行われているか?を実際の実機上で確認したい。」という要望はあると思います。その時にサーバーの時刻を弄るわけにもいきません…。

そこで、運営のチェック用のユーザーにスーパー権限を付与してそのユーザーだけ特別扱いされるようにして解決しました。スーパー権限の付与はサーバー上のデータベースを直接弄ることによって付与することが出来ますので、運営側のメンバー以外には手の出せない所にある形になります。

サーバーとの通信の際に、かならず端末側での時刻を送信するようにしていましたので、スーパーユーザーからのアクセス時はサーバーの時刻ではなくクライアントから送られた端末時間でオーバーライドするようにしてました。

この仕組みを用意したことで、イベント開始前に実機上でイベントの確認を出来るようにしていました。
※ほかにもスーパーユーザーはメンテナンス中の状況になっていても、それを無視してプレイできる等といった形を取って、メンテ前に確認できる状況も作っていました

最後に

そんな感じで、HTTP/HTTPS通信でサーバー上にあるデータを取得してくることでコンテンツ追加を実現しているという話でした。


この記事が気に入ったらサポートをしてみませんか?