通信対戦に必要だったこと

『トランプ・ナポレオン』で通信対戦を作成したときに必要だったことを書いておきます。オンラインマルチプレイヤーのゲームに必要なことは大抵同じであるので、他のものを作るときにも参考になると思います。

作成することは大きく分けて3つに分類できるでしょう。
通信を開始するところ、つなげてから切断するまでと切断時で分けています。一般的にオンラインゲームを作るといった場合はつなげてから切断するまでに注目されていると思います。オンラインゲームというのは通信しているときだけなので当然ですが、接続をするところと切断するところはゲームの面白さとかには関係ないですが重要です。この部分はどのように作るかが作成者の考えによって大きく変わるようなので、正解がなく難しいです。
以下の1と3が接続をするところと切断するところであり、2が通信中のところです。

  1. マッチメイキング
  2. 同期
  3. 切断
マッチメイキングはオンラインで一緒に遊ぶプレイヤーを見つけるための処理です。通信を確立する段階です。他のユーザーが知り合いの場合は別として、基本的には知らない人と遊びます。

ユーザー同士が一緒に遊ぶにはまず相手を探さなければなりません。インターネットの仕組みではIPアドレスがわかると通信ができるようになります。このIPアドレスを相手に伝えれば良いのですが、どうやって伝えるかが問題になります。

マッチメイキングでは特定の場所(固定されている)に自分の情報を登録し相手に見つけてもらうか、その逆を行います。自分と相手が同じところにアクセスして仲介してもらうことでIPアドレスを教えあうことになるわけです。
固定されている場所というのはサーバーになるわけですが、自前で用意しなくてもUnity Multiplayerではサービスとして提供されます。(今後有料になるかもしれませんが、まだわかりません。)

2つ目に同期ということを行いました。 これは複数の端末間でのゲームの進行状況の足並みをそろえるための処理です。通信自体は確立してからの話になります。
すべての状況を一致させるということは不可能ですが、大事な情報は一致させるということで同期が必要になります。リアルタイムで刻一刻と一致させる必要な場合もあれば、特定のタイミングで全員をそろえるという場合もあります。

『トランプ・ナポレオン』 のようなトランプゲームでは特定のタイミングで同期すれば良いです。誰が何のカードを出したかというのをカードが出されるたびに情報の共有を行い、進行させていけばうまく行きます。ランダム要素がないなら、カードの情報だけ揃えればゲームの状況は一致します。(このようなときはゲームの処理は誰が行っても同じ結果になるので、端末ごとに処理を行う分散型の設計が可能です。)
全員の進行状況をそろえる方法は単純です。先に処理が終わったユーザーは他のユーザーが終わるのを待っていて、全員の状況が同じであると判定されたら次に進むというようにしました。

最後に切断です。おそらく一番面倒なことです。どういったやり方が良いのかというのは自分で決めなければいけません。
切断が起こるタイミングはわからないので、起こる可能性のある箇所には対処を入れていく必要があります。変なタイミングで切断すると、アプリが動かなくなったりすることが結構起こります。頑張ってデバッグしましょう。

『トランプ・ナポレオン』 の対処については以前に記事にしました。切断されてもゲームが続くというように設計されています。このようなことを行うにはゲームを途中から行えるような再現機能かオンラインとオフラインの処理が融合しているような作りが必要です。
規模が大きい場合は切断時に一旦ゲームを終了して、その後同じ状況に復帰させるという作りが安全だと思います。(切り替えに時間がかかりますが、オンラインとオフラインの処理が完全に切り離せるので問題が置きにくいはずです。)
オンラインとオフラインの処理が融合しているというのは同期の部分をif文で分岐しているというだけです。 各ユーザーが処理すべきところもコンピュータで処理するように置き換えるようになっていれば問題ありません。コードがわかりにくくなるデメリットが大きいですが、即座に切り替わるというのはメリットです。 『トランプ・ナポレオン』ではこちらの方法で作られているため、コードが複雑化しています。