人工知能半減期SDK:回顧

画像



1998年のリリースの時点で、Half-lifeはそのゲームデザインを温かく歓迎しました。これは、人工知能のおかげで可能になりました。 AIのこの影響はそれをもたらしました。 HL が歴史上最も重要なゲームの 1つと呼んだもの。



そして20年後でも、そのコードを研究して、 シンプルだが効果的な AIシステムの作成について多くを学ぶことができます。 すべてのAIロジックはC ++でハードコーディングされており、オブジェクト指向ではありません。したがって、最近のエンジンよりも理解しやすい(拡張はそれほど簡単ではありませんが)。



この記事では、Half-Life 1のオープンSDKを見て、タスクスケジューラシステム、その実装(ステートマシンに類似)、センサーシステムなど、AIのさまざまな側面を分析します。 記事を読んだ後、これらの概念を使用する原理とゲームでの実装をより深く理解できます。



協調型AIとモンスター

スクリーンショット1:ガードバーニーがモンスターの1人と戦っている



Half-Life SDKをダウンロード



Half-LifeのValve SDKのインストールは非常に簡単で( FEARツールとは異なります )、MODを開発する場合は元のゲームのみが必要です。 必要なものは次のとおりです。



  1. Half-Life SDKのバージョン2.3をダウンロードするか、リソースのないソースのみを ダウンロードするか、モデルを含む完全なSDKのコピーをダウンロードします。
  2. SDK modを使用して開発したい場合は、ファイルを任意のディレクトリ(できればゲームのあるフォルダー)に解凍します。 数秒かかります。その結果、モデルとソースコードを含む多数のカタログが作成されます。


Half-Life SDK AIファイル

スクリーンショット2:Half-Life SDKバージョン2.3のC ++ゲームコード。



私たちはコードを扱います



コードベースは、FEARやQuake 3ほど構造化されていません。 いくつかのサブディレクトリがありますが、ファイルにはあま​​り明確な名前がなく、C ++クラスの実装はいくつかのファイルに散らばっており、その名前からはほとんど何も理解できません。





AIを学習または変更する場合、ゲーム内のさまざまなアクターの動作が含まれているため、ほとんどの時間を/dll/



ディレクトリに費やします。



科学者AI

スクリーンショット3:科学者とのゲームのカットシーン。



プランナーと目標システム



schedule.[h,cpp]



ファイルには、非常に単純な目標駆動型システムが含まれています。 これは、手続き的に組み合わせることができるいくつかのレベルのタスクで構成されています。



タスク



タスクは、特定の目的を持つ短い霧化された動作です。 たとえば、ほとんどの俳優ハーフライフは、次のタスクをサポートTASK_WALK_PATH



TASK_CROUCH



TASK_STAND



TASK_GUARD



TASK_STEP_FORWARD



TASK_DODGE_RIGHT



TASK_FIND_COVER_FROM_ENEMY



TASK_EAT



TASK_STOP_MOVING



TASK_TURN_LEFT



TASK_REMEMBER



。 これらはヘッダーファイルの列挙として定義され、C ++メソッドとして実装されます。



条件



条件は、世界の俳優の状況を表現するために使用されます。 論理セットは堅固、条件が非常にコンパクトビットフィールドとして表現することができるが、その場合に条件はたとえばより32ではないかもしれないので、条件はCOND_NO_AMMO_LOADED



COND_SEE_HATE



COND_SEE_FEAR



COND_SEE_DISLIKE



COND_ENEMY_OCCLUDED



COND_ENEMY_TOOFAR



COND_HEAVY_DAMAGE



COND_CAN_MELEE_ATTACK2



COND_ENEMY_FACING_ME







計画



計画は一連のタスク(任意のパラメーター)で構成され、条件のビットフィールドを考慮して、計画が適用されない時期を判断します。 デバッグを容易にするために、プランオブジェクトには名前があります。



目標



目標はより高いレベルにあり、計画で構成されています。 目標のロジックは、必要に応じて、失敗したタスクと現在のコンテキストに基づいて計画を選択できます。 Half-Lifeの目標の例: GOAL_ATTACK_ENEMY



GOAL_MOVE



GOAL_TAKE_COVER



GOAL_MOVE_TARGET



およびGOAL_EAT







Valveが使用するコードはQuakeエンジンから抽出されたものであり、C ++に変換されたという事実にもかかわらず、かなり明白です。 ファイルと構造体の名前は似ています。





スクリーンショット4:空tro部隊が研究センターで警報を発しました。



ステートマシン



実際には、これらの計画とタスクはすべて、ステートマシンに似た構造で互いに接続されています。 最上位では、 monsterstate.cpp



の関数が呼び出されてAIが更新されます。



 void CBaseMonster :: RunAI ( void );
      
      





次に、 MaintainSchedule()



最新計画の適用可能性を確認しMaintainSchedule()



GetSchedule()



を使用して新しい計画を選択するオーバーロード関数を呼び出します。 生成されたクラスの助けを借りて、ニーズに応じて変更できます。たとえば、 barney.cpp



またはscientist.cpp



参照してください。



下位レベルでは、 StartTask()



およびRunTask()



関数は、 enum



構造で定義された各タスク識別子のロジックを実装します。 これらはCBaseMonster



から継承されたクラスにも実装されています。 その結果、 switch



構造として実装されたステートマシンによく似ています。



 void CScientist :: RunTask( Task_t *pTask ) { switch ( pTask->iTask ) { case TASK_RUN_PATH_SCARED: if ( MovementIsComplete() ) TaskComplete(); if ( RANDOM_LONG(0,31) < 8 ) Scream(); break; case TASK_MOVE_TO_TARGET_RANGE_SCARED: /* ... */ break; case TASK_HEAL: if ( m_fSequenceFinished ) { TaskComplete(); } else { if ( TargetDistance() > 90 ) TaskComplete(); pev->ideal_yaw = UTIL_VecToYaw( /* ... */ ); ChangeYaw( pev->yaw_speed ); } break; default: CTalkMonster::RunTask( pTask ); break; } }
      
      





より典型的なアプローチは、これらの各case



ブロックを独自のクラスで実装することですが、既存の実装では、モジュール性を犠牲にして、必要に応じて別のオブジェクトのロジックを使用する方がはるかに簡単です。



また、AIには2つの状態が保存されることに注意してください。 したがって、ゲームコードを使用すると、アクターの目標を簡単に作成し、それらを達成するための最良の方法を見つけることができます。 これは、有限状態マシンと集中システムの興味深い組み合わせです。





スクリーンショット5:科学者とのゲームカットシーン。



センサーシステムの実装



ベースmonster.[h,cpp]



には、すべての俳優に視覚、嗅覚、聴覚を与えるコードがあります。



 void CBaseMonster :: Look ( int iDistance );
      
      





ビジョン関数は、 SF_MONSTER_PRISONER



SF_MONSTER_WAIT_TILL_SEEN



などのさまざまなフラグをチェックして、必要に応じて設計者に制御を提供します。 この式では、視界や視野角などのパラメーターも考慮されます。



 CSound* CBaseMonster :: PBestSound ( void );
      
      





聴覚と嗅覚のコードは同様に機能し、サウンドイベントのみを使用します。 モンスターの注意を必要とするオブジェクトのリストが保存されており、センサーシステムはフォーカスに最適なオブジェクトを選択します。



まとめと補足資料



一般に、このシステムの背後にあるソースコードは、単純ではありますが非常に有益です。 人工知能による意思決定の簡単な実装を選択する場合は、このアプローチを選択する必要があります。 ただし、各タスクを独自のオブジェクトに実装する価値がある場合があります。最近では、商用ゲームは通常このソリューションを使用しています。





スクリーンショット6:Half-LifeのElemental分隊の動作。



AI Half-Lifeコードには、他の興味深いアイデアも含まれています。



  1. ゲームコードは、ナビゲーションポイントを3Dベクトルと場所の種類のみの形式で表します! それらは下部ナビゲーションシステムに接続されていますが、モンスターが続く「パン粉」の古い学校のシステムでも使用できます。
  2. Half-Lifeは、ユニットの動作に多くの人を驚かせました。 ただし、ゲームにはこれらのユニットを制御する最上位のAIがありません。つまり、すべての動作は自然に現れます。


Half-Lifeのモンスター以外の何かを再作成する場合は、ボットフレームワークを学習することをお勧めします。 マルチプレイヤーゲーム用のAIボットを作成し、サードパーティのHalf-life MODで使用できます。 ここにあります:






All Articles