Objective-C
Go
iOS
minecraft
asterisk

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

More than 1 year has passed since last update.

by @mixiappwchr


おしゃべりマルチとは

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

おしゃべりマルチ

screen (2).png

という音声チャットをやりながら、マインクラフトPE など、ゲームのマルチプレイができるというアプリをリリースさせていただきました。

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


主な設計

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


3つのサーバーとアプリが連携


  • APIサーバー

  • 音声サーバー

  • マイクラプロキシ兼リアルタイムイベントサーバー

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

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

スクリーンショット 2015-09-17 0.47.52.png

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

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


構成内容



  • サーバー


    • API(Web兼務)サーバー


      • Go製

      • frameworkは最初revelにしようと思ったが、フルスタックすぎる点や起動周りが不透明なところがあったので、ミニマルで高速なgoji をベースに、欲しい機能をのせてカスタムしたものを利用



      • ORMはgormを利用。基本的にORMにはあまり機能を求めないので、基本的な機能だけあれば十分。ただgormが結構癖があり、冷や汗もののバグをいくらか出して死にそうになった 。



      • goのパッケージ管理はgomを利用しています。便利。

      • そんなにwebで公開する部分はないのだが、HTML,JS周りは以下を利用した比較的モダンな感じなフロントエンド周りはサーバー側と密にならない設計になっている





    • 音声サーバー



      • asterisk ベース。サーバー側のチューニングはこれから

      • 大変だったのはシステムとの繋ぎこみが情報が少なく大変だった。



      • チャットのセッションごとにサーバーを切り替え分散できるように制御することで、スケールを容易にしている。

      • 音声サーバーの追加、削除は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

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

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

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

ダウンロード.jpeg

と、あーだこーだしてたら、マインクラフトエンジニアとなっていました。

ほぼ通信の仕方を把握できているため、いろんなものが作れそうです。

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


マインクラフトPE自体の大幅アップデートで死にそうになる

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

そのうちgo製のminecraftマルチサーバーを実装したい。


goって楽しい


早い、やすい、うまい、楽しい

細かいクローラーなど細かいものは作ったことはありましたが、実際のプロダクションで作ったのは初めてです。

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

自分自身の話ですが、今回フリーランスでの開発の受託で、インフラまですべてまるっと担当することによりコスト感をきちんと考えて動こうと決めました。

会社勤めの時は直接インフラ費用などをみることがなく、なかなか意識するタイミングがなかったのですが、今回その点は勉強しながら良い経験になりました。

そして想定通りサーバー負荷は驚くほど軽くリソースはあまりかさばらないため、頑張った甲斐がありました。

ダウンロード (1).jpeg

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

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

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


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

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

ダウンロード (2).jpeg

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


スピードあふれる開発期間



  • 開発期間


    • プロジェクト構想を練っている時間を合わせると3ヶ月ですが、実際の実装期間は2ヶ月ほど。また別の大きな案件をもう一つ持っているので正味1人月ほどの期間でした。




  • 開発人数


    • 企画 2名

    • デザイナー 1名  

    • サーバーサイド  俺

    • webフロントエンジニア 俺

    • iOSエンジニア 俺

    • インフラ構築 俺



はい、死にそうでした。

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

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

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

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

なので


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

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

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

エンジニア募集!

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

ひとりぼっちのサービス開発における技術選択の遷移と戦略


appwchr post


次世代のスーパーエンジニアたちも学ぶ!マインクラフトで触れる技術たちその1

あんなすごいエンジニアともであえるかも??Qiitaユーザーが集まるSlack Teamを作ってみたよ!

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

API開発の効率化の架け橋!APIのStubサーバーを導入して,API開発に効率化、スピード化、柔軟性を手に入れよう!

アプリエンジニアから見てAPI設計において気をつけてもらえるとうれしいこと

Goodbye... Jenkins... Jenkinsを卒業してお手軽CI! iOSもAndroidもCircle CIでアプリのCIを回そう

まだTestFlight使ってたの?急げ!終了目前のTestFlightから,今すぐにiOSもDeployGateに移行しよう!移行パターンも紹介するよ。

Swiftを使ってみて直面した闇。現時点で現場でSwiftを採用すべきかどうかの判断材料

iOSの開発をする上で絶対に使うべき!外せない!webサービス、開発ツール集【完全版】

注目のiBeacomなどの波に乗り遅れないために!iOSのBluetooth開発を容易にするライブラリを書きました。

まだまだあった!iOSの開発を劇的に改善する最新のwebサービス、開発ツール集1

さらに快適なアプリ開発を!iOSの開発をもっと劇的に改善する最新のwebサービス、開発ツール集2

スパゲッティから脱出!iOS開発における遷移の問題をすっきり解決する便利ルーティングライブラリをご紹介