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

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

インターンでゲームのデバッグツール機能開発をした話

こんにちは、アカツキサマーインターンシップ2019第2期生の伊藤です。 

今回、8/1〜8/23の平日16日の間*1、株式会社アカツキでサーバサイドエンジニアとして就業してきました。

この場を借りて、インターンで何をやったのか、色々アレコレどうだったのかを振り返りたいと思います。

インターン内定まで

4月のサポーターズ逆求人イベントで、アカツキの人事さんとエンジニアの方とお話する機会がありました。

丁度ゲーム系のインターンを探していたので、イベント後早速選考を進めることにし、5月中にはインターンの内定を得ることができました。選考自体はプログラミングのWebテストと1回の面接のみで、特に対策等は行っていません。

やったこと

僕はサーバサイドのコースで応募したので、面接の段階でRubyのコースとElixirのコースを選ぶタイミングがありました。元々はゲームサーバのプロダクションコードを触りたいなと思っていたのですが、以前から気になっていたElixirにここで触れるのも巡り合わせかなと思い、Elixirのコースを選択しました。*2内容はデバッグツールの開発ということで、個人的にゲーム開発を行っている自身としても良い経験を得られそうだと感じていました。

さて、実際にインターンでやったことですが、主に以下の3つの機能実装となります。

  • デバッグツールのパーティ編成機能
  • デバッグツールのパーティメンバー能力値操作機能
  • デバッグツールのパーティメンバースキル操作機能

以上を実装する背景は、テスト環境において、様々なレベルの敵とのバトルのデバッグや、特定のゲーム進行状況を再現しづらいという点を解消するというものでした。デバッグはプログラムに詳しくない方々も行うので、簡単な操作で複雑な状況を再現出来ることが必要不可欠でした。

今回担当したタイトルでは、ゲームロジックがサーバに寄った設計になっているため、デバッグツールはWebアプリケーションとして実装されています。技術的には、WebアプリケーションフレームワークとしてPhoenix、UIフレームワークとしてVue.jsが採用されています。

詰まったこと

初めて触れる言語ということもあり、Elixir周りで躓くことが多々ありました。また、Vue.jsに慣れていないためVue.jsの気持ちに沿ったデータ構造設計が行えず、最終的にリファクタリング作業をすることで無駄に工数を増やしてしまうということがありました。

以下でざっくり振り返ります。

Elixirの詰まりポイント

Elixirは動的型付けではありますが、Typespecという型表記法やDialyzerという静的型解析ツールがあり、比較的型に対する意識が高い言語です。

また、Elixirはトラディショナルなオブジェクト指向言語とは異なり、クラスという概念はありません。*3さらに継承も無いため、それぞれ独立した構造体、リストやマップなどによってデータを表現することになります。この辺はなんとなくGo言語に近い雰囲気を感じます。

なるほどプリミティブと構造体で上手いことデータ構造を表現して、Dialyzerを用いれば静的型付け言語と同じような気持ちでコードを書けそうだ、というのが最初の感想でした。

ここで問題となったのが、DialyzerはStructural Subtypingでは無さそう(=Nominal Subtyping)ということでした。Nominal Subtypingとは型名だけでデータ構造を特定するような型システムのことで、C言語やJavaなどほとんどの言語ではこちらが採用されているようです。対となるStructural Subtypingは、ある型のデータ構造を含む、より大きなデータ構造があった場合に、大きい方を小さい方の型としても扱うことが出来るような型システムです。こちらはML系言語(OCamlとか)などで採用されているようです。

Elixirのような継承を許さない構造体を扱う言語の静的型解析にはStructural Subtypingを期待してしまうのですが、どうやら違うようです。なので、基本的に複数の構造体の結合はMapとして表現するしかない、ということが起きます。そもそもMap.mergeしているのだからMapになるだろうと言われればそれまでですが。厳密にやりたいなら、その複数の構造体の結合を新たな構造体として定義する必要があります。

静的型解析が要らないというのであればこれは問題ですら無いのですが*4、新たに巨大なコードベースに立ち向かうには型という案内図があった方が都合が良いです。その案内図(型定義)が大雑把(map)過ぎて、案内図の機能を果たしていないというのが今回の問題でした。*5

素人の感想ですが、Ectoを使っているとやりがちな問題なのかな?と思いました。

なぜこのようなことになっているのか詳しく理由を聞くと、途中からDialyzerを導入したプロジェクトなので現状仕方なくそうしているということでした。問題意識はあるようですので、今後改善されて行くのだろうなと思います。

Vue.jsの詰まりポイント

Vue.jsはリアクティブにデータバインディングしてくれるイマドキなフロントエンドフレームワークなのですが、どこまでならリアクティブにバインディングしてくれるのかを理解していないと辛いことになります(なりました)。特に変なデータ更新の仕方をするとハマりがちなことかと思います。

Vue.jsはdataで定義したフィールドは追跡してくれるのですが、新たに追加されたフィールドは基本的に面倒を見てくれません。内部的にはクラスのsetterを利用しているため、テンプレートの方で指定しているフィールドがなければそのsetterは生成されないようです。*6

結論として、データはsetterが引かれるような更新の仕方をするべきでした。

感想

田舎の大学に通っているため、3週間とはいえ東京で生きていけるか不安でしたが、意外となんとかなりました。まあ、人ごみと暑さにはなかなか慣れませんが…

遠方(岩手)からの参加だったのでマンスリーマンションを用意して頂きましたが、結構快適でした。洗濯機・冷蔵庫・電子レンジ・IH以外ほとんど何も無いので、ある程度日用品調達は必要でしたが、真下にコンビニがあったので特に困ることも無く。アカツキのある目黒まで電車で2駅なので、通勤もそれほど苦ではありませんでした。

業務内容はメンターさんが事前にきっちりタスク化してくださっていたので、ほとんどやるだけと言う感じでした。個人的には、もう少し他の社員さんとも絡みたかったなという感想です。

全体を通して満足感のあるインターンだったと感じています。

*1:途中、学会で抜けたので実際は14日間

*2:実はRubyもまともに触ったことは無いが、関数型言語の側面が強いElixirの方が興味が強かった

*3:その代わりプロトコルという機能でオブジェクト指向の特徴の1つであるポリモルフィズムを実現している

*4:実装上は問題無い

*5:一言で言うとGoの埋め込み型が欲しい

*6:動的に生やす方法はある