ゲームにダイアログツリーを実装するにはどうすればよいですか?


51

ゲームにダイアログツリーシステムを実装する最良の方法は何ですか?NPCに、プレーヤーにさまざまな応答セットを提供します。応答の一部は、プレーヤーにアイテムがあるか、前のイベントが発生したときにのみ表示されます。


2
BOUNTYは、特にトリガーフレーズとNPCテキストの翻訳を処理する方法に関する優れたアイデアです。NPCが会話を開始したプレーヤーに応じて異なる言語を理解して話すことができるように。gamedev.stackexchange.com/questions/31/のビルディングブロックアプローチを使用した場合でも、テキストリポジトリ内にロジックを配置することはお勧めできません。しかし、それらを分割すると、コードを理解することがはるかに難しくなります。
ヘンドリックブルーマーマン

回答:


17

ダイアログツリーはXMLを使用して実行する必要があります。より複雑な操作を行う必要がある場合は、スクリプトファイルへの参照を使用して、応答の条件と応答をネストされたツリーに保存します。

特に数トンの会話に値するRPGをまとめる場合は、スクリプトとダイアログを分離しておく必要があります。その後、simpleXMLなどのライブラリを使用して、XMLファイルを読み取ることができます。

SOについても同様の質問があります。例:https : //stackoverflow.com/questions/372915/game-logic-in-xml-files


XMLの場合は+1。コード自体に埋め込むよりもはるかに優れており、コードを再コンパイルせずに変更を行うことができ、いくつかの強力なエディターで読み取ることができる標準形式です。
AttackingHobo

34
XMLは単なる形式です(そしてIMO、悪いものです)。本当にこの答えは、「基本的なロジックとフローを含むが、主に対話で構成される小さなドメイン言語を作成し、それを解析する」ということです。その一般的な方法で、私はこの答えに同意します。
イプスィーク

5
正確には、XMLは単なるコンテナーであり、Luaまたは他のスクリプト言語を使用してこれを実装することもできます(そして、より人間が読みやすく、人間が編集できるように定義できます)。
LearnCocos2D

4
XMLは解析に費用がかかり、大量のメモリを消費します。ストレージ形式として使用しても構いませんが、ダイアログツリーを実行時に使用されるバイナリ形式に変換するユーティリティを作成します。PCでメモリ使用量を気にしない場合は問題ないかもしれませんが、他のプラットフォームではメモリコストがかかります。
BigSandwich

1
XMLの場合は-1。@Ipsquiggleと@BigSandwich
o0 '

20

私は、luaやrubyのようなスクリプト言語を埋め込み、ダイアログ対話をコーディングすることを検討します。

したがって、ダイアログスクリプトは次のようになります。

switch showDialog "Why don't you just leave me along!", "Okay", "But I found your dog!"
    case 1:
        showDialog "And stay gone!"
    case 2:
        if playerHasObject "dog"
            showDialog "Thank you!"
        else
            showDialog "Liar!"

これは、AIのコーディングや、実行時に微調整するのに役立つその他の単純なものにも適しています。デバッグで(またはイースターエッグとして)実行中に起動できるエディターをアプリケーションに追加することもできます。


1
ロジックを追加できるので、これはストレートXMLよりも好みです。ただし、テキスト自体はおそらくコードではなくXMLである必要があります。(編集、他の言語へのローカライズなど)。
イアン

ローカライズ/簡単な編集が必要な場合、Qtのtr(QString)関数/マクロのような別のファイルに囲まれたテキストを書き込む関数でテキストをラップできます。pepper.troll.no/s60prereleases/doc/linguist-hellotr.html
ネイラー

ここでロジックをシミュレートするためにxmlの属性または追加のタグを使用するのをやめるべきですか?
lathomas64

16

ゲームStendhalでは、有限状態マシンを使用してNPCを実装します。

次の図は、クエストチュートリアルの書き方の小さな例を示しています。

状態がIDLE、ATTENDING、およびQUEST_OFFEREDのFSM

最初は、NPCはアイドル状態にあり、歩き回っている可能性があります。プレイヤーは「こんにちは」と言って会話を始めることができ、NPCは参加中の状態になります。この状態では、彼の「ジョブ」に関する質問に答え、ゲームの「ヘルプ」を提供します。プレイヤーがクエストを要求すると、NPCはプレイヤーがクエストを受け入れる(「はい」)または拒否する(「いいえ」)のを待つ状態QUEST_OFFEREDになります。

遷移に付加できる一連の条件を定義しました。たとえば、クエストを完了することは、PlayerHasItemWithHimConditionが満たされた場合にのみ可能です。

トランジションが実行された後、NPCはテキストを言ったり、アクションを実行したりできます。条件と同様に、プレイヤーにクエスト報酬を与えるために使用されるEquipItemActionのような再利用可能なアクションのセットを定義しました。

AndConditionOrCondition、およびNotConditionを使用して、複数の条件を組み合わせることができます。通常、クエストの完了時に実行されるアクションが多数あるため、MultipleActionsクラスもあります。

Stendhalでの実際の実装は、他の(人間の)言語で簡単に翻訳できないことに苦しんでいますが、一般的な概念は良いと思います。



5

翻訳を追加する場合、上記のロジックに引き続きXMLを使用できます。そのような複雑さを経験する場合、独自の対話ツールを作成する必要があります。対話テキストは、表示する言語に応じて交換できるデータベースのキーとして保存されます。

たとえば、次のことができます。

<dialogue id="101" condition="!npc.carsFixed">
  <message>Localize.FixMyCar</message>
  <choices>
    <choice condition="hero.carFixingSkill > 5" priority="7" id="Localize.Sure">
      <command>hero.carFixingSkills += 1</command>
      <command>npc.carFixed = true</command>
      <command>hero.playSmokeAnimation()</command>
      <command>nextDialogue = 104</command>
    </choice>
    <choice condition="hero.carFixingSkill <= 5" id="Localize.CantFix">
      <command>nextDialogue = 105</command>
    </choice>
    <choice id="Localize.FixYourself">
      <command>npc.likesHero -= 1</command>
    </choice>
  </choices>
</dialogue>

次に、クエストテキストレンダラーで「Localize.FixMyCar」を適切に翻訳されたテキストに置き換えます。

ツールは、プレーヤーが編集可能な生のXMLとともに選択可能な言語で表示するものを表示します。

同様に、参照したから次のようなものを使用できます。

npc.add(ConversationStates.ATTENDING,
        ConversationPhrases.QUEST_MESSAGES, 
        null,
        ConversationStates.QUEST_OFFERED, 
        Localization[ "BringMeABeer" ],
        null);

キーが十分に説明的である場合、完全なテキストを持たなくても問題になりません。

このようなものも同様に便利です:

Localization[ "<Location>.<NPC_name>.<Dialogue_text_key>" ];

4

データは、LUAスクリプトまたはXMLファイルでキャラクターを駆動します。NPCを操作するときは、NPCに添付されているファイルを取得して読み込み、トリガーされた可能性のあるゲーム変数を調整し、有効な応答を生成します。

この方法で行うことの最大の利点は、ダイアログに簡単に移動して操作したり、新しい文字を追加したりできることです。また、各ケースを処理する特別なロジックでコードベースを台無しにすることも避けます。


1
LUAではなくLuaです。:)
RCIX

2
君のためだけにやったんだ ;)
デビッドマグロウ

4

XMLを使用する場合は、XMLファイルを編集するための小さなツールを作成してください。さもなければ、あなたは夢中になります。


編集するツールがまだない場合は、そもそもそれを使用しても意味がありません。独自の形式を作成することもできます。
o0 '。

3

かなり深いダイアログツリーのセットがある場合は、ChatMapperを使用します。完全に機能する無料バージョンがあり、このツールを使用すると、ダイアログツリーをXMLにエクスポートできます。私はこれを使用してきましたが、複雑なダイアログツリーを視覚化して整理するための優れた方法です。


1

ダイアログが複雑な場合、ダイアログの実装に必要な最も重要なことは、対話の複雑さを理解する方法です。これを視覚化するために、何らかの種類のノードエディタをお勧めしますが、推奨する優れたオープンシステムはありません。


1

これらのタイプのゲームを指示するために独自のスクリプト言語を使用すると思います(そうでない場合は、そうする必要があります)。次に、ダイアログ処理用にスクリプトを拡張します。
ダイアログロジックの作成中に他のゲーム変数を操作できます。ゲームエンジンはレゴのようなものです。レンガのみをプログラミングし、スクリプトはそれらを使用します。スクリプトインタプリタまたはコンパイラを作成するかどうかは関係ありません。ただし、スクリプトは常に便利です。


0

単純なオートマトンは次のことを行います。

(dialogueline_id, condition) -> (next_id, response)

次のようになります。

(1, troll is hungry?) -> (2, say "troll be hungry")
(2, player has bananas?) -> (3, say "hey, you have bananas!")
(3, ) -> (-1, (say "i like bananas, i take them and eat, you may pass, bye", remove bananas, feed the troll))
(2, player does not have bananas?) -> (-1, say "go away!!!")

ゲームでは、IDを見つけ、IDと条件を一致させようとします。

条件とアクションをモデル化する必要があります。オブジェクト、関数ポインター、XML ...

優れたダイアログエディターも便利です。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.