Xml Dialog Tree For C++

Started by
7 comments, last by LorenzoGatti 7 years, 8 months ago

So I am using TinyXML to parse to C++ and I have a dialog XML document. What is the best way to get a dialog tree going that lets you traverse to the next dialog sequence?

I have this so far but not sure how well it will work:


<?xml version="1.0" encoding="UTF-8"?>
<dialog id='1'>
  <message name="Boss" text="Testing the dialog system!"></message>
  <response condition="True" nextDialogue='2'>
    response text
  </response>
  <response condition="False" nextDialogue='3'>
    response text
  </response>
</dialog>
<dialog id='2'>
  <message name="Boss" text="Testing the dialog system!"></message>
  <response condition="True" nextDialogue='4'>
    response text
  </response>
  <response condition="False" nextDialogue='5'>
    response text
  </response>
</dialog>
Advertisement

Beware the naive approach of one object per DOM item. The memory requirements quickly balloon into enormity.

Consider an existing library as discussed here.

Is XML really a good DSL for dialog trees?

Seems like it'd be rather obtuse and inflexible, but I haven't ever used it for that task.

Beware the naive approach of one object per DOM item. The memory requirements quickly balloon into enormity.

Consider an existing library as discussed here.

People seem to be recommending TinyXML in there which is what I am currently using.

Is XML really a good DSL for dialog trees?

Seems like it'd be rather obtuse and inflexible, but I haven't ever used it for that task.

I am not sure, I have seen a few dialogs done in XML however, it isnt very common, I see more LUA stuff with dialog which could be a second option

Is XML really a good DSL for dialog trees?

Seems like it'd be rather obtuse and inflexible, but I haven't ever used it for that task.

A good DSL it is not, but the format is almost entirely irrelevant once you build a tool (e.g. a few hours with HTML and JavaScript) for an editor. :p

Sean Middleditch – Game Systems Engineer – Join my team!

My main issue I am having right now is figuring out how to do tree traversal stuff with my XML, eg. nextDialogue='2' should send me to <dialog id='2'>

any ideas on this?

From my experience... hell no. It turned into a mess.

Is XML really a good DSL for dialog trees?

Seems like it'd be rather obtuse and inflexible, but I haven't ever used it for that task.

Really a JSON that describes a directed graph would be much better than an XML.

My main issue I am having right now is figuring out how to do tree traversal stuff with my XML, eg. nextDialogue='2' should send me to <dialog id='2'>

any ideas on this?

From what I learned the hardway, XML works great for binary stuff... such as defining a tree where things can long go down in branches, but can never have a subtree that holds another a subset from another subtree. Otherwise, the data and parsing requirements just grows into something incredibly absurd.

Truth of the matter is that Dialogue is rarely ever binary. Or follows a tree. It's more like a bundle of spaghetti noodles were there's plenty of complexities, more than a true or false choice, multiple different paths, and logic to test.

If you're absolutely required to use an XML file, I strongly suggest reading the XML once, and build a data-structure from it. You won't have a tree in the XML, you'll just have a set of definitions.


<?xml version="1.0" encoding="UTF-8"?>
<dialog id='1'>
  <message name="Boss" text="Testing the dialog system!"></message>
  <Selection = '1' nextDialogue='2'>
     < text > This is selection one, it takes you to dialgon 2 </text>
  </selection>
  <Selection = '2' nextDialogue='3'>
     < text > this is selection two, this takes you to dialogue 3 </text>
   </section>
  <selection = '3' nextDialogue='4'>
     < text > this is selection three, it takes you to dialogue 4 </text>
  <selection>
</dialog>

By building a local copy of a directed graph, it should be trivial to traverse through your selection of dialogues. This directed graph is then treated like a state machine. When an option is selected, you're pushed to the next state. Depending on how the graph was connected, you may or may not be able to return to the previous state. This is a pretty standard practice for dialogues.

A notice at the beginning: Also my opinion is that XML is fine as intermediary file-format, useable in automated processing, and for small enough problems.

AFAIK the sample in the OP is not a well-formed XML document as it lacks a root element. Let's say it looks more like this:


<?xml version="1.0" encoding="UTF-8"?>
<dialogtree>
  <dialog id='1'>
    <message name="Boss" text="Testing the dialog system!"></message>
    <response condition="True" nextDialogue='2'>
      response text
    </response>
    <response condition="False" nextDialogue='3'>
      response text
    </response>
  </dialog>
  <dialog id='2'>
    <message name="Boss" text="Testing the dialog system!"></message>
    <response condition="True" nextDialogue='4'>
      response text
    </response>
    <response condition="False" nextDialogue='5'>
      response text
    </response>
  </dialog>
</dialogtree>

Looking into the DOM the standard way is done by using XPath. There is TinyXPath, not exactly an active project, but the features you need are not challenging, so good chances are it will work fine for you. Then looking for the <dialog> with id=2 would then use an expression like

/dialogtree/dialog[@id='2']

if the level of the dialog element is known, or perhaps

//dialog[@id='2']

if not. However, on success it returns the addressed node.
Of course, XPath is sufficiently complex in itself. Iterating the DOM "manually" using TinyXML's build-in TiXmlVisitor class is possible, too. Your specialized class instance then decides on a node-by-node basis whether the currently visited node is the wanted one, and remembers the once found node. This is, AFAIS, the way of doing things as is intended by TinyXML itself.

Not related to browsing DOM, but nevertheless worth mentioning: whitespace handling. In a declaration like this (notice the indentation just made to let XML look user friendly)


    <response condition="False" nextDialogue='3'>
      response text
    </response>

is the text you want to display with whitespace like in this string (also notice the line break, please)

" response text

"

or without leading and trailing whitespace like in this string

"response text"

The distinction between wanted and unwanted leading and trailing whitespace is not really possible here. A better approach would be to make all text() within respective nodes be wanted text, so that the given example would probably look e.g. so:

    <response condition="False" nextDialogue='3'>response text</response>

My main issue I am having right now is figuring out how to do tree traversal stuff with my XML, eg. nextDialogue='2' should send me to <dialog id='2'>

any ideas on this?

"Tree traversal" related to the XML document structure when you need to follow dialogue links? Don't do it! Before you use your dialogue graph you should have left behind its artificially tree-structured XML representation, which is just an utilitarian file format that has no place beyond asset loading.

As a reasonably simple data structure for a read-only dialogue graph I'd suggest a std::vector of fairly complex Dialog objects corresponding to the "dialog" elements ("Exchange" would be a better name), that refer to their successors using indices into the vector; it would be easy to load from the XML files because the numbers in the "nextDialogue" attributes could be used immediately, without converting them to pointers in a separate pass.

Omae Wa Mou Shindeiru

This topic is closed to new replies.

Advertisement