views:

619

answers:

4

I've always been interested in the data structures involved in an RPG (Role-Playing Game). In particular, I'm curious about dialogue and events based actions.

For example: If I approach an NPC at point x in the game, with items y and quests z, how would I work out what the NPC needs to say? Branching dialogue and responding to player input seems as trivial as having a defined script, and user input causes the script reader to jump to a particular line in the script, which has a corresponding set of response lines (much like a choose your own adventure)

However, tying in logic to work out if the player has certain items, and completed certain quests seems to really ruin this script based model.

I'm looking for ideas (not necessarily programming language examples) of how to approach all of this dialogue and logic, and separate it out so that it's very easy to add new branching content, without delving into too much code.

This is really an open question. I don't believe there's a single solution, but it'd be good to get the ball rolling with some ideas. As more of a designer than a programmer, I'm always interested in ways to separate content and code.

+1  A: 

I'd venture to say that most modern games (be they RPGs, action games, anything above basic card/board games) generally consist of several components: The display engine, the core data structures, and typically a secondary scripting engine. One example which was popular for a time (and may still be; I haven't even spoken to a game developer in years) was LUA.

The decision-making you're talking about (events, conversation branches, etc) is typically handled by the secondary scripting engine, as the scripting languages are more flexible and typically easier to use for the game's designers. Again, most of the real story-driven or game-driving logic will actually happen here, where it can be swapped out and changed relatively easily. (At least, compared to running a full build of all the code!)

The primary game engine combines the data structures related to the world (geometry, etc), the data structures related to the player(s) and other actor(s) needed, and the scripts to drive the encounters, and uses all of that to display the final, integrated environment.

John Rudy
This looks like the way to go, so a scripting engine and an engine to handle all of the decision making. Any idea how these might fit together?
mac_55
Not being a pro in that world, I really don't have much else to go on. I'd recommend hitting the bookshelves -- there are actually books on CRPG design and development available; they should take you through the core architecture. Good luck!
John Rudy
+1  A: 

You can certainly use a scripting language to handle dialogue. Basically a script might look like this:

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

This is fine for most games. The scripting language can be simple and you can write more complicated logical branches. Your engine will have some representation of the world that is exposed to the scripting language. In this example, this means the name of the hero and the items in the inventory, but you could expose anything you like. You also define functions that could be called by scripts to do things like show a message or play some sound effect. You need to keep track of some global data that is shared between scripts, such as whether a door is open or a quest is done (perhaps as part of the map and quest classes).

In some games however, scripting could get tedious, especially if the dialogue is more dynamic and depends on many conditions (say, character mood and stats, npc knowledge, weather, items, etc.) Here it is possible to store your dialogue tree in some format that allows easily specifying preconditions and outcomes. I don't know if this is the way to do it, but I've once asked a question about storing game logic in XML files. I've found this approach to be effective for my game (in which dialogue is heavily dependent on many factors). In particular, in the future I could easily make a simple dialogue editor that doesn't require much scripting and allow you to simply define dialogue and branches with a graphical user interface.

Firas Assaad
This is a great and very useful comment, along with the link you posted. I've thought about doing this in XML and the example you gave seems quite logical. I guess this could also be done in json? Also, you give a great idea about having a GUI to simply define dialogue and branches
mac_55
+1  A: 

For example: If I approach an NPC at point x in the game, with items y and quests z, how would I work out what the NPC needs to say? Branching dialogue and responding to player input seems as trivial as having a defined script, and user input causes the script reader to jump to a particular line in the script, which has a corresponding set of response lines (much like a choose your own adventure)

However, tying in logic to work out if the player has certain items, and completed certain quests seems to really ruin this script based model.

Not at all. You simply factor the conditionals into the data.

Let's say you have your list of dialogues, numbered 1 to 400 or whatever like the Choose Your Own Adventure book examples. I assume each dialogue may consist of the text spoken by the NPC, followed by a list of responses available to the player.

So the next step is to add the conditionals in there, by simply attaching conditions to each response. The easiest way is to do this with a scripting language, so you have a short and simple piece of code that returns True if this response is available to the player and False if it is not.

eg. (XML format, but could be anything)

<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>

In your scripting language, you'd need a 'rats_left_in_world' function that you can call to retrieve the value in question.

What if you have no scripting language? Well, you could have the programmer code an individual condition for each situation in your dialogue - a bit tedious, not all that difficult if your dialogue is written up-front. Then just refer to a condition by name in the conversation script.

A more advanced scheme, still not requiring a scripting language, might use a tag for each condition, like so:

<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>

You can add as many conditions in there as you need, as long as they can be easily specified with one or two values. If all conditions are met, the response is available.

Kylotan
Spot the invalid XML attribute for bonus points - a good reason why XML should be done in an editor.
Kylotan
This is a good answer. I don't have enough XML foo to spot the invalid attribute. So it looks like the scripting is actually pretty easy, the parsing on the other hand...should maybe be parsed off to a decent programmer? (see what I did there?)
mac_55
Also, I was wondering how you'd keep track of which dialogue branches the player has visited or should visit next? E.g. When I go back to an NPC, how do I work out what line to say, based on whether a quest has been given out etc. Perhaps have a variable per character that stores the nextDialogue to happen on the next visit?
mac_55
With an XML parsing library reading the above into some simple structures becomes 30 minutes' work or so, easy stuff. As for choosing dialogue branches, that's really down to your game. Some games will start with the same dialogue each time. Or you could just start with the first dialogue that passes the conditions. For this to work you might need to run scripts or code after a certain dialogue has been displayed, allowing you to mark it as having been read, as well as do other stuff like hand out items or whatever.
Kylotan
@Kylotan: The invalid attribute value is "the rats_left_in_world() < 10". Is this exemplary of how you do your real-world development? Not necessarily XML and such, but structurally? Or do you let some 3rd-party or in-house scripting engine take care of this stuff?
Superstringcheese
@Superstringcheese: as far as I know there is no 3rd party engine for this sort of thing (without essentially building your game as a mod for an existing RPG), so you'd definitely write a system something like the above, maybe using the scripting language you already have embedded, and maybe with a bespoke tool to edit the data. You would want to push it out to data in some form because you would want designers to be creating and editing this data, not programmers.
Kylotan
+1  A: 

It's interesting, there's seems to be a core idea being missed here. We're having a discussion that relates to a programmer performing the task. Indeed, the code examples above are coupled to code, not content.

In game development, it's the content developers that we programmers want to empower. They will not (this is very important) look at code. Period. Now and again you get a technical artist or technical designer, and they're wonderful and don't mind it; but, the majority of content authors are not technically inclined.

I understand the question is for your own edification; but, it should be pointed out that, in industry, when we solve these types of problems our end users (the people utilizing the technology we're developing) are not engineers.

A system like this (branching dialogue) requires a representation in a tool that is relatively intuitive to use. For example, Unreal's Kismet visual scripting system could be utilized.

Essentially, the data structures (more than likely a branching tree as it's easy to represent/debug/etc.) would be crafted by a programmer, as would the nodes that represent the object in script. The system with its ability to link to world objects (more than likely also represented by nodes in visual scripting), etc. would then be crafted and the whole kitten caboodle linked together in some glorious bit of elegant code.

After all of that, a designer would actually be able to build a visual representation of the dialogue branching in the visual scripting language. This would be map-encounter specific, more than likely. Of course, you could procedurally generate these; but, that's more of a programmer desire than a designer's.

Just thought I'd add that bit of knowledge and insight.

EDIT: Noticed there's an XML example. I'm not sure what other designers/artists/etc. feel about it; but, the ones I've worked with cringe at the idea of touching a text file.

A.A. Grapsas