f4エンジニアブログ

f4samuraiの中の人たちが書いています

調査のコツは「思考を全部書き殴ること!」 

 

はじめに

ネイティブエンジニアの桑田です。スマホゲームのプロジェクトでUnityを使った実装を担当しています。

今回は社内向けに書いた記事を紹介します。

記事のテーマは「今までで解決するのが一番難しかった技術的問題」だったのですが、ここではUnityのバージョンを2018から2021に更新した際のビルドエラーとの格闘を思い返しつつ、「仕事をうまく進める上でのちょっとしたコツ」と絡めて書きたいと思います。

 

本題

Unity2018からUnity2021へのアップデートは三世代アップということもあり、かなり大規模な変更を含んでいたので、修正内容はソースコードからビルド設定の変更まで多岐に渡りました。表面的なソースコードのエラー修正が終わり、エディタ上では動作に問題がないことを確認した後の、アプリのビルドやストアアップロード関連のエラーは特に原因が分かりにくく、苦労させられました。

 

エラーの原因を要約すると

 

  • UnityのFrameworkを生成する処理(2021で追加)よりも先にFrameworkを必要とする処理が存在した
  • 不要なFrameworkを削除する既存処理のせいで、本来必要なUnityのFramework(2021で追加)もまとめて消されていた
  • 普通に誤字があった

 

となるのですが、これらが複合していたため、どれか1つを正しても別の要因のせいでエラーになり、問題の特定が難しくなっていました。

これらの問題を修正して、アプリビルドとストアアップロードが無事に終了して安堵していたら、その後に「iOS12.2未満の端末でアプリが起動しない」という不具合に直面しました。

 

調査の結果、原因は「Swiftライブラリの追加を削除した」ことでした。

iOS12.2未満だと標準でSwiftライブラリが導入されていないため、アプリ側で追加する必要があります。

もともとは追加する設定になっていたのですが、色々な検証をしている最中に設定を外してしまっており、それによって問題が起きていました。

 

どれもこれも後から振り返ってみればシンプルな原因でしたが、これらの原因を特定するために行った調査、検証、修正はものすごく疲れました。

不具合を直すために処理を変えると別の不具合が起きたり、組み合わせ次第によって新たなエラーが起きたり……

実装意図のわからない古い処理や、普段わざわざ確認しない設定項目を洗う必要があり、さらにアプリの運用業務と並列して調査を行っているため、何日間も成果が出ないと焦りも募り、一歩も前に進められていないとどんどん苦しくなっていきます。

 

それでもなんとか調査を乗り越えて修正まで漕ぎつけられました。

そのコツは、検証作業ログを雑に書き殴っていたことだと思います。

弊社エンジニアの基本方針として、「なるべく調査・検証ログは資料として残して会社全体で共有しよう」というものがあり、自分も不具合の原因の詳細や調査内容についてはNotionページに書き残しながら作業をしていました。

「資料に残す」というと、どうしても綺麗に書かないといけないとか、理路整然としてなければいけないとか、ハードルが高く感じると思います。最終的な資料としてはそのほうが良いのですが、調査段階においては「思ったことを全部書き殴る」くらいの雑さのほうが良いです。

自分が書いていた実際のログを引用してみると、

 

「よくわからないが多分ここが怪しい」

「いや待て、ここの処理ってなんだ?」

ipaファイルが出力されてねえ!」

「この仮説通りならうまくいくはず」

「失敗。なんでだよ!!!」

「設定をOFFにしたら通ったっぽい!!!!!!!!! うおおおおおおおおおお!!!!」

 

と、主観や感想や感情がめちゃくちゃ入っており、とても全文を載せられないほど文章が荒れ狂っています。

答えを知ってから読み返すと道中の仮説は半分くらい間違っているし、めちゃくちゃ遠回りをしているし、文体もおかしいので資料としては失格です。

しかし感情を乗せまくったことで、自分がどこでつまずいていて、どこを怪しんでいて、何を勘違いしていて、どういう道程で答えに辿り着いたのかという流れは鮮明に理解できます。

 

真っ当な資料としては当然NGですが、未知のエラーを調査するときはこれくらい雑に思考を書き散らすほうが良いと思います。

これには以下のメリットがあります。

思考を書き出すメリット

 

1.仮説を言語化して可能性を一つ一つ潰していくのを視覚化できる

頭の中で考えてばかりだと結局どのような可能性が残っていて何を検証したのかがこんがらがってしまうので、文章化は大事です。

 

2.これまでの思考の流れを思い返せるので、以前の仮説を再現させやすい

検証には何日間もかかるので、どんどん最初に検証した内容を忘れていきます。

いろいろ考えたけどやっぱり最初の方法が正しかったなとなった際に、思考と検証のログを残しておけば当時の状況を再現させやすいです。

 

3.テンション感も記録できるので自分がどこで詰まっているのかわかりやすい

「どこで一番つまずいたのか」「何が一番わからなかったのか」というのは、綺麗な資料からは読み取れません。

生の感情を直接資料にぶつけて残すことで印象に残りやすくなり、今後類似する不具合と相対したときに気を付けるべきポイントがイメージしやすくなると思います。

 

4.思考の流れやテンションが視覚化されるので他者からアドバイスをもらいやすい

検証に他者の手を借りる場合、前提や仮説や感想など筆者の思考の流れが全部書かれた資料であれば

「ここの前提の認識に誤りがある」「この仮説であればこっちのアプローチのほうが良い」などの指摘を受けやすくなるでしょう。

結論だけ書いてしまうと、自分の調査内容に問題があったとしてもそれに気づいてもらいにくくなります。

また上述した通り、どこで一番つまずいているかも一目瞭然なので、調査を引き継ぐ際も便利です。

赤裸々な文章を人に見られるのは恥ずかしいですが、背に腹は代えられません。

 

5.成果が出なくても文章量が増えるので仕事してる感を得られて焦りが緩和される

これが割とバカにならなくて、検証して失敗して別の検証してを繰り返していると、目に見える成果が出ず無駄に工数を使っている感がしてどうにも気分が落ちていきます。

なかなか成果を出せない時間が続くと、短期間で成果の出る別の作業をやりたくなってしまいます。テスト勉強中に部屋の掃除を始めてしまうアレです。

しかし思考ログを全部書き殴ってると、その文章全てが作業の成果として蓄積されていくので、仕事した感が出て自分を満足させられ、ストレスが緩和されます。また、上司に対して「私はちゃんと仕事やってますよ」というアピールにもなります。

 

6.文章を書くハードルが下がる

ちゃんとした文章を書こうと思うとなかなか筆が進みません。

「ちゃんとしてなくていいからとにかく思ったことを全部書け!」の心持ちでいきましょう。

まとめ

この辺りのコツは、学生の座学とも通じるなあと思います。

黒板の板書をただノートに綺麗に書き写したり教科書の文章に蛍光ペンを引くだけでは頭に入ってきません。

ノートとは自分の思考を書き出して理解を深めるためにあり、綺麗に書くことそのものは目的ではありません。

そこに自分の感情を入れ込みまくって「これなんで?」「こうじゃない?」「こうなのか!」「じゃあこっちは?」「これだ!!!」と落書きをしまくることで自分だけのノートが出来上がり、自分に最適化されたノートが完成します。そうしたノートを読み返したほうが復習も捗るでしょう。

「授業中のノートはメモ書きとして扱い、授業が終わった後に復習がてら綺麗にまとめる」

というのは勉強法としては王道です。「東大生のノートは汚い」という風説もあります。(本当か?)

というわけで、私が思う仕事をうまく進めるコツは「調べ物をするときは、自分の思考の流れをだらだらと書き殴ろう」でした!

ゲーム業界でこれから働く新入社員に教えたいこと

はじめに

ネイティブエンジニアの松村です!

もうすぐ4月、新入社員が入社する時期ですね!

 

ゲーム業界は

「あのアニメや漫画のゲームを作りたい」

「こういうゲームシステムで世界中の人を楽しませたい」

といった夢を叶えられる素晴らしい業界です。

 

自分も、幸運にも何度か好きな作品に携われたこともあります。

新入社員の方々には、ぜひそのような夢を叶えてほしい、そういう思いを込めて、今回は「新入社員に教えたいこと」を記事にいたしました。

教えたいこと

自分が新入社員に教えたい事は

  1. 文章力
  2. コミュニケーション力
  3. ゲームをより好きになる事

です。

教えたい理由

この3つを教えたい理由は、自分が個人的にゲーム会社で働く上での基礎的な能力だと感じているからです。

そして、この3つを身につけると、業務を行う上で様々な部分が円滑になり、加えて学習というスキル自体にバフをかけたようなメリットがあると思っています。

どのような方法で教えるか

文章力を上げるには

まず、文章力を上げるには、日記を書くことをおすすめします。内容は人に見せなくて構いません。

仕事のことでも、趣味のことでも、書くテーマは自由です。日記を書くことで、日々の思考を言語化しアウトプットができるようになります。

例えば、

「今日は良い日だった。」

という粗い解像度で日々暮らしているのと

「今日は朝、限定販売のパンを購入することができた。前日早めに目覚ましをかけた努力が成果を上げた。昨日の自分に感謝したい気分だ。」

という細かい解像度を持っており、それを伝えることができるのとでは雲泥の差です。

どこが違うかというと

・出来事の原因を説明できている

・複数の出来事を関連付けられている

という点が違います。

前者の文は、なぜ良い日だったか原因がわかりません。
また、どうしたらその良い日を再現できるかもわかりません。

後者の文は、

・出来事をリストアップする

・出来事の関係性を考える

ことができており、この結果よい日を再現するための方法がわかり、他人にも伝えられるノウハウとなっているとも言えます。

実際に仕事を行っていると、スケジュール作成、工程管理、工数見積もり、デバッグ、そして実装に至るまで、あらゆる業務は文章化、言語化能力を必要とします。

このスキルは、日記を書く習慣から養うことができます。日記から発展して、日々の業務、学習したこと、遭遇した問題とその解決策を文章にすることで、思考を整理し、明確に表現する能力が向上するのです。

最初は思ったように文章を書けないかもしれませんが、上手く書けなくて悔しい、あの人のように素晴らしい文章を書きたい、と思うことこそが成長のきっかけとなると思っています。

コミュニケーション能力を身につけるには


コミュニケーション能力は、自分が好きなゲーム、アニメ、映画、食べ物など何でも構わないので、好きなものを語ることが能力を高めるきっかけとなると思います。

「昔のゲームって、ちまちまレベル上げするのが楽しかったよね〜」

「自由にマップを移動できるものが多く、好き勝手移動すると、突然強い敵がでたりして、そういうところも面白かったよね」

「考えてみると、この2つは関連しているよね、レベル上げすると、いろんなところに行けるようになる。これってまさに、作業と報酬になってる。昔のストーリーに縛られないゲームならではの魅力って、こういうことだったんだね」

このように、どこが面白いかを会話しているうちに、内容の深堀りをしたり、相手に伝わらないことを更に解像度を上げて説明をしたりと、思考力やコミュニケーション能力が鍛えられます。

聞き手側が「どこが好きなの?」とか「それは違うんじゃない?」とか話を深堀りしてくれる人だと、より成長が早くなるのではないかと思います。

この能力を若くして身につければ、仕事を円滑に進めたり、自分の環境を自分でコントロールしたりすることができるようになります。

自分の中で悩みや問題を溜め込まずに、個人、そしてプロジェクトの成長や進行を促進するコミュニケーション能力は早くに身に着けてほしい能力です。

ゲームをより好きになって、いろんなゲームを知る

就職活動の時によく業界研究と言われるように、ゲームを作るならゲームについて知ることが、仕事をするために重要です。

このために必要なことはゲームを好きになり、ゲームをたくさん遊ぶことです。

この能力は、業界で働いていくうえで大事な能力である以上に、楽しくゲームを作るうえでの重要な能力です。

例えば、

「デッキ構築型のローグライクなカードゲームに、強化や進化、限界突破を入れてマネタイズしたいんだよね」

とプランナーから言われた時に、各々のゲームの要素を知らなければ、非常に苦労します。

逆にゲームをやっているだけで

「ああ、あれとあれを組み合わさればいいのか!」

と理解でき、コミュニケーションが円滑になり、仕事の着手が早まります。

もちろん、すべてのゲームをプランナーレベルで知る必要はありませんし、わからない時は質問することができれば問題ありません。

そして質問に答えてもらった時に、「それは面白そうだね!」とポジティブに業務に取り組むことができれば、自分もチームも楽しくゲームが作れるかと思います。

ここで一つ例を出すと、実際のゲーム開発では

「キャンプの楽しさをゲームに落とし込みたい!」

といった意見が出ることもあるかもしれません。この時重要になるのは、今までのゲーム経験とどうすればゲームになるかを考えられることです。

そのために、ゲームをより好きになり、色んなゲームを知っておいてほしいです。

まとめ

今回は「新入社員に教えたいこと」というテーマで、自分の考えをまとめさせていただきました。

文章力、コミュニケーション力の向上は時間がかかるものなので、日記を書いたり、好きなものを語るなどを習慣として、あせらず続けていくことをオススメします。

そして、エンジニアとしては技術力も非常に重要ではありますが、この業界で充実した毎日を過ごすために、ゲームをより好きになって、知識も夢も目標も大きく広げていってほしいと思っています。

Apple Privacy Manifest対応でやるべきことについて

はじめに

みなさんこんにちは。ネイティブエンジニアです。
今回は『Privacy Manifests』対応についてやるべきこと、実際に取り組んでいることを説明いたします。

 

『Privacy Manifests』とは、Appleにより提供されるプライバシー対策のアップデートです。2024年春より実施されることが通達されており、対応しないとアプリの審査が通らず、リジェクトされると言われています。

 

2024年春の実施開始となると、早ければあと1ヶ月となります。具体的な対応期限や、どれほど厳しく運用されるかは通達されていませんが、Unityのアップデートが必要な可能性もあり、早期に準備をはじめ、理解をしておくことが望ましいです。

対応が必要なこと

まず、対応が必要な項目についてリストアップしました。

  • Xcode15を使いPrivacy Manifestsを出力できるようにする
    • Privacy Manifestsを作成し、以下の内容を記載する
  • Privacy Manifests対応がされたSDKを使用する
    • コード署名のあるSDKを使用
  • Unityを使用している場合、Privacy Manifests、署名対応がされたバージョンに更新する


Xcode15の使用

Privacy Manifests を作れるのはXcode15からです。
また、4/29 からXcode15の利用が必須となるため、早めのアップデートを行いましょう。

 

この時、MacOS Sonomaにアップデートすると基本的にXcode14以前が使えなくなります。
Xcode14も必要な場合は、Ventureをインストールするなどで対応しましょう。

Privacy Manifestsの作成

最初にPrivacy Manifestsの作成方法を説明します。

Xcode15を開き
File > New > File …から、ResourceのカテゴリにあるApp Privacyを選んでください。


PrivacyInfoと初期の名前が設定されています。こちらは変更しないでください。
ビルド対象を指定するTargetも選択してください。


作成すると以下のように空のPrivacy Manifestsが作成されます。



Privacy Manifestsの記載

Privacy Manifestsには以下の内容を記載することが必要です。

  • ATTの使用状況と、トラッキングドメインの記載
  • 使用しているデータとタイプの記載
  • 使用しているRequiredReasonAPIの記載

一つ一つ確認していきます。

 

ATTの使用状況と、トラッキングドメインの記載

ATT(App Tracking Transparency)とはアプリ起動時に

「(アプリ名)が他社のAppやWebサイトを横断してあなたのアクティビティの追跡をすることを許可しますか?」

を表示し、パーソナライズした広告提供のため利用されるIDFAの使用時にユーザーの同意を求めるものです。
ATTを使用している場合は、Privacy Tracking Enabled (NSPrivacyTracking)を選択し、YESにしてください。

 

そして、ATTで使用するトラッキングの通信先のドメインを、Privacy Tracking Domains (NSPrivacyTrackingDomains)により設定してください。
Privacy Tracking Domains を選択し、(+)ボタンを押すか、右クリックからのAdd Rowのメニューから行を追加し、ドメインを記載してください。

使用しているデータとタイプの記載

アプリが収集する、ユーザーのデータのカテゴリと、データを収集する理由を記載します。

 

記載すべき内容は、App Store Connectのアプリのプライバシーの内容と同じであるため、その内容を確認し、Privacy Manifestsに記載していきます。


元となる情報源はこちらです。
新規アプリではこの内容を確認し設定していきましょう。

developer.apple.com

 

データの用途は、Privacy Nutrition Label Types(NSPrivacyCollectedDataTypes)に記載します。
データごとに記載が必要な項目とその意味は次の通りです。

 

Collected Data Type 収集するデータの種類

Collection Purposes 使用の目的

Used for Tracking        トラッキングに目的に使用しているか

Linked to User        ユーザーのアイデンティティに結びつくデータか



「トラッキング」や「ユーザーに関連付けられたデータ」という言葉は、以下のように理解をしています。

 

ユーザーのトラッキングに使用されるデータ(Data Used to Track You)
アプリを通じて収集された後に、第三者と共有されるデータ

ユーザーに関連付けられたデータ(Data Linked to You)
アプリが収集した後、誰のものであるか認識されるデータ

ユーザーに関連付けられないデータ(Data Not Linked to You)
アプリが収集した後、ユーザーには紐づけられず匿名なデータ

 

正確な情報については以下のAppleのサイトをご確認ください。 

developer.apple.com

 

Required Reason APIの使用の記載

Privacy Accessed API Types(NSPrivacyAccessedAPITypes)

 

以下にリストアップされる、使用理由の登録が必要となるAPIに関しては、アプリの実装状況を調べてPrivacy Manifestsへの記載が必要です。

developer.apple.com

 

Unityでアプリを開発している場合こちらのサイトにある
「Unity の C# .Net Framework API」を参考にしてください

docs.unity3d.com

 



例えば、UserDefaultsの場合、Privacy Accessed API Typesを追加し、
Privacy Accessed API TypeにUser Defalutsを選択、
Privacy Accessed API Reasonsは以下の、User defaults API項目より、該当する利用の選択肢を全て選んでください。

developer.apple.com

 

Required Reason APIの使用状況の検索

実際に、APIを洗い出す方法を説明します。
iOSのネイティブコードはこちらを検索

developer.apple.com

 

Unityの場合、以下記載のAPIソースコードから検索します

docs.unity3d.com

 

grepでも検索できますが、ripgrepのほうがより高速に検索できるため

brew install ripgrep

でインストールし、以下のコマンドで検索します
(※ripgrepはテキストのみ対応でバイナリ検索は行わないことは注意してください)

 

UnityのAPI検索のため csファイルの検索を実行する場合

rg --type cs \

   -e 'fileInfo.CreationTime' \

   -e 'directoryInfo.CreationTime' \

   -e 'fileInfo.LastAccessTime' \

   -e 'directoryInfo.LastAccessTime' \

   -e 'fileInfo.LastWriteTime' \

   -e 'directoryInfo.LastWriteTime' \

   -e 'fileInfo.CreationTimeUtc' \

   -e 'directoryInfo.CreationTimeUtc' \

   -e 'fileInfo.LastAccessTimeUtc' \

   -e 'directoryInfo.LastAccessTimeUtc' \

   -e 'fileInfo.LastWriteTimeUtc' \

   -e 'directoryInfo.LastWriteTimeUtc' \

   -e 'File.GetCreationTime' \

   -e 'Directory.GetCreationTime' \

   -e 'File.GetLastAccessTime' \

   -e 'Directory.GetLastAccessTime' \

   -e 'File.GetLastWriteTime' \

   -e 'Directory.GetLastWriteTime' \

   -e 'File.GetCreationTimeUtc' \

   -e 'Directory.GetCreationTimeUtc' \

   -e 'File.GetLastAccessTimeUtc' \

   -e 'Directory.GetLastAccessTimeUtc' \

   -e 'File.GetLastWriteTimeUtc' \

   -e 'Directory.GetLastWriteTimeUtc' \

   '/path/to/unityproject'

 

iOSのネイティブコードを検索する場合

rg -i  \

   -e 'creationDate' \

   -e '\.modificationDate' \

   -e '\.fileModificationDate' \

   -e '\.contentModificationDateKey' \

   -e 'getattrlist\(' \

   -e 'getattrlistbulk\(' \

   -e 'fgetattrlist\(' \

   -e 'stat\.st_' \

   -e 'fstat\(' \

   -e 'fstatat\(' \

   -e 'lstat\(' \

   -e 'getattrlistat\(' \

   -e 'systemUptime' \

   -e 'mach_absolute_time\(' \

   -e 'volumeAvailableCapacityKey' \

   -e 'volumeAvailableCapacityForImportantUsageKey' \

   -e 'volumeAvailableCapacityForOpportunisticUsageKey' \

   -e 'volumeTotalCapacityKey' \

   -e 'systemFreeSize' \

   -e 'systemSize' \

   -e 'statfs\(' \

   -e 'statvfs\(' \

   -e 'fstatfs\(' \

   -e 'activeInputModes' \

   '/path/to/unityproject'

 

バイナリファイルから見つける場合はこちらのサイトで紹介されていた
nmというコマンドを使うようです。

buildersbox.corp-sansan.com

 

このコマンドは、アプリのAPIを調べるときには必要なさそうですがSDKで使われているかをチェックする時に使えそうです。

 

Privacy Manifests対応のSDKを使用する

Privacy Manifests対応は、アプリで使用しているSDKに対しても求められます。

 

アプリの箇所で説明した

  • 使用しているデータとタイプの記載
  • 使用しているRequiredReasonAPIの記載

が必要となります。
加えて、以下のSDKについては署名対応も必要となります。

 

developer.apple.com

 

SDKの対応状況については、詳細にまとめてくださった方の情報を紹介させていただきます。

dev.classmethod.jp

 

Unityを利用している場合は

C#のコードで提供されるSDK
自分でデータタイプ、RequiredReasonAPIを確認しPrivacy Manifests対応を行う

 

iOSのバイナリがある場合
SDKの提供元のPrivacy Manifests対応SDKを使用する

 

といった対応になります。
プロジェクト、会社ごとに使用しているSDKは違うため、社内で使用しているSDKリストを作成し、確認していくことをおすすめします。

 

SDKの対応状況確認

SDKのPrivacy Manifests対応は、提供元が対応しないと完了しません。
以下のような手順で、会社のプロジェクト全体で整理したうえで、SDK対応を進めていくのがいいかと思います。

  1. SDK Privacy Manifests対応リストの作成
  2. 公式サイトの確認
  3. GitHubリポジトリのRelease状況、Issueの確認
  4. SDK提供元への問い合わせ


SDKへの署名

SDKに対してのコード署名は、Appleが名指ししている以下のSDKは対応が必須です。

developer.apple.com

 

この中にはUnityFrameworkも含まれているため、Unityのアップデートも必要になります。
こちらは後述いたします。

 

Xcode15で、XCFrameworkを確認すれば、以下のような表示でSDKに対する署名の状況がわかります。



詳細についてはこちらのドキュメントや

developer.apple.com

 

こちらの動画で説明されていますのでご確認ください。

developer.apple.com

 

Privacy Manifests対応のUnityを使用する

UnityはAppleから名指しされているSDKであるため、Privacy Manifests対応・署名対応が行われたバージョンを使用する必要があります。
Privacy Manifestsに対応されているUnityは以下のバージョンからとなります。


Unity2021.3.35f1
Unity2022.3.18f1
Unity2023.2.7f1

 

署名については、上記バージョンでは対応されていないようなので、対応後のバージョンアップが必要です。

 

Unityで作ったアプリのPrivacy Manifests対応

Unityで作ったアプリのPrivacy Manifests対応は、この資料の前半で説明した手順でXcode15でPrivacyInfo.xcprivacyを作成し Assets/Plugins(またはAssets/Plugins/iOS)フォルダにいれることで、Unity側のPrivacy ManifestsとアプリのPrivacy Manifestsが統合されます。
詳細は以下をご確認ください。

 

docs.unity3d.com

 

まとめ

今回は『Privacy Manifests』についてやるべきことを書きました。

執筆時点での情報に基づいているため、情報が古くなっていたら申し訳ありません。


Unityについてはこちらのフォーラムでも、Unity社内の人も含めた情報交換が行われているので参考になります。このフォーラムによると署名処理はまだ実装されていないようです。

forum.unity.com

 

今回調査した結果、アプリ自体のPrivacy Manifests対応は、そこまで時間がかかるものではないようです。しかし、Unityやその他SDKのアップデートは、SDK提供元の対応が必要ですし、最新版へのアップデートは互換性を保つための修正や動作確認に時間がかかることが予想されます。そのため、早期に準備しておくべきだと感じました。

 

今回の記事が参考になりましたら幸いです。

新卒のインストラクターだったらコードリーディングを教えたい

前置き

CTO/CHROの松野です。
最近は暖かい日も増えてきて、春を感じるようになりました。f4samuraiにも、4月には4名の新入社員が入社する予定です(この文章「4」が多いですね)。

そこで今回は、僕が新卒時代に教わって今も役に立っていることを書きたいと思います。

新卒で教わったこと

新卒で入社した会社はSIerでした。そこで最初に配属されたプロジェクトがオープンソースソフトウェア(OSS)を調査研究するプロジェクト」でした。

僕は2003年入社なのですが、当時はいろんなOSSが誕生していました。中にはエンタープライズ用途を想定したOSSもありましたが、金融業界や流通業界などミッションクリティカルなシステムにも使えるのか?を調査をするプロジェクトです。

調査したOSSを例にあげますと、

などがありました。会社で一番使われていたプログラミング言語Javaなので、Javaで書かれたソフトが多いです。

ちゃんと使えるかどうかを判断するために、OSSなのでソースコードを読んでみよう、ということで、先輩と一緒にコードリーディングをしていきました。

コードリーディングの進め方

コードリーディングについては、以前このブログで掲載した他メンバーの記事も参考になりますので、ご覧下さい。

f4samurai.hateblo.jp

この記事と違うのは、対象がプロジェクトのコードではなく、世の中で広く流通しているオープンソースだ、というところでしょうか。

最初に読んだソースコードJUnit

JUnitは、ソフトウェア開発において自動テストという概念を持ち込んだ画期的なソフトウェアです。 JavaのプログラムをテストするコードをJavaで書くためのライブラリで、ご存じの方も多いと思います。

JUnitソースコードは、GitHubで公開されています(僕が見たのはJUnit4なのでリンクもJUnit4に貼りますが、最新バージョンはJUnit5ですね)。

github.com

コードを見ると分かるのですが、めちゃくちゃきれいなんですよね。 本当に見本みたいな書き方がされていて、心が震えたことを覚えています。

もう一つすごいのは、JUnitのテストコード自体も、JUnitで書かれていることです。自分自身で思想を体現しているし、テストコードのサンプルにもなっているし、このソフトウェアの中ですべてが完結していて美しいです。

対象のソースコードが多い場合は

OSSによっては、ソースコードの量がめちゃくちゃ多いこともあります。その場合は、

  • ディレクトリ単位で、どんな機能を持っているの考える(仮説を立てる)
  • 重要そうなソースファイルをいくつか開いて、仮説を検証する
  • それぞれの機能がどのように結びついているのかを確認する
  • HTTPリクエストの処理や、サーバの起動処理など、一つのシーケンスに沿って処理を追う

などがポイントかなと思います。

やって良かったこと

コードリーディングの対象がオープンソースだったので、一流のエンジニアが書いたソフトウェアを読むこと自体がとても勉強になりました。

 

例えば、デザインパターンを勉強したときに「概念は分かるけどどうやって使うの?」と疑問に思っていたのですが、実際にオープンソースとして実装されているのを見ることで理解を深めることができました。また、コメントはこの粒度で、こういった内容を書くといいのか、みたいなことも参考になりました。

 

僕は最近CHROの業務割合が多くなり、プログラミングからは離れているのですが、たまに人手の足りない新規事業チームから「アプリの改修したいんだけど、やってもらえませんか?」とお願いされることがあります。
全然知らない人が書いたコードを渡されても、あまり抵抗感なく読み始められたのは、新卒のときにコードリーディングをやっていたおかげかな、と感じて、新卒時代の僕に感謝しています。

 

誰でも爆速でチャットツールを立ち上げる方法

はじめに

はじめまして!サーバサイドエンジニアの酒井です。

僕は4ヵ月前(2023年10月)にf4samuraiに入社しました。

前職はシステムインテグレーターAWSの講師や営業、クラウド環境の設計/構築/運用といった業務を行っていたのですが「ゲーム開発に挑戦したい!」という思いで転職してきました。

今回は社内向けに「Rocket.Chat」の紹介記事を公開したところ反響があったのでエンジニアブログでも紹介します。

www.rocket.chat

Rocket.Chatのご紹介

業務で使用するチャットツールとしては他にChatwork,Slack,Teamsなどが有名だと思います。これらのチャットサービスはどちらかというと社内向けツールで、その場限りの利用をすることは少ないかなと思います。また不特定多数のユーザが利用するチャットとしてはDiscordが有名ですが、アカウント登録やチャットへの招待が必要です。

 

Rocket.Chatは上記チャットツールと違う点があります。それはユーザがアカウントの登録をする必要がなく、匿名で利用できることです。また、「究極のオープンソースWebチャットプラットフォーム」と謳っています。オープンソースなので無償で使うことができ、クラウド環境とオンプレ環境どちらでもセットアップして使うことができます。

 

匿名ユーザで質問ができますので、イベント時のQAツールとしてはもってこいの代物です。スマホから使えてメールアドレスなども不要です。また、問題のある発言は管理側で消すこともブロックすることも可能です。AWS上に環境構築したとすると、料金はAWS利用料だけで済みます。

Rocket.Chatの環境構築

実際にRocketChatを使えるようにするための手順を解説します。ここでは、AWS上に環境を構築することを想定しています。

  1. AWSのアカウントを用意(EC2を扱えるIAMユーザー)
  2. Amazon Linux2 インスタンスの作成
    インスタンスタイプ:t3.large あたり(あまり小さいサイズだと動作が不安定かも)。個人的にm6.large推奨。1000名もこれで大丈夫
    ・AMIは「Amazon Linux2」を選択(2023だとコマンド変えないとダメかも)
    ・パブリックアクセスが可能なものにする(ELB の配下に置いたり EIP をつけたり...)HTTPS 対応とするために ELB 配下とするのが楽でよいかと思います
    ・SSM 対応の IAM Role の付与(AmazonSSMManagedInstanceCore)
  3. 下記をユーザーデータに貼り付けて起動

#!/bin/bash

 

 

# install docker & jq

yum install -y docker jq

systemctl enable docker

 

# install docker-compose

curl -L https://github.com/docker/compose/releases/download/1.29.2/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose

chmod +x /usr/local/bin/docker-compose

 

# make docker-compose.yml

cat << _EOF_ > /home/ec2-user/docker-compose.yml

version: '2'

 

services:

  rocketchat:

    image: rocketchat/rocket.chat:latest

    command: >

      bash -c

        "for i in `seq -s " " 1 30`; do

          node main.js &&

          s=$$? && break || s=$$?;

          echo \"Tried $$i times. Waiting 5 secs...\";

          sleep 5;

        done; (exit $$s)"

    restart: unless-stopped

    volumes:

      - ./uploads:/app/uploads

    environment:

      - PORT=3000

      - ROOT_URL=http://localhost:3000

      - MONGO_URL=mongodb://mongo:27017/rocketchat

      - MONGO_OPLOG_URL=mongodb://mongo:27017/local

    depends_on:

      - mongo

    ports:

      - 80:3000

  mongo:

    image: mongo:4.0

    restart: unless-stopped

    volumes:

     - ./data/db:/data/db

    command: mongod --smallfiles --oplogSize 128 --replSet rs0 --storageEngine=mmapv1

  mongo-init-replica:

    image: mongo:4.0

    command: >

      bash -c

        "for i in `seq -s " " 1 30`; do

          mongo mongo/rocketchat --eval \"

            rs.initiate({

              _id: 'rs0',

              members: [ { _id: 0, host: 'localhost:27017' } ]})\" &&

          s=$$? && break || s=$$?;

          echo \"Tried $$i times. Waiting 5 secs...\";

          sleep 5;

        done; (exit $$s)"

    depends_on:

      - mongo

_EOF_

 

# add permission

gpasswd -a ec2-user docker

 

# run

systemctl start docker

cd /home/ec2-user

docker-compose up -d

 

 4.Rocket.Chat にアクセス(上記のユーザデータだと TCP:80)して初期設定をする

 

初期セットアップ

  • 最初の [管理者情報] は、後で使うのでメモっておきます
  • 次の [組織情報] は、全部空欄で OK です
  • 次の [サーバー情報] は、種類はプライベート、電子メールはいいえにしておきます
  • 次の [サーバーを登録する] は、スタンドアローン利用を選んでおきます

 

匿名ユーザでのアクセスを強制し、個人情報を登録できないようにする

  • 匿名ログインの許可([管理] → [アカウント] → [匿名での読み取りを許可] & [匿名での書き込みを許可])
  • 匿名ユーザに DM 権限の付与([管理] → [権限] → [Anonymous] を [User] と同じにする)。大規模セミナーの時はDMは禁止のままにする
  • 新規アカウントの作成禁止([管理] → [アカウント] → [登録] → [登録フォームの選択] を無効)。管理者用だけ作っておく

 

トップページの表示を変更してユーザフレンドリーにする

  • [管理] → [レイアウト] → [コンテンツ] 

<p>セミナー QA部屋へようこそ!</p>

<p>画面左側(←)の"#general"をクリックし、

"または匿名で話す"ボタンをクリックして、好きなお名前を設定してください。</p>

 

以上で、最低限動作するための環境構築は完了です!ファイルダウンロード機能を使う場合は、以下も設定します。

 

ファイルダウンロード時の URL 指定

  • 「管理] → [全般] → [サイト URL] に正しい URL を入力(これをしないとダウンロード URL がおかしくなる)

実際にイベントで使用した後で、チャットのログを残しておきたいこともあります。その場合は、以下の操作を行ってください。

 

チャットログを保存する

  • データは mongo db に保存されるので、そこから吸い出せばよい

sudo docker exec -it ec2-user_mongo_1 bash

mongo

use rocketchat

db.rocketchat_message.find().forEach(printjson)

もし環境をリセットしたい場合は以下手順を実施します。

  • EC2 を再作成する場合は、EC2 をシャットダウンします。再作成時にはカスタム AMI を指定すれば初期設定済みのインスタンスが立ち上がります

イベント毎にコンテナを down/up する場合は、以下のコマンドを実行します。

docker-compose down

docker-compose up -d

まとめ

いかがでしたでしょうか。


一度設定してしまえば、プライベートでも会社のイベント運営時にも使用できます。
勉強会だったり、オンラインゲームでやり取りする時などは特に便利ですね!

 

ここまで読んでくださってありがとうございました!

 

Google Apps Script(GAS)を使ってLINEから入力できる家計簿を作った話

はじめに

初めまして!f4samuraiサーバサイドエンジニアの田中です。

今回は社内の第4回技術記事コンテストで優秀賞をもらった記事を紹介します。

技術記事コンテストには毎回テーマがあります。僕が受賞した第4回のテーマは「今までで一番の作り物」でした。

仕事で作ったものはBtoBサービスが多く書きづらかったのでプライベートで作った一番のもの(というよりただ直近作ったものかも)を紹介します。

家計簿サービスを作るきっかけ

家計簿の管理、皆様はどうされていますでしょうか?

もともと我が家では家計簿を共有できる良い感じのアプリがなかったので、Googleフォームから日々の買い物内容を入力しそれをGoogleスプレッドシートで管理していました。

僕はこれで十分だったのですが、同居人から「ブラウザを開いてフォームに入力するのは面倒だからLINEとかでできるようにしてほしい」という要望がありました。

ちょうど【LINE】Messaging API+スプレッドシートで同棲生活の家計計算を自動化というほぼ同じようなことをしている記事を見つけたので、今回は+α でCI/CDを含めた仕組みを作ったことを共有します。

サービスの概要

  • 下記のようにLINE上から入力した家計簿情報をLINE Messaging API,Google Apps Script(以下GAS)を経由してスプレッドシートに登録させる
  • 加えてCI/CDを行い、ログをGCP Cloud Loggingにためてアラート発報をSlackに連携する

入力は、次のルールで行います。

1行目:カテゴリ
2行目:金額
3行目:購入日(yyyyMMDDやdd、今日、昨日とかの文字列)
4行目:購入方法
5行目:メモ

下記のようにカテゴリなど一部データはスプレッドシートで入力規則を指定しています。

LINEに入力された内容は、スプレッドシートに連携されます。

スプレッドシートでは分析など各種管理を実行することができます。

データの削除もLINEから実行することができます。

CI/CDの導入

GASは開発・実行環境がいらず簡単なスクリプトだとブラウザ上でコードを書いてそのままデプロイできる気軽さが大きなメリットだと思いますが、

  1. GitHubと直接連携してソース管理ができない
  2. テストを実行する基盤がない

といったデメリットがあります。

今回のサービスを作っていくと保守性を高める上で無視できないレベルのコード量になりそうだったので下記方法で解消しました。

  1. GitHubとの連携
    GitHubとの連携のためこちらの仕組みを導入しました。

    github.com

    claspとはGoogle製のOSSツールで、GASをローカルで開発・管理できるツールです。

    ReadMeにもありますが、clasp pushなどのコマンド操作で簡単にGASにデプロイできる点、個人的に読みやすく保守のしやすいTypeScriptで書いたコードをGASのスクリプトファイル形式gsに変換してくれる点で便利でした。

    また、ローカルでエディタを用いた開発や、GitHubソースコード管理もできるようになります。

  2. テスト
    claspを入れたことでコードをTypescript化できたので、JavaScipt用のテストフレームワークJest でテストを作成いたしました。

    また、claspもJestも特に複雑な設定をすることなくそのままパイプライン上でも使えるので、mainブランチへのマージなどを契機にテストやデプロイまでできるようにしました。

今後とまとめ

このサービスを運用してかれこれ1年近く経っているのですが、最近同居人から

  • 金額とメモ以外の入力が面倒くさい(LINEのリッチメニューでボタンぽちぽち形式にできそうだけどメニュー数の上限があって難しい)
  • というか入力そのものが面倒くさい(Google Vision APIとかでレシート画像からテキスト変換できそう)

という要望がきており、面倒くさいという感情はこういう何かを生み出すアイデアに直結するエンジニアにとって大事な資質でもあるなと改めて思いました。



2023年サマーインターンシップ振り返り~運営編~

はじめに

新年あけましておめでとうございます!ネイティブエンジニアの松村です!

2024年も新規タイトルの開発、エンジニアブログの執筆、ゲームの運用と幅広い分野で頑張っていきます!

 

前回はサマーインターンシップ振り返り~企画編~を年末に執筆しました。

今回は2023年サマーインターンシップ振り返り~運営編~と題して、実際にサマーインターンを運営している中で

  • 学生さんからもらった質問
  • 学生さんにアドバイスしたこと
  • インターンと実際の開発現場の比較

などを書いていきます。

 

よろしければご覧ください。

サマーインターンシップについておさらい

サマーインターンシップは、2023年9月6日(水)〜 9月8日(金)の3日間で開催しました。

 

1チームがプランナー3名、エンジニア2名、UIデザイナー2名の7人で構成され、合計4チームで行いました。

このサマーインターンシップは、UIデザインリーダー、COO兼ディレクター、エンジニアリーダー、人事メンバーが企画したもので、「f4samuraiで運営していたタイトルの素材を使い、オリジナルのカードゲームを作る」というものです。

サマーインターンシップの中で一番知ってもらいたかったのは「チームでゲーム開発をする面白さ」です!

 

そして、エンジニアを目指している学生さんにはこんなことも学んでもらえると良いな……と思っていました。

 

  • スケジュールを立て、期間内に要望を実現する方法
  • ゲームの基盤・ライブラリを作成すると、品質と開発速度が格段に上がること
  • 面白さを具体化する方法
  • 現場のプロたちとのコミュニケーション
  • 自分の得意なところ、苦手なところを認識すること

 

この目標は、インターン生と最終日に振り返りミーティングを行ったのですがそこで意見を伺う中で概ね達成できたように感じました。サマーインターン内容詳細はこちらの記事をご覧ください。

学生さんからもらった質問

サマーインターン中に学生さんからさまざまな質問をもらいました。


サマーインターンでゲーム開発する上での疑問点はもちろんのこと、実際の開発現場についても聞かれることが多かったです。その内容の一部を共有させていただきます。

同じように疑問に思う学生さんにとって参考になれば非常に幸いです。

 

gitについて

エンジニアの学生さんから一番質問が多かったのは「gitについての質問」です!

 

「gitは使えるほうが良いでしょうか?」といった質問をはじめとし、実際の使い方に対する質問まで多岐にわたりました。

まず、ゲーム開発現場では必ずgitなどのソースコード管理ツールを使いますので、どのようなものかを理解し、操作を学んでおくとスムーズに開発を進められます。

 

もちろん弊社では、入社後にgitの使い方を学べるような研修を準備をしていますが、今回のサマーインターンシップのような共同開発や、個人開発でも非常に役に立ち、使いこなせると開発を円滑にできるツールですので、日頃から使っておくことをオススメいたします!

英語力の必要性

次に「英語力は必要でしょうか?」といった質問もありました。

「苦手意識があるけど、学習しておく必要があるか?」という意図での質問でした。

 

僕も英語はスラスラ読めるわけでなく、翻訳サイトなどを利用しながら読んでいますので、そのぐらいのレベルでも構いません。ただ英語のドキュメントや、エラー文言に苦手意識を持たないでほしい、と思っています。

 

例えば、英語のエラー文言を調査することで問題を解決できたことが何度もあります。また、プログラムのライブラリを使うときは、英語の公式ドキュメントや、海外のフォーラムなどに投稿された内容を参考にして作業を行うこともあります。

 

最近はWebブラウザが翻訳してくれたり、ChatGPTでも翻訳してくれるので、これはどういう意味だろう?と思ったときにちゃんと調べて対応することができれば問題ないかと思います。

エンジニアは企画に携われますか?

「エンジニアは企画に携われますか?」という質問も多かったです。

 

今回のサマーインターンでは企画に深く関わることも多かったので、実際の現場もそのような働き方を求められるのか?という意図で聞かれた質問でした。

 

プランナーとエンジニア、お互いのレベル感や作るゲーム内容によって、役割の範囲が変わること・変えなければいけないことがあると思いますが、基本的にはプランナーの役割は「どんな価値や体験を届けたいか?届けるために何を作るか?」を考えることで、エンジニアの役割は「そのために何をどう作るか?どう実現するか?」を考えて実行することです。

 

もう少し別の表現で説明すると、「どういう仕様にしようかな?」とか「どういうバトルにしようかな?」とか、ゲームのルール部分はディレクターやプランナーが企画します。それを実現する方法を考えるのはエンジニアです。例えば、動きやカメラワーク、データの持ち方の詳細については、エンジニアがゲームの形を想像して設計をします。そして関係者と相談しながら実装を進めていきます。

 

f4samuraiでは技術力を活かせるのはもちろんのこと、エンジニアだけど企画に対する思いも発信できる環境と風土があると個人的には思っています。

インターンと実際の開発現場の比較

サマーインターンの参加者や内定者の方から、実際の仕事について聞かれることも多かったので、ここで詳しく説明いたします。

業務の全体像

まずは業務の全体像を説明します。
実際のゲーム開発においてエンジニアは以下の作業を行います。

 

  • インゲームの実装 (サマーインターンシップで実装したところ)
  • アウトゲームの実装
  • 基盤の作成
  • ツールの作成
  • アプリ・アセットの開発
  • 進捗管理・リリース管理などのワークフロー設計・運用
  • 開発環境の整備
    • 自動化、バリデーション
    • これら自体の構成管理、システム・モジュールアップデート

 

インゲームはバトル、音ゲー、パズルなど遊びに当たる部分です。今回サマーインターンシップで実装を行ったのもこの部分になります。実際の作業の割合でいえば2割ぐらいかなと思います。

 

アウトゲームは、編成、育成、強化などインゲームに戦略性や育成性をもたせる部分です。

 

基盤は、通信、画面遷移、データの保存、読み込みなどゲームの土台となる基本機能です。

 

ツールは様々なものがありますが、自分が携わったことがあるところですと、アドベンチャーパートなどのシナリオを作るツールや、演出を作るためのツールなどが代表的かなと思います。

 

また、日々の開発や運用を成り立たせるワークフローの設計と運用もエンジニアが行います。

具体例をあげるなら、2D・3Dの素材を作成するための仕組みや、デザイナー・イラストレーターが仕組みを使いこなせるようになるためのドキュメント作成といったところでしょうか。

 

ゲームは開発後の運用フェーズにおいても、大勢の人数が携わり、日々多くの素材が作られます。そのため、チーム全体を考慮して、ワークフローを設計・運用する能力がエンジニアには求められます。

 

このように、エンジニアが実装するものは非常に幅広く、知識も経験も求められます。

ゲーム開発を仕事にする上で必要なこと

上記のような仕事を担っていく上で、必要になってくるのは以下のようなところだと思っています。

  1. 学習力
  2. 運用を想定した設計力
  3. 長期的な目線を持つこと

 

1.学習力

サマーインターンは3日と短い期間だったので、今までに身につけた知識でほとんどの作業がカバーできたかもしれません。しかし実際の仕事では、使ったことのないライブラリを使ったり、プランナーが提案するアイデアを実現したりする上で、新しい技術をキャッチアップする学習力が重要になります。

 

ゲーム業界のエンジニアは新しく生まれた技術を取り入れて、業務を効率化したり、今までに無いものを作り出したりすることを求められるため、常に学び続ける必要があります。

 

といっても、学生時代のように暗記が必要なわけでもないので、面白いな、新しいなと感じたことにチャレンジしたり、最新の技術で何か作ってみよう!という好奇心があれば楽しく学んでいけるものです!

2.運用を想定した設計力

運用型ゲームでは、長期にわたって運用することを前提とした設計も重要になってきます。

 

プログラムが動くだけでなく、データの変更が容易にでき、プランナーやクリエイターが毎月の運用を行いやすいように作る必要があります。

 

具体的には、ファイルからデータを読み込み、戦闘時のパラメータやステージの構造などを変更しやすい仕組みにしておくなど、ただ作るだけではなく、その仕組みを使う人やプレイヤーのことを考えた設計を行うことが求められます。

3.長期的な目線を持つこと

ゲーム開発を仕事とする場合、開発、運用、そして学習、どの部分においても長期的な目線を持つことが重要になってきます。

 

特に、新卒や若手のときには、苦手だと感じていることに向き合い、日々の仕事や基礎を大切にすることが重要です。
僕も若い頃は文章を書くことが苦手だったり、不具合を出して落ち込んだりしましたが、そのことにしっかり向き合ったことが、いまでは大きな財産となりました!

 

自分にはできないだろうと思うのではなく、目指したい先輩や目標に向けて長い目で頑張ることが大切です。

まとめ

今回、サマーインターンシップ振り返り~運営編~として、学生さんに向けるメッセージといった形で記事をまとめてみました。

今年2024年のサマーインターンシップでは、ここに上げたような、仕事への心構えや新たな技術を学べるような場にもしていきたいです。

学生さんは、是非引き続き情報をチェックしていただければ幸いです。

 

加えて今年はこのブログで、育成の話題や会社の雰囲気、技術情報をより一層お届けできればと思っています!

 

本年もよろしくお願いいたします。