How to organize XML documents containing dialog trees for NPCs

Started by
5 comments, last by Splo 14 years, 10 months ago
Ok, so I am working on a Dialog Manager system for a SIMS-like game. The dialog tree (all possible dialog options) for a NPC in the game will be stored in an XML file. Each NPC will have their own separate dialog XML. When the game initially starts I need to load the dialog trees for all NPCs and store them in a vector of objects of type Dialog. So what I am not sure about is how to load all the XML files in the beginning. One option would be to store all XML files in a folder dedicated to dialogs, i.e. folder structure like so: /media /Dialogs NPC1dialog.xml NPC2dialog.xml NPC3dialog.xml ........... ........... and then just read every XML file in that folder and load the necessary dialog information. A second option is to have a file (maybe just a TXT) that contains a list of all the XMLs to be loaded and then when the game starts I read a line from that file (each line corresponds to a path to a dialog XML file), open the corresponding XML, do the necessary processing, and repeat until there are lines to be read. The file would look something like this: Dialogs.txt: NPC1dialog.xml NPC2dialog.xml NPC3dialog.xml ........... ........... which option do you think is better? Or is there are a third, even better way of reading all the dialog XMLs?
Advertisement
How about: Each NPC holds a reference to the resource containing its dialog text.

For instance:
<Npc Name="Bob">  <DialogResource>/resources/bob.dialog</DialogResource></Npc>


Now your organization doesn't matter so much, and you can write XSL transforms to move things around, if you decide to later put all of your dialogs under say /resources/dialog/.

In time the project grows, the ignorance of its devs it shows, with many a convoluted function, it plunges into deep compunction, the price of failure is high, Washu's mirth is nigh.

But in that case I would have 2 files per NPC as opposed to 1. If I have 20 NPCs in the game that's 40 files instead of 20. Isn't it better to keep the number of files low?

FYI, right now my dialog XML looks like this:

<<?xml version="1.0" ?>
<NPCid value = '1' />
<Questions>
<Question id = '[GUID]'>
<Text>Some Text</Text>
<Answer id = '[GUID]'>
<Text>Blah-blah</Text>
<Action Type = 'GoTo' id = '[GUID]' />
<Action Type = 'Set' var = "Val1" value = "10" />
</Answer>
</Question>
</Questions>

Quote:Original post by lougv22
FYI, right now my dialog XML looks like this:
<<?xml version="1.0" ?>
<NPCid value = '1' />
<Questions>
<Question id = '[GUID]'>
<Text>Some Text</Text>
<Answer id = '[GUID]'>
<Text>Blah-blah</Text>
<Action Type = 'GoTo' id = '[GUID]' />
<Action Type = 'Set' var = "Val1" value = "10" />
</Answer>
</Question>
</Questions>
Why all the ID numbers? Since you are using a textual format to start with, might as well use actual names, and save yourself a world of confusion.

Tristam MacDonald. Ex-BigTech Software Engineer. Future farmer. [https://trist.am]

Quote:Original post by lougv22
But in that case I would have 2 files per NPC as opposed to 1. If I have 20 NPCs in the game that's 40 files instead of 20. Isn't it better to keep the number of files low?

Because dialog does not necessarily have to be associated with just a single NPC, because an NPC is not just composed of dialog, and because the number of files you have can be reduced using resource compilation methods to process it down to a much more scrunched up format that is significantly faster to parse and load than XML.

As an example: Imagine you have two NPCs who are both historians, you can speak to each of them and get a history of the world. They both tell the same story, up to a point, but after that point it diverges. Do you: Duplicate that text, which can go through several reversions, several localizations, etc. or do you centralize that common text so that you have one area to go to in order to localize and make revisions.

Also, don't assume dialog will be simply questions and answers. It's probably better to view it as NPC/PC (or PC/NPC) speech turns, allowing for multiple responses from each party.

<Dialog>	<DialogStart>		So I heard you like mudkips...		<Responses id="mudkipsLoop">			<Response>				<PcSay>No</>				<Action>					<NpcSay>Are ya sure?</>					<Goto id="mudkipsLoop"/>				</>			</>			<Response>				<PcSay>Yes</>				<Action>					<RunScript value="npc-slap-pc-with-mudkip.script"/>				</>			</>		</>	</></>

In time the project grows, the ignorance of its devs it shows, with many a convoluted function, it plunges into deep compunction, the price of failure is high, Washu's mirth is nigh.

If you can get a hold of it, I'd look at how dialogue trees were implemented in the original Neverwinter Nights for inspiration. In the Aurora toolset, not only can you get more than two people involved in the dialogue, but the actor corresponding to the current node can do a wide variety of actions in addition to saying the text - move, play audio, play animation, give or take something to/from player, run a script, etc.

Another thing is, if localization is on the program, I'd move the dialogue strings out of the dialogue files completely and replace them with unique string references. There are various ways you could organize the strings, from one giant string table (this is how NWN did it for the shipped content) to one string table per dialogue file (so they are in a 1:1 mapping).
I think it would be good to distinguish between definitions and references.

You can define NPCs, questions and answers, and your NPCs hold references to questions and answers.

I would do something like that:
<?xml version="1.0"?><MyGameResources version="1.3">    <NPCs>        <NPC id="Bob">            <Question ref="q.what1">                <Answer ref="a.cook1" condition="hasSkill('cooking') && player.isHungry()">                    <Question ref="q.pancakes1">                        <Answer ref="a.pancakes.ok" action="executeSkill('cooking', 'pancakes');" />                        <Answer ref="a.pancakes.no" />                    </Question>                </Answer>                <Answer ref="a.nothing1" />            </Question>        </NPC>    </NPCs>    <Questions>        <Question id="q.what1">            <text lang="en">What can I do for you?</text>        </Question>        <Question id="q.pancakes1">            <text lang="en">Ok ... How about some pancakes?</text>        </Question>    </Questions>    <Answers>        <Answer id="a.cook1">            <text lang="en">Cook me something good!</text>        </Answer>        <Answer id="a.nothing1">            <text lang="en">Nothing ... your're useless.</text>        </Answer>        <Answer id="a.pancakes.ok">            <text lang="en">Sounds great! Thank you.</text>        </Answer>        <Answer id="a.pancakes.no">            <text lang="en">I hate pancakes. Go to hell.</text>        </Answer>    </Answers></MyGameResources>

There you have your dialog tree an you can easily re-use questions or answers.
You can also localize your game:
<MyGameResources version="1.3">    <Answers>        <Answer id="a.cook1">            <text lang="fr">Cuisine-moi quelquechose de bon !</text>        </Answer>    </Answers></MyGameResources>

I put a possible way to include scripts but of course it highly depends on your game.

To answer to your question, I think it would be tedious to maintain many text files that refer to your XML dialog files.
I would probably define which directories hold my game resources, list all XML files inside and load them, taking care of things like current locale (load only the questions and answers that have a lang attribute equal to currently selected locale).

This topic is closed to new replies.

Advertisement