「敵は最大何体まで?」を仕様にする――数の増え方と1フレームの持ち時間
任天堂の「開発者に訊きました:ピクミン4」(2023年7月20日)には、たくさんのキャラクターを登場させるための工夫が語られている。NINTENDO64で開発していた頃は、ビルボードと呼ばれる平面の板を組み合わせてキャラクターをつくり、処理を軽くしていた。ゲームキューブへ移ると、1匹ずつ3Dモデルで表現できるようになったという。[1]
大勢が動く楽しさを実現するには、その数を支える技術が要る。仕様書に「敵は最大〇体まで出る」「全員が互いにぶつからないように動く」と書くときも、同じ問題がある。その一行は、短い時間の中でコンピュータにどれだけ働いてもらうかを決めている。
敵が2倍になれば、必要な計算も2倍で済むだろうか。仕事の内容によっては、約4倍に増える。今回は、この 数を増やしたときの仕事の増え方(計算量) を考える。
本稿は「ゲームプランナーのためのコンピュータ科学」の第5回である。第1回の「ゲームの上限値はどう決まるのか」で扱った数を記録できる範囲に続き、ここでは 1台の機械が1フレームの中で処理しきれる範囲 に注目する。目標は、上限数と一緒に「誰と関わるか」「どれくらい頻繁に調べるか」を仕様に書けるようになることだ。
1. 1フレームには、短い持ち時間がある
ゲーム画面をつくる1回分の画像を、フレームと呼ぶ。60fpsは1秒間に60フレーム、30fpsは30フレームを表示する速さだ。1秒をその回数で分けると、1フレームの持ち時間が分かる。
Unityの公式資料は、60fpsなら1フレームあたり約16.66ミリ秒、30fpsなら約33.33ミリ秒を予算として示している。ミリ秒は1秒の1,000分の1である。[2]
| 目標とする表示の速さ | 1フレームの持ち時間 |
|---|---|
| 60fps | 約16.66ミリ秒 |
| 30fps | 約33.33ミリ秒 |
この持ち時間には、キャラクターの移動、ぶつかっているかの判定、演出、画面を描く仕事などが入る。実際の機械では役割を分担して並行に進める部分もあるが、それぞれが次の画面に間に合う必要がある。敵を動かす処理だけで予算を使い切るわけにはいかない。間に合わなければ画面の更新が遅れ、処理落ちやフレームレートの低下として表れる。[2]
さらにスマートフォンでは、長く遊んだときの発熱や電池消費も考える。Unityは対策の一般的な目安として、約35%の空き時間を残すことを勧めている。どの端末にも一律に当てはまる保証値ではないが、 持ち時間いっぱいまで仕事を詰めない という考え方が大切になる。[2]
上限を考えるときの問いは、「敵だけなら何体動くか」から「演出も重なる場面で、必要な仕事が持ち時間に収まるか」へ進む。
2. 一体ずつ動かす場合と、全員同士を比べる場合
一体ずつなら、数に比例して増える
まず、決まった方向と速さで敵を動かす場面を考えよう。それぞれの敵について、次の位置を1回ずつ計算するとする。
10体なら10体分、20体なら20体分の仕事になる。一体あたりの仕事が同じなら、 数が2倍になると、仕事も2倍 になる。
全員同士なら、相手も増える
次に「全員が互いにぶつからないように動く」を考える。実現方法はいろいろあるが、ここでは、ぶつかっていないかを全組み合わせで調べる方法から始める。
AとBを調べたら、BとAをもう一度調べる必要はない。また、AとAのように自分自身との組も除く。それでも、敵を1体増やすたびに、それまでいた全員との組が増える。
Robert Nystromの『Game Programming Patterns』「Spatial Partition」章も、戦場のユニットの全組み合わせを調べると、判定回数が数の2乗で増えることを説明している。[3]
具体的な回数を並べてみよう。右列は、一組につき1回調べる場合の回数である。
| 敵の数 | 一体ずつ、次の位置を1回計算する | 全員同士の組み合わせを1回ずつ調べる |
|---|---|---|
| 10体 | 10回 | 45回 |
| 100体 | 100回 | 4,950回 |
| 1,000体 | 1,000回 | 499,500回 |
右列は、敵の数をnとして n×(n−1)÷2 で計算した値だ。自分以外の相手を数え、AとB・BとAの重複分を半分にしている。
10体を20体にすると、組み合わせは45組から190組になる。数は2倍でも、調べる回数は約4倍だ。数が大きくなるほど、この増え方は4倍に近づく。
ここで比べているのは 仕事を繰り返す回数 である。位置の計算1回と衝突の判定1回では、かかる時間が違う。表だけから「1,000体は動かせない」「ゲーム全体が約4倍遅くなる」とは決められない。実際の時間は、処理の内容や実装、動かす機械で測る必要がある。
それでも、仕様書にある 「全員が全員に」「すべての敵が互いに」 は、数の2乗に近い増え方になる可能性の目印だ。こうした言葉を見つけたら、上限を確定する前にエンジニアと相談できる。
3. 近くの相手だけを調べる
全員同士を比べる方法から、調べる相手を減らせないだろうか。遠く離れた敵同士なら、今すぐぶつかる心配は小さい。
「Spatial Partition」章では、場所をマス目で区切り、そこにいるユニットをまとめて扱う方法を紹介している。近くの相手を探すとき、関係するマスから候補を取り出せる。境界を挟んで近接する相手もいるため、必要に応じて隣のマスも調べる。[3]
プランナーが仕様として決めたいのは、 どの距離まで相手を気にすればよいか だ。たとえば「互いに避ける」の対象を近くの敵に限れるなら、その範囲を伝える。範囲攻撃なら、届く範囲をはっきりさせる。それが、調べる候補を絞る実装の手がかりになる。

出典:Robert Nystrom「Spatial Partition」の説明をもとに作成。[3]
ここで仕様上の注意も見えてくる。同じ総数でも、広場に散らばっている場合と、狭い通路に集中している場合では、近くにいる相手の数が違う。 近くだけを調べても、全員が近くに集まれば候補は多い。 上限数に加えて、どれだけ密集する場面があるかも伝えたい。
なお、「近い相手だけに反応する」と決めることと、近い相手を効率よく見つけることは別の仕事だ。近いかどうかを全員同士で毎回確かめていたら、その確認自体に時間がかかる。プランナーが反応の範囲を示し、エンジニアが探し方を選ぶことで、仕様と実装がつながる。
4. 毎回必要な仕事と、少し待てる仕事を分ける
調べる相手の数に加えて、 調べる頻度 も変えられる。遠くで待機している敵の判断まで、目の前で攻撃してくる敵と同じ頻度で更新する必要があるだろうか。
『Factorio』の開発ブログ「Friday Facts #421」(2024年7月26日)は、作業ロボットの更新間隔を、移動中は最大20tick、静止中は最大60tickまで空ける工夫を紹介している。tickはゲーム内部の時間を進める1回分の単位で、画面を描くフレームとは区別する。この変更により、社内で遊んだセーブデータでは全体の処理性能が15%向上したという。[4]
動きを描く際は、記録した移動予定から表示位置を求め、滑らかに見せている。内部の更新を間引く工夫と、見た目の連続した動きを保つ工夫が組み合わされているのだ。[4]
同じ記事には、ロボットの充電や格納などを担うロボポートについて、特別な仕事がない間は更新を休ませ、必要になったら再開する改善もある。テスト用セーブデータで、ロボポートに費やす時間が1tickあたり平均1ミリ秒から0.025ミリ秒へ減った。こちらは ロボポート部分の時間 であり、ゲーム全体の処理時間ではない。[4]
これらの数値は、そのゲームとテスト条件で得られた結果である。自分の企画へ持ち帰れるのは、「少し待てる仕事はまとめて行う」「仕事がない間は休み、必要な出来事で再開する」という考え方だ。
仕様書では、「遠くの敵の判断は粗くてよい」「画面外のものは更新を減らしてよい」から、もう一歩具体的にする。
- 間引く対象:何を決め直す処理か。たとえば、待機中の敵が周囲を見直す判断。
- 許容する遅れ:出来事から反応まで、最大どれくらい待てるか。遊んだ感触を確かめ、秒などの単位で合意する。
- すぐに戻す条件:プレイヤーが近づいた、攻撃を受けたなど、通常の頻度へ戻すきっかけ。
画面外の敵でも、プレイヤーへ攻撃してくるなら結果は遊びに影響する。更新を減らす範囲は、見えるかどうかに加えて、 結果の遅れを許せるか で選ぶ必要がある。敵の判断をどう組み立てるかは「敵AI設計の実務」で扱っている。ここでは、その判断にどれだけの頻度が必要かを仕様にすることが焦点になる。
5. 上限は、最も数が多くなる場面とセットで決める
上限を考える出発点は、普段の散策よりも、ボスの召喚と増援イベントが重なるような場面だ。「通常は少ない」だけでは、その一瞬の持ち時間に収まるかが分からない。
たとえば、次の表を仕様書の相談項目として用意できる。これは特定のゲームの推奨値ではなく、自分の企画で数値や条件を埋めるための枠である。
| 決めること | 仕様書に書く内容 |
|---|---|
| 数の上限 | 通常の敵・召喚・増援を合計した同時存在数。画面外で動く敵も含むか |
| 上限に達したとき | 新たな出現を待たせる、見送るなどの挙動。進行に必要な敵の扱い |
| 関わる相手 | 誰と誰が反応するか。全員同士か、一定の距離にいる相手だけか |
| 更新の頻度 | 間引いてよい判断、許容する遅れ、通常の頻度へ戻す条件 |
| 最も厳しい場面 | 召喚・増援・密集・演出が重なる条件と、その再現方法 |
「全員同士」が含まれる項目は、早い段階でエンジニアに見てもらう。狙った遊びを保ちながら相手を絞れるか、更新の頻度を変えられるかを話し合い、試作を動かして上限を詰めていく。
最後の行は、そのままテスト項目になる。最も数が多い場面を対象機種で再現し、目標のフレーム時間に収まるかを測る。同じ数を狭い場所に集め、攻撃や演出も重ねる。更新を間引いた対象が一斉に通常の頻度へ戻る場面も確認したい。スマートフォンなら、長く遊んだ後も確かめる。
数を減らすと群れの迫力が弱まり、反応範囲を狭めると集団の振る舞いが変わり、更新を減らすと反応が遅れることがある。どこを変えても同じ遊びになるわけではない。プランナーの役割は、守りたい体験と、調整できる範囲を伝えることだ。
「最大何体か」「誰と関わるか」「いつ調べ直すか」 を一緒に書く。その三つが揃うと、仕様書の一行は、短い持ち時間の中で実現できる遊びを話し合う材料になる。
References
1. 任天堂「開発者に訊きました:ピクミン4 Chapter 1」 — 任天堂、2023年7月20日。ビルボードによる軽量化と、ゲームキューブでの3Dモデル化に関する神門氏の説明。
2. Unity「Best practices for profiling game performance」 — Unity、公開日記載なし(2026年9月25日確認)。「Set a frame budget」「Adjust frame budgets on mobile」を参照。
3. Robert Nystrom「Spatial Partition」 — Game Programming Patterns、公開日記載なし(2026年9月25日確認)。全組み合わせの比較、固定マス目、隣接するマスの扱いを参照。著者公開の章原稿でも本文を確認。
4. Rseding・boskid・kovarex「Friday Facts #421 - Optimizations 2.0」 — Factorio、2024年7月26日。「Roboports Optimization」「Smarter update of worker robots」を参照。改善値は各節のテスト用セーブデータにおける結果。
この文書は、Perplexity、Claude、ChatGPT の3つのAIの支援を受けて著述されたものです。引用画像を除き、MIT License にて提供されています。