views:

897

answers:

5

I'm dealing with game dialogue files (conversation between player and non-playable-characters) where dialogue choices and their outcome depend on certain conditions and result in certain actions. Now, I could write a simple parser to handle some sort of language for specifying the pre and post-conditions, but a friend of mine suggested using XML. Conditions could be stored as attributes of a dialogue element and choices and actions are inner elements. I'd then use an eval function to parse these conditions and statements (I'm using Ruby to make this game). To make such an approach simpler, I could then write a simple GUI to manipulate these files without worrying about ugly XML.

But it strikes me as an odd choice to handle logic in XML files. My understanding is that XML files are for the storage and exchange of data, and I always read rants about how people overuse XML for all sorts of things it wasn't designed for. My friends responds by noting how XML IS used for everything, including XHTML and this bullet description language (which also illustrates some logic).

To be honest, using XML would simplify a lot of things for me. Writing a parser can be painful and time consuming, and my requirements are generally simple. But is it really okay or would I regret such a choice later?

For people interested in details, here's what a basic dialogue exchange might look like in an XML file:

<dialogue id="101" condition="!npc.carsFixed">
  <message>Man, fix my car!</message>
  <choices>
    <choice condition="hero.carFixingSkill > 5" priority="7" id="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="I can't...">
      <command>nextDialogue = 105</command>
    </choice>
    <choice id="Fix it yourself">
      <command>npc.likesHero -= 1</command>
    </choice>
  </choices>
</dialogue>

The corresponding code if written in Ruby would be:

def dialogue101
  if !npc.carsFixed
    showMessage("Man, fix my car!")
    choices = []
    if hero.carFixingSkill > 5
      choices.push(Choice.new("Sure!", 7)) 
    else
      choices.push(Choice.new("I can't"))
    end
    choices.push(Choice.new("Fix it yourself"))
    choices = selectTopPriority(choices) if choices.size > 4
    result = showChoices(choices)
    case result
    when "Sure"
      hero.carFixingSkills += 1
      npc.carFixed = true
      hero.playSmokeAnimation
      dialogue104
    when "I can't"
      dialogue105
    when "Fix it yourself"
      npc.likesHero -= 1
    end
  end
end

Stuff like likesHero and carFixingSkills are knowledge pieces player and NPCs can have, which would probably be stored in a hash in the real implementation. I find the dialogue file approach more flexible because I could make an editor to easily edit dialogue and conditions/actions, and because of the complex nature of game conversation trees. A scripting language like Ruby or Lua helps, but it'll require complex structures to handle to logic of such trees.

Back to the original question, is XML the right tool for the job or am I missing something?

+1  A: 

A DSL would be a Mercedes-Benz implementation for this and would be fun to write in Ruby. You are right, it would take a lot of work but it might pay off if it was well written and this game really took off.

One thing to consider if going the XML route is the parser/engine you will be using to render it. Last I checked, REXML was the only show in town for Rubyists. If you like REXML then XML sounds like a good way to go, but if you have not tried it I would suggest doing that before making this decision. I am not picking on REXML, just advising a little caution since you will be completely dependent on this library, whatever you use.

Andrew Cowenhoven
I use REXML in this project, it's good enough for my needs. libxml (http://libxml.rubyforge.org/) is a more efficient alternative that I might consider.
Firas Assaad
+1  A: 

Because you're writing this in Ruby I think that doing it in XML should be sufficient. That way you could make a web application that allows you to work on the dialogue and game logic from anywhere. And other people can collaborate with you, or possibly create user mods - which is always a plus.

As long as you keep your XML files well organized (flowcharts on paper will help) you shouldn't run into any issues, and might even thank yourself for going through the pain of parsing it :)

Jelani Harris
+1  A: 

To get inspiration, or maybe even adoption, take a look at AIML and BuddyScript. AIML is XML for chatbots, BuddyScript is another variant - now owned by Microsoft.

The following is a sample of AIML from http://www.alicebot.org/aiml.html

<category>
<pattern>WHAT ARE YOU</pattern>
<template>
    <think><set name="topic">Me</set></think> 
    I am the latest result in artificial intelligence,
    which can reproduce the capabilities of the human brain
    with greater speed and accuracy.
</template>

If you were to integrate AIML technology (which I think is free) into your game, your NPC's would have AI that your players could talk to. Wouldn't that be interesting?

AIML is modular so all your NPCs could have a common file describing all the standard knowledge about their world. Then you could add specific files for the stuff that would be typic to each race, class, place, individual or task. There are plenty of interesting sample AIML files, for example Eliza.

Situational information, can be added at the start of a conversation, and you may have some software outside the AIML engine listening for "magic" words from the NPC indicating that the NPC wants something to happen in the "real" game world. like "***GIVE PLAYER 20 BUFFALO WINGS".

Guge
After looking into AIML, I think it's a pretty cool idea, though probably an overkill for my game. I'm not a fan of shared knowledge (Oblivion), and customization is per individual so it'd take too much work with such a system.
Firas Assaad
+3  A: 

If you haven't heard of YAML, have a look at it. It's like XML, but XML isn't really made to be written by hand--it's a machine-machine interface that happens to be human-readable (so you are really supposed to create an editor for it). YAML is a human-machine interface, much more writable.

I wouldn't bother with a DSL, YAML maps perfectly.

Bill K
I've used YAML, and I agree with you about readability. I already use XML for other data files and I plan on making a simple dialogue editor to read and edit xml dialogue anyway, so I don't think it'd be a problem.
Firas Assaad
+1  A: 

Unless your game will have less than half a dozen unique dialogs, you should definitely put this information in some kind of data file. XML is a strong contender for the format. I don't speak Ruby, so it may not work in this case, but another option would be to define the dialog as data directly in Ruby code. (I know this would work pretty well in Lua, Python, and Javascript... I assume defining nested data structures is also easy in Ruby.)

We used XML files to define all the static data in Pirates of the Burning Sea, and it was a great way to go. Having a data format like this lets non-programmers control the data and frees up the programmers to work on features instead of data entry. Having those data files be text means that you can keep them under source control so you can tell when they change.

Joe Ludwig
Good point about source control, I haven't thought of that.
Firas Assaad