「オンラインカードゲーム開発」(ポートフォリオ)

とあるトレーディングカードゲームをオンラインで遊べるWebアプリを開発しました。
目次(タップでジャンプ)
アプリのイメージ
百聞は一見にしかずですので、まずはプレイ動画を御覧ください。
一人プレイ(CPU対戦)、スマホ(※音が出ます)
縦持ちで遊べます。
対人(PvP)対戦、PC
※PCの録画環境の事情により無音です。
一人プレイ、PvPいずれもスマホ、タブレット、PCのどれでもプレイ可能です。
オンラインカードゲームアプリ開発概要
目的・目標
トレカゲームを実際にオンラインで遊べ、アプリの可能性を検証する。
開発方針
予算ゼロ、一人開発のため、最小のリソースで最大の効果を最短で得る。
初期目標
可能性を検討するための基盤(インフラ)をメインで開発。またコミュニティ内で気軽に遊べるレベルのアプリとする。
現状仕様
- ブラウザアプリ(Next.jsベース)、インストール不要ですぐ遊べる
- トレカのルールを忠実に再現する
- リアルタイムPvP対戦、CPU対戦が可能
- 直感的にカード操作ができるUI。UI実装は凝らずにシンプルかつ合理的(トレカなので直感操作)なものとする
開発実績
- 開発者:林(コード管理、フルスタック設計とコーディング)
- 期間:2024/9/Mから2025/3/B(約半年間)
- 開発リソース:土日祝年末年始含む、1日10〜12時間のフルコミット開発。通常の開発人月でいえば10人月程度と思われる。+機材や開発環境の経費。
- アプリ規模:約2.5万行(テストコード込、コメント除く)
- アプリURL: (限定公開)
アプリ開発の注目部分
以下、アプリ開発の注目部分についてご説明します。
全体設計
トレカのゲーム進行がターン交代制となっているので、シンプルなサーバー・クライアントモデルで実装しました。ゲームの状態は全てサーバー側で一元管理し、通信が途切れてもリロードで問題なく再開できます。
DBはオブジェクトDBのMongoDBを採用。ゲームステートやカードの状態などテーブル表現しにくい情報でも直感的にDBに読み書きできます。
トレカのルール上「同時アクション」が可能なタイミングがあるので、サーバー側で適切に排他制御を行い、同時アクションの受付も可能としています。
Webアプリということで、開発言語はTypeScript、フレームワークは現状で評価の高いNext.jsとしました。
サーバーは以下の観点で選択しています。
- 開発環境(Next.js)のインスタンスが正常に動作すること
- リアルタイム通信が可能であること(ソケット通信等)
- スケーリング可能なこと
- リーズナブルであること
後ほどソケット通信でお話しますが、結論としてGoogle Cloudを利用しています。
直感的UIの実装
トレカは盤面でカードを移動させる、見た目はシンプルなゲームです(ルールは奥深いですので、ロジックの実装は見た目以上に大変です)。シンプルゆえにUIはドラッグアンドドラッグ(DnD)を活用した直感的な操作を採用し、初めてのプレイヤーでもスムーズにプレイできるようにしました。
ただし開発方針に則り、今回は美麗で凝ったUIの実装はしていません。本当はそうしたほうがゲームとしての価値が上がるのは理解していますが、本プロジェクトでUIに工数をかけてしまうと他の部分の実装ができなくなるおそれがあるため、シンプルかつ、直感的、合理的なUIとしています。
DnDを実装するにあたり、工数を抑えるために既存のDnDモジュールであるDnD kitを採用しました。ただし、DnD kitだけでは所望の動作が実現できなかったため、DnD kitを独自に拡張しています。
また、合法手のカードのエッジ光らせるエフェクトも追加しました。これにより、プレイヤーがトレカのルールに詳しくなくても次の一手を直感的に選択することが可能になります。
安定かつリアルタイム双方向通信の実装
ストレスのないネットワーク対戦を実現するために、リアルタイム双方向通信が必要です。リアルタイム双方向通信の方法として
- ソケット通信を使った独自実装
- Pusherなど外部サービスを使った実装
の2つを検討しました。結論として今回はソケット通信を採用しています。
経緯としてはVercelのサーバーレスファンクションではソケット通信に対応できないので、代わりにPusherなどを利用するのですが、実際Pusherを利用しても不安定すぎてお世辞にもストレスないネットワーク対戦とは言えない状況でした(これにはいろいろ理由がありますがここでは省略します)。
したがい、消去法にてソケット通信を採用し、またソケット通信が利用できるGoogle Cloudを採用しています。これにより、ストレスの少ないネットワーク対戦環境を実現できました。実際に遊んでみていただければ分かると思います。また、高速移動中など通信が不安定な状況においても対戦が継続できることを確認しています(具体的には新幹線vs自宅)。
ソケット通信とPusher等の外部サービスは通信路の仕様が異なるだけで、やり取りするデータは同じです。したがって、リスナーを抽象化し、通信層とアプリ層を分離しました。これによりコードを変更することなくソケット通信とPusherを選択できる設計となっています。
アプリの中枢、ゲームエンジンの実装
最も苦労し、工数がかかったのがこのゲームロジックを再現するゲームエンジンの設計、実装です。
トレカのロジックの主な特徴は
- 将棋や囲碁、チェクと比べてルールが複雑
- カードの種類が豊富で、新しいカードも随時追加される
- カードには効果があり、ある効果の発動が他の効果のトリガーとなることがある(いわゆるコンボ)
です。
これらルールを忠実に再現するロジックの実装に苦労しましたが、以下の設計方針としています。
- プレイヤーが取りうる全ての行動を「アクション」と定義し、このアクションを受け取って処理する窓口を一つつくる
- ゲームの状態はサーバー側で一元管理し、クライアントはそのコピーを持つ
- カードとカードの効果は随時追加され、予断できないので、敢えて外部定義ファイルにはせず、コーディングで汎用的に対応する。ただしコーディングが発散しないよう、適切に構造化する。もちろんコンボの発動も可能。
特にカードの効果を実装するための構造が本アプリの中核的オリジナルノウハウとなります。これにより、どのような効果のカードでも対応できる上に、実装コストも低く抑えられます。
こういう書き方をすると簡単に実現できたように見えますが、実際には超大変でした(笑)当然、ネットにはないノウハウですので、AIも教えてくれません(こういう状況でAIに従うとだいたいトンチンカンな方向に進みます)。
したがい、再設計、リファクタリング、テスト…を何度も繰り返し、今の設計に至っています。
CPUプレイヤーの実装
しっかりゲームエンジンが完成すれば、CPUプレイヤーの実装は(強くなくていいなら)それほど難しくありません。
CPUプレイヤーの要求仕様は「各局面における合法手を最低一つ返す」です。強い弱いにこだわらなければ、CPUプレイヤーの主な仕事は「合法手を返す」ことです。
そしてこの合法手はゲームエンジンから自動的に導き出すことができます。本アプリで実装したゲームエンジンでは、クライアント側で合法手をユーザーに示すために、合法手全てをカード情報に追加で返しています。この情報を使えば、全ての合法手の組み合わせを比較的簡単に生成できます。
なお、CPUプレイヤーも現状サーバー側で動作していますので、PvPと同じネットワーク上での対戦となります。将来的にはCPU(の一部)ロジックをクライアント側で実行するなどの改善は考えられそうです。
CPUプレイヤーの改良案
CPUプレイヤーを改良する方法の一つとして「先読み探索の実装」が挙げられます。Googleのアルファ碁で有名になったモンテカルロ木探索(Monte Carlo Tree Search、MCTS)アルゴリズムなどを応用することで、トレカでも先読みが可能になります。
先読みすることで、より高度なテクニックを使うことができます。例えばトレカでは「場に◯◯のカードがある場合、△△の効果が有効」などのルールがありますが、先読みしない場合、このコンボすら実現できません(※ヒューリスティックを使えば、単純なコンボぐらいなら実現できますが、それがCPUのクセと見破られた時点で勝率が落ちます)。先読みすれば「この△△の効果を利用するために、手札にある◯◯を場に出す」という判断ができるようになります。
探索の課題として大きく
- 不完全情報の補完
- 場面の評価
- 莫大な計算量
があります。
不完全情報とは相手の手札や互いのデッキなど未開示の情報のことで、先読みする上でこれらの情報を補完しないといけません。これも大きな課題の一つです。
場面の評価とは、現在(もしくはシミュレート中の将来)の情報を総合し、自分と相手のどちらが有利か、またどれぐらい有利(不利)かを定量的に判断するロジックです。これが不正確だと、いくら探索しても良い手を選ぶことが難しくなります。
また探索には莫大な計算量も必要となります。
例えば各場面の平均的な合法手数が8だとしても、10手先まで読むには「8^10=約10億」の組み合わせを調べる必要があります。10手先はかなり先と思われるかもしれませんが、さりとてゲーム終了までは程遠いです。
もちろんMCTSは全探索せずに効率よく最善手に近い手を見つける優れた方法ですが、仮にMCTSで合法手数を平均4に絞れたとしても、10手先には100万以上の組み合わせが存在します。
MCTSの理想は勝敗の決する末端の葉まで探索することです。現実には無理ですが、可能な限り計算量を抑えて深く探索するほうが強くなれます。
可能な限り計算量を抑えつつ、莫大な計算量を実行するGPUやクラウド環境などの検討が必要です。
これらの課題を解決するために、かなりの量のリサーチ&エンジニアリングリソースが必要になると考えられます。
そのため、現段階では実装を保留しています(スポンサーwelcomeです!笑)
まとめ
トレーディングカードゲームをオンラインで遊べる、スマホ、タブレット、PC対応のWebアプリを開発し、その内容についてご説明しました。
アプリURL
アプリURLは一般には非公開とし、ご興味のある方を対象に、お試し用として開示いたします。
こちらのフォームからご登録ください。
ご登録頂いたメールにアプリURLをお送りいたします。
また、今後アプリに関する重要な情報をご連絡をさせていただく場合もありますのでご了承ください。いつでも解除できますのでご安心ください。