アーキテクチャをスマートに。

株式会社ネオジニア代表。ITアーキテクトとしてのお仕事や考えていることなどをたまに綴っています。(記事の内容は個人の見解に基づくものであり、所属組織を代表するものではありません)

ネオ富豪の開催にあたって(3)クイックプレイ〜ランディングページ

マスタサーバの実装

そんなこんなで、マスタサーバの実装にとりかかりました。
Web上で簡単に大富豪をプレイできる、というのが今回のアーキテクチャのすごいところなので、クイックプレイという機能をつけようと思いました。要するに、モバイルでもPCでも、特別なアプリをインストールすることなく、すぐ簡単にプレイできるんだから、トップページからすぐにプレイ画面にアクセスすることができる機能を付けることによって、より多くに人に利便性を感じて欲しいと考えたからです。
さてここからは技術者向けの内容になりますが、マスタサーバの内部構成を紹介させていただきます。
まずベースとしてトランプカードのクラス実装があります。これはナポレオンアプリのC++ソースコードをほぼそのままC#にコーディングしなおしたものとなっています*1。つぎに、大富豪のゲームとしての概念をクラス化したモジュールがあり、これがゲームエンジンとしてのメインモジュールとなっています。テストコードもちゃんとあります。やっつけ気味なのであまり網羅できていませんが。(笑
最後に、ゲームエンジンをWebインタフェースでラップするためのモジュールがあり、これがプレイルームの管理から WebSocket ハンドラまでの役割を担っています。ホントはプレイルームの実装はWebに依存しないのでさらに分離できると思います。今後の課題。

大富豪マスタサーバのソフトウェアとしての部分は、ネオ富豪という固有名詞を極力とっぱらい、オープンソースにしたいと思っていました。ところが後述のランディングページがあるため、サイトを2つに分けざるを得ませんでした。こういったサイト分割構成でURL設計をしたことがなかったので、ものすごく迷いました。

考え方としては、抽象度を一つ上のレベルに引き上げるようなイメージです。
すなわち、大富豪をWeb上で対戦するための汎用的なマスタサーバというものがあり、それを今回のネオ富豪という企画にあてはめて具現化して使用する、というイメージです。(余談ですが、オブジェクト指向設計ではこういった概念レベルの抽象化がとても重要だと思ってます)

結果的に、マスタサーバとネオ富豪公式サイトの棲み分けとしては、プレイルームとプレイ画面、Websocketといった
ゲームプレイに関する根幹の部分がマスタサーバ、それ以外が公式サイト、という分け方になっています。

参考までに、クイックプレイが出来るまでの所要時間は55時間でした。完成したのは12月5日でした。実際にはその後も機能拡張したりリファクタリングしているので、その倍はかかっていると思います。
ソースコードここで公開しています。

プロトコル説明ページ

大会に参加してもらう人は、大富豪のプログラムを作るにあたって、どういう仕様で作ればよいのか当然ながらまったく知りません。
そこで、ネオ富豪のプログラム仕様をわかりやすく説明するページが必要だと考えました(実質的には、プログラム仕様というより、プロトコルの仕様説明が大半になりました)。

何か既存のプロトコルを参考にしたわけではななく、全て独自に発案しました。
といっても、全然大したもんじゃないんです。
種明かしをすると、単純にゲームマスターのイベント発行をそのまま通信のタイミングに置き換え、イベント受信側となるプレイヤークラスの引数をそのまま構造体としてJSON展開しただけです。
カードの表現方式は、実は今回のために発案したものではなく、ナポレオンアプリのデバッグログの出力仕様をそのまま使っているんです。

最初のプログラム仕様ページを書き終え、azureにデプロイしたのが、12月9日頃でした。このあと12月12日〜15日まで台湾旅行を強行したため一旦開発が止まります。

認証

ネットワークで接続し、それぞれのクライアントを識別しながら制御しなければいけないため、クライアントを認証する仕組みが必要だと考えました。
IDとパスワードをマスタ側から発行しておき、接続時にそれを送ってもらうことで認証しようかと考えました。
しかしながら、セキュリティと利便性は相反するものです。
プレイヤープログラムに本来の目的とは関係のない、余計な処理の実装を強いることになるのは極力避けたいという思いと、そこまで大規模な大会にはならないであろうから、セキュリティの優先順位は低くてもよさそうだという状況を鑑みて、認証の仕組みは実装しないことにしました。
また、IDパスワードの管理の手間が増えるのが面倒だったという理由もあります。

プレイルーム

ネット対戦を実現するにあたり、1つのサーバでいくつものゲームを同時に取り扱えるようにしたいと考えました。そこで、よくある将棋や麻雀のネット対戦のサイトで一般的な概念として、待合室と部屋、という考え方を実装することにしました。
まず、あらかじめ決められた数のプレイルームを用意しておき、Webページ上でそれらの一覧が見れるようにします。参加者がプレイルームに入室すると、ゲームに参加したことになり、希望のメンバーが揃うとゲーム開始となります。プレイルームには、参加者のプレイヤー以外に、マスタサーバに組み込まれているCOMプレイヤーも居ます。その他には、ゲームマスターが必ずひとつ居て、ゲームの進行や審判役を司っています。また、観戦者がプレイルームに入ってくるかもしれません。観戦者は全員の手札が見れる状態にありますが、観戦者に手番がまわることはありません。
こういった概念をクラスとして実装し、それらのオブジェクトがお互いに連携しあって動作するようになっています。

以下のようにクラス構成になっています。(簡単化のため複雑な構造を省略して表記しています)

  • プレイルーム
  • ゲームマスタ
  • プレイヤー
    • COMプレイヤー
    • 参加者のプレイヤー
  • 観戦者

実装にあたっては、観戦のための仕組みはあとまわしにし、クイックプレイに必要な構成のみ先行して実装し公開しました。それが12月19日ごろです。

ランディングページ

当時ランディングページと言ってたのは、現在のネオ富豪トップページのことです。
WebArchiveによるキャッシュ

実は最初からここまで作るつもりありませんでした。
でもせっかく作るんだったら、Webサービスとして完成させるところまでやらないともったいない!と思い、今回の企画の言い出しっぺのライターさんに相談して(というか巻き込んで)、ランディングページのデザインをお願いしました。
サイトコーディングは、レスポンシブデザインに対応したかったので自社で(自分で)やるつもりでした。
そして出来上がってきたカンプ(デザイン見本)をベースにパーツを切り出してもらい、ASP.NET MVC でコーディングしました。(単なるWebページなので、ASP.NET MVC を使う必要もなかったのですが、開発環境を統一した方が何かと融通が効くし、Azure Webサイトへのデプロイが簡単だったので、そうしました)
もともと Bootstrap を使っていたので、そっちの画面サイズ分割にしたがって4パターンのレイアウトを考え、丸1日がかりでCSSコーディングしました。(1200px以上、1199〜970px、969〜768px、767px以下 の4パターン)
とてもいい物が出来たと思っています。

ついに会社のサブドメイン neof5.neogenia.co.jp も設定し、公式サイトとして12月21日(土)に公開。やっとそれっぽくなってきました。

*1:ナポレオンアプリのソースコードはここで公開しています。https://bitbucket.org/lobin_z0x50/jnapoleon