MagicOnionを使ってリアルタイム通信ゲームを作る -1. 概要-
ゲーム作成の上での動機や制作環境などを軽く紹介します。詳細は別記事で。

目次
概要
2021年の1月頃からこつこつ作っていたテトリス風のリアルタイム通信ゲームが、大分形になってきました。 そこで、今回調べたことをブログの形で何回かに分けて共有しようと思います。
実際に何をしているかは Github上のソースコード を見ていただいたほうが早いと思います。なので、このブログの立ち位置としては
- ライブラリ、アーキテクチャをどういう考えで選定したか
- ハマったポイントはどこか
など、ソースコードだけでは汲み取りにくい部分を補完する形で解説していければと考えています。
第1回である本記事では実際の成果物、制作動機、目標、採用技術などを軽く紹介していきます。
他の記事へのリンクやソースコードはこちらから。
- MagicOnionを使ってリアルタイム通信ゲームを作る -1. 概要-
- MagicOnionを使ってリアルタイム通信ゲームを作る -2. アーキテクチャ-
- MagicOnionを使ってリアルタイム通信ゲームを作る -3. クライアント処理-
- MagicOnionを使ってリアルタイム通信ゲームを作る -4. サーバー処理-
- Githubソースコード / LineDeleteGame
成果物
早速ですが今回作ったゲームはこちらになります。
ご覧の通りテトリスっぽいゲームです。(本家とは微妙にフィールドサイズを変えてます。) ブログを書いている今も色々いじっているので最終形は変わっているかもしれないですが、それぞれ違う端末で二人プレイした結果をリアルタイムで通信、反映しています。
ソースコードや各環境でのセットアップ方法もgithub上に公開しています。コードを見てみたい、コードを見たほうが早い!という方や、 ご自身の環境で動かしてみたいという方はReadMeをご参照ください。
Github / LineDeleteGame動機
私の職業はゲームエンジニアですが、最近はJenkins CIやゲーム開発環境整備が作業の大部分を占め、ゲームロジック本体に触る機会は減っています。 CI周りはそれはそれで楽しかったりするのですが、やっぱりなにかしらゲームも作りたいなという気持ちもあり、趣味でリハビリ的に作り始めることにしました。
「どうせやるなら今まで触ったことがない技術へ挑戦を」ということで今回はリアルタイム通信ゲームを作ろうと決意。 題材にテトリス風味なパズルを選んだのは、
- 今まで作ったことがなかったのでテトリスっぽいゲームの基本ロジックが知りたかった
- リアルタイム通信の組み込みで時間がかかりそうだったので、ある程度遊び方の核が定まっているものを作りたかった
- 10年以上前に「作ってみた動画」を見た時からずっと作ってみようと思っていたが、今までなかなか重い腰が上がらなかったのでこれを機に作ってみようと思った
という理由からです。
ちなみに10年以上前に見たのは下動画です。ロジックの基本部分はこちらを参考にしています。本当に1時間弱で組んでいて今見てもすごいなと思います。
目標
リアルタイム通信ゲームを作るにあたり、以下の目標を掲げました。
サーバーでゲームロジックを動作させ、クライアントで盤面情報をチートできないようにする
クライアントで全てのゲームロジックを実行し、スコアなどの結果のみをサーバーに送信する形式ではユーザー側にチートができる余地を残してしまいます。
そこで今回はチートの余地を極限までなくすため
- クライアントからはユーザーのキー入力だけをサーバーに送信
- 受信したキー入力を元にサーバーが盤面情報を計算、クライアントにリアルタイムで結果を送信して表示
することを目指しました。
オフラインでのゲームプレイもサポートする
きちんとクライアント単体で動くものが作りたかったのでクライアント側にもゲームロジックを配置しつつ、ついでにオフラインのゲームプレイもサポートしました。 この時にクライアントとサーバーとで処理の齟齬が起きないよう、互いに共通のゲームロジックを実行できるようにする必要がありました。
ローカルホストだけでなく、実際にオンライン公開できる場所にサーバー処理を持っていく
いつもは「ローカルホストにサーバー立てて疎通できて終わり」になってしまうことが多かったので、 今回は実際にサーバーを立てて実行するところまで達成したいと考えました。 そのためには何回も環境を作り直す作業が想定されたため、簡単にサーバー環境を構築、破棄できると楽できるなと考えました。
制作環境
目標を達成すべく調べた結果、下記のライブラリ、環境を用いて制作を進めました。 各ライブラリ、ツールの詳細やどういう風に使ったかは次回以降のブログで解説していきます。
動作環境
- Windows 10 (Winsows Subsystems Linux含む)
- Mac Pro(Catalina)
- クライアント兼、localhostでサーバーを起動してデバッグ
- AWS EC2 (Ubuntu 20.4/LTS)
- サーバーをDockerで起動
クライアントはUnity製なのでプラットフォームは問わず動作可能です。 サーバー処理も .Net Coreがマルチプラットフォームをサポートしているので、基本OSを問わず動作します。
使用ライブラリ・ツール
クライアント
- Unity / 2020.2.2.f1
- Unity用のgRPCライブラリ / grpc_unity_package.2.23.0-dev
- MagicOnion / 4.1.2
- MessagePack.Unity / 2.1.152
- UniTask / 2.1.2
基本はUnityによるC#開発です。サーバーとの疎通にMagicOnionを使用しています。 UniTaskは非同期処理も勉強しようと思ったので導入しています。
サーバー
- .Net Core app
- MagicOnion
- LogicLooper / 1.0.2
サーバーは「.Net Core」による機構を使用しました。MagicOnionはクライアントとの疎通用です。 LogicLooperはサーバー側でゲームループを回す際にスレッド管理するのに使っています。
インフラ
- Docker (Docker-compose)
インフラと呼べるものでもないですが、サーバー処理はDockerコンテナ上で動作させます。 Dockerfileをきちんと記述して動かすところまでは苦戦しましたが、 一度処理が固まってしまえばDockerが動く環境ならどこにでも持っていけるというメリットがあります。 初めてクラウド上にサーバーを建てましたが、Dockerで武装したおかげでクラウドサーバー上での実行は そこまで苦労しませんでした。
その他ライセンス
標準のフォント以外でシンプルなフォントを採用。ライセンス条項的にリポジトリに含めて問題ないはずですが認識間違いをしている場合はご指摘いただけると嬉しいです。
次の記事
次回の記事では作成したゲームのシステムアーキテクチャ、及びネットワークアーキテクチャの大枠を解説していきます。