Akatsuki Hackers Lab | 株式会社アカツキ(Akatsuki Inc.)

Akatsuki Hackers Labは株式会社アカツキが運営しています。

アカツキゲームスのサマーインターンに参加しました(バックエンド, Elixir)

 

自己紹介

神戸大学理学研究科物理学専攻M1の濱田悠斗と申します。大学では素粒子物理の実験をやっています。研究関連ではC++, Pythonをよく触ります。趣味でWebのフロントエンドをちょっぴり触っています。

インターン参加の動機

大規模なソフトウェア開発に参加できるサマーインターンを探していました。その中でもゲームのバックエンドかつ関数型言語を大規模プロジェクトで採用している貴重な環境に魅力を感じ、エントリーしました。

 

インターンの参加が決まってからは、会社から送られてきたElixirの本を半分ぐらい読んで準備していました。初めて関数型言語に触れてカルチャーショックを受けたのを覚えています。特にその本の序盤で再帰を使ったmapやreduceを実装の紹介があって恐怖を感じました。

やったこと

メンターの方と相談しながらいくつかタスクをもらって、それを消化していく流れでした。最終的に3つのタスクをいただいて、3つ目のタスクの途中まで出来ました。

デバッグ用管理画面の改修

プレイヤーデータの管理画面においてデータを複数選択して一気に削除しようというタスクでした。ゲームのバランス調整等のデバッグをするためのツールがあります。このツールで以下のような問題があり、それを解決するためのタスクです。

  • プレイヤーのデータ(所持しているアイテムなど)を編集する画面において、データを一括で削除する機能が無い
  • 複数のデータの削除には何度もクリックを繰り返す必要がある

すでに実装されていた個別削除のAPIを複数削除に対応できるように変更し、チームの方とUIのデザインを相談しながら管理画面のフロントエンドを実装しました。

アイテム一括削除の実装において、DBへの問い合わせが発生します。当初の実装では既存の個別削除をするためのクエリを何度も投げていて、1つのアイテムを削除するたびに問い合わせのオーバーヘッドがかかっていました。これでは非効率なので1度のクエリで複数個アイテムを消せるような処理に変更しました。

管理画面のフロントエンドはVue.jsで作成されていました。Vueをちゃんと触るのは初めてで最初の1週間はずっとVueと格闘していました。

新機能開発

ゲームのある新機能開発のタスクでした。具体的にはDBのテーブルを新しく作成し、APIの仕様を少し変えるものです。

DBに新しいテーブルを作成するためにElixirのDBラッパーライブラリEcto, Yactoのドキュメントを読んでプロダクトコードに差し込んで挙動を確認するという作業が新鮮で楽しかったです。

このタスクではゲームのAPIの仕様変更を行ったため、クライアントサイドのエンジニアさんに連絡を取ったり細かいロジックの部分をプランナーさんに確認したりしました。エンジニアの仕事のリアルな部分を知れていい経験になったと思います。

マスターバリデーションのホワイトリスト可視化

マスターバリデーションとは

ゲームの設定データはマスターデータと呼ばれていて、マスターデータの整合性をチェックすることをマスターバリデーションと言います。マスターデータを書き換えた時に、マスターバリデーションを走らせて設定に不備がないか確認をするという感じです。



マスターバリデーションのホワイトリストとは

アップデートによって新しく追加されたバリデーションに対応できないマスターデータや例外的なマスターデータはバリデーションをスキップすることになっています。このバリデーションから除外するマスターデータのIDのリストをホワイトリストと呼ぶことにします。

現在、ホワイトリストはバリデーションのプログラムに定数として定義することで実装されています。この実装の問題点としては以下の2つが挙げられます

  • 各バリデーションでエンジニアがバラバラに記述している
  • エンジニア以外の人がホワイトリストを参照できない (エンジニアでもパッとわからない)
  • エンジニア以外の人がホワイトリストを編集できない

この問題点を解決するタスクに取り組みました。実装の流れを以下のように設定し作業を進めることにしました。

  • 上述のデバッグ用管理画面にホワイトリストを出力する
  • エンジニア以外の人もホワイトリストを編集できるような仕組みを作る

結果的に1つ目の作業まで完了することができました。

バリデーション実行時にホワイトリストを書き出すようにする

まずは、ハードコーディングされているホワイトリストを何かのファイルに書き出すような処理を実装しようと考えました。

バリデーションはいくつか存在する検証環境ごとに走っていて、ホワイトリストも検証環境ごとに表示する必要があります。バリデーションの流れは図のようになっています。



親プロセスが各検証環境のマスターデータを読み込んで、検証環境ごとのプロセスを生み出してバリデーションを走らせます。ここで問題となったのがElixirが関数型言語であることです。一般的なオブジェクト指向ベースでの設計だと、バリデータオブジェクトがホワイトリストを更新しながらバリデーションを進めるという実装が考えられますが、Elixirではそれがしづらくなっています。そこで、図のように各バリデータプロセスにホワイトリストを保持させるプロセスを紐づけてホワイトリストを更新しながらバリデーションを進めることにしました。



ElixirのGenServerというプロセス間通信を実現する仕組みを使って実装を行い、目的の処理を実現しました。

実装を終えた後でメンターの方からのレビューをいただき、次のことがわかりました。

  • 私が実装した仕組みはElixirのETSという機能にある
  • それとは別にプロセス自体にデータを保存できる仕組みがある

どう実装するのが正解なのか、保守性・実行の容易さ・要件を満たしているかを考え、2の方法でホワイトリストの書き出しを実現しました。欲しい機能を実現するためにはいくつかの方法があって、それらの中からベストを選ぶのが大切で難しいことだなあと思いました。

書き出したホワイトリストを管理画面に表示する

書き出したホワイトリストを読み込んで、管理画面に渡すAPIを作成しました。ホワイトリストに示されているIDからアイテムの名前をマスターデータに問い合わせて、その結果を整形してレスポンスとするAPIです。私は前述の仕組みでホワイトリストをjsonファイルで書き出すようにしていました。Elixirで構造化されたjsonから必要な情報を抜き出して整形するのは考えていたよりも大変な作業で、実装の過程ではメンターの方に大変お世話になりました。

感想

技術的なこと

初めてチーム開発に参加して、レビューの文化に感動しました。私が書いたコードをしっかり読んでコメントを下さる人がいることにとてもありがたみと安心感を感じました。実際にゲームとして動いているプロダクトコードを読むことができて、大規模開発のセオリーのようなものを感じ取れた気がします。また、実際のプロジェクトに配属されることでミーティング等に参加させいただき、サーバーエンジニアの周りで働く方々のことも見学することができてよかったです(特にインフラ周りのことしている人かっこいいなと思った)。

全体的なこと

インターン初日は環境構築とオリエンテーションで終わるぐらいに手厚いサポートがありました。リモートで右も左もわからない状況ではとても助かりました。

インターンの期間中に社内の方と話す機会が何度か設けていただき、その中でアカツキゲームスは人に時間をかけているなという印象がありました。特に新卒研修は人によっては数ヶ月に及んでいて、基礎知識をしっかり固めてからプロジェクトに配属される仕組みになっていていいなと思いました。

最後の3日間はホテルを手配してもらって出社させてもらえて楽しかったです。オフィスで仕事すると雰囲気がよくわかるし、社員の方と雑談しながらお仕事できるのは学生にとってかなり貴重な体験であると感じました。

ラウンジの水出しコーヒー美味しかったです。ランチごちそうさまでした。