ゲーム開発の現場では、コードの書き方や設計の選択以外にも、運用やデバッグの効率を左右する要素が存在します。
その中でもログの役割はとても重要です。
ゲームの挙動に直接関与するわけではないので軽視されがちですが、ちゃんとしたログがあるかどうかでゲームの質は大きく変わります。
ログとはシステムの動作状況を記録するものです。
エラーの発見やパフォーマンスの監視、ユーザー行動の分析など、様々な目的で利用されます。
ゲーム開発においても、バグ修正やパフォーマンス最適化はもちろんのこと、今後の機能改善の参考にする場合等、あらゆる局面でログが活用されています。
この記事では、ゲーム開発におけるログについて解説します。
ログの設計や活用方法を知ることで、よりよいゲームの開発につながるはずです。
ログの種類
一言でログと言っても、ログには様々な種類があります。
ゲーム開発においてもそれは同様で、ある程度の規模のゲームとなれば様々なログを活用していることは珍しくありません。
ということで、まずはログの種類について紹介します。
デバッグログ
デバッグログは、開発中のゲームの動作を詳細に記録し、問題の特定や修正に役立てるためのものです。
具体的には、プログラムが特定の処理に入ったことを通知する単純なメッセージや、特定時点の変数の値を通知するメッセージ等をログに出すことが多いです。
機能を実装するエンジニアが自分で確認するために使う場合もあれば、テスターがゲーム画面だけでは確認できない細かい数値等を確認するために使う場合もあったりします。
エラーログ
エラーログは、ゲームで発生したエラーや例外を記録するものです。
エラーログを詳細に記載することで、発生した問題の原因を迅速に特定し、対抗策を講じることが容易になります。
特にユーザーに影響を与える重大なエラーについては、迅速な対応が求められるためエラーログの重要性はとても高いです。
エラーログが出たことをすぐ知ることができるように、エラーログが出た時にチャットやメールで通知を飛ばす仕組みを設けていることも少なくありません。
パフォーマンスログ
パフォーマンスログは、ゲームのパフォーマンスに関する情報を記録するものです。
主にCPU使用率、メモリ使用量、処理時間のような情報を記録します。
パフォーマンスログがあることで、システムのボトルネックを特定しやすくなり、最適化のための改善に役立ちます。
パフォーマンスが低下すると、ラグが発生したり、ゲームが強制終了したり等の問題が発生します。
そのような問題が発生すると、いくらゲームの内容自体が面白いものであってもユーザーはなかなか楽しめません。
常にパフォーマンスは気にするようにしましょう。
ユーザーログ
ユーザーログは、ユーザーの行動や操作履歴を記録するものです。
ユーザーログがあると、「ユーザーがどの機能を多く使用しているか」「どのステージでユーザーが苦戦しているか」「課金アイテムを購入した履歴」等がわかるようになります。
それらをうまく活用することで、「ユーザーが必要としている機能の追加」「ゲームの難易度の調整」「売れる見込みが高い課金アイテムの追加」等の改善をすることができるようになります。
また、ユーザーログは改善だけでなくユーザーからの問い合わせに対する調査にも使います。
例えば、「○月×日にはあったはずのアイテムがいつの間にかなくなっていた」という問い合わせがあった場合はそのユーザーの該当アイテムの使用履歴、売却履歴等のユーザーログを調べます。
もし○月×日以降にアイテムの使用履歴があれば単なるユーザーの勘違いになりますし、逆にアイテムを消費した形跡が見当たらなければ不具合の可能性が高くなります。
余談ですが、ユーザーログを見ていると、思わぬ発見があったりもします。
「ネタ枠で作っていたキャラやスキルが思いのほか使われている」「苦戦するように設計したボスがあっさり倒されてしまっている」等があったりして、見ているだけで意外と楽しかったりもします。
ログの設計
ログは単に情報を記録できれば良いという訳ではありません。
後で有効に活用できるように適切な設計をする必要があります。
目的に応じた記録する情報の設定
まず、どういう目的でログを取るのか目的を明確にして、その目的にあった記録すべき情報を設定しましょう。
先ほど述べたように、ログには様々な種類がありますし、種類に応じて記録すべき情報も異なります。
例えば、エラーログであればエラーの原因の特定に必要な情報を記録する必要がありますし、ユーザーログであれば分析や調査に必要な情報を記録する必要があります。
過不足なく記録すべき情報を設定できるのが理想ではありますが、なかなか難しいものです。
なので僕の場合は、基本的に必要そうな情報はすべて記録するようにしています。
記録すべき情報が増えるとログの容量が増えたり等のデメリットはあるものの、欲しい情報がログから取得できないことに比べればはるかにマシだからです。
実装方法の検討
次に、どういう風にログを実装するかを検討します。
これに関してもログの目的から適切な実装方法を検討する必要があります。
例えば、デバッグログであれば実行中にコンソールに出力されれば十分な場合もありますし、エラーログであればコンソールの出力だけでは不十分なのでテキストファイルとしての出力も必要になります。
さらに、ユーザーログ等の調査や集計に使うようなログであればデータベースに登録するなり何かしらのログツールを採用する必要があります。
ログの管理
ログは記録をしたらそれで終わりではありません。
適切に保管し、必要な時に迅速に情報を取り出せるよう管理しておく必要があります。
ログの保存
まず、ログの保存期間を決めておく必要があります。
僕の今まで関わってきたプロジェクトでは以下のような期間でした。
ログの種類 | 保存期間 | 理由 |
デバッグログ | 数時間~数日 | 大抵はデバッグしている最中、遅くとも翌日くらいしか参照しないため |
エラーログ | 1か月~3か月 | 緊急性の高いエラーであれば即対応するし、そうでなくてもせいぜい1~2か月程度で対応するため |
パフォーマンスログ | 3か月~6か月 | 長期的なスケジュールで改修することが多いため、エラーログより少し長めの期間 |
ユーザーログ | 3か月~無期限 | 問い合わせ等の対応でしか使わないログはせいぜい6か月程度 一方、長期的にデータを集計したいログは無期限 |
次にログの保存方法を決めます。
ログの保存方法にはいくつかの選択肢があります。
代表的なものは以下のようなものです。
保存方法 | メリット | デメリット |
ローカルストレージ | お手軽に実装可能 | 容量がローカルのマシン依存なため有限 |
クラウドストレージ (AWS,GCP等) | 容量は自由に調整可能 アクセス制御やバックアップ機能が充実している | 有料な場合が多く、予算と要相談 |
専用のログ管理サービス (Datadog等) | クラウドストレージと同じメリットに加え、ログ分析などの機能も充実している | クラウドストレージより費用が高くなりがち 機能が多い分、キャッチアップが必要 |
データベース | ユーザーデータ等と同じ保存方法なので、すでにそれらが実装済みであれば流用が可能 自前で検索や集計がしやすい | データベースの容量が膨大に増え、最悪の場合はパフォーマンスにも影響しうる |
ログの保存期間とどれくらい容量が必要かで保存方法を決めるとよいでしょう。
「デバッグログは、2~3日しか保存しないし1GB以下の容量で済むのでローカルストレージに保存する」「ユーザーログは、長期間もしくは無期限に保存するし容量も膨大なのでログサービスを利用する」みたいな感じです。
ログの可視化と分析
ログを効果的に活用するためには、適切な可視化と素早く分析できることが不可欠です。
僕が今まで見たやり方は以下のパターンです。
方法 | メリット | デメリット |
都度エンジニアがログを加工する | 仕組化するコストがかからない | エンジニアの手間がかかる 作業が発生する分の時間がかかる |
自前でログ可視化ツールを用意する | 情報を見たい時にすぐ見れる 自由にカスタマイズ可能 | ツール作成の工数がかかる |
ログ管理サービスを利用する | 情報を見たい時にすぐ見れる ツール作成の工数がない 集計やグラフ化といった、よく使われるような機能は大体揃っている | 大抵のサービスは有料 サービスの仕様を理解するためのキャッチアップが必要 |
都度エンジニアがログを加工する方法は、基本的にはおすすめしません。
小規模なプロジェクトだったり、ツールを用意する時間もお金もない時に応急処置的な感じでやむなく選択する方法です。
ということで、基本的にはログ可視化ツールを用意することにしましょう。
「ログの集計結果を表で確認したい」くらいの要件であれば自前で用意するのもアリですが、「ログの集計結果をグラフで見たい」「現在と過去の特定期間の集計結果を比較したい」等の要件がやや複雑なのであれば専用のログ管理サービスを利用することをおすすめします。
ログが適切に設定されていないと起こる悲劇
今までの説明でログが重要だということはなんとなく理解していただけたと思います。
次に紹介するのはログが適切に設定されていなかったが故に、僕がした苦労話です。
ゲーム内通貨の所持状況が追いづらくて大苦戦
ある日、ユーザーから問い合わせがありました。
「○月1日時点ではゲーム内通貨が10000あったはずなのに、○月3日にアイテムを購入する時には9000しかなかった」といったような内容のものでした。
ユーザーの現在のゲーム内通貨の所持数やアイテム購入ログを追ってみたところ、以下のことがわかりました。
- ユーザーの現在のゲーム内通貨は8500
- ○月1日以降、ゲーム内通貨の変動があったのは○月3日のアイテム購入のみ
- ○月3日に購入したアイテムの値段は500なので、○月3日にゲーム内通貨が9000だったのは合っている
あとは○月1日時点に本当にユーザーのゲーム内通貨が10000だったかどうかを確かめる必要があります。
これが実は○月1日時点で9000だったのであればユーザーの勘違い、本当に10000だったのであれば何かしらの不具合の可能性が高いです。
ところがここで問題が発生します。
ゲーム内通貨の増加数や減少数といった変動する数値はログに取ってありますが、その時のゲーム内通貨の所持数がいくらかはログにしていなかったのです。
※上記にある○月3日のアイテム購入前のゲーム内通貨が9000が合っていると判明したのは、現在のゲーム内通貨と○月3日のアイテム購入ログから逆算しただけです
仕方なく僕は対象ユーザーのゲーム内通貨の変動ログを対象ユーザーがゲームを始めてから現在まで順に追って行って、ゲーム内通貨がいつ・どれくらい所持していたかを計算する羽目になりました。
当然時間がかかったのは言うまでもありません。
ちなみに、○月1日時点のユーザーのゲーム内通貨は9000であったことがわかったので、調査経緯をしっかり説明したうえでユーザーの勘違いである旨を問い合わせの回答としました。
この経験を活かし、僕は何かしらの数値の変動ログを取るときは、必ず変動前(or変動後)の数値を取るようにしています。
今回のパターンで言うと、アイテム購入ログで「購入前のゲーム内通貨の所持数」も取るようにする感じです。
謎のエラーに大苦戦
特定の時間帯にGvG(ギルドvsギルド)が行われるゲームの話です。
「ユーザーはギルドに所属し、特定の時間帯にマッチングしたギルドと対戦をする」といったような仕様のゲームです。
GvG中にちょくちょく発生するエラーが見つかりました。
発生する頻度的に、すべての対戦で発生しているわけでなく、1つか2つくらいの対戦で発生しているようでした。
実際に僕や他の人の対戦では特に問題なくプレイできたことからも、特定の状況で発生するエラーだと思われました。
問題はエラーログの内容でした。
特に専用に設けたエラーログを出しているわけではなく、デフォルトの例外の内容を取っているだけでした。
つまり、「どういう例外が発生したか」「プログラムのどこで発生したか」はわかるものの、「変数の値がどういう時に発生したか」みたいなことまではわかりませんでした。
エラーが発生した箇所から察するに、どうやら特定のスキルを使用した時に発生するらしきことまでは予想できました。
ただし、どのスキルを使ったときに発生するかまでは情報が不足しているのでわかりません。
このままではどうしようもないので、エラーが発生した箇所に新たにログを取る処理を実装することにしました。
当然どのスキルを使用したか等の必要な情報が含まれているログです。
新しいログの実装後、本番環境にデプロイし再度エラーが発生するのを待ちました。
そしてようやくどのスキルでエラーが起こっていたのかがわかり、無事不具合修正ができました。
まとめ
ログを適切に設定することで、ゲームの質は格段に向上します。
ゲームの内容に直接かかわることではないので、ついつい軽視しがちではありますがログもしっかり作っておくことをおすすめします。
もちろん、ログはしっかり作ったけど肝心のゲーム開発がおろそかになってしまったら本末転倒です。
ゲームの規模や開発スケジュール、あなた自身の技術力や予算等を考慮して、無理のない範囲でログの実装に取り掛かるのがよいでしょう。
コメント