三尺です。
今回はスマホアプリの中身の話です。
世に流通しているゲーム・アプリは沢山ありますが、作り方について大きく分けると2種類あります。
1.スタンドアローン型
プログラムとハード(以降クライアントと呼びます)のみで構成されます。
インベーダーゲーム、ファミコンのゲームなど古くのゲームはこの型で、一度発売したらバージョンアップ(修正)できないのが大きな特徴です。
バージョンアップができないと言う事は不具合も修正できないと言う事ですが、昔は不具合を裏技と称しポジティブに扱っていました(笑)
2.オンライン型
プログラムとクライアントの他、インターネット環境とサーバーで構成されます。
現在スマホアプリとしてリリースされているのは殆どがオンライン型です。
オンライン型の最大の特徴は、バージョンアップや不具合修正ができる事。
「無料」で始められて、どんどん追加される強キャラを「ガチャでゲットする」ビジネスモデルは今のところ鉄板で、しばらくは続くと思います。
オンライン型ですが、主にゲームデータやセーブデータをサーバーとクライアントでやりとりしてるだけ、と思っている人も多いのではないでしょうか?
スマホアプリの仕事をする前は自分も、サーバーって結局はユーザー共有のメモリーカードなのかな、と思っていました。
この考えは概ね間違っていないのですが、クライアントのデータをユーザーが書き換える事ができるのを前提としなければなりません。
例えば、悪意あるユーザーがステージのデータを書き換えたとします。
スタンドアローン型だったら、このまま進行できてしまいますが、ゲーム仕様上255までしか対応されていない時に256以上のデータが入ったら、そのパラメータは0になったり変なステージに行ったりします。
オンライン型の場合は、チェックを行い、不正と判断したらエラーメッセージを表示してタイトルに飛ばしてしまいます。
多くのゲームは、データを戻す、そのステージを遊ばなかった事になるのではないでしょうか。
アプリの多くはステージを遊んでアイテムをドロップする仕組みですが、まずステージ開始時にドロップするかしないかを決めてしまいます。
そしてステージリザルトで嘘データをサーバーに送った場合、サーバー側の整合性チェックで、もともと決定されていたデータと違うデータが来た場合、エラーメッセージを表示してタイトルに飛ばします。
文だと分かりにくいので、流れを箇条書きにするとこんな感じです。
ユーザー:「イベントステージを遊ぶぜ!」
↓
クライアント:「イベントステージのデータとドロップ結果の計算をサーバー君よろしく!」
↓
サーバー:「イベントステージのデータとドロップ結果を決めたからクライアント君に送るね!」
↓
クライアント:「サーバー君からデータが来たからイベントステージ始めるね!」
↓
ユーザー:「レアアイテムが出た事にしてデータ書き換えたろ!」
↓
クライアント:「ステージをクリアしたからドロップ結果をサーバー君に送るね!」
↓
サーバー:「あれ、このレアアイテムはドロップしないハズだったのに何かデータ壊れたかな、安全のためデータをステージ遊ぶ前にデータを戻すね!」
まだ、分かりにくいかなー。もっと分かりやすい表現を考えたら修正するかもです。
この「あらかじめデータを決めておく」手法を最初に考えた人は賢いなーと思います。某コンシューマの対戦ゲームでも採用していました。
ネット対戦で負けそうになると切断しちゃうユーザーがいますすが、通信切断による終了は敗北にならないゲームもあるんですよね。
負けたくないのでケーブルを抜く人がいると思いますが、それを防ぐため、対戦開始時に、まず両方共に「負けた情報」を保存します。
そうすると通信切断で終了しても「負けた情報」は残っているので、負けた事になります。
正常に対戦が終わった時は、勝者のみデータを書き換えて終了です。
ついでに言うと、対戦ゲームの中には切断率を保持しているものもあります。
対戦開始時に「切断した」情報をこっそり保存しておき、正常終了した場合は消します。
そして、マッチング条件の中に切断率が近いユーザーという条件を入れれば、切断率が低いユーザー同士が対戦ができる仕組みです。
確か携帯機版のゼルダがこれを採用していたと記憶しています。
オンライン型アプリを比べてみると、ステージを始める・終わる時、ゲームによってロード時間に差があります。
これは、端末の性能やゲーム処理の重さと言うよりは、如何にして最小限のデータのやりとりで済ますか、をこだわっている重要な点で、セールスランキングの上位にいるアプリはだいたいサクサク進みます。
たまーにありますけどね。新しめの会社で初のスマホアプリだと頻繁にロードが入るものとか。
そこはサーバーとクライアントのプログラム設計の経験が物を言うので、なかなか真似できるものではないです。