goからiOSまで一人でアプリ開発をしてたらいつの間にかマインクラフトエンジニアになった話

by [@mixiappwchr](https://twitter.com/mixiappwchr)

# おしゃべりマルチとは

今回UUUM株式会社様からアプリ開発の受託をうけ

[おしゃべりマルチ](http://ohmulti.com/)

![screen (2).png](https://qiita-image-store.s3.amazonaws.com/0/37731/b76336c7-a07c-b087-0563-ce92e2886be4.png)

という音声チャットをやりながら、[マインクラフトPE](https://itunes.apple.com/jp/app/minecraft-pocket-edition/id479516143?mt=8) など、ゲームのマルチプレイができるというアプリをリリースさせていただきました。

マインクラフトだけではなく、モンストや、白猫プロジェクト、その他マルチゲームで使ってもらえると楽しいアプリとなっています。


# 主な設計

今回 複数のサーバーをくみあわせて、音声チャットマルチプレイを実現しています。


## ３つのサーバーとアプリが連携
 
* APIサーバー
* 音声サーバー
* マイクラプロキシ兼リアルタイムイベントサーバー

の３つが協調して動きアプリにサービスを提供します。

本来マイクラマルチは同一内WiFIだと気軽にできるのですが、インターネット越しとなると、ルーターのポートを解放したり、なんだかんだ面倒な点が多いのですが、このアプリをいれると、そのような面倒な点が必要ありません。

![スクリーンショット 2015-09-17 0.47.52.png](https://qiita-image-store.s3.amazonaws.com/0/37731/0e62c7b6-7119-288b-3d70-d17291062457.png)

マイクラプロキシサーバーが通信を代理することで実現をしています。

このようなサービスはなかなかないと思うので裏側の構成を軽く説明します。

## 構成内容

* サーバー
    * API（Web兼務)サーバー
        * Go製
        * frameworkは最初[revel](https://revel.github.io/)にしようと思ったが、フルスタックすぎる点や起動周りが不透明なところがあったので、ミニマルで高速な[goji](https://github.com/zenazn/goji) をベースに、欲しい機能をのせてカスタムしたものを利用
        	* [goji](https://github.com/zenazn/goji) 
        * ORMは[gorm](https://github.com/jinzhu/gorm)を利用。基本的にORMにはあまり機能を求めないので、基本的な機能だけあれば十分。ただgormが結構癖があり、冷や汗もののバグをいくらか出して死にそうになった 。
        	* [gorm](https://github.com/jinzhu/gorm)
        * goのパッケージ管理は[gom](https://github.com/mattn/gom)を利用しています。便利。
    	* そんなにwebで公開する部分はないのだが、HTML,JS周りは以下を利用した比較的モダンな感じなフロントエンド周りはサーバー側と密にならない設計になっている
    		* [gulp](http://gulpjs.com/)
    		* [compass](http://compass-style.org/)
    		* [webpack](https://webpack.github.io/)
    		* [bower](http://bower.io/)
    		* [coffescript](http://coffeescript.org/)
    		
    * 音声サーバー
        * [asterisk](http://www.asterisk.org/)　ベース。サーバー側のチューニングはこれから
        * 大変だったのはシステムとの繋ぎこみが情報が少なく大変だった。
        	* [asterisk](http://www.asterisk.org/)　
        * チャットのセッションごとにサーバーを切り替え分散できるように制御することで、スケールを容易にしている。
        * 音声サーバーの追加、削除はgoで起動周りをラップしていて、自動でサーバー管理情報を自律的に追加、削除ができる。
        
        
        
    * マイクラプロキシ兼リアルタイムイベントサーバー
        * Go製
        * goでマインクラフトの通信をリレーすると同時にプロトコルを解析して、マインクラフトのイベントをハンドリングしたり、フィルタリングできる実装も行いました。
        * 同一ネットワーク内のWiFi通信を前提としている通信をインターネットでリレーするため、遅延にシビアで、かなりパフォーマンスのチューニングを行いました。
        * アプリ側に配置されたプロキシサーバーと連携することでマインクラフトのマルチ通信をプロキシする。NAT越えもこのプロキシサーバーがハンドリングしてルーター配下の端末も接続可能にしている。
        * UDPで,socket.io的なリアルタイムイベントサーバーとしても稼働させている。ただし、イベント周りはサーバー数をひとまず増やしたくなかっただけなのでそのうち切り離す予定
        * web のインターフェースも持っているので通常のhttpでの連携も可能
        * こちらも同じくセッションごとで分散＆自動でサーバー追加、削除する機構を備えています。

* iOS 
	* 今回の肝であるマインクラフトの通信をフックするプロキシをアプリ内にも実装    
	* 音声周りがあまりチューニングできてないので今後の課題。
	* いつも通りCircle CIからのDeloyGate自動配布
	* 残念ながらSwiftはいろいろな理由で開発効率が遅くなるため、開発スピード重視の場合はまだあまり利用しません。Swiftいいですけどね(コンパイルの遅さとか、バージョンアップごとに毎回コンパイルエラーが多発するとかとかがなければ)





* インフラ
	* すべてAWSを利用。ひとりでもAWSがあればできるもん！
    * Ansibleでの管理。デプロイも現状はAnsibleでまかなってる。
    * サーバー監視はNew Relicを当初入れていたが、マインクラフトプロキシや音声サーバーなど独特の監視項目が必要なため,zabbixでの自前監視に入れ替えた。
    * Amazon SNS便利
    
    
    
* 数値解析
	* Google Analyticsに加えて、それほどまだ規模が大きくないのでfluentdで集めたログをmongoDBにためて解析をおこなっている
	
	
# 今回の開発の要所

## マインクラフトPEの技術という誰も登らない山を登る

今回の肝ですが、本当に今回の案件がなければ仕事でこのような技術への挑戦ができる機会などなかったはずです。本当にUUUM株式会社さんには感謝しております。

### マイクラのプロトコル解析を楽しむ

ただマインクラフトの通信をリレーすればいいのではなく、マインクラフトの通信がどのようになっているかを把握しながら、リレーする必要があるため、どのようなプロトコルなのかパケットをながめたり,マインクラフトのマルチサーバーのオープンソース実装である

[pocketmine](https://www.pocketmine.net/)

のソースコードをながめたりと解析にいそしみました。

基本バイナリをながめながら、これは何の指示なの？というのを一つ一つ読み解いていきます。しかもパケットは、カプセル化されてたり、圧縮されてたり、数パターンあるため、パケット一つが一つの意味を持つわけではなかったりします。

ちなみにpocketmineはなんとphpで実装してあり、なかなか面白い実装しているのでながめてみると楽しいです。


![ダウンロード.jpeg](https://qiita-image-store.s3.amazonaws.com/0/37731/89a0bc76-ae05-434d-22bf-163b68ef2a20.jpeg)


と、あーだこーだしてたら、マインクラフトエンジニアとなっていました。
ほぼ通信の仕方を把握できているため、いろんなものが作れそうです。

マイクラPEのプロトコルがどのようになっているかは別途時間ができたら記事にでも書こうと思います。

### マインクラフトPE自体の大幅アップデートで死にそうになる
リリース直後にマインクラフトPE自体の大幅アップデートがおこなわれ、せっかく解析したプロトコルが変わってしまい、苦労して実装した機能が動かなくなるという出来事がありましたが、すでにパケット見ただけで大体このパケットだなとわかるまでなっていたので、修正はそれほど時間はかかりませんでした。

そのうちgo製のminecraftマルチサーバーを実装したい。
	
## goって楽しい
	
### 早い、やすい、うまい、楽しい
細かいクローラーなど細かいものは作ったことはありましたが、実際のプロダクションで作ったのは初めてです。

goを採択した理由は,速度が速く、またリソースも少なくて済むため、サーバーコストを軽減できます。起動やデプロイなど単にプログラムの速度以外も早い早い。

自分自身の話ですが、今回フリーランスでの開発の受託で、インフラまですべてまるっと担当することによりコスト感をきちんと考えて動こうと決めました。
会社勤めの時は直接インフラ費用などをみることがなく、なかなか意識するタイミングがなかったのですが、今回その点は勉強しながら良い経験になりました。
そして想定通りサーバー負荷は驚くほど軽くリソースはあまりかさばらないため、頑張った甲斐がありました。

![ダウンロード (1).jpeg](https://qiita-image-store.s3.amazonaws.com/0/37731/fc5e668f-981a-707b-031c-08554de65162.jpeg)


そのほかに、goを触るのが本当に楽しいという点が選んで良かった点かなと思っています。独特な部分が多く、なかなかとっつきづらい点があるのですが、それが逆に楽しさにつながっています。まわりをみるとperlエンジニアが同じように楽しさを感じている気配もあり、なにか刺さる点があるのだろうかと思ったり。

また今回マインクラフトのプロキシの開発もgoを使うことで並列処理やバイナリの処理なども非常にしやすく開発スピードも早かったです。

サーバー実装から運用周りもひととおり固まったため、今後の案件でも活用を進めていければと思っています。

## 何を作るかの議論の大切さ

今回このサービスを作るに至るまでに、何を作るかはいろいろ議論しました。プロトタイプも作ってみて、それでいいのかどうかなどもやり、作って捨てたコードもいっぱいあります。その結果この方向性に決まったのですが、チーム内でその点を大事に企画を進められたことは、非常によかった点でした。

![ダウンロード (2).jpeg](https://qiita-image-store.s3.amazonaws.com/0/37731/40a91e69-8cd3-7b61-8f96-b1738f924c7a.jpeg)


良いチームメンバーに恵まれるとその点の議論がはやい。



## スピードあふれる開発期間
	
* 開発期間
	* プロジェクト構想を練っている時間を合わせると３ヶ月ですが、実際の実装期間は2ヶ月ほど。また別の大きな案件をもう一つ持っているので正味１人月ほどの期間でした。
	
* 開発人数
    * 企画          2名
    * デザイナー     1名   　
	* サーバーサイド　      俺 
	* webフロントエンジニア 俺
	* iOSエンジニア        俺
	* インフラ構築         俺

はい、死にそうでした。

まあでも開発一人だけで大変なのではと思うでしょうが、基本的に新規サービスを立ち上げる場合、一人で開発するパターンが多いです。

今回はもうちょっといても良かったのですが、メリットとして一人でやることで、すべての設計をサーバーサイドからアプリ、インフラまで一気通貫で考えて作り込むことができるため、コミュニケーションコスト０で最速でサービスリリースまで持っていくことが可能です。

当然過去の積み重ねがあるため設計にあまり迷うことがないこともあるのですが。今回はサーバーサイドも３種類が協調して動き、またマインクラフトのプロトコルをリレーするという難しい点もあったため、サービスすべてを一人でハンドリングしながら作り上げる方が圧倒的にはやかったです。

ただし、リリースしてしまうとやることが増えるため、人数が一人ではとても対応できません。



なので


# そろそろ、だれか手伝っていただけないでしょうか。


おしゃべりマルチプロジェクト及びUUUM株式会社では、普段やらないような技術を最新の技術で乗り越えてくれるエキサイティングなエンジニアを募集しております。

ほかにも今までにないサービスを作っていきますので、一緒に新しいサービスを作り上げてくれるエンジニアをお待ちしております！


[エンジニア募集！](http://www.uuum.jp/recruit/)



ちょっとした続きの記事も書きました。

[ひとりぼっちのサービス開発における技術選択の遷移と戦略](http://qiita.com/appwatcher/items/057ebb08c0a5c89270d6)
	
	

##### appwchr post
----

[次世代のスーパーエンジニアたちも学ぶ！マインクラフトで触れる技術たちその1](http://qiita.com/appwatcher/items/05513e170b42b09ecd9a)

[あんなすごいエンジニアともであえるかも？？Qiitaユーザーが集まるSlack Teamを作ってみたよ！](http://qiita.com/appwatcher/items/00faadbf02f691186a54)

[goからiOSまで一人でアプリ開発をしてたらいつの間にかマインクラフトエンジニアになった話](http://qiita.com/appwatcher/items/6c0280cda9c4c8b3c65f)

[API開発の効率化の架け橋！APIのStubサーバーを導入して,API開発に効率化、スピード化、柔軟性を手に入れよう！](http://qiita.com/appwatcher/items/49807e72d9600db7196d)

[アプリエンジニアから見てAPI設計において気をつけてもらえるとうれしいこと](http://qiita.com/appwatcher/items/4a0dd09c393cc70d961a)

[Goodbye... Jenkins... Jenkinsを卒業してお手軽CI! iOSもAndroidもCircle CIでアプリのCIを回そう](http://qiita.com/appwatcher/items/4cdf39804d6e46ab7af5)

[まだTestFlight使ってたの？急げ！終了目前のTestFlightから,今すぐにiOSもDeployGateに移行しよう！移行パターンも紹介するよ。](http://qiita.com/appwatcher/items/632460e15fbdb81b7a71)

[Swiftを使ってみて直面した闇。現時点で現場でSwiftを採用すべきかどうかの判断材料](http://qiita.com/appwatcher/items/50295e82ab0095902aaa)

[iOSの開発をする上で絶対に使うべき！外せない！webサービス、開発ツール集【完全版】](http://qiita.com/appwatcher/items/07a3babcb9b6cefb307e)

[注目のiBeacomなどの波に乗り遅れないために！iOSのBluetooth開発を容易にするライブラリを書きました。]
(http://qiita.com/appwatcher/items/7491beffd7260b713542)

[まだまだあった！iOSの開発を劇的に改善する最新のwebサービス、開発ツール集１]
(http://qiita.com/appwatcher/items/f0024fe2ac34da345f04)

[さらに快適なアプリ開発を！iOSの開発をもっと劇的に改善する最新のwebサービス、開発ツール集2]
(http://qiita.com/appwatcher/items/c15d7311e71b4c2b77f1)

[スパゲッティから脱出！iOS開発における遷移の問題をすっきり解決する便利ルーティングライブラリをご紹介]
(http://qiita.com/appwatcher/items/259e8d13fff0547e90af)