1
\$\begingroup\$

I am developing a RPG game for Android using LibGDX, at this moment the NPCs in the game have some moving AI (pathfinding), like random directions and stuff. Now I am working on the dialogue system, for that I have the following:

  • DialogueManager class that just renders the current dialogue on the screen if any
  • A Dialogue class which consists of an ArrayList of Strings which are the lines of the dialogue
  • The NPC class holds a Dialogue object, so I can just add(text) to the dialogue.

The result of this is the following

  1. The player is near a NPC and presses Action key
  2. A window is opened showing the current line of the dialogue
  3. When the players touches the screen, the line is replaced by the next one until there is no more lines left and the dialogue window closes and the player can move again
  4. If the player talks to the same NPC, the same dialogue lines are presented

It works fine, but that is not what I really want. I need to make the dialogue to be different depending on some conditions the player has. My dialogues are stored in an XML file:

<npc>
    <name>Alice</name>
    <interaction>
        <dialogue>
            <line>Hello there!</line>
            <line>This is a simple dialogue</line>
        </dialogue>
    </interaction>
</npc>

But I want to have something like this (and I have it in the XML):

<npc>
    <name>Alice</name>
    <interaction>
        <dialogue condition="timesTalked" value="0">
            <line>Hello there!</line>
            <line>You are talking to me the first time!</line>
        </dialogue>
        <dialogue condition="timesTalked" value="1">
            <line>Hmmm...I remember you! Have we met before?</line>
        </dialogue>
        <dialogue condition="haveItem" value="Apple">
            <line>Is that an apple? Gimme!</line>
        </dialogue>
    </interaction>
</npc>

So for example "timesTalked" is a real variable name and "value" is the condition, so the first condition would say

if(timesTalked == 0)
   // do stuff

Now the problem, how can I implement that? I know how to parse the XML, but how can I make it so the conditions work? I don't want to have it all hardcoded in Java, also I dont want to use a scripting language, I think it is good to have XML because is lightweight and easy to use. Thankyou!

\$\endgroup\$
0
\$\begingroup\$

You would need to have some sort of map structure with all scriptable variables in it. That way your XML scripts could access the variables in a less-hardcoded way. Here's a basic example in pseudo code of a potential solution:

class Condition<T>
{
    String Name;
    T Value;

    String dialogLine;

    bool Check(Map<String, T> variables)
    {
        if (variables.keyExists(Name))
        {
            return variables[Name] == Value;
        }

        return false;
    }
}

Basically, you would create a class like this for each condition in your script flow. When you want to display a certain dialogue line, you would check the condition attached to that line and see if it returns true. All your variables that are script accessible should be stored in some sort of global map structure, which might be a little tricky (mainly because of the different object types, but there are some shortcuts to take here, such as limiting the conditions to few predefined variable types), but should be doable. Each time you change a variable, you would want to notify the global variable dictionary.

Edit: Now, the condition also stores the dialog line, which you could then display if Check() returns true.

class ScriptVariableManager
{
    static Map<String, int> IntValues;
    static Map<String, String> StringValues;

    static void IntValueChanged(String name, Int value)
    {
        IntValues[name] = value;
    }
}

This class of course doesn't have to be static, but for the sake of an example here it's easier to consider it a static class. So, when you are incrementing your timesTalked variable, you would also notify the variable manager that value has changed with ScriptVariableManager.IntValueChanged("timesTalked", timesTalked);

The condition checking code would then check the correct Map based on the type of the condition value.

This solution requires some hardcoding (the variable names, and letting the manager know their values), but all in all it's a lot cleaner than hardcoded if-statements. This approach is also a lot more extendable due to it's object oriented architecture. You could even allow nested conditional statements and logical operators.

\$\endgroup\$
  • \$\begingroup\$ Thanks for the detailed answer, basically I can stick with the "value" on the conditions being reduced to only integer values, like referring to an item by its ID, also I guess in Java it would be easier to have a global map of variables. But how would I make this classes to work? Should I attach one to the NPC or just having it static like that? \$\endgroup\$ – NickyP Jul 30 '16 at 14:38
  • \$\begingroup\$ So are you asking me where the conditions should be stored? Or where the variable manager should be held? \$\endgroup\$ – Tyyppi_77 Jul 30 '16 at 14:40
  • \$\begingroup\$ Yes, both of them, how would I have them in my code? \$\endgroup\$ – NickyP Jul 30 '16 at 14:43
  • \$\begingroup\$ That depends on the scope of the variables you want to have access to. If all variables are owned by an NPC (which I don't think will be the case), the NPC could store the variables. If all variables are contained by the World class and all entities can access that, put the variable storage to the World class. As for the conditions, you want to integrate those into your current system where you display a line of dialogue. \$\endgroup\$ – Tyyppi_77 Jul 30 '16 at 14:49
  • \$\begingroup\$ Thankyou! I got the conditions working now, I have set an array of conditions in the NPC class and iterate through them when the player initiates dialogue. Now my question is how can I make the actions on the XML happen according to that conditions? if before I was doing dialogue.addLine("Text here") how can I grab the dialogue from the XML now? \$\endgroup\$ – NickyP Jul 30 '16 at 15:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.