ゲームプログラマのための設計シリーズ:原理・原則編の記事です。
概要
- YAGNIと、ゲーム制作における事情
- 設計におけるKISS原則とは
本文
ゲーム開発とYAGNI
YAGNI(You Ain't Gonna Need It)とは、機能は必要になるまで追加しないという原則です。
プログラムにコードを追加すると
- 書くのに時間を費やす
- コードを読むために必要な時間が増える
- エンバグしてしまうかもしれない
- ビルドにかかる時間増大
- 場合によっては実行速度の低下
などいろいろなリスク・コストが発生します。必要な機能なら当然これらを飲むしかないわけですが、本当に必要になるかわからないような予測に対してこれらのコストを払うのは割に合わないよね、という経験則です。
これは機能そのものだけではなく、設計に対しても同じことが言えます。将来拡張するかもしれない・・・と思って今必要ないインターフェースをこしらえたり凝ったデザインパターンを適用して過剰設計に陥ってしまう経験は自分にもあります。かといって、いつかは設計(抽象化)を施さないとコートベースは徐々に混沌と化してしまうのです。一体いつ設計を改善(リファクタリング)するのが良いのでしょうか?
人によりいろいろ流儀があるとは思いますが、ゲーム開発においては
- ①機能追加が必要となったが、現状の設計ではそれがしにくい場合
- ②アーキテクチャ上の境界なら、いつでも
の二点が特に設計を重視すべきところで、必要ならリファクタリングを要するところかなと思っています。
①については、書籍「リファクタリング 既存のコードを安全に改善する」でもこう述べられています。変更を予期して設計するのではなく、必要になったタイミングで現状にとって適切な設計になるようリファクタリングを施すわけですね。「現状の設計だと、新機能を足そうと思うとコピペコードだらけになるなあ・・・」などと思ったときに、機能追加された世界に最適な設計を施します。
当然ですが、リファクタリングと機能追加はコミットをきっちり分けるのを忘れずに。
②は、ゲームプログラムをざっくり「キャラクターのAI」「物理挙動やコリジョン」「UI」「グラフィックス」「サウンド」「ゲームシステム(スコア計算とか、シーケンスの進行など)」くらいに分けた際の境界です。担当者が異なることも多く、それぞれの独立を保てないと作業もテストもし辛いです。ここは最初から時間をかけてでも設計に気を使うべきところでしょう。
世間ではほかにも様々な意見が展開されています。
- 将来の変更を予測して見極めよ
- 常に一定のコストをかけてリファクタリングを進めよ
などといった方針も挙げられていますが、特に新規ゲームの開発では仕様変更が激しく予測が非常に難しいこと、基本的にプログラマは開発中ずっと忙しいことからこれらの方針は向かないかな~と感じています。
もしリファクタリングのための期間を数日間設けてもいい!と言われたらそれはうれしいですが、結局その後の仕様追加で結局だんだんと歪みが蓄積してしまいますし、仕様が固まるころには時間もなくエンバグのリスクもあるのでリファクタリングどころではないでしょう。
KISS原則
つまり必要な時が来るまでシンプルに保つ、つまりKISS原則(Keep It Simple Stupid、シンプルで愚鈍にする)に従うわけですが、設計における「シンプル」とは何でしょうか。自分は 「利用&依存している状態と前提知識が少ないほどシンプルである」 という風に捉えています。
明確に依存といえるライブラリなど他のプログラムの部位だけではなく、プログラミング言語の言語機能の利用も含めた意味で「利用&依存」という言葉を用いています。どんな言語でも同じように書けるのであればそれは前提知識が少ない≒シンプルであると言えるのではないでしょうか。
シンプル順 | 形態 | 備考 |
---|---|---|
1 | 純粋関数 | 引数以外の依存なし。ほとんど言語機能依存なし |
2 | 純粋でないグローバル関数 | グローバル変数に依存。ほとんど言語機能依存なし |
3 | (既存の関数内にインラインでの記述) | ローカル変数に依存。言語機能依存なし |
4 | クラス(継承なし) | メンバ変数への依存。クラスという言語機能の利用 |
5 | インターフェース(継承) | クラス&継承という言語機能の利用。継承の階層構造の知識を要求 |
6 | 有名なデザインパターンの利用 | 多くはクラスや継承という言語機能の利用。そのデザインパターンへの知識を要求 |
7 | それ以外のマイナーパターンやオレオレアーキテクチャ | 前提知識の持ちようすらなく困難 |
多少のコードの重複を許せばシンプル順を上げられるのであればそうする、くらいの気持ちで取り組むのがオススメです。