ゲームワールド内の大量のエンティティをシミュレートするエレガントな方法


33

いくつかの機能を提供する多くの(多くの)エンティティが存在するゲームがあると仮定します。それらのすべてが常に必要なわけではなく、すべてのフレームで考慮する必要もありません。この問題が存在する私が取り組んでいる具体的な問題は、臓器を含む身体の詳細なシミュレーションです。

ゲームでは、各クリーチャーはより小さな部分(胴体、脚など)に分離された自身の体を持ち、これらの部分には体の中で特定の機能を果たす器官が含まれることがあります。臓器が現在目的を果たしているかアクティブであるかは、実際には明確ではありません。結局のところ、動物には空腹がある可能性があるため、何も消化する必要はありません。各フレーム内のすべてのオブジェクトをチェックまたはシミュレートするのは非常にばかげており、世界に多くのクリーチャーがいるとすぐに非常にコストがかかります。そのため、更新が必要なオブジェクトとそうでないオブジェクトを賢く区別する方法を考えていました。

私が思いついたことは、少なくとも大丈夫なソリューションのようです。シミュレートする必要のあるオブジェクトが存在する「アテンションスタック」と呼ばれる単純なキュー/スタックを作成します(基本的に、読み取られるとすぐに各要素が削除されます。順序は無関係です)。その必要性の注目は、単にスタックに自らを置くオブジェクトまたは他のオブジェクトによってそこに置かれています。これらのオブジェクトは、おそらくsimulate()関数を備えたシンプルなインターフェースを実装するでしょう。

私の以前の消化の例に適用すると、これは次のことを意味します。

プレイヤーはインベントリから食べるもの(パンだと仮定)を選択し、キャラクターの口に入れて、口を注意スタックに置きます。次のフレームでは、スタックから口が取り出され、そのsimulate()関数が呼び出されます。口なので、ここで噛むことをシミュレートするのが妥当でしょう。これは、食べ物を飲み込む準備ができると判断するまで、口がスタックの上に置かれ続ける数フレームの間続く可能性があります。この場合、口は噛んだパンを胃に入れます(直接そこに行かないことは知っていますが、単純化のために食道は省かれています)。これも注意スタックに置かれます。次のフレームでは、消化プロセスのシミュレーションが開始されます。残りの必要な器官についても同様です。

これに関する予測可能な問題は、アイドリングオブジェクトです。眠っている動物はこの良い例です。眠っている動物をスタックに置き、毎回目を覚ます必要があるかどうかを確認することで、前述のように行うことができますが、それが唯一行われているので無駄に思えます。オブジェクトをより効率的にアイドリングするために、特定の時間に実行されるジョブを保存する一種のスケジュールを追加することを計画していました。動物が眠りにつくと、動物が眠りについた後、一定の時間だけスケジュールされる仕事をそのスケジュールに入れます。このジョブは、眠っている動物を再びアテンションスタックに配置します。ここで、注意スタックにない睡眠動物は、AIがシミュレートされていないため、何かに攻撃されるのを逃す可能性があります。

今、私は正直、これが経験不足のためにこの問題のエレガントな解決策に近いかどうかわかりません。使用可能なものに近いですか?これは通常どのように行われますか、誰かが提案やより良い解決策を持っていますか?

回答:


10

これは、まさにStendhalでこの問題を解決した方法です。私たちのケースでは、定期的にではなく、毎ターン発生することがたくさんあります。癒しの呪文、植物の成長、死体の退化、地上のアイテムの有効期限切れ。

ターンごとに増加するターン番号があります。そして、そのターンで通知する必要があるオブジェクトのセットを指す将来のターン番号のマップを維持します。


その間に他の何かがオブジェクトと対話する場合はどうなりますか?たとえば、眠っている動物が石を打つことで目が覚めるかもしれません。その場合、動物のスケジュールを削除する必要がありますか?
エミリアーノ

それは状況に依存します:実行されたアクションが無害である場合(すでに起きている間に目を覚ますなど)、それをそのままにします。ただし、アクションがリソースを使い果たした場合、保留中のキューを検索して削除します。
ヘンドリックブルーマーマン

14

入力の問題と同様の問題のように聞こえます。キーボードには100以上のキーがありますが、すべてのフレームで個々のキーをチェックする必要はありません。

2つの答え:ポーリングまたはシステムメッセージ。

ポーリング=ゲーム内で実際に重要になる任意の時点で、キーボードキー(または、オブジェクトの場合)の状態を照会します。残りの時間は無視してください。

メッセージ=各キーボードキー(オブジェクト)が押されたときまたは解放されたとき(注意が必要なとき)にメッセージキューに何かを入れます。ゲームループの各反復で、キューを調べて、続行する前にすべてのメッセージを解決します。


10

そこで、実装か​​ら一歩戻り、設計の観点から質問を確認します。このシミュレーションに含めるすべての詳細を表示するための堅実な計画はありますか?

例えば:

  • プレーヤーは、空腹の動物と満腹の動物の違いを知ることができますか?
  • ゲーム内でインタラクションを選択している場合、この情報は何らかの形で彼らにとって重要ですか?
  • 動物を見ているプレイヤーは、シミュレートされたイベントの結果を常に予測できますか、それとも乱数で十分でしょうか?

基本的に、一般的な経験則は、シミュレーションを出力よりも複雑にしないことです。羊のアニメーションが放牧、眠り、逃げるだけである場合、一日の終わりに。その場合、どの状態を選択するかを決定する際に、いくつの要因が関係するかは本当に関係ありません。すべてのプレイヤーが見るのは、夜眠り、危険から逃げ、日中に食べる羊です。

ビヘイビアシミュレーションは取り組むのが非常に楽しいですが、常にエンドユーザーエクスペリエンスを念頭に置いてください。


はい、プレイヤーは違いを伝えることができ、ゲームプレイにはいくつかの効果がありますが、現時点では楽しみのための「仕掛け」のようなものです。ドワーフ要塞の傷システムのようなもので、これも非常に詳細ですが無視できます。しかし、すでに述べたように、作業するのはとても楽しいです。それが今の私の主な焦点です。
マークミュラー

9

数年前に取り組んだゲームでも同様の問題が発生しました。オブジェクトのシミュレーションは複雑で、世界のすべてのオブジェクトで実際に詳細に実行することはできませんでした。

解決策は、シミュレーションにLODコンセプトを使用することでした。プレーヤーのビュー内のオブジェクトは、完全なシミュレーションを実行します。プレーヤーから遠く離れたオブジェクトは、非常に単純化されたシミュレーションを定期的に実行しました。オブジェクトがプレーヤーのビューに入ると、それらはコースの定期的なシミュレーション更新から詳細な定期的な更新に移行します。


2

スケジュールのある解決策は良いです。すべてのエンティティには、将来のアクションへのポインタのリストが必要です。これにより、必要に応じて将来のアクションを無効にすることができます。すなわち。眠っている動物は攻撃されるとすぐに目覚めるので、今後はその目覚め動作を無効にする必要があります。


1

このためのデザインパターンがあります。データベースオブジェクトと呼ばれますか?

基本的に、ゲーム世界のすべての非特殊羊を表すことができる1つの「テンプレート」羊を保持し、それらをすべて同じ方法で描画し、テンプレートオブジェクト内に一意のデータを保持します。 -せん断後。その後、羊を一意にする必要があるときはいつでも、その一意の羊を追跡する特定のインスタンスを作成できます。

アニメーションについても同じことが言えます。すべてのインスタンスに共通のアイドルアニメーションまたはイベントの場合、テンプレートインスタンスに常駐でき、より具体的なアニメーションを個別にスケジュールできます。

ずっと前に、メインループがシーン全体でanimate()と呼ばれるプログラミングコンテストのゲームを書いた。関数ポインターを使用して、必要に応じてアイドルアニメーションを他のアニメーションに置き換え、継承されたアニメーション(たとえば、回転ディスク上に立っているキャラクターの回転)をサポートする手法を使用しました。

これは、アニメーションにデリゲートを使用することに本質的に似ています。


3
フライ級パターン、という意味ですか?
右上

0

ステートマシンは機能しますか?動物は、睡眠状態、摂食状態、走行状態などのいずれかです。状態ごとに、活動臓器のリストを関連付けます。したがって、各動物を訪問する各フレームは、状態を切り替え、その状態の臓器のリストを検索し、各臓器で更新を実行します。


動物内で複数の事柄が発生する可能性があるため、事態は複雑になると思います。たとえば、胃が何かを消化しているからといって、心臓が鼓動を停止したり、動物が歩行を停止したりするわけではありません。もちろん、特定の機能を考慮に入れた状態のセットを定義できますが、状態の量はめちゃくちゃ膨大になります。
マークミュラー

状態ごとにすべてのアクティブな臓器を保存し、各フレームごとに実行するため、状態ごとに複数のことが発生する可能性があります。ただし、シミュレーションで起こることの多くは、状態遷移に適合するようです。例えば、噛む->消化。しかし、動物は1つの状態しか持てないというのは正しいと思います。消化器系で起こっている状態遷移とは無関係の手足で起こっている状態遷移があります。しかし、おそらくあなたが持っているものよりも複雑です。考えてみてください。
エリックEngheim
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.