マルチプレイゲームサーバー SmartFoxServer2X の構築

## 通信対戦のゲーム制作カリキュラム
 社員研修としてゲームを制作するカリキュラムが社内にあるのですが、次のステップとして通信対戦(ネットワーク対戦)をさせるカリキュラムを考えています。今後ゲームに限らずVR空間でのマルチプレイ等への展開にも必要な技術だと思います。
　P2P(peer to peer)もテーブルゲーム程度ならいいのですが、サーバーとクライアント機能を装備するのは研修としてはハードルが高いなと思っていました。また、NAT超えの問題とかもありそうで、ネットワークへの接続環境も考慮しなくてはならないです。また、P2Pでは３者対戦以上だとトラフィックも複雑になり通信も重くなりそうです。
　そう考えると、マルチプレイ対応のゲームサーバーに、API接続するのが現実的で理解もしやすいかもしれません。

## ゲームサーバーのクラウドサービス
　社内では受託業務として多くの通信対戦ゲームも多く手掛けてきました。ガラケー時代からネットワーク対戦ゲームはいくつかリリースしていますが、当初は各クライアントがサーバーに対してプログラムで定期的にhttp通信を行い、データのやりとりをしていました。
　その後、ミドルウェアを使用する形が多くなり、コネクションの維持など複雑なことを考えずに実装できるようになりましたが、スマホのソシャゲー時代が来ると、大規模なデータベースとの連動が必須となり、オリジナルのゲームサーバーを構築しました。
　現在は、クラウドサービスを使うことが主流になりました。代表的なサービスが Photon ですが、他にも下記のようなゲームサーバーのクラウドサービスがいくつもあります。

https://www.photonengine.com/ja-jp

https://www.monobitengine.com/

https://aws.amazon.com/jp/gamelift/

https://azure.microsoft.com/ja-jp/products/playfab

https://heroiclabs.com/nakama/

AWSのGame Liftなどは常に発展途上のサービスで、ゲーム構築に携わった弊社社員も苦労した(≒サービスをデバッグした)ようです。

## フリーのマルチプレイゲームサーバーは無いのか？
　研修用なので必要な機能は限定します。ロビー(接続待ち)とマッチング機能、接続したクライアント間のリアルタイムでのデータのやりとり、チャットもできればいいかな位です。社員数が50人程度なので、評価など万一の際に30人同時接続(30CCU)できれば十分です。APIも整備されていて、クライアントは、Unity3DやJavaScriptでアクセスできることを要件とします。
　Photonは社内利用実績もあり、クラウドサービスとしては使いやすく、上記要件も満たしています。料金もトライアルは20CCUまでは無料です。ですが、本来は開発テスト目的でのトライアル無料であり、先々使うであろう研修目的ではどうかと思われます。有料契約ですが、12ヶ月間で100CCUの料金が２万円というのも魅力的ではありますが。
　オープンソースのゲームサーバーとしては、nakama サーバーがありました。他にはGitHubなども探してみましたが、あまりゲームサーバーとして実績やドキュメント、APIの整備されているものは見当たりませんでした。

## SmartFoxServer 2X Community Edition
　そんな中で、SmartFoxServerというのを見つけました。サーバーにインストールするアプリケーションです。採用実績もWEBサイトに掲載されていますが、カードゲームからMMO,レーシングゲームまでリアルタイムでのやりとりにも問題なさそうに思われます。管理画面もWEBインターフェースでわかりやすいように見えます。加えて、サーバー側でスクリプトも動作させられるようなので、発展性もありそうです。
　API等のドキュメントも豊富に掲載されているようです。サンプルプログラムも各言語で提供され、C#(Unity3D)やHTML(JavaScript)でも整備されています。
 SmartFoxServerには、Basic/Pro/2X のエディションがあり、機能比較表もあるのですが、Proと2Xの差異は少なくて何が違うのかよくわかりません。2Xはクラウドホスティングサービスもあるようなので、こちらはクラウド対応にしたバージョンなのかなと予想されます。
　SmartFoxServerは有償のアプリケーションですが、Basic/Proには評価版として20CCUまで無料で使用できるようです。さらに、2Xエディションは100CCUまではCommunityEditionとして商用・非商用含め無料で使えるそうです。(表記など条件有り)

https://www.smartfoxserver.com/

　見た限り、要件に合致するあまりに完璧なゲームサーバーなのに、100CCUまで商用含め無料なんて素敵すぎます。ですが、ほとんど知られていない、日本語での評価記事や質問が全く無いのが気になります。イタリアの会社のようですが。
　なので実際にインストールしてみて評価しようと思います。

## インストール
 今回はLinuxサーバー(Rocky Linux9.2)にインストールします。
 smartfoxserverの[ダウンロードページ](https://www.smartfoxserver.com/download/)からファイルのダウンロードを行います。登録などは不要です。
![image1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59033/5a100a49-a511-6795-0025-38b231ba95b7.jpeg)

```
# wget https://www.smartfoxserver.com/download/get/307
# mv 307 SFS2X_unix_2_19_0.tar.gz
# tar xf SFS2X_unix_2_19_0.tar.gz
# cd SmartFoxServer_2X
# ./sfs2x-service start
```
これだけでゲームサーバーが起動します。何て簡単な！

## 管理画面
　http://IPアドレス:8080 で、ポート8080にブラウザでアクセスします。このポートにアクセスが出来るように、Linuxのファイアーウォールは停止しておきます。
![image1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59033/de464d6c-49e4-9f78-ce69-e99126982ee5.jpeg)
 管理画面にアクセスするにはAdministration Tool 2x のリンクをクリックします。
![image1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59033/d7d858c9-935b-b0d7-fc09-d0df2353b68c.jpeg)
 初期パスワードとして管理者IDと同じsfsadminを入力し、connectボタンを押してログインします。
![image1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59033/2c21ea20-ccbc-107d-8a83-a5b3b2e40092.jpeg)
　管理画面もタブできれいに分類してあり見やすいです。

## サンプルプログラムのインストール
　それでは次にサンプルプログラムを動作させようと思います。SmartFoxServerのDownloadページからEXAMPLEのタブをクリックすると、各種プラットフォーム(Unity/Godot/HTML/iOS/Android/Windows)に対応したサンプルプログラムが用意されています。
　今回は動作確認としてお手軽に検証できそうな、HTML版をインストールしてみます。サンプルにはいくつかのプログラムがフォルダ分けされて格納されています。ドキュメントと照らし合わせ、Trisという３目並べをインストールしてみます。
 Trisのサンプルプログラムは以下のような構成になっています。
```
├─deploy
│  ├─client
│  │  ├─css
│  │  ├─images
│  │  ├─libs
│  │  └─scripts
│  └─extensions
│      ├─Tris
│      └─Tris-JS
└─source
    └─java-extension
```
　まずはソースプログラムを一部修正します。先頭に近い部分に記述されている、 config.host 部分のゲームサーバーのアドレスを 127.0.0.1(localhost)から、ブラウザからアクセスできるIPアドレスまたはホスト名に変更します。

~~~ deploy/client/scripts/main.js
function init()
{
	trace("Application started");

	// Create configuration object
	var config = {};
	config.host = "127.0.0.1";  // <-ここをサーバーのIPアドレスまたはホスト名に変更
	config.port = 8080;
	config.zone = "BasicExamples";
	config.debug = false;
~~~
　次に管理画面のタブから「Servlet manager」をクリックしてWEBサーバーのフォルダを表示します。
　▶ROOT の階層を開き、▶exsamples をクリックして、「＋」を押してフォルダ「Tris」を作成します。
![image1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59033/ce9d49a8-628d-ff07-7484-d8035686e325.jpeg)
 SmartFoxServerのインストールされたフォルダ(SmartFoxServer_2X)の下層の、www/ROOT/exsamples/Tris フォルダに、Trisサンプルプログラムのclientフォルダの中身を、sftpまたはシェルで下層フォルダごとコピーします。管理画面のServlet Manager でもアップロードできますがフォルダはコピーできないので作成しながらなので面倒です。

　最後に、SmartFoxServerのインストールされたフォルダ(SmartFoxServer_2X)の下層の、extension フォルダに、TrisサンプルプログラムのextensionフォルダのTris-JSフォルダを、sftpまたはシェルでフォルダごとコピーします。管理画面のExtension Manager でもTris-JSフォルダを作成すればアップロードできます。

## ネットワーク対戦ゲームの検証
　サンプルプログラムがインストールできたら検証です。ブラウザで下記アドレスを開きます。
 http://IPアドレス:8080/exsamles/Tris-JS/
![image1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59033/39e9fa59-c9c9-2f61-c02b-8ee68ac0ea6a.jpeg)
 「Connect」ボタンを押してエラー表示されなければ正常に接続されていますので、任意の名前を入力して「Login」ボタンを押します。
 ロビー画面に遷移します。
![image1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59033/33049451-d89b-9d4a-7ccb-8c1404ce940e.jpeg)
　ロビー画面では「Start New Game」を押して、新しいゲームの「対戦部屋」を作ります。
![image1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59033/50884ed4-2978-fefc-1a25-f883cf96d5c8.jpeg)
 対戦相手待ちの画面に遷移します。
![image1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59033/e0cbbb88-1f35-d443-eff5-b65b3b45a79d.jpeg)

 ここで、別のブラウザまたは別のタブを開いて、別のユーザーとしてログインします。
![image1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59033/465665e2-22ea-a1e5-6fb1-fbc6b3ee3bf1.jpeg)
 「対戦部屋」という名前が表示されて、ゲームに参加できる状態であることが確認できます。
　ここで「対戦部屋」をクリックして選択し、「Play」ボタンでゲームに参加します。
![image1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59033/e7e744bd-5240-4068-b116-0b2b99981771.jpeg)
 これで通信対戦のゲームがプレイできるようになりました。
　ゲームサーバーも一通り機能するようで、チャットも可能ですし、「Watch」ボタンでゲーム観戦することもできます。

## まとめ
　マルチプレイゲームサーバーとしては上出来です。機能も一通り揃っていますし、APIも整備されてドキュメント充実しているようです。もちろん英語ですが。
　どこまで接続負荷に耐えられるのかは未知数ですが、研修用としては問題無いと思われます。いや、研修用だけではもったいないので、実使用で使えそうかも検討したいですね。

　ざっと構築手順を記載しましたが、実際にはいくつかつまづきました。一番時間を取られたのが、ブラウザのキャッシュです。main.jsファイルを書き換えて、ページをリロードしても反映しないのです。リロードではなくキャッシュを明示的にクリアする必要がありました。どのブラウザ(Chrome/FireFox/Edge)でも同じだったので、jsファイルはキャッシュされる仕様なのですね。