1人前のゲームプログラマーを目指してやったこと考えたこと

 2021年、私は13年務めた某ゲーム会社を退職して新しい会社を立ち上げた。勤めていた会社には本当にお世話になったし、私を成長させていただいた会社である。おかげで個人で作っていたPICO PARKもヒットしてくれた。

 さて本題。

 私がゲームプログラマーを目指しプログラミングを学び出したのは大学1年生からである。なので4年間の大学時代と13年間のゲーム会社時代を通して、いろんなことを考え実行してきた。今日はその中で、一人前に近づくために実行したこと考えたことの中から、特に1人前に近づいたなという実感につながったことを書いておく。

1人前のコーディングを目指して ~他人のコードを読みまくる~

 プログラミングを学び始めてから、様々なプログラミングに関する書籍、GDCやCEDEC資料、SDKドキュメント、コーディング規約は読んできたし参考にしてきた。

 まぁ良書、良資料は読んだ方がいいなんて言われなくても…な話でしょう。

 ただ私はそれと同じくらい他人のソースコードを読むことを重要視してきた。しかし、意外と他人のコードを好きで読んでる人にあまり出会わない。以前いた会社の中では、私はトップクラスで人のソースコードを読んだ自信はある外注会社のソースコードも手に入ったら喜々として読んでいた

 どんなソースコードも他人の考え方を知れる良い機会になったし、良いソースコードと感じたものはとても参考になった。異文化交流してる気分になることもある。何故?というソースコードに出会ったら本人に質問して新しい視点を得られるチャンスにもなった。若手の時、それでLisp大好き先輩の考え方を聞いて新鮮さを感じたのは良い思い出である。また何よりも同僚のソースコードを読んで理解しておくと、いざという時に手助けしやすいし、ダブルチェックになって早期にバグを見つけて教えることもできた。そういうことをしてると同僚や上司からの信頼にも繋がっていった実感がある。

 また、これは会社にいて他人のソースコードが見れる環境にいる人だけの話ではない。今やUnreal Engine のソースコードをダウンロードして読めるし、PICO PARKのネットワーク対応はオープンソース化されていたUnity Netcodeのコードを読んでなかったら実現できなかったくらい役立った。

 なので「他人のコードを読みまくった」ことは本当にやってよかったと思っている。

1人前の設計を目指して ~ 常にその時の状況を考える ~

 プログラミングを学び出して17年たって思うことは、プログラミングに絶対的答えはない、常にその時々の状況に合った最良を検討しないといけない、ということだ。

 ・「自分しか使わない機能のプログラミング」と「他人も使う機能のプログラミング」
 ・「仕様通りに早く実装が求められるパートのプログラミング」と「仕様が変わりやすいパートのプログラミング」
 ・「毎フレーム何度も呼ばれるような機能(例えば数学系関数)のプログラミング」と「ロード画面中にしか呼ばれないような機能のプログラミング」
 ・「マルチスレッドに処理を分散しやすい機能のプログラミング」と「分散しにくい機能のプログラミング」
   ・「オブジェクト指向でゲームを作ってた人ばかりと一緒にするプログラミング」と「Entity Component System でゲームを作ってた人ばかりと一緒にするプログラミング」
 ・「0から設計するプログラミング」と「他人のコードを引き継いでのプログラミング」
 ・「開発初期のプログラミング」と「開発末期のプログラミング」

 これらは状況にもよるが同じ設計にはなりにくい。開発初期にすごく綺麗なコードを書くプログラマーも、開発末期には影響範囲を最小限にするためなどの理由ですごく汚いコードを書かないといけない時がある。また私は他人のコードを引き継ぐ場合は必ず相手の設計思想に合わせるようにしている(今まで複数の設計思想が交わったスパゲティコードを何度見てきたことか)。毎回どんな時も同じような設計になるプログラマーは、その人の中に絶対的正義があるんじゃない、ただその人が持っている設計の選択肢が少ないだけだと思っている

 「実装速度」「拡張性」「汎用性」「可変性」「デバッグしやすさ」「依存性」「可読性」「実行速度」「省メモリ」「並列性」「チームメンバーの慣れ」などなど意識すべきことはいろいろあるが、どんな時も似たような設計ではなく状況にあった適切な設計ができるようになってきたころから、重要な設計を任されやすくなったと感じている。

1人前のデバッグを目指して ~メモリの海を泳ぐ~

画像1

画像2

画像3

 ゲーム開発をしていると必ず開発終盤にバグの修正が仕事の大部分を占める時期がある。チェックチームからバグ報告が上がってきて原因を調査して修正の繰り返しだ。このような時、バグ報告にはダンプファイル が添付され解析する必要も出てくる。ダンプファイルとは、ゲームがフリーズすると吐き出すデバッグに必要な情報が入ったファイルだ。

 このダンプファイル を解析する時、呼び出し履歴、ローカルウィンドウ、ウォッチウィンドウだけで調査してるプログラマーがいる。簡単なバグならそれで十分だろう。

 最適化されたReleaseビルドのダンプファイルの場合、最適化によって、ローカルウィンドウに変数が表示されてなかったり、ソースコード上の停止位置と実際の停止位置がずれている場合もある。またバグによっては、関係ない場所に根本的な原因がある場合もある。

 そのような場合、逆アセンブラ、レジスタ、メモリも駆使しないと追えない場合が出てくる。逆アセンブラで正確な場所を把握し、レジスタ上の変数の値を確認し、メモリを覗いてウォッチも駆使して様々な情報を取得する必要が出てくる。時としてシンボルファイルがなくてウォッチも使えなくてレジスタとメモリと逆アセンブラのみで同様のことをしないといけない時もある。

 元職場にはデバッグが非常にうまい人がいて、逆アセンブラ、レジスタ、メモリ、ウォッチの効果的な活用方法をたくさん教えてくれた。
 効果的にデバッグできるようになり難しいバグの原因も人より早く追えるようになると、開発終盤に同僚から頼られるようになった実感がある

 逆アセンブラ、レジスタ、メモリを正しく使いこなせてこそ1人前だと考えている。これがUnityでC#を使ったゲーム開発だとしても、Windows版をIL2CPPでビルドしていたり家庭用ゲーム機版を作るなれば、ダンプファイル解析で逆アセンブラ、レジスタ、メモリを正しく見るのは必要なスキルである。

1人前の最適化を目指して ~計画性を持つ~


 ゲームプログラミングにおいて、ゲーム以外のプログラミングと比べて優先度が高い要素は何か。面白いかどうかが大事とかもあるが、処理落ちしないことだ。快適にユーザーにプレイ体験を届けるには処理落ちしないことは重要である。

 大体、ある程度開発が進みだすとリーダークラスのプログラマがゲーム全体のプロファイリングをして最適化をしていることが多い。開発初期の段階で、正確にCPUリソース/GPUリソースをどの処理にどのくらい使うようにするのが適切か、ある程度は見積もりできても正確に見積もりするのは難しい。

 とは言っても、普段のプログラミングの中でも意識することはいくらでもある。意識されていないコードを見ると、数フレームに分けられる処理を1フレームでやろうとしてそのフレームだけ処理落ち、巨大な配列をO(N)で検索、キャッシュ化されてない検索処理や重い計算、スレッドの優先度が不適切、毎フレーム重いアローケーション、Unityなら膨大なGC Allocを発生させるなどなど。
 UnityならProfilerが付属しているし、他でもプロファイリングツールは提供されているので、いつでも重い処理がどこにあるかは調べられる。

 大事なことは、目標FPSを意識し、自分の担当箇所に使えるCPU/GPUリソースとCPUコアの把握すること。プログラミングする時も、ついでにできる最適化はその場でして、時間がかかる最適化は「ここがボトルネックになったらこう最適化する」という計画を立てておくことが大事である。キリがいい時にプロファイラーで測定して、最適化もマルチスレッドを使った並列化も含めてやれるようになること。
 なので処理が重い実装になったとしても「自分の担当箇所は使えるCPUリソースに余裕があるので、実装しやすさを優先してあえて冗長的に設計しました」と言うなら全然ありである。大事なのは計画的な最適化だ。

 開発初期から最適化に関する計画を立てながら動き、マルチコアを意識した効果的で安全な並列化を含めた最適化をできるようになっていくと信頼に繋がっていった実感がある

1人前のゲームプログラマーを目指して ~ キャリアとしての1人前を考える ~

 これまではプログラミングの話だったが、ここではゲームプログラマーをキャリアとしてどう考えていたのかも書いておく。

 会社に入社して、私は1人前のゲームプログラマーとは何かを考えるようになった。1人前だなと思う先輩を見ていくうちに、以下の三つのスキルが少なくとも一つは優れていてチームに貢献している人と考えるようになった。もちろん全て優れてると感じた人もいるが、どれか1つだけ優れていて一目置かれてる人もたくさん見てきた。

 1.  テクニカルスキル
  → 純粋なプログラミング能力の高さであったり、最新技術のアンテナの広さであったり、数学物理と言った技術的専門知識の深さであったり、この人にだからこそお願いできる技術的な仕事があるレベルのスキルだ。
 2.  クリエイタースキル
  
→ ゲームの体験価値や面白さに関わる部分をお願いすれば、妥協せず、どんなに仕様や素材に問題があったとしても自律的にまとめあげ、必ず商品レベルまたはそれ以上のアウトプットを出すレベルのスキルだ。
 3.  マネジメントスキル
  → 見積もりスキルであったり、タイムマネジメントスキルであったり、コミュニケーションスキルであったり、若手の育成スキルであったり、この人に人をつけて仕事をお願いすれば、問題は必ず共有がされて短期的にも長期的にも適切なプロジェクト進行をしてくれるレベルのスキルだ。

 私は自分のスキルを、この三つに分類して自己評価するようにした。私の場合さらに、各スキルをもう少し細かく分析して自分の長所や興味を持てそうな部分を見つけ、そこを伸ばすようにした。会社の中で様々なプロジェクトで自分の担当や立場が変わるたびに、今回自分が求められている貢献スキルはどれで、どこなら貢献できるかを考え行動するようになった。

 この考え方でキャリアを積んでいったが、あながち間違っていなかったかなと考えている。

何故1人前のゲームプログラマーを目指したか

 ここまでやってきたこと考えたことをいろいろ書いてきたが、根本的なこれも明文化しておく。

 私は「会社に依存したくない。いざとなったらどこでも生きていけるようになりたい」という気持ちが人一倍強かったのだと思う。常に人生の選択肢を狭めず、やりたいことをやれるようになるには1人前になる必要性を強く感じたからだ。

 だからこそ会社に所属している間には会社に貢献しようという気持ちは強かったし、ちゃんとそれを見てくれて成長させてくれた会社には感謝の気持ちで一杯である。

 会社のおかげで少しは一人前になれたかなとは思っている。

最後に

 ここまでいろいろ書いたが、これはあくまでも私が実感した話である。ゲームプログラマーは十人十色。いろんな人がいる。あくまでもこんなことを考えて動いていたゲームプログラマーが一人いたんだ、くらいに思っていただけたら嬉しい。終わり。

この記事が気に入ったらサポートをしてみませんか?