【Unity1Week】独自サーバーの構築に挑戦しました

こんばんは~!ゲーム制作が大好きな猫です🐈

2021/2/22に開催されたUnity 1週間ゲームジャムに参加してきました!

なお、開催日はねこじゃらシティの活動1周年記念日でもあります!

Unity 1週間ゲームジャムは、その名の通りUnityで1週間の期間でゲームを制作するイベントです。
今回は400作品以上の多数の投稿がありました。
毎回テーマが設定され、今回のテーマは「回」でした。

今回制作したゲームは、「かいて、まわして、ころがす」というパズルゲームです。

お絵かきと玉転がしが可能なステージクリア制のゲームで、各ステージでランキングを競うことが可能です!
アップデートによって柔軟にステージを増やすことができるのが大きな特徴です。

この仕組みを実現するために、今回はバックエンドを独自のサーバーで構築しました。

人目に触れることのなかったサーバー構築周りのお話を中心に、本記事で制作を振り返ることにします。

ゲームシステム

1行でゲームシステムを説明できるシンプルなものにしました。

テーマが「回」であったため、「かいて、まわして、ころがす」ゲームシステムにしました。

「かいて」はステージ上に線を描く操作、「まわして」はステージを自由に回転させる操作、「ころがす」は先の2つの操作によって作られた空間で玉を転がす操作です。

この3つの操作によって玉をゴールまで導くことが目標です。

没になったアイデア

このゲームシステムは、ブレインストーミングを行ってから決定したもので、他にもいくつか考えた案がありました。

  • 線で囲む陣取りゲーム
  • 線を描いて猫を誘導するパズル
  • 小さな惑星の上を周回する
  • オブジェクトに穴をあける
  • レースゲーム

上記にはより面白そうな案があったものの、開発期間の都合上断念し、現状の仕様に落ち着きました。

ゲームジャムでの目標設定

本ゲームジャムでは、オンラインで記録を競える要素を取り入れたいと思い、次の2つを取り入れたゲームを制作することを目標としました。

  • ステージクリア制
  • 各ステージ毎のランキング集計

これらを実現するために、今作では次のサーバー構築に挑戦することにしました。

  • アプリケーションサーバーによるセーブデータ・ランキング管理
  • ストレージサーバーによるコンテンツのストリーミング配信
  • 上記によりステージを継続的に増やせる仕組みの実現

最終的には、アプリケーションサーバーストレージサーバーを独自構築して運用するゲームが完成しました。

unityroomでアセットバンドルを扱うために

unityroomサーバーに直接アセットバンドルを置くことができないため(2021/2/22現在)、アセットバンドルを置くためのストレージサーバーが必要になりました。

ゲームプログラム本体をunityroom側に置き、アセットバンドルのファイル類を別のストレージサーバーに置く構成で行くことにしました。

独自サーバー構築に挑戦した経緯

今回このような目標設定にした理由として、去年末に制作を断念したクリスマスゲームの存在があります。

当初は、クリスマスまでに当サイトにブラウザゲームとして公開する予定で制作を進めていました。
しかし、制作期間の確保が難しくなり、最終的にはゲームの試作とサーバー構築だけで終わってしまいました。

クリスマスゲーム制作では、既にアプリケーションサーバーとストレージサーバーと連携したステージクリア制の仕組みまでは出来ていて、これからゲームの中身を実装していくという段階で中断しました。

そのため、ゲームジャムでは上で構築したサーバーの実運用テストも兼ねて、サーバー連携を必須とすることにしました。

サーバー構成

ゲームジャムに投稿したゲームでは、最終的に下図のようなサーバー構成になりました。

セキュリティとアクセス速度を担保するために、やり取りするデータはすべてCloudflareサーバーを経由するのが主な特徴となっています。

アプリケーションサーバー

ブラウザとのゲームデータのやり取り、ゲームの評価やランキング集計などを行うサーバーです。
以下の処理を行っています。

  • ユーザーログイン・セッション管理
  • ユーザー名管理
  • オプション設定管理
  • ステージ情報管理
  • ステージのアンロック管理
  • ゲームのプレイ評価
  • ランキング集計

チート耐性を持たせるため、重要なロジックはなるべくサーバー側で実装するようにしました。

サーバーにはさくらのVPSを採用し、プログラムはPHP7.4で実装しました。

最終的にはさくらのVPS + nginx + PHP + MySQLの構成になりました。

ブラウザとアプリケーションサーバー間の通信は、Cloudflare経由(リバースプロキシ)で行われています。

Cloudflareはファイアウォールの機能を備えており、セキュリティを強化することが可能です。

ストレージサーバー

主に各種ステージのオブジェクトやテクスチャ、BGM等の巨大なデータを置くためのサーバーです。
これらのデータはアセットバンドルとして、各ステージのプレイ開始時にブラウザからダウンロードされます。

ストレージサーバーは、Raspberry Pi 4(自宅サーバー) + 外付けSSDという独自構築したハードウェアで運用することにしました。

参考:Raspberry Pi Shop by KSY

また、ブラウザとストレージサーバーとのファイルのやり取りには、先でも登場したCloudflareを中継させています。
Cloudflareはファイアウォール以外にCDNによるキャッシュ機能を備えているので、Cloudflareを経由することでファイルを高速にダウンロードすることが可能になります。

余談ですが、当サイトもCloudflareのキャッシュ機能を用いて表示を高速化しています。

クライアント側(Unity)の実装

今回のゲームジャムではサーバー側の開発に時間を取られるため、クライアント側は出来るだけ短期間で実装するために、次のような開発を目指しました。

  • UIの大部分はアセットを利用
  • ゲーム中の玉やステージも全て画像素材で構成
  • 後戻りが発生しないようにクラス設計してから実装

これによって、ゲームシステムとステージは3日ほどで完成しました。
お陰で、残りの期間はサーバー側の実装や技術調査にまわすことができました。

UIアセットの活用

UIには、GUI Kit – Simple Roundをふんだんに活用させていただきました。

フラットデザイン調の綺麗なUIパーツが揃っていて、サンプルも充実した素晴らしいアセットです!
価格以上の価値があります。

画像素材サイトの活用

また、プレイ中のステージのビー玉やゴールフラッグなどの画像には、イラストACの画像素材を利用させていただきました。

無料イラストなら「イラストAC」

イラストACには良質なイラスト素材が豊富に備わっており、ダウンロードできる画像数に制限がありますが無料で使用できます。
制限のない有料会員でも月額1000円少々という破格で利用できる大変おススメのサイトです!

ねこじゃらシティの各種記事サムネイルも、イラストACの画像素材を用いて作成されています。
イラストレーター形式(拡張子が.aiのファイル)にも対応しているため、自由に改変して組みあせることも自由自在です。

クラス設計

今回のゲームジャムでは、クラス設計を行ってからプログラムの実装を進めていくことにしました。
目的は、設計上での矛盾を極力なくし、作業の後戻りをなくすことです。

設計は、次のことを念頭に置いて行いました。

  • クラス間の不要な依存はしないようにする(疎結合にする)
  • 汎用化はほどほどにして必要な機能に絞る

結果として、線を描いたり、ステージを転がしたり、ゴールを検知するといった機能をスムーズに実装することができました。

実装してから気づいた足りないクラスも、クラス図上でどのように足すかを考えることが可能になるため、設計の見通しが良くなる利点もあります。

早く実装できたもう一つの理由には、ゲームのそもそもの仕様がシンプルだったことがあります。

画像付きシェア機能

今作では、Twitterにスコアをシェアする際、Imgurと連携した画像付きツイートができるようにしました。

ゲーム画面をキャプチャしてTwitterに投稿する方法の詳細は、以下記事よりご覧ください。

【Unity】Imgur経由でTwitterにゲーム画面を投稿する
画像共有サービスImgurを用いてTwitterにゲーム画面を投稿する方法の紹介です。 本記事の内容を理解すると、次のようにTwitterの投稿URLを開いて画像をシェアできるようになります。 こんばんは✨🐈また暫く間が ...

開発中に起こった問題

アプリケーションサーバーの選定

制作当初は、バックエンドにニフクラ mobile backend(NCMB)を用いてセーブデータやステージ情報を管理する予定でいました。

しかし、自身のニフクラ mobile backend(NCMB)に対する知識が浅く、調査に時間が掛かってしまったため、今作に限り独自サーバーを使用してバックエンドを構築する方向に切り替えました。

ここで3日間ほど時間をロスしてしまいました。

unityroom上でAddressable Asset Systemを使う際の落とし穴

今作ではアセットバンドルを利用するため、UnityパッケージのAddressable Asset Systemを利用することにしました。

しかし、unityroom上のゲームで扱う際は注意点があります。

それは、Addressable Asset Systemの初期化時にビルドファイルと同階層のStreamingAssetsフォルダを参照してしまうことです。
言い換えると、unityroom提供サーバー上のStreamingAssetsフォルダを参照しようとします。

これは、アセットバンドルの格納先を別サーバーにする場合でも同様です。

しかしながら、unityroom上にStreaminAssetsフォルダを置くことができないため、何もない場所を参照しようとして実行時エラーとなってしまいます。

これを回避するために、Addressable Asset Systemパッケージのソースコードを直接修正して、独自のストレージサーバーのStreamingAssetsフォルダしか参照しないようにしました。ただし、これに関しては他に良い方法があるかもしれません。

開発環境と本番環境の差異

サーバー側のプログラム実装時は、開発用のローカルサーバーを立てて動作テストを行っていました。
しかし、本番サーバー上でランキング機能が動作しないという事態に遭遇しました。

理由は、データベースからランキング一覧を取得する際のSQLが動かないためでした。
開発サーバーのMySQLではRANK関数があるのに対し、本番サーバーではRANK関数がありませんでした。

ただし、幸いなことにRANK関数を使わない方法の紹介記事がありましたので、以下の方法で対応いたしました。

本当に感謝しております!

制作スケジュール

制作できない日もあり、12日オーバーの大遅刻になってしまいましたが、制作期間は10日ほどでした。

  • 1日目
    • 企画考案
  • 2日目
    • プロトタイプ制作
  • 3日目
    • ゲームのクラス設計
  • 4日目
    • ゲームロジック実装
  • 5日目
    • 各画面実装
  • 6~8日目
    • サーバー調査(NCMB or 独自サーバーの選定調査)
    • サーバー側プログラム実装
  • 9日目
    • アセットバンドル調査
    • ストレージサーバー準備
  • 10日目
    • 各種ステージ制作
    • 本番サーバー準備
    • リリース

サーバー調査のところで躓いてしまい、制作期間が延びてしまいました><
NCMBの使用を途中で断念してしまったことが心残りですが、それ以外はおおむね順調でした。

ステージ制作にもっと時間をさければ、ステージ数を増やすこともできましたが、スケジュール上10ステージに収めることで妥協しました。

本来は数十ステージ分のものを10ステージに凝縮しているため、最初と最後のステージでは難易度にかなり開きが出てしまいました。しかしながら、クリア者も出てとても嬉しい限りです。

ステージ10は非常に難しいですが、難易度的には50ステージ目くらいだと思っています。

改善したいこと

今作では、ステージ制作やバランス調整に時間を割けなかったため、結果として面白みに欠けてしまった部分はあると考えています。

しかし、それ以外にも技術的な観点で次の点を改善していきたいです。

  • ローカライズ
  • mBaaSの活用
  • 価格と性能の良いCDNの選定
  • チート対策
  • 利用規約の整備

今作をより多くの方々にプレイしてもらいたいと考え、最終的には日本語と英語の2か国語に対応できたらと考えております。幸いにも大部分が英語なのでローカライズは非常に楽に済みそうです(笑)

今回独自構築したアプリケーションサーバーとストレージサーバーも、将来的には無料またはリーズナブルな価格で利用できるサービスのものに置き換えていきたいです。
mBaaSの候補として気になっているのは、ニフクラ mobile backend(NCMB)Azure PlayFabなどです。

また、チート対策に関してはAnti-Cheat Toolkitという便利アセットがあるので、導入できないか検討していきたいです。

今後多くのプレイヤーにプレイされる可能性を踏まえ、利用規約も定めて運用していきたいと思います。

今後の展開

ゲームジャムで制作した今作から、次の2つの派生ゲームを制作したいと考えています。

リメイク版

リメイク版では、今作を仕様面から見直して、面白くボリュームあるゲームにしていくことを検討しています。
特に、10ステージは非常に少ないため、50ステージ分を遊べるようにしたいと考えています。

リリース後もアップデートでステージを増やせるようにしていくつもりです。
また、先述の改善点も取り入れるつもりです。

完成したゲームは当サイトかitch.ioのようなサイトで公開したいと思います。

学習用教材としての玉転がしゲーム

現状のゲームシステムからお絵かき要素を取り除くとシンプルな玉転がしゲームになります。

これを題材として、玉転がしゲームを作りながらUnityのことを学べる連載型記事を投稿していきたいです。
もしかしたら、リメイク版よりも先に着手するかもしれません。

さいごに

1週間ゲームジャムで独自サーバー構築をしたお話を中心に振り返り記事を書かせていただきました。

ゲームジャムでサーバー構築やアセットバンドルを扱う事例は少ないと思われるので、その実績を残したゲームとして書かせていただきました。

当記事では文字数の都合上、さわりの部分にとどめました。
具体的な方法については、別記事で投稿していきたいと思います。

記事を作成したら、当記事からリンクでたどれるようにしていきます。