web-dev-qa-db-ja.com

RPGダイアログエンジン/構造

私は常にRPG(ロールプレイングゲーム)に関連するデータ構造に興味を持っていました。特に、対話やイベントベースのアクションに興味があります。

例:ゲーム内のポイントxでNPCに近づくと、アイテムyとクエストz =、NPCが言う必要があることをどのように理解しますか?ダイアログを分岐してプレーヤーの入力に応答することは、スクリプトを定義するのと同じくらい簡単に思えます。ユーザー入力により、スクリプトリーダーはにジャンプします。スクリプト内の特定の行。対応する一連の応答行があります(独自の冒険を選択するのと同じように)

ただし、プレーヤーが特定のアイテムを持っていて、特定のクエストを完了したかどうかを判断するためにロジックを結び付けると、このスクリプトベースのモデルが実際に台無しになるようです。

このダイアログとロジックのすべてにアプローチする方法のアイデア(必ずしもプログラミング言語の例ではありません)を探しており、コードをあまり掘り下げることなく、新しい分岐コンテンツを非常に簡単に追加できるように分離しています。

これは本当に未解決の質問です。単一の解決策があるとは思いませんが、いくつかのアイデアでボールを転がすのは良いことです。私はプログラマーというよりデザイナーとして、コンテンツとコードを分離する方法に常に興味を持っています。

20
mac_55

例:ゲームのポイントxでアイテムyとクエストzを使用してNPCに近づくと、NPCに必要なものをどのように計算しますか?対話の分岐とプレイヤー入力への応答は、スクリプトが定義されているのと同じくらい簡単に思えます。ユーザー入力により、スクリプトリーダーは、対応する一連の応答行があるスクリプト内の特定の行にジャンプします(自分で選択するのと同じです)。冒険)

ただし、プレーヤーが特定のアイテムを持っていて、特定のクエストを完了したかどうかを判断するためにロジックを結び付けると、このスクリプトベースのモデルが実際に台無しになるようです。

どういたしまして。条件をデータに組み込むだけです。

1から400までの番号が付けられた、または「きみならどうする?」の本の例のようなダイアログのリストがあるとします。各ダイアログは、NPCによって話されたテキストと、それに続くプレイヤーが利用できる応答のリストで構成されていると思います。

したがって、次のステップは、各応答に条件を添付するだけで、そこに条件を追加することです。最も簡単な方法は、スクリプト言語を使用してこれを行うことです。そのため、この応答がプレーヤーに利用できる場合はTrueを返し、利用できない場合はFalseを返す短くて単純なコードがあります。

例えば。 (XML形式ですが、何でもかまいません)

<dialogue id='1'>
  <text>
    Couldst thou venture forth and kill me 10 rats, perchance?
  </text>
  <response condition="True" nextDialogue='2'>
    Verily! Naught could be better than slaying thy verminous foes. Ten ratty
    carcasses shall I bring unto thee.
  </text>
  <response condition="rats_left_in_world() < 10" nextDialogue='3'>
    Nay, brother! Had thou but ten rats remaining, my sword would be thine,
    but tis not to be.
  </response>
</dialogue>

スクリプト言語では、問題の値を取得するために呼び出すことができる「rats_left_in_world」関数が必要です。

スクリプト言語がない場合はどうなりますか?さて、あなたはプログラマーにあなたの会話の各状況のために個々の条件をコーディングさせることができます-あなたの会話が前もって書かれているなら、少し退屈ですが、それほど難しいことではありません。次に、会話スクリプトで条件を名前で参照します。

スクリプト言語を必要としない、より高度なスキームでは、次のように各条件にタグを使用できます。

<response>
  <condition type='min_level' value='50'/>
  Sadly squire, my time is too valuable for the likes of thee. Get thyself a
  farm hand or stable boy to do thy bidding!
</response>

1つまたは2つの値で簡単に指定できる限り、必要な数の条件をそこに追加できます。すべての条件が満たされている場合、応答が利用可能です。

19
Kylotan

おもしろいですが、ここでは核となるアイデアが見落とされているようです。タスクを実行するプログラマーに関連する議論があります。実際、上記のコード例は、コンテンツではなくコードに結合されています。

ゲーム開発において、私たちプログラマーが力を与えたいのはコンテンツ開発者です。彼らは(これは非常に重要ですが)コードを見ません。限目。テクニカルアーティストやテクニカルデザイナーを何度も迎えますが、彼らは素晴らしく、気にしません。しかし、コンテンツ作成者の大多数は技術的に傾いていません。

私は質問があなた自身の啓蒙のためであることを理解しています。しかし、業界では、この種の問題を解決するとき、エンドユーザー(私たちが開発している技術を利用している人々)はエンジニアではないことを指摘しておく必要があります。

このようなシステム(分岐ダイアログ)では、比較的直感的に使用できるツールでの表現が必要です。たとえば、UnrealのKismetビジュアルスクリプトシステムを利用できます。

基本的に、データ構造(表現/デバッグなどが簡単な分岐ツリー)は、スクリプトでオブジェクトを表すノードと同様に、プログラマーによって作成されます。次に、ワールドオブジェクト(おそらくビジュアルスクリプトのノードによっても表される)などにリンクする機能を備えたシステムが作成され、子猫のcaboodle全体がいくつかの素晴らしいエレガントなコードでリンクされます。

その後、設計者は実際に、ビジュアルスクリプト言語で分岐するダイアログの視覚的表現を構築できるようになります。これは、おそらくマップエンカウンター固有のものです。もちろん、これらを手続き的に生成することもできます。しかし、それはデザイナーよりもプログラマーの欲求です。

ちょっとした知識と洞察を加えたいと思っただけです。

編集:XMLの例があることに気づきました。他のデザイナー/アーティストなどが何なのかわかりません。それについて感じます。しかし、私が一緒に仕事をしたものは、テキストファイルに触れるというアイデアに夢中になっています。

6
A.A. Grapsas

最近のほとんどのゲーム(RPG、アクションゲーム、基本的なカード/ボードゲーム以外のもの)は、一般に、表示エンジン、コアデータ構造、通常はセカンダリスクリプトエンジンなど、いくつかのコンポーネントで構成されています。しばらくの間人気があった1つの例(そして今でもそうかもしれません;私は何年もゲーム開発者と話をしていません)はLuaでした。

スクリプト言語はより柔軟で、ゲームの設計者にとって通常使いやすいため、話している意思決定(イベント、会話ブランチなど)は通常、セカンダリスクリプトエンジンによって処理されます。繰り返しになりますが、実際のストーリー駆動型またはゲーム駆動型のロジックのほとんどは実際にここで発生し、交換して比較的簡単に変更できます。 (少なくとも、すべてのコードのフルビルドを実行する場合と比較して!)

プライマリゲームエンジンは、世界に関連するデータ構造(ジオメトリなど)、必要なプレーヤーと他のアクターに関連するデータ構造、およびエンカウンターを駆動するスクリプトを組み合わせ、それらすべてを使用して最終的な統合環境を表示します。

5
John Rudy

確かに、スクリプト言語を使用して会話を処理できます。基本的に、スクリプトは次のようになります。

ShowMessage("Hello " + hero.name + ", how can I help you?")
choices = { "Open the door for me", "Tell me about yourself", "Nevermind" }
chosen = ShowChoices(choices)
if chosen == 0
    if hero.inventory["gold key"] > 0
        ShowMessage("You have the key! I'll open the door for you!")
        isGateOpen = true
    else
        ShowMessage("I'm sorry, but you need the gold key")
    end if
else if chosen == 1
    if isGateOpen
        ShowMessage("I'm the gate keeper, and the gate is open")
    else
        ShowMessage("I'm the gate keeper and you need gold key to pass")
    end if
else
    ShowMessage("Okay, tell me if you need anything")
end if

これはほとんどのゲームで問題ありません。スクリプト言語は単純で、より複雑な論理ブランチを作成できます。エンジンには、スクリプト言語に公開されている世界の表現が含まれます。この例では、これはヒーローの名前とインベントリ内のアイテムを意味しますが、好きなものを公開できます。また、メッセージの表示や効果音の再生などを行うためにスクリプトから呼び出すことができる関数を定義します。ドアが開いているか、クエストが実行されているかなど、スクリプト間で共有されているグローバルデータを追跡する必要があります(おそらくマップクラスとクエストクラスの一部として)。

ただし、一部のゲームでは、特にダイアログがより動的で、多くの条件(たとえば、キャラクターの気分と統計、NPCの知識、天気、アイテムなど)に依存する場合、スクリプトが面倒になる可能性があります。ここで、ダイアログツリーをに保存できます。前提条件と結果を簡単に指定できる形式。これがその方法かどうかはわかりませんが、私はかつて ゲームロジックをXMLファイルに保存することについての質問 を尋ねました。このアプローチは私のゲームに効果的であることがわかりました(会話は多くの要因に大きく依存しています)。特に、将来的には、スクリプトをあまり必要とせず、グラフィカルユーザーインターフェイスを使用してダイアログとブランチを簡単に定義できる、シンプルなダイアログエディターを簡単に作成できるようになりました。

4
Firas Assaad

それは素晴らしい質問です。私はクライアントのためにそれを数回解決しなければなりませんでした。最初はあなたと非常によく似たXML構造から始めましたが、現在はJSONを使用しています。ここで例を見ることができます: http://www.branchtrack.com/projects/on029pq6.json または https://dl.dropboxusercontent.com/u/11433463/branchtrack/ on029pq6.json (読みやすくするためにプリティファイします)。

完全な開示:上記のリンクは、ダイアログを分岐するためのオンラインエディターであるBranchTrackで生成され、私はCEOです。何でもお気軽にお問い合わせください。

2
Sergey Snegirev

私は最近、このために何かを開発する必要があり、非常に基本的なテキストファイル構造を選択しました。結果のコードとテキスト形式は、次の場所で確認できます。

https://github.com/scottbw/dialoguejs

スクリプトの洗練度とプログラマー以外の編集のしやすさの間にはトレードオフがあります。

私はダイアログの非常にシンプルなソリューションを選択し、関連するゲームイベントのトリガーをセカンダリスクリプト言語で個別に処理します。

最終的には、セカンダリスクリプトエンジンでイベントをトリガーするために使用されるテキストダイアログ形式に「ステージの指示」を追加する方法を追加する可能性がありますが、ダイアログファイル自体にコードのようなものを入れる必要はありません。

2
Scott Wilson

最近、 Chat Mapper を作成しながら、このような問題に取り組みました。私がやっていることは、ダイアログをツリー内のノードとしてグラフィカルにプロットすることです。その後、各ノードには条件とそれに関連付けられたスクリプトがあります。ツリーをトラバースしてノードにヒットすると、条件をチェックしてそのノードが有効かどうかを確認し、有効である場合は、そのノードに関連付けられたスクリプトを実行します。これはかなり単純なアイデアですが、テストからはうまく機能しているようです。スクリプトには.NETLuaインタープリターを使用しています。

1
Ben McIntosh

私のソリューションでは、ノードごとに7行のテキストで構成されるカスタムテキストファイル形式を開発しました。各行は、ストライドリストまたは単なるテキスト行にすることができます。各ノードには位置番号があります。番号の最後の桁はタイプであるため、新しい質問、確認、以前の結果に基づくアクションの繰り返しなど、10種類のノードがあります。

各ダイアログのアクティブ化は、データストアへの選択クエリから始まります。データストアの結果は、適切なノードと照合するために、ストライドリストのメンバーと比較できます。これはif/thenよりも残酷ですが、ストライドセパレータ以外の構文が必要ないため、テキスト設定ファイルが小さくなります。ワイルドカードのシステムを使用して、選択したクエリ結果をNPCの音声に挿入できるようにします。

最後に、簡単な構成ファイルでは不十分な場合に備えて、カスタムスクリプトがインターフェイスできるようにするAPIフックがあります。 nodejsでWebアプリのGUIを作成して、構成ファイルを視覚的にスクリプト化できるようにする予定です:D

1
CommaToast