大規模ゲーム開発で存在感を高めるErlang/Elixir ─ Nintendo Switch™とロマサガRSの事例から
大規模なゲーム開発で、プログラミング言語Erlang/Elixirの存在感が増しています。Nintendo SwitchのErlang活用事例と、ロマサガRSにおけるElixirの導入事例について、アカツキ島崎清山さんに解説してもらいました。
2019年6月1日、永田町JA共済ビルにて、Erlang & Elixir Fest 2019が開催されました。Erlang/Elixirを利用する開発者らを集めて国内で開催されるメインイベントとしては、2017年のElixir Conf Japanから数えて、今年で3回目を迎えたことになります。
参加費6,000円の一般枠が事前登録で埋まり、当日の来場者も150人を超えたErlang & Elixir Fest 2019は、過去2回にも増してErlang/Elixirの可能性を強く感じさせるイベントとなりました。セッションも全体を通して多彩でしたが、中でも目を引いたのは、ゲーム開発における存在感でしょう。
基調講演では、Nintendo Switch向けのプッシュ通知システムNPNS(Nintendo Push Notification Service)で、Erlang製のメッセージングサーバejabberdがどのように活用されているかが、任天堂の渡邉大洋さんにより紹介されました。
また、アカツキの梶原星平さんと関山友輝さんからは、スクウェア・エニックスの配信ゲーム「ロマンシング サガ リ・ユニバース」(ロマサガRS)における実践的なElixirの導入事例が語られました。
なぜ、こういったゲーム開発、それもユーザ数が数百万から数千万を超えるような大規模なゲーム開発において、Erlang/Elixirが選ばれるのでしょうか?
Erlang & Elixir Festを主催するJapan Elixir Associationの代表であり、アカツキでロマサガRSにおけるElixir導入にも関わった島崎清山さんへの取材を通して、ゲーム開発の現場でErlang/Elixirが選択される理由を探ります。
- そもそもErlang/Elixirとは
- ロマサガRSの裏側を支えるElixir
- Nintendo Switchのプッシュ通知システムを支えるErlang
- さまざまな大規模ゲーム開発で採用されるErlang/Elixir
そもそもErlang/Elixirとは
そもそもErlang/Elixirとは、どのようなプログラミング言語なのでしょう。まずはっきりさせる必要があるのは、「Elixir」と「Erlang」の2つは、それぞれ別々のプログラミング言語だということです。では、なぜErlang/Elixirと併記して語られるのでしょうか?
堅牢さと並行性を兼ね備えたErlang
Erlangは、スウェーデンの通信機器メーカーであるエリクソンのもと、計算機科学者のジョー・アームストロング(Joe Armstrong)らによって開発された言語です。
通信アプリケーションの開発を目的としていることから、プログラミング言語のレベルで堅牢性と並行性を実現しやすいように設計されているのが特徴です。その歴史は1986年にまで遡りますが、現在でもWhatsAppやLINEなど、有名なネットワークサービスの裏側で利用されています。
Erlangのコードは、当初はProlog製のインタプリタで実行されていました。しかし、実用性の問題から、コンパイルして仮想マシンで実行する仕組みが1992年に開発されます。このErlang VM(Erlang用の仮想マシン)上で動作する、Erlangとは別の新しい言語として2012年に誕生したのが、Elixirです。
つまり、ElixirとErlangの関係は、仮想マシンを利用する別の言語という意味で、KotlinとJavaの関係に似ています。KotlinがJavaと完全に相互運用が可能であるように、ElixirからもErlangの力を完全に利用できます。Elixirもまた、Erlangと同様の堅牢性と並行性を兼ね備えているということです。
幅広い現場で受け入れられたElixir
Elixirを開発したジョゼ・バリム(José Valim)は、Ruby on Railsのコミッタだったこともあり、Rubyに似た構文でErlangの長所を備えた言語として、Elixirを開発したと言われています。
ジョゼはさらに、パイプ演算子、メタプログラミングのためのマクロなど、主にWebアプリケーションの開発で生産性に寄与するさまざまな機能を、Elixirに取り入れました。その結果、Erlangの堅牢性や並行性に魅力を感じながらも採用に踏み切れないでいた開発の現場でも、Elixirは広く受け入れられるようになります。
実際、島崎さんは「アカツキにおいて、Erlangを採用するのは現実的ではなかった」と言います。アカツキはもともとRubyの開発者を多く擁していたため、Elixirがあったからこそ会社として採用に踏み切れたというわけです。
世界中で利用されるゲーマー向けのチャットシステムのDiscordでも、より現代的かつ開発者への負担が少ない形でErlang VMを活用できる言語として、当初からElixirが採用されています。
How Discord Scaled Elixir to 5,000,000 Concurrent Users
日本におけるElixir開発者コミュニティの始まり
島崎さんによると、アカツキがロマサガRSでElixirの採用を決めたのは2017年のことでした。その前年にあたる2016年ころから、アカツキだけでなくドリコムやmixiでも、自社サービスやゲーム開発にElixirを本番投入することを検討していたようです。
それと同時に、それに伴うリスクの受け皿として開発者コミュニティの必要性が各社の間で意識されるようになり、ドリコムの大原常徳さんが主体となって、「tokyo.ex」というElixirコミュニティが活動を開始しました(大原さんが執筆したElixirの解説が関連記事の欄にあります)。
さらに、Elixirをプログラミング言語として広めることを目的として、前述のElixir Conf Japanが参加者300人という規模で開催されました。このときは、Elixirの生みの親であるジョゼも来日して、基調講演を行っています。
ロマサガRSの裏側を支えるElixir
アカツキが開発に携わるロマサガRSでは、バトルの計算処理を含め、ゲームロジックの計算をクライアント側ではなく全てElixir製のサーバ側で処理しています。この設計は、主にチート対策が目的で、ビジネス上の要請によるものでした。
アカツキでは、当初、クライアント側でロジックの計算を実施するという設計も検討されていたそうです。しかし、島崎さんは「クライアントでロジックを実装してしまうことでチートが可能になると、真剣にプレイしていただくファンの方々が離れていってしまう」と考え、サーバ側でゲームロジックを処理することを提案しました。
この提案の鍵となったのが、Elixirの実用性と生産性です。
Erlang VM上で動作することによるElixirの実用性
実用性に関しては、Erlang VM上で動作することによる強みが、Elixirにも当てはまります。
例えば、ElixirにはErlang VMの軽量プロセスを使ったTask
という仕組みがあり、これをボイラープレート的に使って関数を呼ぶだけで、その関数を非同期に実行できます。これと似た処理を、例えばRuby on Railsで実現するには、Redisのキューに入れて背後のバッチサーバで動かすといった仕組みを導入することが多いでしょう。
ロマサガRSでは、この仕組みを利用して、一部の処理をオフロードしています。Erlang VMの処理速度に加え、こういった処理も一因となって、結果的に平均50msという速さでレスポンスを返せているとのことです。「レスポンスの速さはゲームのプレイ体験に大きく寄与してくれた」と島崎さんは考えています。
また、ETS(Erlang Term Storage)というErlangのオンメモリデータベースも活用されています。具体的には、「技の強さ」のようなゲームにおけるマスタデータはRDBから取り出すのでなく、起動時にETSへ読み込んで、高速に取り出せるようになっています。
ユーザデータの格納にはRDBが利用されていますが、この面でもElixirを採用したことによる利点があったそうです。同様のサーバをRuby on Railsで構成した場合と比べると、コネクション数が数分の一に減り、「おかげでAmazon Auroraの負荷が減り、コネクション数の上限値も気にしなくて済むようになった」と言います。
ロマサガRSがElixirによって手に入れたチーム開発の「生産性」
これら実用的な機能に加えて、ロマサガRSの開発でElixirが大きく寄与したというのが、「品質の高いコードをチームで維持、共有する」ことによる生産性の側面です。
「ロマサガは、従来からシステムが複雑で奥深いことが、ゲームとしての面白さのひとつだった」という島崎さんは、ロマサガRSの開発当初から、その面白さを運営型ゲームで損なわないために、コード品質を保つことが極めて重要であると考えていたそうです。
生産性に関して島崎さんがまず挙げるのは、チーム開発における高密度かつ簡潔なコードの価値です。
例えば、Elixirに限らず多くの関数型言語が備えるパターンマッチをうまく使うことで、分岐処理の見通しがよくなります。また、Elixirのパイプ演算子を使って複数の処理をつなげるイディオムを活用すれば、一時変数を大きく減らすことができ、コード密度が上がります。こうした構文は、多くの処理を次々とつなげるゲームのバトルロジックを簡潔に保つのにうってつけです。
チームで同一のコードを開発していると、コードのスタイルに迷ったり、それについての議論が始まったりすることもよくあります。Elixirには標準でコードフォーマッタが備わっていることから、こうした「自転車置き場の屋根の色」をめぐる議論を避けられたことも、チーム開発における生産性向上には有効だったといいます。
ロマサガRSの開発にElixirがもたらした生産性の鍵として、島崎さんがもうひとつ挙げるのは、コンパイル時解析1や型検査ツール2の存在です。テストに加え、これらをCircle CIによる継続的インテグレーションに組み込んだことで、大胆なリファクタリングが可能になりました。
そのおかげで、納期との戦いでコード品質が犠牲になりがちな開発後期から終盤にかけても、迅速にパフォーマンスチューニングを施すことができ、ゲームで遊ぶユーザにとっても処理時間の高速化という利益を提供できたと言います。
さらに、リリース後の機能修正や追加においても、開発速度を維持し続けられているとのことです。
Nintendo Switchのプッシュ通知システムを支えるErlang
Erlang & Elixir Fest 2019で最も注目を集めたのは、Nintendo Switchのプッシュ通知システム(NPNS)におけるErlang製サーバソフトウェアの利用でした。
Nintendo Switchは、あらためて説明するまでもなく世界中で楽しまれている家庭用ゲーム機であり、2017年3月の発売から2019年3月末までで3,500万台弱が販売されています。その膨大な数の端末に対するプッシュ通知を実現するために、Erlangが使われているのです。
この事実だけでも、Erlang & Elixir Festの会場を沸かせるには十分ですが、開発・運用を4~5人でまかなっていることや、最大想定で1億接続のスケーラビリティを、最大でも数秒の遅延で達成するという途方もない要件など、まさに大規模サービスにおけるErlangの真価を伝える発表だったと言えるでしょう。
ejabberdで1日あたり約20億の通知を処理
Switch端末へのプッシュ通知を実現するには、Switch端末とサーバとの間で常時接続しながらメッセージの送受信を実行するプロトコルが必要です。
NPNSでは、そのために独自プロトコルを開発するのではなく、十分に枯れている既存のメッセージングプロトコルXMPP(Extensible Messaging and Presence Protocol)を採用しました。
そして、XMPPサーバとして選定したのが、ErlangによるOSS実装のejabberdです。
ejabberd | robust, massively scalable and extensible XMPP server
渡邉さんによる当日の発表資料には、Erlangによる実装を選んだ理由として、処理系がクラスタ化に対応していたことが挙げられています。これは、Erlangが分散環境での利用に強い言語であることを示しています。
結果としてNPNSでは、1,000万台以上の同時接続と1日あたり約20億の通知をさばきながら、現時点まで一度もクラスタ全体の停止には至っていません。
トラブルシューティングでも生きるErlangの強み
この事例で印象的なのは、達成した結果だけでなく、その過程でのトラブルシューティングにもErlangの強みが生かされていることです。
例えば、本番稼動しているマシンに接続できるリモートシェルから軽量プロセスやメモリの状況を確認したり、そのまま無停止で更新版のデプロイをするホットコードデプロイを実施したりといった奮戦の記録が、当日の発表資料に生々しくつづられています(45ページ)。
さまざまな大規模ゲーム開発で採用されるErlang/Elixir
ここまで、Erlang & Elixir Fest 2019における2つのセッションを軸に、ゲーム開発におけるErlang/Elixirの活用事例を紹介しました。この他にも、各社のゲーム開発の裏側ではErlang/Elixirが採用されています。
まずgumiでは、リアルタイム対戦ゲームの通信処理で、Erlang製のサーバにより実装したリアルタイム通信プロトコルを開発、運用しています(下記の記事を参照)。ドリコムやmixi(XFLAG)でも、ゲームサーバにElixirが採用されています。
秒間10万メッセージをさばけ! リアルタイム対戦バトルゲームを支える負荷試験の挑戦 - CodeZine
また、ゲームサーバそのものではありませんが、ディライトワークスが手掛けるFGOでは、Erlang製のツールによる本番データを利用した負荷試験が実施されていることで有名です。
FGO を支える負荷試験ツール - shiguredo - Medium
島崎さんは、大規模ゲーム開発でErlang/Elixirを導入するメリットは、表面的な技術の話にとどまらないと言います。サーバ安定による安眠、メンテナンシビリティが高いコードによる生産性と心の健康、高速なレスポンスによるゲームのプレイ体験への寄与といった観点からも、これからのゲーム開発の現場ではErlang/Elixirを強く推奨していきたいとのことです。
これからErlang/Elixirを始めたい開発者におすすめの学び方
最後に、これからErlang/Elixirを始めたい人や、開発チームでの採用を検討している人は、どのように学んでいけばよいのでしょうか? 島崎さんおすすめのパスをいくつか紹介します。
Erlang/Elixirを学び尽くしたいならば、Erlangから学ぶのがよいでしょう。先入観なしに並行処理と関数プログラミングを習得するためにおすすめの本は、学ぶ焦点が絞れるジョー・アームストロング『プログラミングErlang』(2008年訳書刊行、オーム社)です。
プログラミングErlang 感想 Joe Armstrong - 読書メーター
さらにErlang VMの力を引き出せる中級者になるには、フレッド・エベール(Fred Hebert)『すごいErlangゆかいに学ぼう! 』(2014年訳書刊行、オーム社)で学び、並行処理を活用したアプリケーションを開発しましょう。
すごいErlangゆかいに学ぼう! 感想 Fred Hebert - 読書メーター
業務で採用する場合は、条件式の書き方や変数への再代入などで、Elixirの方がロジックを書きやすいはずですから、今から導入するのであれば、Elixirを採用しない理由はないでしょう。
すぐElixirを使いたい人には、デイヴ・トーマス(Dave Thomas)『プログラミングElixir』(2016年訳書刊行、オーム社)さえ読めば、WebフレームワークPhoenixをはじめとした豊富なライブラリを活用して、アプリケーション開発を進められます。
プログラミングElixir 感想 Dave Thomas - 読書メーター
取材・執筆:鹿野桂一郎(技術書出版ラムダノート)
【修正履歴】Fred Hebert氏のカタカナでの表記をご指摘により修正いたしました。(2019年8月1日12時15分)