『関西ゲーム勉強会 2016夏』に参加してきました!
300人規模の勉強会で驚きました。
年に2回ほど開催していて、この冬にも開催予定だそうです。
その中で、サイバーコネクトツーのシニアプログラマーである猪上哲郎さんの講演「多人数格闘アクションゲームにおけるAIの設計と実装」でメモしたものを記事にしておきたいと思います。
前置き
月に一度、社内のプログラマー内で講義を行っている
情報共有を行う試み
扱うテーマは様々で、言語仕様・グラフィック・ローカライズ・ゲームエンジン・AIなど
今日は実際にプロジェクトで使ったAIの実装手法について取り上げる
うまくいった部分もある半面、犠牲にした部分もある
AI実装の背景
◆ジャンル
ジャンルは対戦3D アクションゲーム
敵味方が複数存在
ステージは立体的な構成
アイテムやギミックも配置
◆物量
50を超えるキャラ分のAIを実装 難易度を合わせるとx何倍となる
プロジェクトによっては100を超えることも珍しくない
キャラの性能をカテゴライズしそのカテゴリ分のAIを用意することで対応
例えば遠距離キャラ・近距離キャラなど分類
しかし性能がユニークなものが多く通用しそうになかった
◆AI実装人数
PGひとりという状態
他のものも担当するので専任ではない
50超x難易度
◆見積もり
まともにやるとこなせない量 ⇒ 工夫が必要!
◆PG以外のセクションと作業分担
プログラマで部品を作り、ゲームデザイナーに調整込みで組み立ててもらう
どういったツールにしようか
ツールのイメージ
◆どんなツールが必要か
① シンプルなものが必要
スクリプトのように自由度が高いのは複雑なものも組めてしまうので除外した
できるだけ簡単に扱えるものがいい
② 当時ノードベースのグラフィカルスクリプトが流行っていた
ツール作成に時間がかかる 工数で折り合いがつかない
スクリプト同様自由そう ‥という理由から却下
③ 昔のプロジェクトで「コンボテーブル」というものを使ったことがある
近距離、中距離、遠距離に応じて行動をいくつか登録しておきランダムに選択
しかしそれよりもゲームが複雑なので拡張が必要だった
◆拡張要望
① 距離以外の条件も扱えるようにしたい
残体力、標的との間の障害物の有無なども行動の選択する際の条件にしたい
より細かく行動ごとに実行条件を付けていきたい
論理演算も使えるようにする
② 実行可能な行動が複数あったときに乱数以外の要素で偏りを入れたい
キャラの個性にあった行動を選択させたい
乱数だけだと同じものがずっと続く恐れがある もっと絶対的な偏りを入れたい
行動に優先度を持たせておき、複数並んだ場合は優先度が高い法を必ず選ぶ
③ 状況が次々と変わる場合に変化に順応していく
回復アイテムを取りに行く途中で敵を発見、攻撃的なキャラの場合は
取りに行くのをやめて敵を攻撃してほしい
何かを実行中に、より望ましい行動ができるようになったらそちらに繊維する
望ましさの定義に「優先度」を使用する
優先度が高いと割り込む
◆拡張要望まとめ
優先度の設定ができる条件付き行動テーブル
※ここで実際の表を表示しつつ説明
名前:コマンド1 優先度:1 ビヘイビア:パワーアップ 条件:パワーアップ可能
頻度:100 リキャスト:0
(‥というように各行動に6つの項目があり、いくつも行動が並ぶ)
補足
・優先度:高いものが上にいくようソート
・条件:行動を行うための条件
・頻度:複数の選択肢が出てきた場合にひとつを選ぶための指標
(くじ引きのあたりの数)
・リキャスト:行動完了後しばらく行えなくなる時間 単位はフレーム
① 優先度が高く、かつ条件を満たしているものがあるものから実行する
② 一度実行したものはしばらくの間実行できなくなる(リキャスト)
③ 何かを実行中にに、より優先度が高い行動が行えるようになったらキャンセルする
④ 同じ優先度のものが複数候補に挙がった場合は頻度に従って選択する(頻度)
・優先度が高いほうから順に実行可能なものを探す
・同じ条件のものが複数ある場合、頻度に従ってどちらかを選ぶ
コマンド5は頻度100、コマンド6は頻度80の場合‥
計算式は 100/(100+80)*100=56%
コマンド5が選ばれてパートナーに近づくという行動を実行
・キャンセルして割り込みができるのは優先度が高いものだけ
‥これを繰り返す
◆やりたいことを追加
とある条件を満たしたときに、行動内容を「がらっと」変えたい
例:体力が一定割合いかになった後は強烈な技を連発してくる ボスキャラなど
⇒ テーブルを複数所持できて、切り替えられるようにする
(条件追加もできないことはなかったがやると複雑になるので)
例:体力2割以上はテーブルA 2割未満はテーブルB
プログラマーの実装
プログラマは何を実装したのか?
◆PGが作る部品
主に以下の5つ(量産対象は2つ)
① 行動(ビヘイビアクラス) 量産対象
② 条件(コンディションクラス)量産対象
③ 選択アルゴリズム(セレクタ)コア
④ コントローラクラス
体を動かすためのインターフェース
ツールからは見えてこない部分
⑤ センサークラス
AI内外の状態を監視し、更新する部分 ツールからは見えてこない部分
◆①行動
1選択肢につき1クラス
◆1選択肢につき1クラスを対応させる目的
・他の選択肢との依存性をなくすため
どういった流れで行動が開始されても不都合なくつながるように
・行動をきれいに終了させるため
投擲物を拾って投げる行動の場合、持ったまま行動を終了してしまうと
投擲物を本来扱わない行動側で投擲物の後始末をしないといけなくなる
終了時に使い切ってから終わる(キャンセルの場合も同様)
◆②条件
1選択肢につき1クラス
◆③選択アルゴリズム
ルール通りのアルゴリズムを組むだけなので割愛
◆④コントローラークラス
体を動かすインターフェース
対戦キャラクターゲームの場合操作の方法は大きく二つ ゲームパッドとAI
二つの操作方法を別々の実装にすると片方はできるが片方はできなくなることがある
◆⑤センサークラス
AIの内部状態の更新と外部の把握を行うクラス
最も負荷になる部分なので「負荷対策」を行った
⇒ 情報の更新頻度を細かく調整できるようにしている
例えば自分の周りの壁の状況を確認 四方八方にレイを飛ばすのは負荷が高い
1フレ-ムに5個までというような制限をかけて、残りは別のフレームに分散する
負荷の分散をセンサークラスで担っていた
結果
作業分担をした結果
◆目標に対しての成果
50超のAIを少ないPGでこなすという目標は達成
五月雨式の量産が行えた
ゲームデザイナーもすぐに使い方を理解してくれて実装、調整を行えた
◆良かったこと
行動、条件が細かくカプセルかされたことに伴い、不具合の追跡が簡単だった
未完成のキャラも完成している部分だけを先行して作業できた
◆うまくいかなかったこと行動の独立性が高く、複数の講道館のつながりが乏しかった
例:特定の行動を行った後に条件次第で追撃させたい
行動履歴を条件下することで可能ではあったが、直前の行動を条件として
続いてやってほしいことを優先度が高いところに配置するしかなく、
テーブルの見た目的にどうリンクしているかが見えなかった
⇒ 解決案:
行動の後に「サブテーブル」へジャンプ、一時的にそのテーブル内で行動させる
おおもとのルールを変えることなく適応させられる
例:場同じ条件で複数の行動を登録したい
条件を複製し、登録したい行動に張り付けていけば可能だったが
内容を変更したくなった場合にすべてを修正する必要があった
また、発動条件を持つものは「リキャストを共有」させたかった
まとめ
・作業分担して量産を行える 部具合も追跡しやすい
・タイトルに依存しないので別ジャンルのゲームにも応用が利く
・出来上がったAIの動きとしては反省点も多かった
複数の行動間のつながりが弱かった
後から出る要望や試行に対応しにくい
・ツールorプログラム?
適材適所
用途に合わせて使い分けるのが良い
ボスはユニークな制御が多い
例えば、印象的なボスはプログラムで作り、ザコはツールで量産など
最後に
弊社のAI実装は、各プロジェクト内の担当たちが試行錯誤して実装する形をとっており、研究・リサーチされた成果が各プロジェクトとに還元されるということはできていないので‥
このような機会に交流、勉強したい
Q&A
◆Q.ツール作成の工数は?
A.ツール作成コストは1カ月くらい
ツールプログラマに任せたので思ったより少ない工数
◆Q.AIの難易度に関して難易度別への対応は個別にテーブルを用意したのか
A.そうなる
1つの難易度ごとにファイルが分かれている 完全に別のテーブルで制御