Search Unity

Feedback How/where to store dialogues for RPG-like interactions

Discussion in 'Scripting' started by A_Box, Feb 21, 2022.

  1. A_Box

    A_Box

    Joined:
    Feb 3, 2020
    Posts:
    62
    Hi all,
    I finished the dialogue window for my game, and now i have to figure out where and how to store all the text that the NPCs will use.

    Considering that i'd like to have lots of dialogues for different combinations of: talking NPC, your relationship with them, time of day, current events - and so on...

    Do you have any advice on what type of file should i use, and how to differentiate and find the multiple kinds of dialogues? Do you think XML files are a valid option?

    Thanks for you time
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,745
    No.

    So lets say you have a problem you need to solve.

    You decide to use XML.

    Now you have two problems.

    Congratulations.

    It's 2022. Nobody should use XML unless you absolutely must. It's the worst of all possible worlds, especially in Unity world.

    Leverage the incredible power of the Unity editor and use something like ScriptableObjects.

    If you absolutely must fiddle with a text file, then consider JSON, but do not under any circumstances consider XML.
     
    A_Box likes this.
  3. Lethn

    Lethn

    Joined:
    May 18, 2015
    Posts:
    1,583
    When it comes to things like factions, choices in games or anything of that nature believe it or not I've taken my cues from Fallout 2. In that game it seems as though they've made heavy use of integers going from the save game editor and it works brilliantly. This will also make for easy saving and loading of information and you can just have your scenes change based on the integers.

    Let's say you've got some game world with a faction system in it and your player can join, simply make a PlayerFactionInteger and keep track of that.

    Code (CSharp):
    1. public bool doesPlayerBelongToFaction;
    2. public int playerFactionInteger = 0;
    3.  
    4. if ( playerFactionInteger == 0; )
    5.  
    6. {
    7.       doesPlayerBelongToFaction = false;
    8. }
    This is the sort of thing that I've done with keeping track of what villages the player has captured in my game and it works perfectly and is quick and easy to access. You then have the more complicated code running off what these integers are doing.
     
    A_Box likes this.
  4. A_Box

    A_Box

    Joined:
    Feb 3, 2020
    Posts:
    62
    @Kurt-Dekker Thanks for the tip! I had no idea XML files where so bad. I was fidgeting with RimWorld and i saw that it saves on XMLs, and thought they were pretty nice considering that they are very user-readable and easy to manually edit...
    Are they bad because they are inefficient? Or because they are a mess to work with? Or both?
     
  5. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,745
    User-readable?! Easy to manually edit?!!!!!?!

    Screen Shot 2022-02-21 at 8.31.47 AM.png

    (I know, I know, the above is not pretty-printed, but still... barf-o-rama with all the tag hell!)

    If you think XML is readable and editable, wait until you hear about JSON!

    Seriously though, just use ScriptableObjects. That is readable AND editable, directly in the Unity editor, and you can click and follow references all around your project.

    Problems with Unity "tiny lite" built-in JSON:

    In general I highly suggest staying away from Unity's JSON "tiny lite" package. It's really not very capable at all and will silently fail on very common data structures, such as Dictionaries and Hashes and ALL properties.

    Instead grab Newtonsoft JSON .NET off the asset store for free, or else install it from the Unity Package Manager (Window -> Package Manager).

    https://assetstore.unity.com/packages/tools/input-management/json-net-for-unity-11347

    Also, always be sure to leverage sites like:

    https://jsonlint.com
    https://json2csharp.com
    https://csharp2json.io
     
    A_Box likes this.
  6. A_Box

    A_Box

    Joined:
    Feb 3, 2020
    Posts:
    62
    @Kurt-Dekker Thx for the useful links. A quick question:
    if i have this on my JSON:
    {
    "NPCs" : [
    {
    "Name" : "Mark",
    "Age" : 30,
    "Dialogue" : [
    {
    "Happy": [
    "I'm Mark, and I'm happy",
    "I'm Mark, and this is a good day"
    ],
    },
    {
    "Sad": [
    "I'm Mark, and I'm sad",
    "I'm Mark, and this is a bad day"
    ]
    }
    ]
    },
    {
    "Name" : "Gio",
    "Age" : 28,
    "Dialogue" : [
    {
    "Happy": [
    "I'm Gio, and I'm happy",
    "I'm Gio, and this is a good day"
    ],
    },
    {
    "Sad": [
    "I'm Gio, and I'm sad",
    "I'm Gio, and this is a bad day"
    ]
    }
    ]
    }
    ]
    }

    But i only need Mark's first happy dialogue, do i have to do
    Code (CSharp):
    1. Root root = JsonUtility.FromJson<Employees>(jsonFile.text);
    and then navigate inside the saved object "root" to what i need, or is there a method to directly search for what i want inside the file, without saving it all on the temporary "root" variable?

    Code (CSharp):
    1.     public class Dialogue
    2.     {
    3.         public List<string> Happy { get; set; }
    4.         public List<string> Sad { get; set; }
    5.     }
    6.  
    7.     public class NPC
    8.     {
    9.         public string Name { get; set; }
    10.         public int Age { get; set; }
    11.         public List<Dialogue> Dialogue { get; set; }
    12.     }
    13.  
    14.     public class Root
    15.     {
    16.         public List<NPC> NPCs { get; set; }
    17.     }
     
  7. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,745
    You can parse stuff incrementally with NewtonSoft, which may be necessary if you have a single honkin' big JSON file. See the Parse API within there... you basically pick each piece apart until you find what you want.

    Personally I dislike writing parse code like that because it rapidly becomes a maintenance nightmare.

    I would sooner break it into multiple JSON files than go digging through the JSON.

    I would also use ScriptableObjects unless there really was a compelling reason to go JSON.
     
    A_Box likes this.
  8. A_Box

    A_Box

    Joined:
    Feb 3, 2020
    Posts:
    62
    Ok, thanks for the feedback!
     
  9. calbond

    calbond

    Joined:
    Nov 8, 2022
    Posts:
    1
    I am super new to Unity and this was very helpful. I had the same issue- was looking for how to store NPC text and states- and this was the first I had heard about using Scriptable Objects. Looks like exactly what will help me. I also found a great tutorial here: