[ Golang ] CUI の通信ゲームを作ってみた – 技術選定 –

この記事は約5分で読めます。

Go言語で CUI の通信ゲームを作ってみたので、そのゲームの紹介と、作り方、作成時に得た知見をご紹介します。

本記事では、ゲームの紹介と通信ゲームを作るまでに決めることについて、解説します。

今回はガキ使のボードゲームで大きな笑いを取っていた

Gobblet Gobblers(ゴブレットゴブラーズ)

を作りました!

ゴブレットゴブラーズについては、分かりやすい記事があったので、ご紹介しマス

ゴブレット・ゴブラーズ | コマを被せて遊ぶ三目並べゲーム
『ゴブレット・ゴブラーズ』は大・中・小3つの大きさのコマを使って遊ぶ、2人用三目並べゲームです。クリティカルシンキングと記憶力を鍛えることができる、子ども用のよくできた三目並べゲームです。

制作物

通信ゲーム作成に関して考慮すべきこと

まず通信ゲーム作成で仕様として決める時に考えたことは主に以下です。

この仕様決めてからプログラムの構成を考えていきました。

  • どんなインターフェースにするのか
  • 通信方法
    • P2P or Server-Client?
    • リアルタイム通信の実現方法

今回の仕様

どんなインターフェースか

WebブラウザではなくCUIを選択しました。

理由は,Go言語のみでゲームを実現したかったからです。(wasm使えばGoでもできますが…笑)

フェーズ毎に考えていて、CUIの次はWebブラウザ用で作ってみようと思います。Webブラウザの方がフロントがリッチにかけるので、どちらもおすすめです。

通信方法

P2P or Server-Client

今回は、Server-Client方式を採用しました。

P2P型

ゲームをするユーザ二人がお互いに通信しあう方式です。ゲームのロジックは各ユーザで持っています。

  • メリット
    • 処理速度が早い
    • 製作者がサーバを管理をする必要がない
  • デメリット
    • ゲーム不正・正当性を保ちづらい
    • 外部通信が難しい

メリットはやはり、製作者がサーバを管理する必要が無くなることですね。

デメリットは、ゲームの正当性が保ちづらいことです。管理者がいないからです。

そして、プライベートネットワーク内(例:同じWFiでつながっている)なら通信できますが、グローバルネットワークだと、IPv4ではNAT越えをする必要があります。(現在IPv6も存在しますが、あまり普及しておりません)

今のゲーム(スマホ通信やPS4などのゲーム)ではほとんど使われていません

余談ですが、Winny(ファイル共有ソフト)やブロックチェーン などにP2P型の通信を採用しています。特にブロックチェーン では各ユーザがみんなで監視をする仕組みを導入しており、「P2P」や「非中央集権」という言葉が多く聞こえるようになりました。

Server-Client型

サーバクライアント型は、サーバがゲームのロジックをもっていて、クライアントは、サーバから送られるデータを使って、処理をします。この型はゲームするユーザ同士が直接通信せず、サーバを通してデータのやり取りをします。

  • メリット
    • ゲームの管理が容易
    • グローバルに
  • デメリット
    • リアルタイム通信の方式を
    • 外部通信が難しい

今回はこの方法を用いました。

P2Pだとインターフェースとロジックを切り分けるのが難しいからです。インターフェースは、初期ではCUI、後からWebにするつもりだったので、ServerClientにしました。

リアルタイム通信実現方法

ここが一番悩みました。

まず考えたのはUDP/TCPプロトコルです。UDPは受け取り側との接続は意識しませんが、TCPはコネクションが貼れるかをチェックします(3ハンドシェイク)。HTTPではTCPを利用しています

詳しい違いは以下のサイトをご参照ください。

「TCP」と「UDP」の違い|「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典
「TCP」と「UDP」の違いを何となく説明しています。

CUIだけだとUDPでも良いのですが、Webとの親和性を考えるとTCPが良いと思います。(Websocketなど、ほとんどTCPでの通信が主流です)

次に、TCPを使ったときの、通信方式です。

基本的にサーバークライアント型では、サーバーからクライアントへリクエストを送ることは難しいです。なぜなら、サーバはグローバルネットワークにあっても、クライアントはプライベートネットワークからリクエストする為、サーバからはクライアントの場所を特定することが難しいからです。

リアルタイムなwebアプリを実現する方法(ポーリング、Comet、Server Sent Events、WebSocket) - Qiita
リアルタイムなwebアプリを実現する方法について、サンプルコードを作成しながら検証する。 注意点 この記事で記載している実現方法はいずれもHTTPレベルの仕組みで実現されるものであり、サンプルコードはあくまで実装例です。 サンプルコ...
  • ポーリング
  • WebSocket
  • HTTP/2

ポーリング

定期的に、クライアントからサーバへリクエストを投げることで、リアルタイムもどきを実現します。もどきとしたのは、定期的→リアルタイムでなく一定間隔で更新されるものだからです。今までの通信方式から変えなくてもいい代わりに、リアルタイム性が低いです。

WebSocket

WebSocketはTCPコネクションをクライアントとサーバを繋ぎっぱなしにしておくことで、相互に通信します。Webの通信ゲームはこのWebSocketがよく使われます。TCPコネクションを繋ぎっぱなしにするのは、メモリ管理等も必要になるので、大規模に作る場合は注意が必要です。

以前、websocketを使ったLine風チャットアプリを作成したのでその記事も是非見てください。

Go言語入門~ WebSocket でチャットアプリ~

HTTP/2

今までHTTP/1.1プロトコルが使われていましたが、HTTP/2という最新バージョンが公開されていて、HTTP/2も利用され始めています。HTTP/2は標準で双方向通信が利用できます。まだ、全てで使えるわけでないので、注意が必要です。

WebでいうとgrpcなどがHTTP/2使われています。

どれを使うのか

今回はボードゲームでリアルタイムに関しては、そこまで重要ではありません。その為、管理が簡単なポーリングを選択しました。

作成まとめ

  • どんなインターフェースにするのか→CUI
  • 通信方法
    • P2P or Server-Client?→Server-Client
    • リアルタイム通信の実現方法→ポーリング

次回、実装について・知見を紹介していきます

それでは。

タイトルとURLをコピーしました