格闘ゲーム開発で学んだ「危険な共通化」の話―若手と、過去の自分に向けた設計メモ
Photo by Attentie Attentie on Unsplash
これは、若手ゲームプログラマーの皆さんと過去の自分に向けた設計メモです。
格闘ゲームは、共通化の判断ミスが一番はっきり表に出るジャンルです。
キャラが増える。
技が増える。
調整が入る。
そのたびに、「あのときの共通化、やらなければよかった」というコードが増えていきます。
目次
- DRYとOCPをあらためて整理する
- DRYを意識しすぎると起きること格闘ゲームでは、攻撃処理が大量に出てきます。
- 調整フェーズで必ず崩れる
- 何を共通と見なすか
- OCPを意識した設計にするとどうなるか
- 過去の自分に対してのアドバイス
- おわりに
DRYとOCPをあらためて整理する
まず、言葉を一度ちゃんと揃えておきます。
DRY(Don’t Repeat Yourself)
同じコードを何度も書かない、という原則。コピペを減らし、修正箇所を一箇所にまとめるための考え方です。
OCP(Open-Closed Principle:開放閉鎖の原則)
既存のコードを変更せず、拡張によって機能を追加できるように設計しよう、という原則です。
どちらも正しい。ただし、優先順位と適用範囲を間違えると事故る。
このメモの結論はシンプルで、
DRYよりも先にOCPを考えろ
という話です。
DRYを意識しすぎると起きること格闘ゲームでは、攻撃処理が大量に出てきます。
- 通常技
- 必殺技
- 投げ
- 空中攻撃
若手(と過去の自分)がやりがちなのが、
「攻撃処理はだいたい同じだから、まとめよう」
という判断。
確かに、ヒット判定、ダメージ計算、硬直処理は似ています。
ここでDRYだけを見てしまうと、1つの巨大な攻撃関数が生まれます。
調整フェーズで必ず崩れる
開発最終版、必ず企画からこんなリクエストがあります。
- このキャラのこのアクションだけ無敵時間を発生させたい
- この技だけ派生させたい
- この投げは演出優先にしたい
すると共通関数の中に、
- if キャラA
- if 技ID == ○○
が積み重なります。
気づいたときには、誰も触りたくない神モジュールが誕生してしまいます。
これはDRYを守った結果ではありません。DRYを誤用した結果です。
何を共通と見なすか
ここで立ち止まって考えるべきなのは、
- その技は何のために存在しているか
- 将来、同じ理由で一緒に変更されるか
格ゲーの必殺技や超必殺技は、別キャラの見た目が似ていた技があったとしても、役割も変更理由も違います。だから後半で必ず分岐します。
OCPを意識した設計にするとどうなるか
安全なのは、
- 攻撃処理の骨組みだけを安定させる
- 技ごとの差分は拡張で表現する
設計です。
- 攻撃開始〜終了の流れ
- ヒット判定のタイミング
ここは閉じる。キャラ固有・技固有の部分は開く。
そうしておくと、
- 新キャラ追加
- 技調整
- パッチ対応
で、既存コードを壊さずに済みます。
過去の自分に対してのアドバイス
- 共通化=似ているものをまとめる、ではない
- DRYは「目的と変更理由」が一致したときだけ使え
- 迷ったらOCPを優先しろ
- 格闘ゲームは後半ほど例外が増える前提で設計しろ
若手の頃の自分に一言だけ残すなら、
今は同じでも、
後で別れるものは最初から分けておけ。
それだけで睡眠時間は増えるし、デートをキャンセルして彼女を怒らせずに済みます。
おわりに
X(旧Twitter)やBlueskyを中心に日々発信しております。
ご興味をお持ちいただけましたら、ぜひ弊社Webサイトや私のXもご覧いただけますと幸甚でございます。
https://www.tatsu-mi-systemsolution.jp/
https://x.com/itchie_tatsumi
https://bsky.app/profile/itchie-tatsumi.bsky.social